patch-2.3.41 linux/drivers/net/tokenring/smctr.c
Next file: linux/drivers/net/tokenring/smctr.h
Previous file: linux/drivers/net/tokenring/madgemc.h
Back to the patch index
Back to the overall index
- Lines: 378
- Date:
Fri Jan 28 08:04:58 2000
- Orig file:
v2.3.40/linux/drivers/net/tokenring/smctr.c
- Orig date:
Fri Jan 7 19:13:22 2000
diff -u --recursive --new-file v2.3.40/linux/drivers/net/tokenring/smctr.c linux/drivers/net/tokenring/smctr.c
@@ -17,11 +17,10 @@
* JS Jay Schulist <jschlst@turbolinux.com>
*
* To do:
- * 1. MCA SMC TokenCard Support. (Some support is already done).
- * 4. Multicast support.
+ * 1. Multicast support.
*/
-static const char *version = "smctr.c: v1.0 1/1/00 by jschlst@turbolinux.com\n";
+static const char *version = "smctr.c: v1.1 1/1/00 by jschlst@turbolinux.com\n";
static const char *cardname = "smctr";
#ifdef MODULE
@@ -29,6 +28,7 @@
#include <linux/version.h>
#endif
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
@@ -48,6 +48,7 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/mca.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -66,6 +67,10 @@
0
};
+#ifdef CONFIG_MCA
+static unsigned int smctr_posid = 0x6ec6;
+#endif
+
static int ringspeed = 0;
/* SMC Name of the Adapter. */
@@ -91,6 +96,7 @@
/* C */
static int smctr_checksum_firmware(struct net_device *dev);
+static int __init smctr_chk_isa(struct net_device *dev);
static int smctr_chg_rx_mask(struct net_device *dev);
static int smctr_clear_int(struct net_device *dev);
static int smctr_clear_trc_reset(int ioaddr);
@@ -109,11 +115,8 @@
static int smctr_enable_adapter_ram(struct net_device *dev);
static int smctr_enable_bic_int(struct net_device *dev);
-/* F */
-static int __init smctr_find_adapter(struct net_device *dev);
-
/* G */
-static int __init smctr_get_boardid(struct net_device *dev);
+static int __init smctr_get_boardid(struct net_device *dev, int mca);
static int smctr_get_group_address(struct net_device *dev);
static int smctr_get_functional_address(struct net_device *dev);
static unsigned int smctr_get_num_rx_bdbs(struct net_device *dev);
@@ -478,13 +481,171 @@
return (0);
}
+static int smctr_chk_mca(struct net_device *dev)
+{
+#ifdef CONFIG_MCA
+ struct net_local *tp = (struct net_local *)dev->priv;
+ int current_slot;
+ __u8 r1, r2, r3, r4, r5;
+
+ current_slot = mca_find_unused_adapter(smctr_posid, 0);
+ if(current_slot == MCA_NOTFOUND)
+ return (-ENODEV);
+
+ mca_set_adapter_name(current_slot, smctr_name);
+ mca_mark_as_used(current_slot);
+ tp->slot_num = current_slot;
+
+ r1 = mca_read_stored_pos(tp->slot_num, 2);
+ r2 = mca_read_stored_pos(tp->slot_num, 3);
+
+ if(tp->slot_num)
+ outb(CNFG_POS_CONTROL_REG, (__u8)((tp->slot_num - 1) | CNFG_SLOT_ENABLE_BIT));
+ else
+ outb(CNFG_POS_CONTROL_REG, (__u8)((tp->slot_num) | CNFG_SLOT_ENABLE_BIT));
+
+ r1 = inb(CNFG_POS_REG1);
+ r2 = inb(CNFG_POS_REG0);
+
+ tp->bic_type = BIC_594_CHIP;
+
+ /* IO */
+ r2 = mca_read_stored_pos(tp->slot_num, 2);
+ r2 &= 0xF0;
+ dev->base_addr = ((__u16)r2 << 8) + (__u16)0x800;
+ request_region(dev->base_addr, SMCTR_IO_EXTENT, smctr_name);
+
+ /* IRQ */
+ r5 = mca_read_stored_pos(tp->slot_num, 5);
+ r5 &= 0xC;
+ switch(r5)
+ {
+ case 0:
+ dev->irq = 3;
+ break;
+
+ case 0x4:
+ dev->irq = 4;
+ break;
+
+ case 0x8:
+ dev->irq = 10;
+ break;
+
+ default:
+ dev->irq = 15;
+ break;
+ }
+ if(request_irq(dev->irq, smctr_interrupt, SA_SHIRQ, smctr_name, dev))
+ return (-ENODEV);
+
+ /* Get RAM base */
+ r3 = mca_read_stored_pos(tp->slot_num, 3);
+ if(r3 & 0x8)
+ {
+ if(r3 & 0x80)
+ tp->ram_base = ((__u32)(r3 & 0x7) << 13) + 0xFD0000;
+ else
+ tp->ram_base = ((__u32)(r3 & 0x7) << 13) + 0x0D0000;
+ }
+ else
+ {
+ if(r3 & 0x80)
+ tp->ram_base = ((__u32)(r3 & 0x7) << 13) + 0xFC0000;
+ else
+ tp->ram_base = ((__u32)(r3 & 0x7) << 13) + 0x0C0000;
+ }
+
+ /* Get Ram Size */
+ r3 &= 0x30;
+ r3 >>= 4;
+
+ tp->ram_usable = (__u16)CNFG_SIZE_8KB << r3;
+ tp->ram_size = (__u16)CNFG_SIZE_64KB;
+ tp->board_id |= TOKEN_MEDIA;
+
+ r4 = mca_read_stored_pos(tp->slot_num, 4);
+ if(r4 & 0x8)
+ tp->rom_base = ((__u32)(r4 & 0x7) << 13) + 0xD0000;
+ else
+ tp->rom_base = ((__u32)(r4 & 0x7) << 13) + 0xC0000;
+
+ /* Get ROM size. */
+ r4 >>= 4;
+ if(r4 == 0)
+ tp->rom_size = CNFG_SIZE_8KB;
+ else
+ {
+ if(r4 == 1)
+ tp->rom_size = CNFG_SIZE_16KB;
+ else
+ {
+ if(r4 == 2)
+ tp->rom_size = CNFG_SIZE_32KB;
+ else
+ tp->rom_size = ROM_DISABLE;
+ }
+ }
+
+ /* Get Media Type. */
+ r5 = mca_read_stored_pos(tp->slot_num, 5);
+ r5 &= CNFG_MEDIA_TYPE_MASK;
+ switch(r5)
+ {
+ case (0):
+ tp->media_type = MEDIA_STP_4;
+ break;
+
+ case (1):
+ tp->media_type = MEDIA_STP_16;
+ break;
+
+ case (3):
+ tp->media_type = MEDIA_UTP_16;
+ break;
+
+ default:
+ tp->media_type = MEDIA_UTP_4;
+ break;
+ }
+ tp->media_menu = 14;
+
+ r2 = mca_read_stored_pos(tp->slot_num, 2);
+ if(!(r2 & 0x02))
+ tp->mode_bits |= EARLY_TOKEN_REL;
+
+ /* Disable slot */
+ outb(CNFG_POS_CONTROL_REG, 0);
+
+ tp->board_id = smctr_get_boardid(dev, 1);
+ switch(tp->board_id & 0xffff)
+ {
+ case WD8115TA:
+ smctr_model = "8115T/A";
+ break;
+
+ case WD8115T:
+ smctr_model = "8115T";
+ break;
+
+ default:
+ smctr_model = "Unknown";
+ break;
+ }
+
+ return (0);
+#else
+ return (-1);
+#endif /* CONFIG_MCA */
+}
+
static int smctr_chg_rx_mask(struct net_device *dev)
{
struct net_local *tp = (struct net_local *)dev->priv;
int err = 0;
if(smctr_debug > 10)
- printk("%s: smctr_chg_rx_mask\n", dev->name);
+ printk("%s: smctr_chg_rx_mask\n", dev->name);
smctr_enable_16bit(dev);
smctr_set_page(dev, (__u8 *)tp->ram_access);
@@ -804,7 +965,7 @@
return (0);
}
-static int __init smctr_find_adapter(struct net_device *dev)
+static int __init smctr_chk_isa(struct net_device *dev)
{
struct net_local *tp = (struct net_local *)dev->priv;
int ioaddr = dev->base_addr;
@@ -813,7 +974,10 @@
int i;
if(smctr_debug > 10)
- printk("%s: smctr_find_adapter %#4x\n", dev->name, ioaddr);
+ printk("%s: smctr_chk_isa %#4x\n", dev->name, ioaddr);
+
+ if((ioaddr & 0x1F) != 0)
+ return (-ENODEV);
/* Checksum SMC node address */
for(i = 0; i < 8; i++)
@@ -823,7 +987,7 @@
}
if(chksum != NODE_ADDR_CKSUM)
- return (-1); /* Adapter Not Found */
+ return (-ENODEV); /* Adapter Not Found */
/* Grab the region so that no one else tries to probe our ioports. */
request_region(ioaddr, SMCTR_IO_EXTENT, smctr_name);
@@ -843,7 +1007,7 @@
return (-1);
/* Get adapter ID */
- tp->board_id = smctr_get_boardid(dev);
+ tp->board_id = smctr_get_boardid(dev, 0);
switch(tp->board_id & 0xffff)
{
case WD8115TA:
@@ -1011,7 +1175,7 @@
return (0);
}
-static int __init smctr_get_boardid(struct net_device *dev)
+static int __init smctr_get_boardid(struct net_device *dev, int mca)
{
struct net_local *tp = (struct net_local *)dev->priv;
int ioaddr = dev->base_addr;
@@ -1020,22 +1184,35 @@
tp->board_id = BoardIdMask = 0;
- BoardIdMask |= (INTERFACE_CHIP+TOKEN_MEDIA+PAGED_RAM+BOARD_16BIT);
- tp->extra_info |= (INTERFACE_584_CHIP + RAM_SIZE_64K
- + NIC_825_BIT + ALTERNATE_IRQ_BIT);
-
- r = inb(ioaddr + BID_REG_1);
- r &= 0x0c;
- outb(r, ioaddr + BID_REG_1);
- r = inb(ioaddr + BID_REG_1);
+ if(mca)
+ {
+ BoardIdMask |= (MICROCHANNEL+INTERFACE_CHIP+TOKEN_MEDIA+PAGED_RAM+BOARD_16BIT);
+ tp->extra_info |= (INTERFACE_594_CHIP+RAM_SIZE_64K+NIC_825_BIT+ALTERNATE_IRQ_BIT+SLOT_16BIT);
+ }
+ else
+ {
+ BoardIdMask|=(INTERFACE_CHIP+TOKEN_MEDIA+PAGED_RAM+BOARD_16BIT);
+ tp->extra_info |= (INTERFACE_584_CHIP + RAM_SIZE_64K
+ + NIC_825_BIT + ALTERNATE_IRQ_BIT);
+ }
- if(r & BID_SIXTEEN_BIT_BIT)
- {
- tp->extra_info |= SLOT_16BIT;
- tp->adapter_bus = BUS_ISA16_TYPE;
- }
- else
- tp->adapter_bus = BUS_ISA8_TYPE;
+ if(!mca)
+ {
+ r = inb(ioaddr + BID_REG_1);
+ r &= 0x0c;
+ outb(r, ioaddr + BID_REG_1);
+ r = inb(ioaddr + BID_REG_1);
+
+ if(r & BID_SIXTEEN_BIT_BIT)
+ {
+ tp->extra_info |= SLOT_16BIT;
+ tp->adapter_bus = BUS_ISA16_TYPE;
+ }
+ else
+ tp->adapter_bus = BUS_ISA8_TYPE;
+ }
+ else
+ tp->adapter_bus = BUS_MCA_TYPE;
/* Get Board Id Byte */
IdByte = inb(ioaddr + BID_BOARD_ID_BYTE);
@@ -3536,10 +3713,6 @@
return (-ENOMEM);
#endif
- /* See if we have a SMCTR card floating around. */
- if((ioaddr & 0x1F) != 0)
- return (-ENODEV); /* No Adapter */
-
/* Setup this devices private information structure */
tp = (struct net_local *)kmalloc(sizeof(struct net_local),
GFP_KERNEL);
@@ -3549,11 +3722,16 @@
dev->priv = tp;
dev->base_addr = ioaddr;
- err = smctr_find_adapter(dev);
+ /* Actually detect an adapter now. */
+ err = smctr_chk_isa(dev);
if(err < 0)
{
- kfree_s(tp, sizeof(struct net_local));
- return (-ENODEV);
+ err = smctr_chk_mca(dev);
+ if(err < 0)
+ {
+ kfree_s(tp, sizeof(struct net_local));
+ return (-ENODEV);
+ }
}
tp = (struct net_local *)dev->priv;
@@ -5696,6 +5874,12 @@
{
if(dev_smctr[i])
{
+#ifdef CONFIG_MCA
+ struct net_local *tp
+ = (struct net_local *)dev_smctr[i]->priv;
+ if(tp->slot_num)
+ mca_mark_as_unused(tp->slot_num);
+#endif
unregister_trdev(dev_smctr[i]);
release_region(dev_smctr[i]->base_addr,
SMCTR_IO_EXTENT);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)