patch-2.3.41 linux/drivers/net/tokenring/tms380tr.c

Next file: linux/drivers/net/tokenring/tms380tr.h
Previous file: linux/drivers/net/tokenring/smctr.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.40/linux/drivers/net/tokenring/tms380tr.c linux/drivers/net/tokenring/tms380tr.c
@@ -1,5 +1,5 @@
 /*
- *  tms380tr.c: A network driver for Texas Instruments TMS380-based
+ *  tms380tr.c: A network driver library for Texas Instruments TMS380-based
  *              Token Ring Adapters.
  *
  *  Originally sktr.c: Written 1997 by Christoph Goos
@@ -10,14 +10,16 @@
  *  This software may be used and distributed according to the terms
  *  of the GNU Public License, incorporated herein by reference.
  *
- *  This device driver works with the following TMS380 adapters:
+ *  The following modules are currently available for card support:
+ *	- tmspci (Generic PCI card support)
+ *	- abyss (Madge PCI support)
+ *  
+ *  The following cards are currently lacking support, even
+ *  though they were supported in previous versions, because
+ *  their code did not get migrated into a seperate module:
  *	- SysKonnect TR4/16(+) ISA	(SK-4190)
- *	- SysKonnect TR4/16(+) PCI	(SK-4590)
- *	- SysKonnect TR4/16 PCI		(SK-4591)
- *      - Compaq TR 4/16 PCI
- *      - Thomas-Conrad TC4048 4/16 PCI
- *      - 3Com 3C339 Token Link Velocity
- *      - Any ISA or PCI adapter using only the TMS380 chipset
+ *  They are no longer supported by this driver, at least until
+ *  a module gets written for them.
  *
  *  Sources:
  *  	- The hardware related parts of this driver are take from
@@ -27,14 +29,16 @@
  *  	- Also various other drivers in the linux source tree were taken
  *  	  as samples for some tasks.
  *      - TI TMS380 Second-Generation Token Ring User's Guide
- *      - TI datasheets for respective chips
- *	- David Hein at Texas Instruments 
+ *  	- TI datasheets for respective chips
+ *  	- David Hein at Texas Instruments 
+ *  	- Various Madge employees
  *
  *  Maintainer(s):
  *    JS	Jay Schulist		jschlst@turbolinux.com
  *    CG	Christoph Goos		cgoos@syskonnect.de
  *    AF	Adam Fritzler		mid@auk.cx
- *
+ *    MLP       Mike Phillips           phillim@amtrak.com
+ *     
  *  Modification History:
  *	29-Aug-97	CG	Created
  *	04-Apr-98	CG	Fixed problems caused by tok_timer_check
@@ -42,22 +46,33 @@
  *	27-May-98	JS	Formated to Linux Kernel Format
  *	31-May-98	JS	Hacked in PCI support
  *	16-Jun-98	JS	Modulized for multiple cards with one driver
- *         Sep-99	AF      Renamed to tms380tr (supports more than SK's)
+ *	   Sep-99	AF	Renamed to tms380tr (supports more than SK's)
  *      23-Sep-99	AF      Added Compaq and Thomas-Conrad PCI support
  *				Fixed a bug causing double copies on PCI
  *				Fixed for new multicast stuff (2.2/2.3)
  *	25-Sep-99	AF	Uped TPL_NUM from 3 to 9
  *				Removed extraneous 'No free TPL'
+ *	22-Dec-99	AF	Added Madge PCI Mk2 support and generalized
+ *				parts of the initilization procedure.
+ *	30-Dec-99	AF	Turned tms380tr into a library ala 8390.
+ *				Madge support is provided in the abyss module
+ *				Generic PCI support is in the tmspci module.
  *
  *  To do:
- *    1. Selectable 16 Mbps or 4Mbps
- *    2. Multi/Broadcast packet handling (this may have fixed itself)
- *
+ *    1. Multi/Broadcast packet handling (this may have fixed itself)
+ *    2. Write a sktrisa module that includes the old ISA support
+ *    3. Allow modules to load their own microcode
+ *    4. Speed up the BUD process -- freezing the kernel for 3+sec is
+ *         quite unacceptable.
+ *    5. Still a few remaining stalls when the cable is unplugged.
  */
 
-static const char *version = "tms380tr.c: v1.03 29/09/1999 by Christoph Goos, Adam Fritzler\n";
+#ifdef MODULE
+static const char *version = "tms380tr.c: v1.07 21/01/2000 by Christoph Goos, Adam Fritzler\n";
+#endif
 
 #ifdef MODULE
+#define EXPORT_SYMTAB
 #include <linux/module.h>
 #include <linux/version.h>
 #endif
@@ -78,6 +93,7 @@
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/irq.h>
+#include <asm/uaccess.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/pci.h>
@@ -90,45 +106,6 @@
 #include "tms380tr.h"		/* Our Stuff */
 #include "tms380tr_microcode.h"	/* TI microcode for COMMprocessor */
 
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int tms380tr_portlist[] __initdata = {
-	0x0A20, 0x1A20, 0x0B20, 0x1B20, 0x0980, 0x1980, 0x0900, 0x1900,
-	0
-};
-
-/* A zero-terminated list of IRQs to be probed. 
- * Used again after initial probe for tms380tr_chipset_init, called from tms380tr_open.
- */
-static unsigned short tms380tr_irqlist[] = {
-	3, 5, 9, 10, 11, 12, 15,
-	0
-};
-
-/* A zero-terminated list of DMAs to be probed. */
-static int tms380tr_dmalist[] __initdata = {
-	5, 6, 7,
-	0
-};
-
-/* 
- * Table used for card detection and type determination.
- */
-struct cardinfo_table  cardinfo[] = {
-  { 0, 0, 0, 
-    "Unknown TMS380 Token Ring Adapter"},
-  { TMS_ISA, 0, 0, 
-    "SK NET TR 4/16 ISA"},
-  { TMS_PCI, PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TOKENRING, 
-    "Compaq 4/16 TR PCI"},
-  { TMS_PCI, PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_TR, 
-    "SK NET TR 4/16 PCI"},
-  { TMS_PCI, PCI_VENDOR_ID_TCONRAD, PCI_DEVICE_ID_TCONRAD_TOKENRING,
-    "Thomas-Conrad TC4048 PCI 4/16"},
-  { TMS_PCI, PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C339,
-    "3Com Token Link Velocity"},
-  { 0, 0, 0, NULL}
-};
-
 /* Use 0 for production, 1 for verification, 2 for debug, and
  * 3 for very verbose debug.
  */
@@ -137,24 +114,24 @@
 #endif
 static unsigned int tms380tr_debug = TMS380TR_DEBUG;
 
-/* The number of low I/O ports used by the tokencard. */
-#define TMS380TR_IO_EXTENT 32
-
 /* Index to functions, as function prototypes.
  * Alphabetical by function name.
  */
 
+/* "A" */
 /* "B" */
 static int      tms380tr_bringup_diags(struct net_device *dev);
 /* "C" */
 static void	tms380tr_cancel_tx_queue(struct net_local* tp);
 static int 	tms380tr_chipset_init(struct net_device *dev);
 static void 	tms380tr_chk_irq(struct net_device *dev);
+#if 0
 static unsigned char tms380tr_chk_frame(struct net_device *dev, unsigned char *Addr);
+#endif
 static void 	tms380tr_chk_outstanding_cmds(struct net_device *dev);
 static void 	tms380tr_chk_src_addr(unsigned char *frame, unsigned char *hw_addr);
 static unsigned char tms380tr_chk_ssb(struct net_local *tp, unsigned short IrqType);
-static int 	tms380tr_close(struct net_device *dev);
+int	 	tms380tr_close(struct net_device *dev);
 static void 	tms380tr_cmd_status_irq(struct net_device *dev);
 /* "D" */
 static void 	tms380tr_disable_interrupts(struct net_device *dev);
@@ -176,20 +153,15 @@
 static int 	tms380tr_init_card(struct net_device *dev);
 static void 	tms380tr_init_ipb(struct net_local *tp);
 static void 	tms380tr_init_net_local(struct net_device *dev);
-static void 	tms380tr_init_opb(struct net_local *tp);
-static void 	tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static int 	tms380tr_isa_chk_card(struct net_device *dev, int ioaddr, struct cardinfo_table **outcard);
-static int      tms380tr_isa_chk_ioaddr(int ioaddr);
+static void 	tms380tr_init_opb(struct net_device *dev);
+void	 	tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+/* "M" */
 /* "O" */
-static int 	tms380tr_open(struct net_device *dev);
+int		tms380tr_open(struct net_device *dev);
 static void	tms380tr_open_adapter(struct net_device *dev);
 /* "P" */
-static int 	tms380tr_pci_chk_card(struct net_device *dev, struct cardinfo_table **outcard);
-int 		tms380tr_probe(struct net_device *dev);
-static int 	tms380tr_probe1(struct net_device *dev, int ioaddr);
 /* "R" */
 static void 	tms380tr_rcv_status_irq(struct net_device *dev);
-static void 	tms380tr_read_addr(struct net_device *dev, unsigned char *Address);
 static int 	tms380tr_read_ptr(struct net_device *dev);
 static void 	tms380tr_read_ram(struct net_device *dev, unsigned char *Data,
 			unsigned short Address, int Length);
@@ -199,6 +171,7 @@
 /* "S" */
 static int 	tms380tr_send_packet(struct sk_buff *skb, struct net_device *dev);
 static void 	tms380tr_set_multicast_list(struct net_device *dev);
+static int	tms380tr_set_mac_address(struct net_device *dev, void *addr);
 /* "T" */
 static void 	tms380tr_timer_chk(unsigned long data);
 static void 	tms380tr_timer_end_wait(unsigned long data);
@@ -207,269 +180,61 @@
 static void 	tms380tr_update_rcv_stats(struct net_local *tp,
 			unsigned char DataPtr[], unsigned int Length);
 /* "W" */
-static void 	tms380tr_wait(unsigned long time);
+void	 	tms380tr_wait(unsigned long time);
 static void 	tms380tr_write_rpl_status(RPL *rpl, unsigned int Status);
 static void 	tms380tr_write_tpl_status(TPL *tpl, unsigned int Status);
 
-/*
- * Check for a network adapter of this type, and return '0' if one exists.
- * If dev->base_addr == 0, probe all likely locations.
- * If dev->base_addr == 1, always return failure.
- */
-int __init tms380tr_probe(struct net_device *dev)
-{
-	int i;
-	int base_addr = dev ? dev->base_addr : 0;
-
-	if(base_addr > 0x1ff)    /* Check a single specified location. */
-		return (tms380tr_probe1(dev, base_addr));
-	else if(base_addr != 0)  /* Don't probe at all. */
-		return (-ENXIO);
-
-	/* 
-	 * Let's check for pci adapters first 
-	 */
-	if (tms380tr_probe1(dev,0) == 0)  /* Success */
-		return 0 ;
-
-	/*
-	 * No pci cards found, let's check for isa
-	 */
+#define SIFREADB(reg) (((struct net_local *)dev->priv)->sifreadb(dev, reg))
+#define SIFWRITEB(val, reg) (((struct net_local *)dev->priv)->sifwriteb(dev, val, reg))
+#define SIFREADW(reg) (((struct net_local *)dev->priv)->sifreadw(dev, reg))
+#define SIFWRITEW(val, reg) (((struct net_local *)dev->priv)->sifwritew(dev, val, reg))
 
-	for(i = 0; tms380tr_portlist[i]; i++)
-	{
-		int ioaddr = tms380tr_portlist[i];
-		if(check_region(ioaddr, TMS380TR_IO_EXTENT)) /* Region already used */
-			continue;
-		if(!tms380tr_probe1(dev, ioaddr))
-			return (0);
-	}
 
-	return (-ENODEV);
-}
 
-struct cardinfo_table * __init tms380tr_pci_getcardinfo(unsigned short vendor, 
-							unsigned short device)
+#if TMS380TR_DEBUG > 0
+static int madgemc_sifprobe(struct net_device *dev)
 {
-	int cur;
-	for (cur = 1; cardinfo[cur].name != NULL; cur++) {
-		if (cardinfo[cur].type == 2) /* PCI */
-		{
-			if ((cardinfo[cur].vendor_id == vendor) && (cardinfo[cur].device_id == device))
-				return &cardinfo[cur];
-		}
-	}
+        unsigned char old, chk1, chk2;
 	
-	return NULL;
-}
+	old = SIFREADB(SIFADR);  /* Get the old SIFADR value */
 
-/*
- * Detect and setup the PCI SysKonnect TR cards in slot order.
- */
-static int __init tms380tr_pci_chk_card(struct net_device *dev, 
-					struct cardinfo_table **outcard)
-{
-	struct pci_dev *pci_device = NULL ; 
-	struct cardinfo_table *card;
-	int i;
-
-	if(!pci_present())
-		return (-1);	/* No PCI present. */
- 
-	while ( (pci_device=pci_find_class(PCI_CLASS_NETWORK_TOKEN_RING<<8, pci_device))) { 
-
-		unsigned int pci_irq_line;
-		unsigned int pci_ioaddr;
-
-		/* Remove I/O space marker in bit 0. */
-		pci_irq_line = pci_device->irq ; 
-		pci_ioaddr = pci_device->resource[0].start ; 
-/*		pci_ioaddr &= ~3; */
-
-		/* Don't return from here, just continue on the card discovery loop - MLP */
-		if (!(card = tms380tr_pci_getcardinfo(pci_device->vendor, pci_device->device)))  
-			continue ; 
-
-		if(check_region(pci_ioaddr, TMS380TR_IO_EXTENT))
-			continue;
-
-		request_region(pci_ioaddr, TMS380TR_IO_EXTENT, card->name);
-		if(request_irq(pci_device->irq, tms380tr_interrupt, SA_SHIRQ,
-				card->name, dev)) { 
-			release_region(pci_ioaddr, TMS380TR_IO_EXTENT) ; 
-			return (-ENODEV); /* continue; ?? */
-		}
-		/* At this point we have found a valid tms380tr PCI TR card. */
-
-		pci_ioaddr &= ~3 ; 
-		dev->base_addr	= pci_ioaddr;
-		dev->irq 	= pci_irq_line;
-		dev->dma	= 0;
-
-		dev->addr_len = 6;
-		tms380tr_read_addr(dev, (unsigned char*)dev->dev_addr);
+        chk1 = 0;       /* Begin with check value 0 */
+        do {
+		madgemc_setregpage(dev, 0);
+                /* Write new SIFADR value */
+		SIFWRITEB(chk1, SIFADR);
+		chk2 = SIFREADB(SIFADR);
+		if (chk2 != chk1)
+			return -1;
 		
-		printk("%s: %s found at %#4x, IRQ %d, ring station ",
-		       dev->name, card->name, pci_ioaddr, dev->irq);
-		printk("%2.2x", dev->dev_addr[0]);
-		for (i = 1; i < 6; i++)
-			printk(":%2.2x", dev->dev_addr[i]);
-		printk(".\n");
-
-		if (outcard)
-			*outcard = card;
+		madgemc_setregpage(dev, 1);
+                /* Read, invert and write */
+		chk2 = SIFREADB(SIFADD);
+		if (chk2 != chk1)
+			return -1;
+
+		madgemc_setregpage(dev, 0);
+                chk2 ^= 0x0FE;
+		SIFWRITEB(chk2, SIFADR);
+
+                /* Read, invert and compare */
+		madgemc_setregpage(dev, 1);
+		chk2 = SIFREADB(SIFADD);
+		madgemc_setregpage(dev, 0);
+                chk2 ^= 0x0FE;
+
+                if(chk1 != chk2)
+                        return (-1);    /* No adapter */
+                chk1 -= 2;
+        } while(chk1 != 0);     /* Repeat 128 times (all byte values) */
+
+	madgemc_setregpage(dev, 0); /* sanity */
+        /* Restore the SIFADR value */
+	SIFWRITEB(old, SIFADR);
 
-		return 0 ; 
-	}
-
- 	return (-1); 
+        return (0);
 }
-
-/*
- * Detect and setup the ISA SysKonnect TR cards.
- */
-static int __init tms380tr_isa_chk_card(struct net_device *dev, int ioaddr,
-					struct cardinfo_table **outcard)
-{
-	int i, err;
-	unsigned long flags;
-	struct cardinfo_table *card = NULL;
-
-	err = tms380tr_isa_chk_ioaddr(ioaddr);
-	if(err < 0)
-		return (-ENODEV);
-
-	if(virt_to_bus((void*)((unsigned long)dev->priv+sizeof(struct net_local)))
-		> ISA_MAX_ADDRESS)
-	{
-		printk("%s: Memory not accessible for DMA\n", dev->name);
-		kfree(dev->priv);
-		return (-EAGAIN);
-	}
-
-	/* FIXME */
-	card = &cardinfo[1];
-
-	/* Grab the region so that no one else tries to probe our ioports. */
-	request_region(ioaddr, TMS380TR_IO_EXTENT, card->name);
-	dev->base_addr = ioaddr;
-
-	/* Autoselect IRQ and DMA if dev->irq == 0 */
-	if(dev->irq == 0)
-	{
-		for(i = 0; tms380tr_irqlist[i] != 0; i++)
-		{
-			dev->irq = tms380tr_irqlist[i];
-			err = request_irq(dev->irq, &tms380tr_interrupt, 0, card->name, dev);
-			if(!err)
-				break;
-		}
-
-		if(tms380tr_irqlist[i] == 0)
-		{
-			printk("%s: AutoSelect no IRQ available\n", dev->name);
-			return (-EAGAIN);
-		}
-	}
-	else
-	{
-		err = request_irq(dev->irq, &tms380tr_interrupt, 0, card->name, dev);
-		if(err)
-		{
-			printk("%s: Selected IRQ not available\n", dev->name);
-			return (-EAGAIN);
-		}
-	}
-
-	/* Always allocate the DMA channel after IRQ and clean up on failure */
-	if(dev->dma == 0)
-	{
-		for(i = 0; tms380tr_dmalist[i] != 0; i++)
-		{
-			dev->dma = tms380tr_dmalist[i];
-			err = request_dma(dev->dma, card->name);
-			if(!err)
-				break;
-		}
-
-		if(dev->dma == 0)
-		{
-			printk("%s: AutoSelect no DMA available\n", dev->name);
-			free_irq(dev->irq, NULL);
-			return (-EAGAIN);
-		}
-	}
-	else
-	{
-		err = request_dma(dev->dma, card->name);
-		if(err)
-		{
-			printk("%s: Selected DMA not available\n", dev->name);
-			free_irq(dev->irq, NULL);
-			return (-EAGAIN);
-		}
-	}
-
-	flags=claim_dma_lock();
-	disable_dma(dev->dma);
-	set_dma_mode(dev->dma, DMA_MODE_CASCADE);
-	enable_dma(dev->dma);
-	release_dma_lock(flags);
-
-	printk("%s: %s found at %#4x, using IRQ %d and DMA %d.\n",
-		dev->name, card->name, ioaddr, dev->irq, dev->dma);
-
-	if (outcard)
-		*outcard = card;
-
-	return (0);
-}
-
-/*
- * Passing an ioaddr of 0 tells us to do a pci card search
- */
-
-static int __init tms380tr_probe1(struct net_device *dev, int ioaddr)
-{
-	static unsigned version_printed = 0;
-	struct net_local *tp;
-	int err;
-	struct cardinfo_table *card = NULL;
-
-	if(tms380tr_debug && version_printed++ == 0)
-		printk(KERN_INFO "%s", version);
-
-#ifndef MODULE
-	dev = init_trdev(dev, 0);
-	if(dev == NULL)
-		return (-ENOMEM);
 #endif
-	if (ioaddr == 0) {
-		err = tms380tr_pci_chk_card(dev, &card);
-	} else {
-		err = tms380tr_isa_chk_card(dev, ioaddr, &card);
-	}
-	if(err < 0)
-		return (-ENODEV);
-
-	/* Setup this devices private information structure */
-	tp = (struct net_local *)kmalloc(sizeof(struct net_local), GFP_KERNEL | GFP_DMA);
-	if(tp == NULL)
-		return (-ENOMEM);
-	memset(tp, 0, sizeof(struct net_local));
-	init_waitqueue_head(&tp->wait_for_tok_int);
-	tp->CardType = card;
-	
-	dev->priv		= tp;
-	dev->init		= tms380tr_init_card;
-	dev->open		= tms380tr_open;
-	dev->stop		= tms380tr_close;
-	dev->do_ioctl		= NULL ; 
-	dev->hard_start_xmit    = tms380tr_send_packet;
-	dev->get_stats		= tms380tr_get_stats;
-	dev->set_multicast_list = &tms380tr_set_multicast_list;
-	return (0);
-}
 
 /* Dummy function */
 static int __init tms380tr_init_card(struct net_device *dev)
@@ -481,42 +246,6 @@
 }
 
 /*
- * This function tests if an adapter is really installed at the
- * given I/O address. Return negative if no adapter at IO addr.
- */
-static int __init tms380tr_isa_chk_ioaddr(int ioaddr)
-{
-	unsigned char old, chk1, chk2;
-
-	old = inb(ioaddr + SIFADR);	/* Get the old SIFADR value */
-
-	chk1 = 0;	/* Begin with check value 0 */
-	do {
-		/* Write new SIFADR value */
-		outb(chk1, ioaddr + SIFADR);
-
-		/* Read, invert and write */
-		chk2 = inb(ioaddr + SIFADD);
-		chk2 ^= 0x0FE;
-		outb(chk2, ioaddr + SIFADR);
-
-		/* Read, invert and compare */
-		chk2 = inb(ioaddr + SIFADD);
-		chk2 ^= 0x0FE;
-
-		if(chk1 != chk2)
-			return (-1);	/* No adapter */
-
-		chk1 -= 2;
-	} while(chk1 != 0);	/* Repeat 128 times (all byte values) */
-
-    	/* Restore the SIFADR value */
-	outb(old, ioaddr + SIFADR);
-
-	return (0);
-}
-
-/*
  * Open/initialize the board. This is called sometime after
  * booting when the 'ifconfig' program is run.
  *
@@ -524,14 +253,14 @@
  * registers that "should" only need to be set once at boot, so that
  * there is non-reboot way to recover if something goes wrong.
  */
-static int tms380tr_open(struct net_device *dev)
+int tms380tr_open(struct net_device *dev)
 {
 	struct net_local *tp = (struct net_local *)dev->priv;
 	int err;
 	
 	/* Reset the hardware here. Don't forget to set the station address. */
 	err = tms380tr_chipset_init(dev);
-	if(err)
+  	if(err)
 	{
 		printk(KERN_INFO "%s: Chipset initialization error\n", 
 			dev->name);
@@ -548,7 +277,6 @@
 
 	printk(KERN_INFO "%s: Adapter RAM size: %dK\n", 
 	       dev->name, tms380tr_read_ptr(dev));
-
 	tms380tr_enable_interrupts(dev);
 	tms380tr_open_adapter(dev);
 
@@ -566,8 +294,8 @@
 	/* If AdapterVirtOpenFlag is 1, the adapter is now open for use */
 	if(tp->AdapterVirtOpenFlag == 0)
 	{
-	  tms380tr_disable_interrupts(dev);
-	  return (-1);
+		tms380tr_disable_interrupts(dev);
+		return (-1);
 	}
 
 	dev->start = 1;
@@ -579,10 +307,6 @@
 	tp->timer.function	= tms380tr_timer_chk;
 	tp->timer.data		= (unsigned long)dev;
 	add_timer(&tp->timer);
-	
-#ifdef MODULE
-	MOD_INC_USE_COUNT;
-#endif
 
 	return (0);
 }
@@ -610,47 +334,20 @@
 static int tms380tr_chipset_init(struct net_device *dev)
 {
 	struct net_local *tp = (struct net_local *)dev->priv;
-	unsigned char PosReg, Tmp;
-	int i, err;
+	int err;
 
 	tms380tr_init_ipb(tp);
-	tms380tr_init_opb(tp);
+	tms380tr_init_opb(dev);
 	tms380tr_init_net_local(dev);
 
-	/* Set pos register: selects irq and dma channel.
-	 * Only for ISA bus adapters.
-	 */
-	if(dev->dma > 0)
-	{
-		PosReg = 0;
-		for(i = 0; tms380tr_irqlist[i] != 0; i++)
-		{
-			if(tms380tr_irqlist[i] == dev->irq)
-				break;
-		}
-
-		/* Choose default cycle time, 500 nsec   */
-		PosReg |= CYCLE_TIME << 2;
-		PosReg |= i << 4;
-		i = dev->dma - 5;
-		PosReg |= i;
-
-		if(tp->DataRate == SPEED_4)
-			PosReg |= LINE_SPEED_BIT;
-		else
-			PosReg &= ~LINE_SPEED_BIT;
-
-		outb(PosReg, dev->base_addr + POSREG);
-		Tmp = inb(dev->base_addr + POSREG);
-		if((Tmp & ~CYCLE_TIME) != (PosReg & ~CYCLE_TIME))
-			printk(KERN_INFO "%s: POSREG error\n", dev->name);
-	}
 	err = tms380tr_reset_adapter(dev);
 	if(err < 0)
 		return (-1);
+
 	err = tms380tr_bringup_diags(dev);
 	if(err < 0)
 		return (-1);
+
 	err = tms380tr_init_adapter(dev);
 	if(err < 0)
 		return (-1);
@@ -690,7 +387,7 @@
 
 	skb_queue_head_init(&tp->SendSkbQueue);
 	tp->QueueSkb = MAX_TX_QUEUE;
-
+	
 	/* Create circular chain of transmit lists */
 	for (i = 0; i < TPL_NUM; i++)
 	{
@@ -713,7 +410,7 @@
 		tp->Rpl[i].NextRPLAddr = htonl((unsigned long) virt_to_bus(&tp->Rpl[(i+1) % RPL_NUM]));
 		tp->Rpl[i].Status = (RX_VALID | RX_START_FRAME | RX_END_FRAME | RX_FRAME_IRQ);
 		tp->Rpl[i].FrameSize = 0;
-		tp->Rpl[i].FragList[0].DataCount = SWAPB(tp->MaxPacketSize);
+		tp->Rpl[i].FragList[0].DataCount = cpu_to_be16((unsigned short)tp->MaxPacketSize);
 
 		/* Alloc skb and point adapter to data area */
 		tp->Rpl[i].Skb = dev_alloc_skb(tp->MaxPacketSize);
@@ -731,7 +428,7 @@
 			skb_put(tp->Rpl[i].Skb, tp->MaxPacketSize);
 
 			/* data unreachable for DMA ? then use local buffer */
-			if(tp->CardType->type == TMS_ISA && virt_to_bus(tp->Rpl[i].Skb->data) + tp->MaxPacketSize > ISA_MAX_ADDRESS)
+			if(tp->dmalimit && virt_to_bus(tp->Rpl[i].Skb->data) + tp->MaxPacketSize > tp->dmalimit)
 			{
 				tp->Rpl[i].SkbStat = SKB_DATA_COPY;
 				tp->Rpl[i].FragList[0].DataAddr = htonl(virt_to_bus(tp->LocalRxBuffers[i]));
@@ -780,28 +477,37 @@
 /*
  * Initializes the open parameter block.
  */
-static void tms380tr_init_opb(struct net_local *tp)
+static void tms380tr_init_opb(struct net_device *dev)
 {
+	struct net_local *tp;
 	unsigned long Addr;
 	unsigned short RplSize    = RPL_SIZE;
 	unsigned short TplSize    = TPL_SIZE;
 	unsigned short BufferSize = BUFFER_SIZE;
+	int i;
+
+	tp = (struct net_local *)dev->priv;
 
 	tp->ocpl.OPENOptions 	 = 0;
 	tp->ocpl.OPENOptions 	|= ENABLE_FULL_DUPLEX_SELECTION;
 	tp->ocpl.FullDuplex 	 = 0;
 	tp->ocpl.FullDuplex 	|= OPEN_FULL_DUPLEX_OFF;
 
-	/* Fixme: If mac address setable:
-	 * for (i=0; i<LENGTH_OF_ADDRESS; i++)
-	 *	mac->Vam->ocpl.NodeAddr[i] = mac->CurrentAddress[i];
+        /* 
+	 * Set node address 
+	 *
+	 * We go ahead and put it in the OPB even though on
+	 * most of the generic adapters this isn't required.
+	 * Its simpler this way.  -- ASF
 	 */
+        for (i=0;i<6;i++)
+                tp->ocpl.NodeAddr[i] = ((unsigned char *)dev->dev_addr)[i];
 
 	tp->ocpl.GroupAddr	 = 0;
 	tp->ocpl.FunctAddr	 = 0;
-	tp->ocpl.RxListSize	 = SWAPB(RplSize);
-	tp->ocpl.TxListSize	 = SWAPB(TplSize);
-	tp->ocpl.BufSize	 = SWAPB(BufferSize);
+	tp->ocpl.RxListSize	 = cpu_to_be16((unsigned short)RplSize);
+	tp->ocpl.TxListSize	 = cpu_to_be16((unsigned short)TplSize);
+	tp->ocpl.BufSize	 = cpu_to_be16((unsigned short)BufferSize);
 	tp->ocpl.Reserved	 = 0;
 	tp->ocpl.TXBufMin	 = TX_BUF_MIN;
 	tp->ocpl.TXBufMax	 = TX_BUF_MAX;
@@ -836,7 +542,7 @@
  */
 static void tms380tr_disable_interrupts(struct net_device *dev)
 {
-	outb(0, dev->base_addr + SIFACL);
+	SIFWRITEB(0, SIFACL);
 
 	return;
 }
@@ -847,7 +553,7 @@
  */
 static void tms380tr_enable_interrupts(struct net_device *dev)
 {
-	outb(ACL_SINTEN, dev->base_addr + SIFACL);
+	SIFWRITEB(ACL_SINTEN, SIFACL);
 
 	return;
 }
@@ -948,8 +654,7 @@
 
 		tp->QueueSkb++;
 		/* Is buffer reachable for Busmaster-DMA? */
-		if(tp->CardType->type == TMS_ISA && virt_to_bus((void*)(((long) skb->data) + skb->len))
-			> ISA_MAX_ADDRESS)
+		if(tp->dmalimit && virt_to_bus((void*)(((long) skb->data) + skb->len)) > tp->dmalimit)
 		{
 			/* Copy frame to local buffer */
 			i 	= tp->TplFree->TPLIndex;
@@ -975,11 +680,11 @@
     
 		/* Save the skb for delayed return of skb to system */
 		tpl->Skb = skb;
-		tpl->FragList[0].DataCount = (unsigned short) SWAPB(length);
+		tpl->FragList[0].DataCount = cpu_to_be16((unsigned short)length);
 		tpl->FragList[0].DataAddr  = htonl(virt_to_bus(newbuf));
 
 		/* Write the data length in the transmit list. */
-		tpl->FrameSize 	= (unsigned short) SWAPB(length);
+		tpl->FrameSize 	= cpu_to_be16((unsigned short)length);
 		tpl->MData 	= newbuf;
 
 		/* Transmit the frame and set the status values. */
@@ -1057,48 +762,41 @@
 /*
  * The typical workload of the driver: Handle the network interface interrupts.
  */
-static void tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+void tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct net_device *dev = dev_id;
 	struct net_local *tp;
-	int ioaddr;
 	unsigned short irq_type;
 
-	if(dev == NULL)
-	{
+	if(dev == NULL) {
 		printk("%s: irq %d for unknown device.\n", dev->name, irq);
 		return;
 	}
 
 	dev->interrupt = 1;
 
-	ioaddr = dev->base_addr;
 	tp = (struct net_local *)dev->priv;
 
-	irq_type = inw(ioaddr + SIFSTS);
+	irq_type = SIFREADW(SIFSTS);
 
-	while(irq_type & STS_SYSTEM_IRQ)
-	{
+	while(irq_type & STS_SYSTEM_IRQ) {
 		irq_type &= STS_IRQ_MASK;
 
-		if(!tms380tr_chk_ssb(tp, irq_type))
-		{
+		if(!tms380tr_chk_ssb(tp, irq_type)) {
 			printk(KERN_INFO "%s: DATA LATE occurred\n", dev->name);
 			break;
 		}
 
-		switch(irq_type)
-		{
-			case STS_IRQ_RECEIVE_STATUS:
-				tms380tr_reset_interrupt(dev);
-				tms380tr_rcv_status_irq(dev);
-				break;
+		switch(irq_type) {
+		case STS_IRQ_RECEIVE_STATUS:
+			tms380tr_reset_interrupt(dev);
+			tms380tr_rcv_status_irq(dev);
+			break;
 
-			case STS_IRQ_TRANSMIT_STATUS:
-				/* Check if TRANSMIT.HALT command is complete */
-				if(tp->ssb.Parm[0] & COMMAND_COMPLETE)
-				{
-					tp->TransmitCommandActive = 0;
+		case STS_IRQ_TRANSMIT_STATUS:
+			/* Check if TRANSMIT.HALT command is complete */
+			if(tp->ssb.Parm[0] & COMMAND_COMPLETE) {
+				tp->TransmitCommandActive = 0;
 					tp->TransmitHaltScheduled = 0;
 
 					/* Issue a new transmit command. */
@@ -1109,40 +807,51 @@
 				tms380tr_tx_status_irq(dev);
 				break;
 
-			case STS_IRQ_COMMAND_STATUS:
-				/* The SSB contains status of last command
-				 * other than receive/transmit.
-				 */
-				tms380tr_cmd_status_irq(dev);
-				break;
-
-			case STS_IRQ_SCB_CLEAR:
-				/* The SCB is free for another command. */
-				tp->ScbInUse = 0;
-				tms380tr_chk_outstanding_cmds(dev);
-				break;
-
-			case STS_IRQ_RING_STATUS:
-				tms380tr_ring_status_irq(dev);
-				break;
+		case STS_IRQ_COMMAND_STATUS:
+			/* The SSB contains status of last command
+			 * other than receive/transmit.
+			 */
+			tms380tr_cmd_status_irq(dev);
+			break;
+			
+		case STS_IRQ_SCB_CLEAR:
+			/* The SCB is free for another command. */
+			tp->ScbInUse = 0;
+			tms380tr_chk_outstanding_cmds(dev);
+			break;
+			
+		case STS_IRQ_RING_STATUS:
+			tms380tr_ring_status_irq(dev);
+			break;
 
-			case STS_IRQ_ADAPTER_CHECK:
-				tms380tr_chk_irq(dev);
-				break;
+		case STS_IRQ_ADAPTER_CHECK:
+			tms380tr_chk_irq(dev);
+			break;
 
-			default:
-				printk(KERN_INFO "Unknown Token Ring IRQ\n");
-				break;
+		case STS_IRQ_LLC_STATUS:
+			printk(KERN_DEBUG "tms380tr: unexpected LLC status IRQ\n");
+			break;
+			
+		case STS_IRQ_TIMER:
+			printk(KERN_DEBUG "tms380tr: unexpected Timer IRQ\n");
+			break;
+			
+		case STS_IRQ_RECEIVE_PENDING:
+			printk(KERN_DEBUG "tms380tr: unexpected Receive Pending IRQ\n");
+			break;
+			
+		default:
+			printk(KERN_INFO "Unknown Token Ring IRQ (0x%04x)\n", irq_type);
+			break;
 		}
 
 		/* Reset system interrupt if not already done. */
 		if(irq_type != STS_IRQ_TRANSMIT_STATUS
-			&& irq_type != STS_IRQ_RECEIVE_STATUS)
-		{
+			&& irq_type != STS_IRQ_RECEIVE_STATUS) {
 			tms380tr_reset_interrupt(dev);
 		}
 
-		irq_type = inw(ioaddr + SIFSTS);
+		irq_type = SIFREADW(SIFSTS);
 	}
 
 	dev->interrupt = 0;
@@ -1436,7 +1145,7 @@
 /*
  * The inverse routine to tms380tr_open().
  */
-static int tms380tr_close(struct net_device *dev)
+int tms380tr_close(struct net_device *dev)
 {
 	struct net_local *tp = (struct net_local *)dev->priv;
 	dev->tbusy = 1;
@@ -1469,13 +1178,9 @@
 		release_dma_lock(flags);
 	}
 	
-	outw(0xFF00, dev->base_addr + SIFCMD);
-	if(dev->dma > 0)
-		outb(0xff, dev->base_addr + POSREG);
-
-#ifdef MODULE
-	MOD_DEC_USE_COUNT;
-#endif
+	SIFWRITEW(0xFF00, SIFCMD);
+	if(dev->dma > 0) /* what the? */
+		SIFWRITEB(0xff, POSREG);
 
 	tms380tr_cancel_tx_queue(tp);
 
@@ -1549,7 +1254,7 @@
 /*
  * Wait for some time (microseconds)
  */
-static void tms380tr_wait(unsigned long time)
+void tms380tr_wait(unsigned long time)
 {
 #if 0
 	long tmp;
@@ -1570,7 +1275,6 @@
  */
 static void tms380tr_exec_sifcmd(struct net_device *dev, unsigned int WriteValue)
 {
-	int ioaddr = dev->base_addr;
 	unsigned short cmd;
 	unsigned short SifStsValue;
 	unsigned long loop_counter;
@@ -1579,9 +1283,9 @@
 	cmd = (unsigned short)WriteValue;
 	loop_counter = 0,5 * 800000;
 	do {
-		SifStsValue = inw(ioaddr + SIFSTS);
+		SifStsValue = SIFREADW(SIFSTS);
 	} while((SifStsValue & CMD_INTERRUPT_ADAPTER) && loop_counter--);
-	outw(cmd, ioaddr + SIFCMD);
+	SIFWRITEW(cmd, SIFCMD);
 
 	return;
 }
@@ -1595,22 +1299,19 @@
 	struct net_local *tp = (struct net_local *)dev->priv;
 	unsigned short *fw_ptr = (unsigned short *)&tms380tr_code;
 	unsigned short count, c;
-	int ioaddr = dev->base_addr;
 
 	/* Hardware adapter reset */
-	outw(ACL_ARESET, ioaddr + SIFACL);
+	SIFWRITEW(ACL_ARESET, SIFACL);
 	tms380tr_wait(40);
 	
-	c = inw(ioaddr + SIFACL);
+	c = SIFREADW(SIFACL);
 	tms380tr_wait(20);
 
 	if(dev->dma == 0)	/* For PCI adapters */
 	{
-		c &= ~(ACL_SPEED4 | ACL_SPEED16);	/* Clear bits */
-		if(tp->DataRate == SPEED_4)
-			c |= ACL_SPEED4;		/* Set 4Mbps */
-		else
-			c |= ACL_SPEED16;		/* Set 16Mbps */
+		c &= ~(ACL_NSELOUT0 | ACL_NSELOUT1);	/* Clear bits */
+		if(tp->setnselout)
+		  c |= (*tp->setnselout)(dev);
 	}
 
 	/* In case a command is pending - forget it */
@@ -1618,18 +1319,20 @@
 
 	c &= ~ACL_ARESET;		/* Clear adapter reset bit */
 	c |=  ACL_CPHALT;		/* Halt adapter CPU, allow download */
+	c |= ACL_BOOT;
+	c |= ACL_SINTEN;
 	c &= ~ACL_PSDMAEN;		/* Clear pseudo dma bit */
-	outw(c, ioaddr + SIFACL);
+	SIFWRITEW(c, SIFACL);
 	tms380tr_wait(40);
 
 	/* Download firmware via DIO interface: */
 	do {
 		/* Download first address part */
-		outw(*fw_ptr, ioaddr + SIFADX);
+		SIFWRITEW(*fw_ptr, SIFADX);
 		fw_ptr++;
 
 		/* Download second address part */
-		outw(*fw_ptr, ioaddr + SIFADD);
+		SIFWRITEW(*fw_ptr, SIFADD);
 		fw_ptr++;
 
 		if((count = *fw_ptr) != 0)	/* Load loop counter */
@@ -1637,17 +1340,17 @@
 			fw_ptr++;	/* Download block data */
 			for(; count > 0; count--)
 			{
-				outw(*fw_ptr, ioaddr + SIFINC);
+				SIFWRITEW(*fw_ptr, SIFINC);
 				fw_ptr++;
 			}
 		}
 		else	/* Stop, if last block downloaded */
 		{
-			c = inw(ioaddr + SIFACL);
+			c = SIFREADW(SIFACL);
 			c &= (~ACL_CPHALT | ACL_SINTEN);
 
 			/* Clear CPHALT and start BUD */
-			outw(c, ioaddr + SIFACL);
+			SIFWRITEW(c, SIFACL);
 			return (1);
 		}
 	} while(count == 0);
@@ -1663,7 +1366,6 @@
 {
 	int loop_cnt, retry_cnt;
 	unsigned short Status;
-	int ioaddr = dev->base_addr;
 
 	tms380tr_wait(HALF_SECOND);
 	tms380tr_exec_sifcmd(dev, EXEC_SOFT_RESET);
@@ -1679,7 +1381,7 @@
 		do {			/* Inspect BUD results */
 			loop_cnt--;
 			tms380tr_wait(HALF_SECOND);
-			Status = inw(ioaddr + SIFSTS);
+			Status = SIFREADW(SIFSTS);
 			Status &= STS_MASK;
 
 			if(tms380tr_debug > 3)
@@ -1701,11 +1403,16 @@
 		}
 	} while(retry_cnt > 0);
 
-	Status = inw(ioaddr + SIFSTS);
-	Status &= STS_ERROR_MASK;	/* Hardware error occurred! */
-
-	printk(KERN_INFO "%s: Bring Up Diagnostics Error (%04X) occurred\n",
-		dev->name, Status);
+	Status = SIFREADW(SIFSTS);
+	
+	/* Hardware error occurred! */
+	Status &= 0x001f;
+	if (Status & 0x0010)
+		printk(KERN_INFO "%s: BUD Error: Timeout\n", dev->name);
+	else if ((Status & 0x000f) > 6)
+		printk(KERN_INFO "%s: BUD Error: Illegal Failure\n", dev->name);
+	else
+		printk(KERN_INFO "%s: Bring Up Diagnostics Error (%04X) occurred\n", dev->name, Status & 0x000f);
 
 	return (-1);
 }
@@ -1727,7 +1434,6 @@
 	unsigned char *sb_ptr = (unsigned char *) &tp->ssb;
 	unsigned short Status;
 	int i, loop_cnt, retry_cnt;
-	int ioaddr = dev->base_addr;
 
 	/* Normalize: byte order low/high, word order high/low! (only IPB!) */
 	tp->ipb.SCB_Addr = SWAPW(virt_to_bus(&tp->scb));
@@ -1740,14 +1446,14 @@
 		retry_cnt--;
 
 		/* Transfer initialization block */
-		outw(0x0001, ioaddr + SIFADX);
+		SIFWRITEW(0x0001, SIFADX);
 
 		/* To address 0001:0A00 of adapter RAM */
-		outw(0x0A00, ioaddr + SIFADD);
+		SIFWRITEW(0x0A00, SIFADD);
 
 		/* Write 11 words to adapter RAM */
 		for(i = 0; i < 11; i++)
-			outw(ipb_ptr[i], ioaddr + SIFINC);
+			SIFWRITEW(ipb_ptr[i], SIFINC);
 
 		/* Execute SCB adapter command */
 		tms380tr_exec_sifcmd(dev, CMD_EXECUTE);
@@ -1761,7 +1467,7 @@
 			tms380tr_wait(HALF_SECOND);
 
 			/* Mask interesting status bits */
-			Status = inw(ioaddr + SIFSTS);
+			Status = SIFREADW(SIFSTS);
 			Status &= STS_MASK;
 		} while(((Status &(STS_INITIALIZE | STS_ERROR | STS_TEST)) != 0)
 			&& ((Status & STS_ERROR) == 0) && (loop_cnt != 0));
@@ -1792,7 +1498,7 @@
 			if((Status & STS_ERROR) != 0)
 			{
 				/* Initialization error occurred */
-				Status = inw(ioaddr + SIFSTS);
+				Status = SIFREADW(SIFSTS);
 				Status &= STS_ERROR_MASK;
 				/* ShowInitialisationErrorCode(Status); */
 				return (-1); /* Unrecoverable error */
@@ -1820,7 +1526,6 @@
 {
 	struct net_local *tp = (struct net_local *)dev->priv;
 	unsigned long Addr = 0;
-	unsigned char i = 0;
 
 	if(tp->CMDqueue == 0)
 		return;		/* No command execution */
@@ -1839,14 +1544,6 @@
 			/* Execute OPEN command	*/
 			tp->CMDqueue ^= OC_OPEN;
 
-			/* Copy the 18 bytes of the product ID */
-			while((tp->CardType->name[i] != '\0') 
-			      && (i < PROD_ID_SIZE))
-			{
-				tp->ProductID[i] = tp->CardType->name[i];
-				i++;
-			}
-
 			Addr = htonl(virt_to_bus(&tp->ocpl));
 			tp->scb.Parm[0] = LOWORD(Addr);
 			tp->scb.Parm[1] = HIWORD(Addr);
@@ -2001,7 +1698,7 @@
 {
 	struct net_local *tp = (struct net_local *)dev->priv;
 
-	tp->CurrentRingStatus = SWAPB(tp->ssb.Parm[0]);
+	tp->CurrentRingStatus = be16_to_cpu((unsigned short)tp->ssb.Parm[0]);
 
 	/* First: fill up statistics */
 	if(tp->ssb.Parm[0] & SIGNAL_LOSS)
@@ -2071,19 +1768,18 @@
 {
 	int i;
 	unsigned short AdapterCheckBlock[4];
-	unsigned short ioaddr = dev->base_addr;
 	struct net_local *tp = (struct net_local *)dev->priv;
 
 	tp->AdapterOpenFlag = 0;	/* Adapter closed now */
 
 	/* Page number of adapter memory */
-	outw(0x0001, ioaddr + SIFADX);
+	SIFWRITEW(0x0001, SIFADX);
 	/* Address offset */
-	outw(CHECKADDR, ioaddr + SIFADR);
+	SIFWRITEW(CHECKADDR, SIFADR);
 
 	/* Reading 8 byte adapter check block. */
 	for(i = 0; i < 4; i++)
-		AdapterCheckBlock[i] = inw(ioaddr + SIFINC);
+		AdapterCheckBlock[i] = SIFREADW(SIFINC);
 
 	if(tms380tr_debug > 3)
 	{
@@ -2234,8 +1930,8 @@
 	tms380tr_read_ram(dev, (unsigned char *)&tp->intptrs.BurnedInAddrPtr,
 			ADAPTER_INT_PTRS, 16);
 	tms380tr_read_ram(dev, (unsigned char *)&adapterram,
-			(unsigned short)SWAPB(tp->intptrs.AdapterRAMPtr), 2);
-	return SWAPB(adapterram); 
+			cpu_to_be16((unsigned short)tp->intptrs.AdapterRAMPtr), 2);
+	return be16_to_cpu(adapterram); 
 }
 
 /*
@@ -2246,22 +1942,21 @@
 {
 	int i;
 	unsigned short old_sifadx, old_sifadr, InWord;
-	unsigned short ioaddr = dev->base_addr;
 
 	/* Save the current values */
-	old_sifadx = inw(ioaddr + SIFADX);
-	old_sifadr = inw(ioaddr + SIFADR);
+	old_sifadx = SIFREADW(SIFADX);
+	old_sifadr = SIFREADW(SIFADR);
 
 	/* Page number of adapter memory */
-	outw(0x0001, ioaddr + SIFADX);
+	SIFWRITEW(0x0001, SIFADX);
 	/* Address offset in adapter RAM */
-	outw(Address, ioaddr + SIFADR);
+        SIFWRITEW(Address, SIFADR);
 
 	/* Copy len byte from adapter memory to system data area. */
 	i = 0;
 	for(;;)
 	{
-		InWord = inw(ioaddr + SIFINC);
+		InWord = SIFREADW(SIFINC);
 
 		*(Data + i) = HIBYTE(InWord);	/* Write first byte */
 		if(++i == Length)		/* All is done break */
@@ -2273,30 +1968,8 @@
 	}
 
 	/* Restore original values */
-	outw(old_sifadx, ioaddr + SIFADX);
-	outw(old_sifadr, ioaddr + SIFADR);
-
-	return;
-}
-
-/*
- * Reads MAC address from adapter ROM.
- */
-static void tms380tr_read_addr(struct net_device *dev, unsigned char *Address)
-{
-	int i, In;
-	unsigned short ioaddr = dev->base_addr;
-
-	/* Address: 0000:0000 */
-	outw(0, ioaddr + SIFADX);
-	outw(0, ioaddr + SIFADR);
-
-	/* Read six byte MAC address data */
-	for(i = 0; i < 6; i++)
-	{
-		In = inw(ioaddr + SIFINC);
-		*(Address + i) = (unsigned char)(In >> 8);
-	}
+	SIFWRITEW(old_sifadx, SIFADX);
+	SIFWRITEW(old_sifadr, SIFADR);
 
 	return;
 }
@@ -2447,7 +2120,7 @@
 		/* Get the frame size (Byte swap for Intel).
 		 * Do this early (see workaround comment below)
 		 */
-		Length = (unsigned short)SWAPB(rpl->FrameSize);
+		Length = be16_to_cpu((unsigned short)rpl->FrameSize);
 
 		/* Check if the Frame_Start, Frame_End and
 		 * Frame_Complete bits are set.
@@ -2463,15 +2136,16 @@
 			 * Length2 is there because there have also been
 			 * cases where the FrameSize was partially written
 			 */
-			Length2 = (unsigned short)SWAPB(rpl->FrameSize);
+			Length2 = be16_to_cpu((unsigned short)rpl->FrameSize);
 
 			if(Length == 0 || Length != Length2)
 			{
 				tp->RplHead = SaveHead;
 				break;	/* Return to tms380tr_interrupt */
 			}
-#if 0	/* This might happen for multicast or broadcast packets.
-	   The upper layers are expected to handle this, not here */
+#if 0  		/* This might happen for multicast or broadcast packets.
+		   The upper layers are expected to handle this, not here */
+
 			/* Drop frames sent by myself */
 			if(tms380tr_chk_frame(dev, rpl->MData))
 			{
@@ -2552,8 +2226,7 @@
 			skb_put(rpl->Skb, tp->MaxPacketSize);
 
 			/* Data unreachable for DMA ? then use local buffer */
-			if(tp->CardType->type == TMS_ISA && virt_to_bus(rpl->Skb->data) + tp->MaxPacketSize
-			   > ISA_MAX_ADDRESS)
+			if(tp->dmalimit && virt_to_bus(rpl->Skb->data) + tp->MaxPacketSize > tp->dmalimit)
 			{
 				rpl->SkbStat = SKB_DATA_COPY;
 				rpl->FragList[0].DataAddr = htonl(virt_to_bus(tp->LocalRxBuffers[rpl->RPLIndex]));
@@ -2568,7 +2241,7 @@
 			}
 		}
 
-		rpl->FragList[0].DataCount = SWAPB(tp->MaxPacketSize);
+		rpl->FragList[0].DataCount = cpu_to_be16((unsigned short)tp->MaxPacketSize);
 		rpl->FrameSize = 0;
 
 		/* Pass the last RPL back to the adapter */
@@ -2619,6 +2292,7 @@
 	return;
 }
 
+#if 0
 /*
  * Check if it is a frame of myself. Compare source address with my current
  * address in reverse direction, and mask out the TR_RII.
@@ -2639,6 +2313,20 @@
 
 	return (1);  /* It is my frame. */
 }
+#endif
+
+static int tms380tr_set_mac_address(struct net_device *dev, void *addr)
+{
+	struct net_local *tp = (struct net_local *)dev->priv;
+	struct sockaddr *saddr = addr;
+	
+	if (tp->AdapterOpenFlag || tp->AdapterVirtOpenFlag) {
+		printk(KERN_WARNING "%s: Cannot set MAC/LAA address while card is open\n", dev->name);
+		return -EIO;
+	}
+	memcpy(dev->dev_addr, saddr->sa_data, dev->addr_len);
+	return 0;
+}
 
 #if TMS380TR_DEBUG > 0
 /*
@@ -2651,80 +2339,73 @@
 	for (i = 0, j = 0; i < length / 8; i++, j += 8)
 	{
 		printk(KERN_DEBUG "%02x %02x %02x %02x %02x %02x %02x %02x\n",
-			Data[j+0],Data[j+1],Data[j+2],Data[j+3],
-			Data[j+4],Data[j+5],Data[j+6],Data[j+7]);
+		       Data[j+0],Data[j+1],Data[j+2],Data[j+3],
+		       Data[j+4],Data[j+5],Data[j+6],Data[j+7]);
 	}
 
 	return;
 }
 #endif
 
-#ifdef MODULE
+int tmsdev_init(struct net_device *dev)
+{
+	if (dev->priv == NULL)
+	{
+		struct net_local *tms_local;
+		
+		dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL | GFP_DMA);
+		if (dev->priv == NULL)
+			return -ENOMEM;
+		memset(dev->priv, 0, sizeof(struct net_local));
+		tms_local = (struct net_local *)dev->priv;
+		init_waitqueue_head(&tms_local->wait_for_tok_int);
+	}
+	
+	/* These can be overridden by the card driver if needed */
+	dev->init		= tms380tr_init_card;
+	dev->open		= tms380tr_open;
+	dev->stop		= tms380tr_close;
+	dev->do_ioctl		= NULL; 
+	dev->hard_start_xmit	= tms380tr_send_packet;
+	dev->get_stats		= tms380tr_get_stats;
+	dev->set_multicast_list = &tms380tr_set_multicast_list;
+	dev->set_mac_address	= tms380tr_set_mac_address;
 
-static struct net_device* dev_tms380tr[TMS380TR_MAX_ADAPTERS];
-static int io[TMS380TR_MAX_ADAPTERS]	= { 0, 0 };
-static int irq[TMS380TR_MAX_ADAPTERS] 	= { 0, 0 };
-static int mem[TMS380TR_MAX_ADAPTERS] 	= { 0, 0 };
-
-MODULE_PARM(io,  "1-" __MODULE_STRING(TMS380TR_MAX_ADAPTERS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(TMS380TR_MAX_ADAPTERS) "i");
-MODULE_PARM(mem, "1-" __MODULE_STRING(TMS380TR_MAX_ADAPTERS) "i");
+	return 0;
+}
 
-int init_module(void)
-{
-	int i;
+#ifdef MODULE
 
-	for(i = 0; i < TMS380TR_MAX_ADAPTERS; i++)
-	{
-		irq[i] = 0;
-		mem[i] = 0;
-		dev_tms380tr[i] = NULL;
-		dev_tms380tr[i] = init_trdev(dev_tms380tr[i], 0);
-		if(dev_tms380tr[i] == NULL)
-			return (-ENOMEM);
-
-		dev_tms380tr[i]->base_addr = io[i];
-		dev_tms380tr[i]->irq       = irq[i];
-		dev_tms380tr[i]->mem_start = mem[i];
-		dev_tms380tr[i]->init      = &tms380tr_probe;
-
-		if(register_trdev(dev_tms380tr[i]) != 0)
-		{
-			kfree_s(dev_tms380tr[i], sizeof(struct net_device));
-			dev_tms380tr[i] = NULL;
-			if(i == 0)
-			{
-				printk("tms380tr: register_trdev() returned non-zero.\n");
-				return (-EIO);
-			}
-			else
-				return (0);
-		} 
+EXPORT_SYMBOL(tms380tr_open);
+EXPORT_SYMBOL(tms380tr_close);
+EXPORT_SYMBOL(tms380tr_interrupt);
+EXPORT_SYMBOL(tmsdev_init);
+EXPORT_SYMBOL(tms380tr_wait);
 
-	}
+struct module *TMS380_module = NULL;
 
-	return (0);
+int init_module(void)
+{
+	printk("%s", version);
+	
+	TMS380_module = &__this_module;
+	return 0;
 }
 
 void cleanup_module(void)
 {
-	int i;
-
-	for(i = 0; i < TMS380TR_MAX_ADAPTERS; i++)
-	{
-		if(dev_tms380tr[i])
-		{
-			unregister_trdev(dev_tms380tr[i]);
-			release_region(dev_tms380tr[i]->base_addr, TMS380TR_IO_EXTENT);
-			if(dev_tms380tr[i]->irq)
-				free_irq(dev_tms380tr[i]->irq, dev_tms380tr[i]);
-			if(dev_tms380tr[i]->dma > 0)
-				free_dma(dev_tms380tr[i]->dma);
-			if(dev_tms380tr[i]->priv)
-				kfree_s(dev_tms380tr[i]->priv, sizeof(struct net_local));
-			kfree_s(dev_tms380tr[i], sizeof(struct net_device));
-			dev_tms380tr[i] = NULL;
-		}
-	}
+	TMS380_module = NULL;
 }
-#endif /* MODULE */
+#endif
+
+
+/*
+ * Local variables:
+ *  compile-command: "gcc -DMODVERSIONS  -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c tms380tr.c"
+ *  alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c tms380tr.c"
+ *  c-set-style "K&R"
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)