All of lore.kernel.org
 help / color / mirror / Atom feed
* [BK PATCHES] 2.6.x net driver updates
@ 2003-10-14 19:06 Jeff Garzik
  0 siblings, 0 replies; 28+ messages in thread
From: Jeff Garzik @ 2003-10-14 19:06 UTC (permalink / raw)
  To: torvalds; +Cc: linux-kernel, netdev

I've tried to keep it to fixes, and created a separate queue
(net-drivers-2.[45]-exp) for non-fixes.

Linus, please do a

	bk pull bk://kernel.bkbits.net/jgarzik/net-drivers-2.5

This will update the following files:

 drivers/net/8139too.c           |    2 +
 drivers/net/Kconfig             |    4 +--
 drivers/net/b44.c               |   15 +++---------
 drivers/net/defxx.c             |    4 +--
 drivers/net/e1000/e1000_main.c  |   35 ++++++++++++++++++++++------
 drivers/net/hamradio/bpqether.c |    6 ----
 drivers/net/hamradio/scc.c      |    4 +--
 drivers/net/hp100.c             |   10 ++++----
 drivers/net/natsemi.c           |    2 -
 drivers/net/pcmcia/pcnet_cs.c   |   23 ++++++++++++------
 drivers/net/tulip/tulip_core.c  |    1 
 drivers/net/tulip/xircom_cb.c   |   35 ++++++++++++++--------------
 drivers/net/wireless/atmel.c    |    1 
 drivers/net/wireless/atmel_cs.c |   11 +++++---
 include/linux/ethtool.h         |   11 ++++----
 net/core/ethtool.c              |   49 ++++++++++++++++++++++++----------------
 16 files changed, 123 insertions(+), 90 deletions(-)

through these ChangeSets:

<pp@ee.oulu.fi> (03/10/14 1.1370)
   [PATCH] b44 enable interrupts after tx timeout (2.6-test version)
   
   Resending the patch I sent some time ago for b44.c that nukes the
   2.4 compatibility cruft as well.
   
   I'll do one for 2.4.23pre6 ASAP, hopefully being able sync the driver fully
   with the one in 2.6 (free_netdev() etc.).

<manfred@colorfullife.com> (03/10/14 1.1369)
   [netdrvr natsemi] fix ring clean
   
   Too much copy&paste in a call to pci_unmap_single.

<jgarzik@redhat.com> (03/10/14 1.1368)
   [netdrvr tulip] add pci id
   
   Contributed by Ken Zalewski.

<simon@thekelleys.org.uk> (03/10/14 1.1367)
   [PATCH] - atmel wireless driver
   
   1) Remove "#include <linux/version.h>" which was not needed and added
      bad extra compile dependencies.
   
   2) Fix typo in module description.
   
   3) Make card detection code cope with buggy SMC CIS entries.

<jgarzik@redhat.com> (03/10/14 1.1366)
   [netdrvr 8139too] another new PCI ID
   
   Contributed by Josh Litherland, Donald Becker, and others.

<jgarzik@redhat.com> (03/10/14 1.1365)
   [netdrvr 8139too] add pci id
   
   contributed by "JaReK" and Donald Becker.

<scott.feldman@intel.com> (03/10/14 1.1364)
   [PATCH] hang on ZEROCOPY/TSO when hitting no-Tx-resources
   
   * Critical bug fix: under heavy Tx stress using ZEROCOPY or TSO, if we
     ran out of Tx descriptors, we didn't calculate for the context
     descritor used as the first of the ZEROCOPY/TSO send, nor do we clean
     up the context desriptor bits in the case where the send isn't going
     to fit, where we need to undo the mappings.  This bug was introduced
     with the 5.2.16 patch set which included a workaround for a hang
     on 82544 over PCI-X.  This workaround cause the check for no-Tx-
     rosource logic to change, and this bug slipped in.

<ak@muc.de> (03/10/14 1.1363)
   [PATCH] Fix warnings in defxx.c
   
   Fix harmless 64bit warnings in defxx.c

<ak@muc.de> (03/10/14 1.1362)
   [PATCH] Fix warnings in hp100
   
   Fix some harmless integer/pointer size mismatch warnings in hp100.c
   on 64bit compiles

<ak@muc.de> (03/10/14 1.1361)
   [PATCH] Mark non 64bit clean network drivers
   
   This marks some net drivers which are clearly not 64bit (judging from
   the warnings) as !64BIT.
   
   -Andi

<pe1rxq@amsat.org> (03/10/14 1.1360)
   [hamradio bpqether] fix ancient debug line
   
   removes a verry old debug line from the bpqethernet driver that
   only fills logs.

<pe1rxq@amsat.org> (03/10/14 1.1359)
   [hamradio scc] fix probe function
   
   fix for the probe function of the scc driver which now uses
   an uninitialised scc struct for requesting an io region.

<scott.feldman@intel.com> (03/10/14 1.1358)
   [PATCH] ethtool_ops eeprom stuff
   
   Finally got around to adding ethtool_ops to e100-3.0.x.  I found a bug
   with get_eeprom() and it seems to work best if we add get_eeprom_len() to
   the ops list.  Also moved check for offest + len < size into ethtool.c.
   
   I was able to test [GS]EEPROM, PHYS_ID, GSTATS, GSTRINGS, and TEST, and
   everything looks good.
   
   Should I send same for 2.4?

<rmk+lkml@arm.linux.org.uk> (03/10/14 1.1357)
   [PATCH] Fix pcnet_cs network hotplug
   
   pcnet_cs registers the network device too early.  The effect of this
   is that the networking hotplug scripts are unable to bring the device
   up automatically.
   
   There are two issues:
   - we were registering the net device before we finished setting up
     the device (eg, reading the MAC address.)
   - we were using DEV_CONFIG_PENDING to block the net device "open"
     callback, and as we know the other methods may be called prior
     to open.
   
   My only concern with this patch is that we set info->node.dev_name
   after we register the net device, so use of cardctl during the
   hotplug scripts may give unexpected results.  However, I am not
   aware of anyone using cardctl to read the device name in network
   hotplug scripts.
   
   Please review and merge.  Thanks.

<shemminger@osdl.org> (03/10/14 1.1356)
   [netdrvr xircom_cb] fix race in statistics pointer setting
   by converting to use alloc_etherdev.



diff -Nru a/drivers/net/8139too.c b/drivers/net/8139too.c
--- a/drivers/net/8139too.c	Tue Oct 14 15:02:25 2003
+++ b/drivers/net/8139too.c	Tue Oct 14 15:02:25 2003
@@ -248,6 +248,8 @@
 	{0x14ea, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
 	{0x14ea, 0xab07, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
 	{0x11db, 0x1234, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+	{0x1432, 0x9130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+	{0x02ac, 0x1012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
 
 #ifdef CONFIG_SH_SECUREEDGE5410
 	/* Bogus 8139 silicon reports 8129 without external PROM :-( */
diff -Nru a/drivers/net/Kconfig b/drivers/net/Kconfig
--- a/drivers/net/Kconfig	Tue Oct 14 15:02:25 2003
+++ b/drivers/net/Kconfig	Tue Oct 14 15:02:25 2003
@@ -1616,7 +1616,7 @@
 
 config TLAN
 	tristate "TI ThunderLAN support"
-	depends on NET_PCI && (PCI || EISA)
+	depends on NET_PCI && (PCI || EISA) && !64BIT
 	---help---
 	  If you have a PCI Ethernet network card based on the ThunderLAN chip
 	  which is supported by this driver, say Y and read the
@@ -2412,7 +2412,7 @@
 
 config RCPCI
 	tristate "Red Creek Hardware VPN (EXPERIMENTAL)"
-	depends on NETDEVICES && EXPERIMENTAL && PCI
+	depends on NETDEVICES && EXPERIMENTAL && PCI && !64BIT
 	help
 	  This is a driver for hardware which provides a Virtual Private
 	  Network (VPN). Say Y if you have it.
diff -Nru a/drivers/net/b44.c b/drivers/net/b44.c
--- a/drivers/net/b44.c	Tue Oct 14 15:02:25 2003
+++ b/drivers/net/b44.c	Tue Oct 14 15:02:25 2003
@@ -25,8 +25,8 @@
 
 #define DRV_MODULE_NAME		"b44"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"0.9"
-#define DRV_MODULE_RELDATE	"Jul 14, 2003"
+#define DRV_MODULE_VERSION	"0.91"
+#define DRV_MODULE_RELDATE	"Oct 3, 2003"
 
 #define B44_DEF_MSG_ENABLE	  \
 	(NETIF_MSG_DRV		| \
@@ -80,15 +80,6 @@
 
 static int b44_debug = -1;	/* -1 == use B44_DEF_MSG_ENABLE as value */
 
-#ifndef PCI_DEVICE_ID_BCM4401
-#define PCI_DEVICE_ID_BCM4401      0x4401
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-#define IRQ_RETVAL(x) 
-#define irqreturn_t void
-#endif
-
 static struct pci_device_id b44_pci_tbl[] = {
 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
@@ -869,6 +860,8 @@
 	b44_init_hw(bp);
 
 	spin_unlock_irq(&bp->lock);
+
+	b44_enable_ints(bp);
 
 	netif_wake_queue(dev);
 }
diff -Nru a/drivers/net/defxx.c b/drivers/net/defxx.c
--- a/drivers/net/defxx.c	Tue Oct 14 15:02:25 2003
+++ b/drivers/net/defxx.c	Tue Oct 14 15:02:25 2003
@@ -2664,8 +2664,8 @@
  
 static void my_skb_align(struct sk_buff *skb, int n)
 {
-	u32 x=(u32)skb->data;	/* We only want the low bits .. */
-	u32 v;
+	unsigned long x=(unsigned long)skb->data;	
+	unsigned long v;
 	
 	v=(x+n-1)&~(n-1);	/* Where we want to be */
 	
diff -Nru a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
--- a/drivers/net/e1000/e1000_main.c	Tue Oct 14 15:02:25 2003
+++ b/drivers/net/e1000/e1000_main.c	Tue Oct 14 15:02:25 2003
@@ -30,7 +30,7 @@
 
 /* Change Log
  *
- * 5.2.18	9/13/03
+ * 5.2.20	9/30/03
  *   o Bug fix: SERDES devices might be connected to a back-plane
  *     switch that doesn't support auto-neg, so add the capability
  *     to force 1000/Full.
@@ -39,6 +39,9 @@
  *     Jumbo Frames or with the reduced FIFO in 82547.
  *   o Better propagation of error codes. [Janice Girouard 
  *     (janiceg@us.ibm.com)].
+ *   o Bug fix: hang under heavy Tx stress when running out of Tx
+ *     descriptors; wasn't clearing context descriptor when backing
+ *     out of send because of no-resource condition.
  *
  * 5.2.16	8/8/03
  *   o Added support for new controllers: 82545GM, 82546GB, 82541/7_B1
@@ -61,7 +64,7 @@
 
 char e1000_driver_name[] = "e1000";
 char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
-char e1000_driver_version[] = "5.2.19-k1";
+char e1000_driver_version[] = "5.2.20-k1";
 char e1000_copyright[] = "Copyright (c) 1999-2003 Intel Corporation.";
 
 /* e1000_pci_tbl - PCI Device ID Table
@@ -1545,6 +1548,7 @@
 	unsigned int first)
 {
 	struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
+	struct e1000_tx_desc *tx_desc;
 	struct e1000_buffer *buffer_info;
 	unsigned int len = skb->len, max_per_txd = E1000_MAX_DATA_PER_TXD;
 	unsigned int offset = 0, size, count = 0, i;
@@ -1640,17 +1644,29 @@
 		}
 	}
 
-	if(E1000_DESC_UNUSED(&adapter->tx_ring) < count) {
+	if(E1000_DESC_UNUSED(&adapter->tx_ring) < count + 2) {
 
 		/* There aren't enough descriptors available to queue up
-		 * this send, so undo the mapping and abort the send. 
-		 * We could have done the check before we mapped the skb,
-		 * but because of all the workarounds (above), it's too
-		 * difficult to predict how many we're going to need.*/
-		i = first;
+		 * this send (need: count + 1 context desc + 1 desc gap
+		 * to keep tail from touching head), so undo the mapping
+		 * and abort the send.  We could have done the check before
+		 * we mapped the skb, but because of all the workarounds
+		 * (above), it's too difficult to predict how many we're
+		 * going to need.*/
+		i = adapter->tx_ring.next_to_use;
+
+		if(i == first) {
+			/* Cleanup after e1000_tx_[csum|tso] scribbling
+			 * on descriptors. */
+			tx_desc = E1000_TX_DESC(*tx_ring, first);
+			tx_desc->buffer_addr = 0;
+			tx_desc->lower.data = 0;
+			tx_desc->upper.data = 0;
+		}
 
 		while(count--) {
 			buffer_info = &tx_ring->buffer_info[i];
+
 			if(buffer_info->dma) {
 				pci_unmap_page(adapter->pdev,
 					       buffer_info->dma,
@@ -1658,8 +1674,11 @@
 					       PCI_DMA_TODEVICE);
 				buffer_info->dma = 0;
 			}
+
 			if(++i == tx_ring->count) i = 0;
 		}
+
+		adapter->tx_ring.next_to_use = first;
 
 		return 0;
 	}
diff -Nru a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
--- a/drivers/net/hamradio/bpqether.c	Tue Oct 14 15:02:25 2003
+++ b/drivers/net/hamradio/bpqether.c	Tue Oct 14 15:02:25 2003
@@ -196,12 +196,8 @@
 	eth = (struct ethhdr *)skb->mac.raw;
 
 	if (!(bpq->acpt_addr[0] & 0x01) &&
-	    memcmp(eth->h_source, bpq->acpt_addr, ETH_ALEN)) {
-		if (net_ratelimit())
-			printk(KERN_DEBUG "bpqether: wrong dest %s\n",
-			       bpq_print_ethaddr(eth->h_source));
+	    memcmp(eth->h_source, bpq->acpt_addr, ETH_ALEN))
 		goto drop_unlock;
-	}
 
 	if (skb_cow(skb, sizeof(struct ethhdr)))
 		goto drop_unlock;
diff -Nru a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
--- a/drivers/net/hamradio/scc.c	Tue Oct 14 15:02:25 2003
+++ b/drivers/net/hamradio/scc.c	Tue Oct 14 15:02:25 2003
@@ -1762,7 +1762,7 @@
 
 #ifndef SCC_DONT_CHECK
 
-			if(request_region(scc->ctrl, 1, "scc-probe"))
+			if(request_region(hwcfg.ctrl_a, 1, "scc-probe"))
 			{
 				disable_irq(hwcfg.irq);
 				Outb(hwcfg.ctrl_a, 0);
@@ -1774,7 +1774,7 @@
 				if (InReg(hwcfg.ctrl_a,R13) != 0x55)
 					found = 0;
 				enable_irq(hwcfg.irq);
-				release_region(scc->ctrl, 1);
+				release_region(hwcfg.ctrl_a, 1);
 			}
 			else
 				found = 0;
diff -Nru a/drivers/net/hp100.c b/drivers/net/hp100.c
--- a/drivers/net/hp100.c	Tue Oct 14 15:02:25 2003
+++ b/drivers/net/hp100.c	Tue Oct 14 15:02:25 2003
@@ -1265,9 +1265,9 @@
 {
 	/* pdlptr is starting address for this pdl */
 
-	if (0 != (((unsigned) pdlptr) & 0xf))
-		printk("hp100: %s: Init rxpdl: Unaligned pdlptr 0x%x.\n",
-		       dev->name, (unsigned) pdlptr);
+	if (0 != (((unsigned long) pdlptr) & 0xf))
+		printk("hp100: %s: Init rxpdl: Unaligned pdlptr 0x%lx.\n",
+		       dev->name, (unsigned long) pdlptr);
 
 	ringptr->pdl = pdlptr + 1;
 	ringptr->pdl_paddr = virt_to_whatever(dev, pdlptr + 1);
@@ -1292,8 +1292,8 @@
 			    register hp100_ring_t * ringptr,
 			    register u32 * pdlptr)
 {
-	if (0 != (((unsigned) pdlptr) & 0xf))
-		printk("hp100: %s: Init txpdl: Unaligned pdlptr 0x%x.\n", dev->name, (unsigned) pdlptr);
+	if (0 != (((unsigned long) pdlptr) & 0xf))
+		printk("hp100: %s: Init txpdl: Unaligned pdlptr 0x%lx.\n", dev->name, (unsigned long) pdlptr);
 
 	ringptr->pdl = pdlptr;	/* +1; */
 	ringptr->pdl_paddr = virt_to_whatever(dev, pdlptr);	/* +1 */
diff -Nru a/drivers/net/natsemi.c b/drivers/net/natsemi.c
--- a/drivers/net/natsemi.c	Tue Oct 14 15:02:25 2003
+++ b/drivers/net/natsemi.c	Tue Oct 14 15:02:25 2003
@@ -1530,7 +1530,7 @@
 	for (i = 0; i < TX_RING_SIZE; i++) {
 		if (np->tx_skbuff[i]) {
 			pci_unmap_single(np->pci_dev,
-				np->rx_dma[i], np->rx_skbuff[i]->len,
+				np->tx_dma[i], np->tx_skbuff[i]->len,
 				PCI_DMA_TODEVICE);
 			dev_kfree_skb(np->tx_skbuff[i]);
 			np->stats.tx_dropped++;
diff -Nru a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
--- a/drivers/net/pcmcia/pcnet_cs.c	Tue Oct 14 15:02:25 2003
+++ b/drivers/net/pcmcia/pcnet_cs.c	Tue Oct 14 15:02:25 2003
@@ -681,10 +681,6 @@
     } else {
 	dev->if_port = 0;
     }
-    if (register_netdev(dev) != 0) {
-	printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n");
-	goto failed;
-    }
 
     hw_info = get_hwinfo(link);
     if (hw_info == NULL)
@@ -699,7 +695,6 @@
     if (hw_info == NULL) {
 	printk(KERN_NOTICE "pcnet_cs: unable to read hardware net"
 	       " address for io base %#3lx\n", dev->base_addr);
-	unregister_netdev(dev);
 	goto failed;
     }
 
@@ -733,8 +728,6 @@
     ei_status.word16 = 1;
     ei_status.reset_8390 = &pcnet_reset_8390;
 
-    strcpy(info->node.dev_name, dev->name);
-    link->dev = &info->node;
     SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 
     if (info->flags & (IS_DL10019|IS_DL10022)) {
@@ -743,6 +736,21 @@
 	mii_phy_probe(dev);
 	if ((id == 0x30) && !info->pna_phy && (info->eth_phy == 4))
 	    info->eth_phy = 0;
+    }
+
+    link->dev = &info->node;
+    link->state &= ~DEV_CONFIG_PENDING;
+
+    if (register_netdev(dev) != 0) {
+	printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n");
+	link->dev = NULL;
+	goto failed;
+    }
+
+    strcpy(info->node.dev_name, dev->name);
+
+    if (info->flags & (IS_DL10019|IS_DL10022)) {
+	u_char id = inb(dev->base_addr + 0x1a);
 	printk(KERN_INFO "%s: NE2000 (DL100%d rev %02x): ",
 	       dev->name, ((info->flags & IS_DL10022) ? 22 : 19), id);
 	if (info->pna_phy)
@@ -758,7 +766,6 @@
     printk(" hw_addr ");
     for (i = 0; i < 6; i++)
 	printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));
-    link->state &= ~DEV_CONFIG_PENDING;
     return;
 
 cs_failed:
diff -Nru a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
--- a/drivers/net/tulip/tulip_core.c	Tue Oct 14 15:02:25 2003
+++ b/drivers/net/tulip/tulip_core.c	Tue Oct 14 15:02:25 2003
@@ -224,6 +224,7 @@
 	{ 0x1186, 0x1561, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x1626, 0x8410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x1737, 0xAB09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+	{ 0x1737, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x17B3, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
  	{ 0x10b9, 0x5261, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X },	/* ALi 1563 integrated ethernet */
 	{ 0x10b7, 0x9300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* 3Com 3CSOHO100B-TX */
diff -Nru a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c
--- a/drivers/net/tulip/xircom_cb.c	Tue Oct 14 15:02:25 2003
+++ b/drivers/net/tulip/xircom_cb.c	Tue Oct 14 15:02:25 2003
@@ -230,7 +230,8 @@
 	   This way, we can fail gracefully if not enough memory
 	   is available. 
 	 */
-	if ((dev = init_etherdev(NULL, sizeof(struct xircom_private))) == NULL) {
+	dev = alloc_etherdev(sizeof(struct xircom_private));
+	if (!dev) {
 		printk(KERN_ERR "xircom_probe: failed to allocate etherdev\n");
 		goto device_fail;
 	}
@@ -250,7 +251,7 @@
 
 	SET_MODULE_OWNER(dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
-	printk(KERN_INFO "%s: Xircom cardbus revision %i at irq %i \n", dev->name, chip_rev, pdev->irq);
+
 
 	private->dev = dev;
 	private->pdev = pdev;
@@ -259,7 +260,6 @@
 	dev->irq = pdev->irq;
 	dev->base_addr = private->io_port;
 	
-	
 	initialize_card(private);
 	read_mac_address(private);
 	setup_descriptors(private);
@@ -272,7 +272,12 @@
 	SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 	pci_set_drvdata(pdev, dev);
 
-	
+	if (register_netdev(dev)) {
+		printk(KERN_ERR "xircom_probe: netdevice registration failed.\n");
+		goto reg_fail;
+	}
+		
+	printk(KERN_INFO "%s: Xircom cardbus revision %i at irq %i \n", dev->name, chip_rev, pdev->irq);
 	/* start the transmitter to get a heartbeat */
 	/* TODO: send 2 dummy packets here */
 	transceiver_voodoo(private);
@@ -287,10 +292,12 @@
 	leave("xircom_probe");
 	return 0;
 
+reg_fail:
+	kfree(private->tx_buffer);
 tx_buf_fail:
 	kfree(private->rx_buffer);
 rx_buf_fail:
-	kfree(dev);
+	free_netdev(dev);
 device_fail:
 	return -ENODEV;
 }
@@ -305,22 +312,16 @@
 static void __devexit xircom_remove(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
-	struct xircom_private *card;
+	struct xircom_private *card = dev->priv;
+
 	enter("xircom_remove");
-	if (dev!=NULL) {
-		card=dev->priv;
-		if (card!=NULL) {	
-			if (card->rx_buffer!=NULL)
-				pci_free_consistent(pdev,8192,card->rx_buffer,card->rx_dma_handle);
-			card->rx_buffer = NULL;
-			if (card->tx_buffer!=NULL)
-				pci_free_consistent(pdev,8192,card->tx_buffer,card->tx_dma_handle);
-			card->tx_buffer = NULL;			
-		}
-	}
+	pci_free_consistent(pdev,8192,card->rx_buffer,card->rx_dma_handle);
+	pci_free_consistent(pdev,8192,card->tx_buffer,card->tx_dma_handle);
+
 	release_region(dev->base_addr, 128);
 	unregister_netdev(dev);
 	free_netdev(dev);
+	pci_set_drvdata(pdev, NULL);
 	leave("xircom_remove");
 } 
 
diff -Nru a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
--- a/drivers/net/wireless/atmel.c	Tue Oct 14 15:02:25 2003
+++ b/drivers/net/wireless/atmel.c	Tue Oct 14 15:02:25 2003
@@ -37,7 +37,6 @@
 ******************************************************************************/
 
 #include <linux/config.h>
-#include <linux/version.h>
 #include <linux/init.h>
 
 #include <linux/kernel.h>
diff -Nru a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
--- a/drivers/net/wireless/atmel_cs.c	Tue Oct 14 15:02:25 2003
+++ b/drivers/net/wireless/atmel_cs.c	Tue Oct 14 15:02:25 2003
@@ -84,7 +84,7 @@
 static int irq_list[4] = { -1 };
 
 MODULE_AUTHOR("Simon Kelley");
-MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethnet cards.");
+MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("Atmel at76c50x PCMCIA cards");
 MODULE_PARM(irq_mask, "i");
@@ -404,9 +404,12 @@
 					goto mismatch;
 				for (k = 0; k < j; k++) {
 					while ((*p != '\0') && (*p != '/')) p++;
-					if (*p == '\0')
-						goto mismatch;
-					p++;
+					if (*p == '\0') {
+						if (*q != '\0')
+							goto mismatch;
+					} else {
+						p++;
+					}
 				}
 				while((*q != '\0') && (*p != '\0') && 
 				      (*p != '/') && (*p == *q)) p++, q++;
diff -Nru a/include/linux/ethtool.h b/include/linux/ethtool.h
--- a/include/linux/ethtool.h	Tue Oct 14 15:02:25 2003
+++ b/include/linux/ethtool.h	Tue Oct 14 15:02:25 2003
@@ -307,14 +307,14 @@
  *
  * get_eeprom:
  *	Should fill in the magic field.  Don't need to check len for zero
- *	or wraparound but must check offset + len < size.  Fill in the data
- *	argument with the eeprom values from offset to offset + len.  Update
- *	len to the amount read.  Returns an error or zero.
+ *	or wraparound.  Fill in the data argument with the eeprom values
+ *	from offset to offset + len.  Update len to the amount read.
+ *	Returns an error or zero.
  *
  * set_eeprom:
  *	Should validate the magic field.  Don't need to check len for zero
- *	or wraparound but must check offset + len < size.  Update len to
- *	the amount written.  Returns an error or zero.
+ *	or wraparound.  Update len to the amount written.  Returns an error
+ *	or zero.
  */
 struct ethtool_ops {
 	int	(*get_settings)(struct net_device *, struct ethtool_cmd *);
@@ -328,6 +328,7 @@
 	void	(*set_msglevel)(struct net_device *, u32);
 	int	(*nway_reset)(struct net_device *);
 	u32	(*get_link)(struct net_device *);
+	int	(*get_eeprom_len)(struct net_device *);
 	int	(*get_eeprom)(struct net_device *, struct ethtool_eeprom *, u8 *);
 	int	(*set_eeprom)(struct net_device *, struct ethtool_eeprom *, u8 *);
 	int	(*get_coalesce)(struct net_device *, struct ethtool_coalesce *);
diff -Nru a/net/core/ethtool.c b/net/core/ethtool.c
--- a/net/core/ethtool.c	Tue Oct 14 15:02:25 2003
+++ b/net/core/ethtool.c	Tue Oct 14 15:02:25 2003
@@ -122,7 +122,8 @@
 		info.n_stats = ops->get_stats_count(dev);
 	if (ops->get_regs_len)
 		info.regdump_len = ops->get_regs_len(dev);
-	/* XXX: eeprom? */
+	if (ops->get_eeprom_len)
+		info.eedump_len = ops->get_eeprom_len(dev);
 
 	if (copy_to_user(useraddr, &info, sizeof(info)))
 		return -EFAULT;
@@ -245,29 +246,34 @@
 static int ethtool_get_eeprom(struct net_device *dev, void *useraddr)
 {
 	struct ethtool_eeprom eeprom;
+	struct ethtool_ops *ops = dev->ethtool_ops;
 	u8 *data;
-	int len, ret;
+	int ret;
 
-	if (!dev->ethtool_ops->get_eeprom)
+	if (!ops->get_eeprom || !ops->get_eeprom_len)
 		return -EOPNOTSUPP;
 
 	if (copy_from_user(&eeprom, useraddr, sizeof(eeprom)))
 		return -EFAULT;
 
-	len = eeprom.len;
 	/* Check for wrap and zero */
-	if (eeprom.offset + len <= eeprom.offset)
+	if (eeprom.offset + eeprom.len <= eeprom.offset)
+		return -EINVAL;
+
+	/* Check for exceeding total eeprom len */
+	if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev))
 		return -EINVAL;
 
-	data = kmalloc(len, GFP_USER);
+	data = kmalloc(eeprom.len, GFP_USER);
 	if (!data)
 		return -ENOMEM;
 
-	if (copy_from_user(data, useraddr + sizeof(eeprom), len))
-		return -EFAULT;
+	ret = -EFAULT;
+	if (copy_from_user(data, useraddr + sizeof(eeprom), eeprom.len))
+		goto out;
 
-	ret = dev->ethtool_ops->get_eeprom(dev, &eeprom, data);
-	if (!ret)
+	ret = ops->get_eeprom(dev, &eeprom, data);
+	if (ret)
 		goto out;
 
 	ret = -EFAULT;
@@ -285,32 +291,37 @@
 static int ethtool_set_eeprom(struct net_device *dev, void *useraddr)
 {
 	struct ethtool_eeprom eeprom;
+	struct ethtool_ops *ops = dev->ethtool_ops;
 	u8 *data;
-	int len, ret;
+	int ret;
 
-	if (!dev->ethtool_ops->set_eeprom)
+	if (!ops->set_eeprom || !ops->get_eeprom_len)
 		return -EOPNOTSUPP;
 
 	if (copy_from_user(&eeprom, useraddr, sizeof(eeprom)))
 		return -EFAULT;
 
-	len = eeprom.len;
 	/* Check for wrap and zero */
-	if (eeprom.offset + len <= eeprom.offset)
+	if (eeprom.offset + eeprom.len <= eeprom.offset)
+		return -EINVAL;
+
+	/* Check for exceeding total eeprom len */
+	if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev))
 		return -EINVAL;
 
-	data = kmalloc(len, GFP_USER);
+	data = kmalloc(eeprom.len, GFP_USER);
 	if (!data)
 		return -ENOMEM;
 
-	if (copy_from_user(data, useraddr + sizeof(eeprom), len))
-		return -EFAULT;
+	ret = -EFAULT;
+	if (copy_from_user(data, useraddr + sizeof(eeprom), eeprom.len))
+		goto out;
 
-	ret = dev->ethtool_ops->set_eeprom(dev, &eeprom, data);
+	ret = ops->set_eeprom(dev, &eeprom, data);
 	if (ret)
 		goto out;
 
-	if (copy_to_user(useraddr + sizeof(eeprom), data, len))
+	if (copy_to_user(useraddr + sizeof(eeprom), data, eeprom.len))
 		ret = -EFAULT;
 
  out:

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [BK PATCHES] 2.6.x net driver updates
@ 2005-03-09 17:22 Jeff Garzik
  0 siblings, 0 replies; 28+ messages in thread
From: Jeff Garzik @ 2005-03-09 17:22 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: Netdev, Linux Kernel

[-- Attachment #1: Type: text/plain, Size: 36 bytes --]

Janitorial and viro-authored stuff.

[-- Attachment #2: changelog.txt --]
[-- Type: text/plain, Size: 6002 bytes --]

Please do a

	bk pull bk://gkernel.bkbits.net/net-drivers-2.6

This will update the following files:

 include/linux/dp83840.h                  |   41 --------
 drivers/net/3c503.c                      |   67 +++++++------
 drivers/net/3c509.c                      |    4 
 drivers/net/3c515.c                      |   32 ++----
 drivers/net/3c527.c                      |    2 
 drivers/net/amd8111e.c                   |    4 
 drivers/net/arcnet/arc-rawmode.c         |    4 
 drivers/net/arcnet/arc-rimi.c            |   14 +-
 drivers/net/arcnet/arcnet.c              |   30 ++---
 drivers/net/arcnet/com20020.c            |    6 -
 drivers/net/arcnet/com90io.c             |    4 
 drivers/net/arcnet/com90xx.c             |    8 -
 drivers/net/arcnet/rfc1051.c             |    8 -
 drivers/net/arcnet/rfc1201.c             |   12 +-
 drivers/net/bonding/bond_3ad.c           |    2 
 drivers/net/bonding/bond_3ad.h           |    1 
 drivers/net/bonding/bond_alb.c           |    4 
 drivers/net/cs89x0.c                     |    4 
 drivers/net/depca.c                      |    4 
 drivers/net/dgrs.c                       |    6 -
 drivers/net/eepro100.c                   |   10 -
 drivers/net/es3210.c                     |   32 +++---
 drivers/net/ethertap.c                   |    4 
 drivers/net/ewrk3.c                      |   87 +++++++++--------
 drivers/net/ioc3-eth.c                   |    1 
 drivers/net/irda/act200l-sir.c           |    3 
 drivers/net/irda/irtty-sir.c             |    4 
 drivers/net/irda/ma600-sir.c             |   12 --
 drivers/net/irda/sir_dev.c               |    4 
 drivers/net/irda/tekram-sir.c            |    3 
 drivers/net/loopback.c                   |    2 
 drivers/net/lp486e.c                     |    8 -
 drivers/net/ni65.c                       |    3 
 drivers/net/ns83820.c                    |    3 
 drivers/net/pcmcia/ibmtr_cs.c            |    7 -
 drivers/net/pcmcia/xirc2ps_cs.c          |   23 +---
 drivers/net/ppp_deflate.c                |    4 
 drivers/net/ppp_generic.c                |    2 
 drivers/net/pppoe.c                      |    2 
 drivers/net/s2io.c                       |   75 ++++++--------
 drivers/net/s2io.h                       |    8 -
 drivers/net/sb1000.c                     |   28 ++---
 drivers/net/shaper.c                     |    2 
 drivers/net/slhc.c                       |   27 -----
 drivers/net/smc-mca.c                    |   37 ++++---
 drivers/net/smc-ultra.c                  |   34 +++---
 drivers/net/smc-ultra32.c                |   30 +++--
 drivers/net/tokenring/ibmtr.c            |  158 ++++++++++++++-----------------
 drivers/net/tulip/interrupt.c            |    2 
 drivers/net/tun.c                        |    4 
 drivers/net/via-rhine.c                  |    2 
 drivers/net/via-velocity.c               |    2 
 drivers/net/wan/cosa.c                   |    7 -
 drivers/net/wd.c                         |   36 ++++---
 drivers/net/wireless/airo.c              |   25 +---
 drivers/net/wireless/prism54/isl_ioctl.c |    2 
 drivers/net/wireless/ray_cs.c            |    5 
 drivers/net/wireless/strip.c             |   16 +--
 include/linux/ibmtr.h                    |   15 +-
 include/net/slhc_vj.h                    |    3 
 60 files changed, 454 insertions(+), 535 deletions(-)

through these ChangeSets:

Adrian Bunk:
  o drivers/net/via-rhine.c: make a variable static const
  o drivers/net/sb1000.c: make some variables static
  o drivers/net/lp486e.c: make some code static
  o drivers/net/3c509.c: make 2 structs static
  o drivers/net/3c527.c: make a struct static
  o drivers/net/amd8111e.c: make 2 functions static
  o drivers/net/loopback.c: make a function static
  o drivers/net/ethertap.c: make 2 functions static
  o drivers/net/dgrs.c: make 3 functions static
  o drivers/net/depca.c: make 2 structs static
  o drivers/net/bonding/: make 3 functions static
  o drivers/net/s2io.c: cleanups
  o drivers/net/pppoe.c: make a struct static
  o drivers/net/ppp_deflate.c: make 2 structs static
  o drivers/net/via-velocity.c: make a function static
  o drivers/net/tun.c: make 2 functions static
  o drivers/net/tulip/interrupt.c: make a variable static
  o drivers/net/shaper.c: make a variable static
  o drivers/net/slhc.c: remove 2 functions
  o remove dp83840.h

Alexander Viro:
  o 3c503 (iomem + isa-ectomy)
  o ibmtr 2/2: ibmtr annotations - the rest
  o ibmtr 1/2: iomem annotations - trivial part
  o es3210 iomem annotions and isa-ectomy
  o ewrk3 iomem annotations + isa-ectomy
  o wd iomem annotations + isa-ectomy
  o smc-ultra32 iomem annotations + isa-ectomy
  o smc-ultra iomem annotations + isa-ectomy
  o smc-mca iomem annotations and isa-ectomy

Domen Puncer:
  o net/ewrk3: replace schedule_timeout() with msleep_interruptible()
  o net/tekram-sir: replace schedule_timeout() with msleep()
  o net/ns83820: replace schedule_timeout() with msleep()
  o net/ni65: replace schedule_timeout() with msleep()
  o net/sir_dev: replace schedule_timeout() with msleep()
  o net/xirc2ps_cs: replace Wait() with msleep()
  o net/ma600-sir: replace schedule_timeout() with msleep()
  o net/irtty-sir: replace schedule_timeout() with msleep()
  o net/act2001-sir: replace schedule_timeout() with msleep()
  o arcnet: remove casts

François Romieu:
  o strip: use of netdev_priv

Nishanth Aravamudan:
  o net/cosa: replace schedule_timeout() with msleep()
  o net/airo: replace schedule_timeout() with msleep()/ssleep()
  o net/cs89x0: replace schedule_timeout() with msleep()

Paul Mackerras:
  o remove bogus exports in ppp

Pavel Machek:
  o eepro100 kill obsolete ifdefs

Randy Dunlap:
  o sb1000: reduce ioctl stack usage
  o ray_cs: reduce stack usage (sockaddr)
  o prism54: use NULL for pointer

Steffen Klassert:
  o Add MODULE_VERSION to the 3c515 driver
  o Use netdev_priv in the 3c515 driver


[-- Attachment #3: patch --]
[-- Type: text/plain, Size: 103920 bytes --]

diff -Nru a/drivers/net/3c503.c b/drivers/net/3c503.c
--- a/drivers/net/3c503.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/3c503.c	2005-03-09 12:20:51 -05:00
@@ -103,8 +103,15 @@
 	return -ENXIO;
 
     for (addr = addrs; *addr; addr++) {
-	unsigned base_bits = isa_readb(*addr);
-	int i = ffs(base_bits) - 1;
+	void __iomem *p = ioremap(*addr, 1);
+	unsigned base_bits;
+	int i;
+
+	if (!p)
+		continue;
+	base_bits = readb(p);
+	iounmap(p);
+	i = ffs(base_bits) - 1;
 	if (i == -1 || base_bits != (1 << i))
 	    continue;
 	if (el2_probe1(dev, netcard_portlist[i]) == 0)
@@ -145,6 +152,8 @@
 {
 	/* NB: el2_close() handles free_irq */
 	release_region(dev->base_addr, EL2_IO_EXTENT);
+	if (ei_status.mem)
+		iounmap(ei_status.mem);
 }
 
 #ifndef MODULE
@@ -262,42 +271,46 @@
     if ((membase_reg & 0xf0) == 0) {
 	dev->mem_start = 0;
 	ei_status.name = "3c503-PIO";
+	ei_status.mem = NULL;
     } else {
 	dev->mem_start = ((membase_reg & 0xc0) ? 0xD8000 : 0xC8000) +
 	    ((membase_reg & 0xA0) ? 0x4000 : 0);
-
 #define EL2_MEMSIZE (EL2_MB1_STOP_PG - EL2_MB1_START_PG)*256
+	ei_status.mem = ioremap(dev->mem_start, EL2_MEMSIZE);
+
 #ifdef EL2MEMTEST
 	/* This has never found an error, but someone might care.
 	   Note that it only tests the 2nd 8kB on 16kB 3c503/16
 	   cards between card addr. 0x2000 and 0x3fff. */
 	{			/* Check the card's memory. */
-	    unsigned long mem_base = dev->mem_start;
+	    void __iomem *mem_base = ei_status.mem;
 	    unsigned int test_val = 0xbbadf00d;
-	    isa_writel(0xba5eba5e, mem_base);
+	    writel(0xba5eba5e, mem_base);
 	    for (i = sizeof(test_val); i < EL2_MEMSIZE; i+=sizeof(test_val)) {
-		isa_writel(test_val, mem_base + i);
-		if (isa_readl(mem_base) != 0xba5eba5e
-		    || isa_readl(mem_base + i) != test_val) {
+		writel(test_val, mem_base + i);
+		if (readl(mem_base) != 0xba5eba5e
+		    || readl(mem_base + i) != test_val) {
 		    printk("3c503: memory failure or memory address conflict.\n");
 		    dev->mem_start = 0;
 		    ei_status.name = "3c503-PIO";
+		    iounmap(mem_base);
+		    ei_status.mem = NULL;
 		    break;
 		}
 		test_val += 0x55555555;
-		isa_writel(0, mem_base + i);
+		writel(0, mem_base + i);
 	    }
 	}
 #endif  /* EL2MEMTEST */
 
 	if (dev->mem_start)
-		dev->mem_end = ei_status.rmem_end = dev->mem_start + EL2_MEMSIZE;
+		dev->mem_end = dev->mem_start + EL2_MEMSIZE;
 
 	if (wordlength) {	/* No Tx pages to skip over to get to Rx */
-		ei_status.rmem_start = dev->mem_start;
+		ei_status.priv = 0;
 		ei_status.name = "3c503/16";
 	} else {
-		ei_status.rmem_start = TX_PAGES*256 + dev->mem_start;
+		ei_status.priv = TX_PAGES * 256;
 		ei_status.name = "3c503";
 	}
     }
@@ -471,16 +484,16 @@
     unsigned short int *wrd;
     int boguscount;		/* timeout counter */
     unsigned short word;	/* temporary for better machine code */
+    void __iomem *base = ei_status.mem;
 
     if (ei_status.word16)      /* Tx packets go into bank 0 on EL2/16 card */
 	outb(EGACFR_RSEL|EGACFR_TCM, E33G_GACFR);
     else
 	outb(EGACFR_NORM, E33G_GACFR);
 
-    if (dev->mem_start) {	/* Shared memory transfer */
-	unsigned long dest_addr = dev->mem_start +
-	    ((start_page - ei_status.tx_start_page) << 8);
-	isa_memcpy_toio(dest_addr, buf, count);
+    if (base) {	/* Shared memory transfer */
+	memcpy_toio(base + ((start_page - ei_status.tx_start_page) << 8),
+			buf, count);
 	outb(EGACFR_NORM, E33G_GACFR);	/* Back to bank1 in case on bank0 */
 	return;
     }
@@ -541,11 +554,12 @@
 el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
 {
     int boguscount;
-    unsigned long hdr_start = dev->mem_start + ((ring_page - EL2_MB1_START_PG)<<8);
+    void __iomem *base = ei_status.mem;
     unsigned short word;
 
-    if (dev->mem_start) {       /* Use the shared memory. */
-	isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
+    if (base) {       /* Use the shared memory. */
+	void __iomem *hdr_start = base + ((ring_page - EL2_MB1_START_PG)<<8);
+	memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
 	hdr->count = le16_to_cpu(hdr->count);
 	return;
     }
@@ -581,23 +595,22 @@
 el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
 {
     int boguscount = 0;
+    void __iomem *base = ei_status.mem;
     unsigned short int *buf;
     unsigned short word;
 
-    int end_of_ring = ei_status.rmem_end;
-
     /* Maybe enable shared memory just be to be safe... nahh.*/
-    if (dev->mem_start) {	/* Use the shared memory. */
+    if (base) {	/* Use the shared memory. */
 	ring_offset -= (EL2_MB1_START_PG<<8);
-	if (dev->mem_start + ring_offset + count > end_of_ring) {
+	if (ring_offset + count > EL2_MEMSIZE) {
 	    /* We must wrap the input move. */
-	    int semi_count = end_of_ring - (dev->mem_start + ring_offset);
-	    isa_memcpy_fromio(skb->data, dev->mem_start + ring_offset, semi_count);
+	    int semi_count = EL2_MEMSIZE - ring_offset;
+	    memcpy_fromio(skb->data, base + ring_offset, semi_count);
 	    count -= semi_count;
-	    isa_memcpy_fromio(skb->data + semi_count, ei_status.rmem_start, count);
+	    memcpy_fromio(skb->data + semi_count, base + ei_status.priv, count);
 	} else {
 		/* Packet is in one chunk -- we can copy + cksum. */
-		isa_eth_io_copy_and_sum(skb, dev->mem_start + ring_offset, count, 0);
+		eth_io_copy_and_sum(skb, base + ring_offset, count, 0);
 	}
 	return;
     }
diff -Nru a/drivers/net/3c509.c b/drivers/net/3c509.c
--- a/drivers/net/3c509.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/3c509.c	2005-03-09 12:20:51 -05:00
@@ -214,7 +214,7 @@
 #endif
 
 #ifdef CONFIG_EISA
-struct eisa_device_id el3_eisa_ids[] = {
+static struct eisa_device_id el3_eisa_ids[] = {
 		{ "TCM5092" },
 		{ "TCM5093" },
 		{ "" }
@@ -222,7 +222,7 @@
 
 static int el3_eisa_probe (struct device *device);
 
-struct eisa_driver el3_eisa_driver = {
+static struct eisa_driver el3_eisa_driver = {
 		.id_table = el3_eisa_ids,
 		.driver   = {
 				.name    = "3c509",
diff -Nru a/drivers/net/3c515.c b/drivers/net/3c515.c
--- a/drivers/net/3c515.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/3c515.c	2005-03-09 12:20:51 -05:00
@@ -86,6 +86,7 @@
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("3Com 3c515 Corkscrew driver");
 MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
 
 /* "Knobs" for adjusting internal parameters. */
 /* Put out somewhat more debugging messages. (0 - no msg, 1 minimal msgs). */
@@ -472,7 +473,7 @@
 
 static void cleanup_card(struct net_device *dev)
 {
-	struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
+	struct corkscrew_private *vp = netdev_priv(dev);
 	list_del_init(&vp->list);
 	if (dev->dma)
 		free_dma(dev->dma);
@@ -570,7 +571,7 @@
 static void corkscrew_setup(struct net_device *dev, int ioaddr,
 			    struct pnp_dev *idev, int card_number)
 {
-	struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
+	struct corkscrew_private *vp = netdev_priv(dev);
 	unsigned int eeprom[0x40], checksum = 0;	/* EEPROM contents */
 	int i;
 	int irq;
@@ -696,8 +697,7 @@
 static int corkscrew_open(struct net_device *dev)
 {
 	int ioaddr = dev->base_addr;
-	struct corkscrew_private *vp =
-	    (struct corkscrew_private *) dev->priv;
+	struct corkscrew_private *vp = netdev_priv(dev);
 	union wn3_config config;
 	int i;
 
@@ -862,7 +862,7 @@
 {
 #ifdef AUTOMEDIA
 	struct net_device *dev = (struct net_device *) data;
-	struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
+	struct corkscrew_private *vp = netdev_priv(dev);
 	int ioaddr = dev->base_addr;
 	unsigned long flags;
 	int ok = 0;
@@ -954,8 +954,7 @@
 static void corkscrew_timeout(struct net_device *dev)
 {
 	int i;
-	struct corkscrew_private *vp =
-	    (struct corkscrew_private *) dev->priv;
+	struct corkscrew_private *vp = netdev_priv(dev);
 	int ioaddr = dev->base_addr;
 
 	printk(KERN_WARNING
@@ -994,8 +993,7 @@
 static int corkscrew_start_xmit(struct sk_buff *skb,
 				struct net_device *dev)
 {
-	struct corkscrew_private *vp =
-	    (struct corkscrew_private *) dev->priv;
+	struct corkscrew_private *vp = netdev_priv(dev);
 	int ioaddr = dev->base_addr;
 
 	/* Block a timer-based transmit from overlapping. */
@@ -1123,14 +1121,13 @@
 {
 	/* Use the now-standard shared IRQ implementation. */
 	struct net_device *dev = dev_id;
-	struct corkscrew_private *lp;
+	struct corkscrew_private *lp = netdev_priv(dev);
 	int ioaddr, status;
 	int latency;
 	int i = max_interrupt_work;
 
 	ioaddr = dev->base_addr;
 	latency = inb(ioaddr + Timer);
-	lp = (struct corkscrew_private *) dev->priv;
 
 	spin_lock(&lp->lock);
 	
@@ -1262,7 +1259,7 @@
 
 static int corkscrew_rx(struct net_device *dev)
 {
-	struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
+	struct corkscrew_private *vp = netdev_priv(dev);
 	int ioaddr = dev->base_addr;
 	int i;
 	short rx_status;
@@ -1329,8 +1326,7 @@
 
 static int boomerang_rx(struct net_device *dev)
 {
-	struct corkscrew_private *vp =
-	    (struct corkscrew_private *) dev->priv;
+	struct corkscrew_private *vp = netdev_priv(dev);
 	int entry = vp->cur_rx % RX_RING_SIZE;
 	int ioaddr = dev->base_addr;
 	int rx_status;
@@ -1420,8 +1416,7 @@
 
 static int corkscrew_close(struct net_device *dev)
 {
-	struct corkscrew_private *vp =
-	    (struct corkscrew_private *) dev->priv;
+	struct corkscrew_private *vp = netdev_priv(dev);
 	int ioaddr = dev->base_addr;
 	int i;
 
@@ -1476,7 +1471,7 @@
 
 static struct net_device_stats *corkscrew_get_stats(struct net_device *dev)
 {
-	struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
+	struct corkscrew_private *vp = netdev_priv(dev);
 	unsigned long flags;
 
 	if (netif_running(dev)) {
@@ -1496,8 +1491,7 @@
 	*/
 static void update_stats(int ioaddr, struct net_device *dev)
 {
-	struct corkscrew_private *vp =
-	    (struct corkscrew_private *) dev->priv;
+	struct corkscrew_private *vp = netdev_priv(dev);
 
 	/* Unlike the 3c5x9 we need not turn off stats updates while reading. */
 	/* Switch to the stats window, and read everything. */
diff -Nru a/drivers/net/3c527.c b/drivers/net/3c527.c
--- a/drivers/net/3c527.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/3c527.c	2005-03-09 12:20:51 -05:00
@@ -197,7 +197,7 @@
 	char		*name;
 };
 
-const struct mca_adapters_t mc32_adapters[] = {
+static const struct mca_adapters_t mc32_adapters[] = {
 	{ 0x0041, "3COM EtherLink MC/32" },
 	{ 0x8EF5, "IBM High Performance Lan Adapter" },
 	{ 0x0000, NULL }
diff -Nru a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
--- a/drivers/net/amd8111e.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/amd8111e.c	2005-03-09 12:20:51 -05:00
@@ -1489,7 +1489,7 @@
 amd8111e crc generator implementation is different from the kernel
 ether_crc() function.
 */
-int amd8111e_ether_crc(int len, char* mac_addr)
+static int amd8111e_ether_crc(int len, char* mac_addr)
 {
 	int i,byte;
 	unsigned char octet;
@@ -1717,7 +1717,7 @@
 /* 
 This function changes the mtu of the device. It restarts the device  to initialize the descriptor with new receive buffers.
 */  
-int amd8111e_change_mtu(struct net_device *dev, int new_mtu)
+static int amd8111e_change_mtu(struct net_device *dev, int new_mtu)
 {
 	struct amd8111e_priv *lp = netdev_priv(dev);
 	int err;
diff -Nru a/drivers/net/arcnet/arc-rawmode.c b/drivers/net/arcnet/arc-rawmode.c
--- a/drivers/net/arcnet/arc-rawmode.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/arcnet/arc-rawmode.c	2005-03-09 12:20:51 -05:00
@@ -87,7 +87,7 @@
 static void rx(struct net_device *dev, int bufnum,
 	       struct archdr *pkthdr, int length)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	struct sk_buff *skb;
 	struct archdr *pkt = pkthdr;
 	int ofs;
@@ -168,7 +168,7 @@
 static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
 		      int bufnum)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	struct arc_hardware *hard = &pkt->hard;
 	int ofs;
 
diff -Nru a/drivers/net/arcnet/arc-rimi.c b/drivers/net/arcnet/arc-rimi.c
--- a/drivers/net/arcnet/arc-rimi.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/arcnet/arc-rimi.c	2005-03-09 12:20:51 -05:00
@@ -230,7 +230,7 @@
  */
 static int arcrimi_reset(struct net_device *dev, int really_reset)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	void __iomem *ioaddr = lp->mem_start + 0x800;
 
 	BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n", dev->name, ASTATUS());
@@ -251,7 +251,7 @@
 
 static void arcrimi_setmask(struct net_device *dev, int mask)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	void __iomem *ioaddr = lp->mem_start + 0x800;
 
 	AINTMASK(mask);
@@ -259,7 +259,7 @@
 
 static int arcrimi_status(struct net_device *dev)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	void __iomem *ioaddr = lp->mem_start + 0x800;
 
 	return ASTATUS();
@@ -267,7 +267,7 @@
 
 static void arcrimi_command(struct net_device *dev, int cmd)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	void __iomem *ioaddr = lp->mem_start + 0x800;
 
 	ACOMMAND(cmd);
@@ -276,7 +276,7 @@
 static void arcrimi_copy_to_card(struct net_device *dev, int bufnum, int offset,
 				 void *buf, int count)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	void __iomem *memaddr = lp->mem_start + 0x800 + bufnum * 512 + offset;
 	TIME("memcpy_toio", count, memcpy_toio(memaddr, buf, count));
 }
@@ -285,7 +285,7 @@
 static void arcrimi_copy_from_card(struct net_device *dev, int bufnum, int offset,
 				   void *buf, int count)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	void __iomem *memaddr = lp->mem_start + 0x800 + bufnum * 512 + offset;
 	TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
 }
@@ -331,7 +331,7 @@
 static void __exit arc_rimi_exit(void)
 {
 	struct net_device *dev = my_dev;
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 
 	unregister_netdev(dev);
 	iounmap(lp->mem_start);
diff -Nru a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
--- a/drivers/net/arcnet/arcnet.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/arcnet/arcnet.c	2005-03-09 12:20:51 -05:00
@@ -181,7 +181,7 @@
 void arcnet_dump_packet(struct net_device *dev, int bufnum, char *desc,
 			int take_arcnet_lock)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	int i, length;
 	unsigned long flags = 0;
 	static uint8_t buf[512];
@@ -244,7 +244,7 @@
  */
 static void release_arcbuf(struct net_device *dev, int bufnum)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	int i;
 
 	lp->buf_queue[lp->first_free_buf++] = bufnum;
@@ -266,7 +266,7 @@
  */
 static int get_arcbuf(struct net_device *dev)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	int buf = -1, i;
 
 	if (!atomic_dec_and_test(&lp->buf_lock)) {
@@ -367,7 +367,7 @@
  */
 static int arcnet_open(struct net_device *dev)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	int count, newmtu, error;
 
 	BUGMSG(D_INIT,"opened.");
@@ -467,7 +467,7 @@
 /* The inverse routine to arcnet_open - shuts down the card. */
 static int arcnet_close(struct net_device *dev)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 
 	netif_stop_queue(dev);
 
@@ -488,7 +488,7 @@
 			 unsigned short type, void *daddr, void *saddr,
 			 unsigned len)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	uint8_t _daddr, proto_num;
 	struct ArcProto *proto;
 
@@ -546,7 +546,7 @@
 static int arcnet_rebuild_header(struct sk_buff *skb)
 {
 	struct net_device *dev = skb->dev;
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	int status = 0;		/* default is failure */
 	unsigned short type;
 	uint8_t daddr=0;
@@ -591,7 +591,7 @@
 /* Called by the kernel in order to transmit a packet. */
 static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	struct archdr *pkt;
 	struct arc_rfc1201 *soft;
 	struct ArcProto *proto;
@@ -674,7 +674,7 @@
  */
 static int go_tx(struct net_device *dev)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 
 	BUGMSG(D_DURING, "go_tx: status=%Xh, intmask=%Xh, next_tx=%d, cur_tx=%d\n",
 	       ASTATUS(), lp->intmask, lp->next_tx, lp->cur_tx);
@@ -705,7 +705,7 @@
 static void arcnet_timeout(struct net_device *dev)
 {
 	unsigned long flags;
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	int status = ASTATUS();
 	char *msg;
 
@@ -754,7 +754,7 @@
 
 	BUGMSG(D_DURING, "in arcnet_interrupt\n");
 	
-	lp = (struct arcnet_local *) dev->priv;
+	lp = dev->priv;
 	if (!lp)
 		BUG();
 		
@@ -989,7 +989,7 @@
  */
 void arcnet_rx(struct net_device *dev, int bufnum)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	struct archdr pkt;
 	struct arc_rfc1201 *soft;
 	int length, ofs;
@@ -1053,7 +1053,7 @@
  */
 static struct net_device_stats *arcnet_get_stats(struct net_device *dev)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	return &lp->stats;
 }
 
@@ -1070,7 +1070,7 @@
 static int null_build_header(struct sk_buff *skb, struct net_device *dev,
 			     unsigned short type, uint8_t daddr)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 
 	BUGMSG(D_PROTO,
 	       "tx: can't build header for encap %02Xh; load a protocol driver.\n",
@@ -1085,7 +1085,7 @@
 static int null_prepare_tx(struct net_device *dev, struct archdr *pkt,
 			   int length, int bufnum)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	struct arc_hardware newpkt;
 
 	BUGMSG(D_PROTO, "tx: no encap for this host; load a protocol driver.\n");
diff -Nru a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c
--- a/drivers/net/arcnet/com20020.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/arcnet/com20020.c	2005-03-09 12:20:51 -05:00
@@ -159,7 +159,7 @@
 
 	/* Initialize the rest of the device structure. */
 
-	lp = (struct arcnet_local *) dev->priv;
+	lp = dev->priv;
 
 	lp->hw.owner = THIS_MODULE;
 	lp->hw.command = com20020_command;
@@ -233,7 +233,7 @@
  */
 static int com20020_reset(struct net_device *dev, int really_reset)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	u_int ioaddr = dev->base_addr;
 	u_char inbyte;
 
@@ -300,7 +300,7 @@
 
 static void com20020_close(struct net_device *dev)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	int ioaddr = dev->base_addr;
 
 	/* disable transmitter */
diff -Nru a/drivers/net/arcnet/com90io.c b/drivers/net/arcnet/com90io.c
--- a/drivers/net/arcnet/com90io.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/arcnet/com90io.c	2005-03-09 12:20:51 -05:00
@@ -248,7 +248,7 @@
 		return -EBUSY;
 	}
 
-	lp = (struct arcnet_local *) (dev->priv);
+	lp = dev->priv;
 	lp->card_name = "COM90xx I/O";
 	lp->hw.command = com90io_command;
 	lp->hw.status = com90io_status;
@@ -290,7 +290,7 @@
  */
 static int com90io_reset(struct net_device *dev, int really_reset)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	short ioaddr = dev->base_addr;
 
 	BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n", dev->name, ASTATUS());
diff -Nru a/drivers/net/arcnet/com90xx.c b/drivers/net/arcnet/com90xx.c
--- a/drivers/net/arcnet/com90xx.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/arcnet/com90xx.c	2005-03-09 12:20:51 -05:00
@@ -529,7 +529,7 @@
  */
 int com90xx_reset(struct net_device *dev, int really_reset)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	short ioaddr = dev->base_addr;
 
 	BUGMSG(D_INIT, "Resetting (status=%02Xh)\n", ASTATUS());
@@ -565,7 +565,7 @@
 static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,
 				 void *buf, int count)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	void __iomem *memaddr = lp->mem_start + bufnum * 512 + offset;
 	TIME("memcpy_toio", count, memcpy_toio(memaddr, buf, count));
 }
@@ -574,7 +574,7 @@
 static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offset,
 				   void *buf, int count)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	void __iomem *memaddr = lp->mem_start + bufnum * 512 + offset;
 	TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
 }
@@ -600,7 +600,7 @@
 
 	for (count = 0; count < numcards; count++) {
 		dev = cards[count];
-		lp = (struct arcnet_local *) dev->priv;
+		lp = dev->priv;
 
 		unregister_netdev(dev);
 		free_irq(dev->irq, dev);
diff -Nru a/drivers/net/arcnet/rfc1051.c b/drivers/net/arcnet/rfc1051.c
--- a/drivers/net/arcnet/rfc1051.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/arcnet/rfc1051.c	2005-03-09 12:20:51 -05:00
@@ -88,7 +88,7 @@
  */
 static unsigned short type_trans(struct sk_buff *skb, struct net_device *dev)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	struct archdr *pkt = (struct archdr *) skb->data;
 	struct arc_rfc1051 *soft = &pkt->soft.rfc1051;
 	int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
@@ -125,7 +125,7 @@
 static void rx(struct net_device *dev, int bufnum,
 	       struct archdr *pkthdr, int length)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	struct sk_buff *skb;
 	struct archdr *pkt = pkthdr;
 	int ofs;
@@ -169,7 +169,7 @@
 static int build_header(struct sk_buff *skb, struct net_device *dev,
 			unsigned short type, uint8_t daddr)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	int hdr_size = ARC_HDR_SIZE + RFC1051_HDR_SIZE;
 	struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size);
 	struct arc_rfc1051 *soft = &pkt->soft.rfc1051;
@@ -220,7 +220,7 @@
 static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
 		      int bufnum)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	struct arc_hardware *hard = &pkt->hard;
 	int ofs;
 
diff -Nru a/drivers/net/arcnet/rfc1201.c b/drivers/net/arcnet/rfc1201.c
--- a/drivers/net/arcnet/rfc1201.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/arcnet/rfc1201.c	2005-03-09 12:20:51 -05:00
@@ -92,7 +92,7 @@
 {
 	struct archdr *pkt = (struct archdr *) skb->data;
 	struct arc_rfc1201 *soft = &pkt->soft.rfc1201;
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	int hdr_size = ARC_HDR_SIZE + RFC1201_HDR_SIZE;
 
 	/* Pull off the arcnet header. */
@@ -134,7 +134,7 @@
 static void rx(struct net_device *dev, int bufnum,
 	       struct archdr *pkthdr, int length)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	struct sk_buff *skb;
 	struct archdr *pkt = pkthdr;
 	struct arc_rfc1201 *soft = &pkthdr->soft.rfc1201;
@@ -376,7 +376,7 @@
 static int build_header(struct sk_buff *skb, struct net_device *dev,
 			unsigned short type, uint8_t daddr)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	int hdr_size = ARC_HDR_SIZE + RFC1201_HDR_SIZE;
 	struct archdr *pkt = (struct archdr *) skb_push(skb, hdr_size);
 	struct arc_rfc1201 *soft = &pkt->soft.rfc1201;
@@ -443,7 +443,7 @@
 static void load_pkt(struct net_device *dev, struct arc_hardware *hard,
 		     struct arc_rfc1201 *soft, int softlen, int bufnum)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	int ofs;
 
 	/* assume length <= XMTU: someone should have handled that by now. */
@@ -476,7 +476,7 @@
 static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
 		      int bufnum)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	const int maxsegsize = XMTU - RFC1201_HDR_SIZE;
 	struct Outgoing *out;
 
@@ -511,7 +511,7 @@
 
 static int continue_tx(struct net_device *dev, int bufnum)
 {
-	struct arcnet_local *lp = (struct arcnet_local *) dev->priv;
+	struct arcnet_local *lp = dev->priv;
 	struct Outgoing *out = &lp->outgoing;
 	struct arc_hardware *hard = &out->pkt->hard;
 	struct arc_rfc1201 *soft = &out->pkt->soft.rfc1201, *newsoft;
diff -Nru a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
--- a/drivers/net/bonding/bond_3ad.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/bonding/bond_3ad.c	2005-03-09 12:20:51 -05:00
@@ -2175,7 +2175,7 @@
  * received frames (loopback). Since only the payload is given to this
  * function, it check for loopback.
  */
-void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u16 length)
+static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u16 length)
 {
 	struct port *port;
 
diff -Nru a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h
--- a/drivers/net/bonding/bond_3ad.h	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/bonding/bond_3ad.h	2005-03-09 12:20:51 -05:00
@@ -290,7 +290,6 @@
 int  bond_3ad_bind_slave(struct slave *slave);
 void bond_3ad_unbind_slave(struct slave *slave);
 void bond_3ad_state_machine_handler(struct bonding *bond);
-void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u16 length);
 void bond_3ad_adapter_speed_changed(struct slave *slave);
 void bond_3ad_adapter_duplex_changed(struct slave *slave);
 void bond_3ad_handle_link_change(struct slave *slave, char link);
diff -Nru a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
--- a/drivers/net/bonding/bond_alb.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/bonding/bond_alb.c	2005-03-09 12:20:51 -05:00
@@ -275,7 +275,7 @@
 }
 
 /* Caller must hold bond lock for read */
-struct slave *tlb_choose_channel(struct bonding *bond, u32 hash_index, u32 skb_len)
+static struct slave *tlb_choose_channel(struct bonding *bond, u32 hash_index, u32 skb_len)
 {
 	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
 	struct tlb_client_info *hash_table;
@@ -627,7 +627,7 @@
 }
 
 /* Caller must hold both bond and ptr locks for read */
-struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bond)
+static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bond)
 {
 	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
 	struct arp_pkt *arp = (struct arp_pkt *)skb->nh.raw;
diff -Nru a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
--- a/drivers/net/cs89x0.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/cs89x0.c	2005-03-09 12:20:51 -05:00
@@ -136,6 +136,7 @@
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
+#include <linux/delay.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -909,8 +910,7 @@
 	writereg(dev, PP_SelfCTL, readreg(dev, PP_SelfCTL) | POWER_ON_RESET);
 
 	/* wait 30 ms */
-	current->state = TASK_INTERRUPTIBLE;
-	schedule_timeout(30*HZ/1000);
+	msleep(30);
 
 #ifndef CONFIG_ARCH_IXDP2X01
 	if (lp->chip_type != CS8900) {
diff -Nru a/drivers/net/depca.c b/drivers/net/depca.c
--- a/drivers/net/depca.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/depca.c	2005-03-09 12:20:51 -05:00
@@ -342,14 +342,14 @@
 static int depca_device_remove (struct device *device);
 
 #ifdef CONFIG_EISA
-struct eisa_device_id depca_eisa_ids[] = {
+static struct eisa_device_id depca_eisa_ids[] = {
 	{ "DEC4220", de422 },
 	{ "" }
 };
 
 static int depca_eisa_probe  (struct device *device);
 
-struct eisa_driver depca_eisa_driver = {
+static struct eisa_driver depca_eisa_driver = {
 	.id_table = depca_eisa_ids,
 	.driver   = {
 		.name    = depca_string,
diff -Nru a/drivers/net/dgrs.c b/drivers/net/dgrs.c
--- a/drivers/net/dgrs.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/dgrs.c	2005-03-09 12:20:51 -05:00
@@ -454,7 +454,7 @@
  *	up some state variables to let the host CPU continue doing
  *	other things until a DMA completion interrupt comes along.
  */
-void
+static void
 dgrs_rcv_frame(
 	struct net_device	*dev0,
 	DGRS_PRIV	*priv0,
@@ -1150,7 +1150,7 @@
 /*
  *	Probe (init) a board
  */
-int __init 
+static int __init 
 dgrs_probe1(struct net_device *dev)
 {
 	DGRS_PRIV	*priv = (DGRS_PRIV *) dev->priv;
@@ -1228,7 +1228,7 @@
        	return rc;
 }
 
-int __init 
+static int __init 
 dgrs_initclone(struct net_device *dev)
 {
 	DGRS_PRIV	*priv = (DGRS_PRIV *) dev->priv;
diff -Nru a/drivers/net/eepro100.c b/drivers/net/eepro100.c
--- a/drivers/net/eepro100.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/eepro100.c	2005-03-09 12:20:51 -05:00
@@ -152,16 +152,6 @@
 
 #define RUN_AT(x) (jiffies + (x))
 
-/* ACPI power states don't universally work (yet) */
-#ifndef CONFIG_PM
-#undef pci_set_power_state
-#define pci_set_power_state null_set_power_state
-static inline int null_set_power_state(struct pci_dev *dev, int state)
-{
-	return 0;
-}
-#endif /* CONFIG_PM */
-
 #define netdevice_start(dev)
 #define netdevice_stop(dev)
 #define netif_set_tx_timeout(dev, tf, tm) \
diff -Nru a/drivers/net/es3210.c b/drivers/net/es3210.c
--- a/drivers/net/es3210.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/es3210.c	2005-03-09 12:20:51 -05:00
@@ -159,6 +159,7 @@
 {
 	free_irq(dev->irq, dev);
 	release_region(dev->base_addr, ES_IO_EXTENT);
+	iounmap(ei_status.mem);
 }
 
 #ifndef MODULE
@@ -271,9 +272,14 @@
 		printk(" assigning ");
 	}
 
-	dev->mem_end = ei_status.rmem_end = dev->mem_start
-		+ (ES_STOP_PG - ES_START_PG)*256;
-	ei_status.rmem_start = dev->mem_start + TX_PAGES*256;
+	ei_status.mem = ioremap(dev->mem_start, (ES_STOP_PG - ES_START_PG)*256);
+	if (!ei_status.mem) {
+		printk("ioremap failed - giving up\n");
+		retval = -ENXIO;
+		goto out1;
+	}
+
+	dev->mem_end = dev->mem_start + (ES_STOP_PG - ES_START_PG)*256;
 
 	printk("mem %#lx-%#lx\n", dev->mem_start, dev->mem_end-1);
 
@@ -353,8 +359,8 @@
 static void
 es_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
 {
-	unsigned long hdr_start = dev->mem_start + ((ring_page - ES_START_PG)<<8);
-	isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
+	void __iomem *hdr_start = ei_status.mem + ((ring_page - ES_START_PG)<<8);
+	memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
 	hdr->count = (hdr->count + 3) & ~3;     /* Round up allocation. */
 }
 
@@ -367,27 +373,27 @@
 static void es_block_input(struct net_device *dev, int count, struct sk_buff *skb,
 						  int ring_offset)
 {
-	unsigned long xfer_start = dev->mem_start + ring_offset - (ES_START_PG<<8);
+	void __iomem *xfer_start = ei_status.mem + ring_offset - ES_START_PG*256;
 
-	if (xfer_start + count > ei_status.rmem_end) {
+	if (ring_offset + count > ES_STOP_PG*256) {
 		/* Packet wraps over end of ring buffer. */
-		int semi_count = ei_status.rmem_end - xfer_start;
-		isa_memcpy_fromio(skb->data, xfer_start, semi_count);
+		int semi_count = ES_STOP_PG*256 - ring_offset;
+		memcpy_fromio(skb->data, xfer_start, semi_count);
 		count -= semi_count;
-		isa_memcpy_fromio(skb->data + semi_count, ei_status.rmem_start, count);
+		memcpy_fromio(skb->data + semi_count, ei_status.mem, count);
 	} else {
 		/* Packet is in one chunk. */
-		isa_eth_io_copy_and_sum(skb, xfer_start, count, 0);
+		eth_io_copy_and_sum(skb, xfer_start, count, 0);
 	}
 }
 
 static void es_block_output(struct net_device *dev, int count,
 				const unsigned char *buf, int start_page)
 {
-	unsigned long shmem = dev->mem_start + ((start_page - ES_START_PG)<<8);
+	void __iomem *shmem = ei_status.mem + ((start_page - ES_START_PG)<<8);
 
 	count = (count + 3) & ~3;     /* Round up to doubleword */
-	isa_memcpy_toio(shmem, buf, count);
+	memcpy_toio(shmem, buf, count);
 }
 
 static int es_open(struct net_device *dev)
diff -Nru a/drivers/net/ethertap.c b/drivers/net/ethertap.c
--- a/drivers/net/ethertap.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/ethertap.c	2005-03-09 12:20:51 -05:00
@@ -343,7 +343,7 @@
 }
 
 
-int __init ethertap_init(void)
+static int __init ethertap_init(void)
 {
 	int i, err = 0;
 
@@ -371,7 +371,7 @@
 }
 module_init(ethertap_init);
 
-void __exit ethertap_cleanup(void)
+static void __exit ethertap_cleanup(void)
 {
 	int i;
 
diff -Nru a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c
--- a/drivers/net/ewrk3.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/ewrk3.c	2005-03-09 12:20:51 -05:00
@@ -273,6 +273,7 @@
 struct ewrk3_private {
 	char adapter_name[80];	/* Name exported to /proc/ioports */
 	u_long shmem_base;	/* Shared memory start address */
+	void __iomem *shmem;
 	u_long shmem_length;	/* Shared memory window length */
 	struct net_device_stats stats;	/* Public stats */
 	struct ewrk3_stats pktStats; /* Private stats counters */
@@ -281,7 +282,7 @@
 	u_char lemac;		/* Chip rev. level */
 	u_char hard_strapped;	/* Don't allow a full open */
 	u_char txc;		/* Transmit cut through */
-	u_char *mctbl;		/* Pointer to the multicast table */
+	void __iomem *mctbl;	/* Pointer to the multicast table */
 	u_char led_mask;	/* Used to reserve LED access for ethtool */
 	spinlock_t hw_lock;
 };
@@ -535,6 +536,9 @@
 
 	lp = netdev_priv(dev);
 	lp->shmem_base = mem_start;
+	lp->shmem = ioremap(mem_start, shmem_length);
+	if (!lp->shmem)
+		return -ENOMEM;
 	lp->shmem_length = shmem_length;
 	lp->lemac = lemac;
 	lp->hard_strapped = hard_strapped;
@@ -590,6 +594,7 @@
 				} else {
 					printk(", but incorrect IRQ line detected.\n");
 				}
+				iounmap(lp->shmem);
 				return -ENXIO;
 			}
 
@@ -768,7 +773,7 @@
 {
 	struct ewrk3_private *lp = netdev_priv(dev);
 	u_long iobase = dev->base_addr;
-	u_long buf = 0;
+	void __iomem *buf = NULL;
 	u_char icr;
 	u_char page;
 
@@ -801,13 +806,13 @@
 	if (lp->shmem_length == IO_ONLY) {
 		outb (page, EWRK3_IOPR);
 	} else if (lp->shmem_length == SHMEM_2K) {
-		buf = lp->shmem_base;
+		buf = lp->shmem;
 		outb (page, EWRK3_MPR);
 	} else if (lp->shmem_length == SHMEM_32K) {
-		buf = ((((short) page << 11) & 0x7800) + lp->shmem_base);
+		buf = (((short) page << 11) & 0x7800) + lp->shmem;
 		outb ((page >> 4), EWRK3_MPR);
 	} else if (lp->shmem_length == SHMEM_64K) {
-		buf = ((((short) page << 11) & 0xf800) + lp->shmem_base);
+		buf = (((short) page << 11) & 0xf800) + lp->shmem;
 		outb ((page >> 5), EWRK3_MPR);
 	} else {
 		printk (KERN_ERR "%s: Oops - your private data area is hosed!\n",
@@ -831,30 +836,28 @@
 		}
 		outb (page, EWRK3_TQ);	/* Start sending pkt */
 	} else {
-		isa_writeb ((char) (TCR_QMODE | TCR_PAD | TCR_IFC), buf);	/* ctrl byte */
+		writeb ((char) (TCR_QMODE | TCR_PAD | TCR_IFC), buf);	/* ctrl byte */
 		buf += 1;
-		isa_writeb ((char) (skb->len & 0xff), buf);	/* length (16 bit xfer) */
+		writeb ((char) (skb->len & 0xff), buf);	/* length (16 bit xfer) */
 		buf += 1;
 		if (lp->txc) {
-			isa_writeb ((char)
-				    (((skb->len >> 8) & 0xff) | XCT), buf);
+			writeb(((skb->len >> 8) & 0xff) | XCT, buf);
 			buf += 1;
-			isa_writeb (0x04, buf);	/* index byte */
+			writeb (0x04, buf);	/* index byte */
 			buf += 1;
-			isa_writeb (0x00, (buf + skb->len));	/* Write the XCT flag */
-			isa_memcpy_toio (buf, skb->data, PRELOAD);	/* Write PRELOAD bytes */
+			writeb (0x00, (buf + skb->len));	/* Write the XCT flag */
+			memcpy_toio (buf, skb->data, PRELOAD);	/* Write PRELOAD bytes */
 			outb (page, EWRK3_TQ);	/* Start sending pkt */
-			isa_memcpy_toio (buf + PRELOAD,
+			memcpy_toio (buf + PRELOAD,
 					 skb->data + PRELOAD,
 					 skb->len - PRELOAD);
-			isa_writeb (0xff, (buf + skb->len));	/* Write the XCT flag */
+			writeb (0xff, (buf + skb->len));	/* Write the XCT flag */
 		} else {
-			isa_writeb ((char)
-				    ((skb->len >> 8) & 0xff), buf);
+			writeb ((skb->len >> 8) & 0xff, buf);
 			buf += 1;
-			isa_writeb (0x04, buf);	/* index byte */
+			writeb (0x04, buf);	/* index byte */
 			buf += 1;
-			isa_memcpy_toio (buf, skb->data, skb->len);	/* Write data bytes */
+			memcpy_toio (buf, skb->data, skb->len);	/* Write data bytes */
 			outb (page, EWRK3_TQ);	/* Start sending pkt */
 		}
 	}
@@ -940,7 +943,7 @@
 	u_long iobase = dev->base_addr;
 	int i, status = 0;
 	u_char page;
-	u_long buf = 0;
+	void __iomem *buf = NULL;
 
 	while (inb(EWRK3_RQC) && !status) {	/* Whilst there's incoming data */
 		if ((page = inb(EWRK3_RQ)) < lp->mPage) {	/* Get next entry's buffer page */
@@ -950,13 +953,13 @@
 			if (lp->shmem_length == IO_ONLY) {
 				outb(page, EWRK3_IOPR);
 			} else if (lp->shmem_length == SHMEM_2K) {
-				buf = lp->shmem_base;
+				buf = lp->shmem;
 				outb(page, EWRK3_MPR);
 			} else if (lp->shmem_length == SHMEM_32K) {
-				buf = ((((short) page << 11) & 0x7800) + lp->shmem_base);
+				buf = (((short) page << 11) & 0x7800) + lp->shmem;
 				outb((page >> 4), EWRK3_MPR);
 			} else if (lp->shmem_length == SHMEM_64K) {
-				buf = ((((short) page << 11) & 0xf800) + lp->shmem_base);
+				buf = (((short) page << 11) & 0xf800) + lp->shmem;
 				outb((page >> 5), EWRK3_MPR);
 			} else {
 				status = -1;
@@ -972,9 +975,9 @@
 					pkt_len = inb(EWRK3_DATA);
 					pkt_len |= ((u_short) inb(EWRK3_DATA) << 8);
 				} else {
-					rx_status = isa_readb(buf);
+					rx_status = readb(buf);
 					buf += 1;
-					pkt_len = isa_readw(buf);
+					pkt_len = readw(buf);
 					buf += 3;
 				}
 
@@ -1001,7 +1004,7 @@
 								*p++ = inb(EWRK3_DATA);
 							}
 						} else {
-							isa_memcpy_fromio(p, buf, pkt_len);
+							memcpy_fromio(p, buf, pkt_len);
 						}
 
 						for (i = 1; i < EWRK3_PKT_STAT_SZ - 1; i++) {
@@ -1153,9 +1156,9 @@
 	csr = inb(EWRK3_CSR);
 
 	if (lp->shmem_length == IO_ONLY) {
-		lp->mctbl = (char *) PAGE0_HTE;
+		lp->mctbl = NULL;
 	} else {
-		lp->mctbl = (char *) (lp->shmem_base + PAGE0_HTE);
+		lp->mctbl = lp->shmem + PAGE0_HTE;
 	}
 
 	csr &= ~(CSR_PME | CSR_MCE);
@@ -1184,7 +1187,7 @@
 	u_long iobase = dev->base_addr;
 	int i;
 	char *addrs, bit, byte;
-	short *p = (short *) lp->mctbl;
+	short __iomem *p = lp->mctbl;
 	u16 hashcode;
 	u32 crc;
 
@@ -1192,7 +1195,7 @@
 
 	if (lp->shmem_length == IO_ONLY) {
 		outb(0, EWRK3_IOPR);
-		outw(EEPROM_OFFSET(lp->mctbl), EWRK3_PIR1);
+		outw(PAGE0_HTE, EWRK3_PIR1);
 	} else {
 		outb(0, EWRK3_MPR);
 	}
@@ -1202,7 +1205,7 @@
 			if (lp->shmem_length == IO_ONLY) {
 				outb(0xff, EWRK3_DATA);
 			} else {	/* memset didn't work here */
-				isa_writew(0xffff, (int) p);
+				writew(0xffff, p);
 				p++;
 				i++;
 			}
@@ -1219,8 +1222,8 @@
 				outb(0x00, EWRK3_DATA);
 			}
 		} else {
-			isa_memset_io((int) lp->mctbl, 0, (HASH_TABLE_LEN >> 3));
-			isa_writeb(0x80, (int) (lp->mctbl + (HASH_TABLE_LEN >> 4) - 1));
+			memset_io(lp->mctbl, 0, HASH_TABLE_LEN >> 3);
+			writeb(0x80, lp->mctbl + (HASH_TABLE_LEN >> 4) - 1);
 		}
 
 		/* Update table */
@@ -1237,13 +1240,13 @@
 				if (lp->shmem_length == IO_ONLY) {
 					u_char tmp;
 
-					outw((short) ((long) lp->mctbl) + byte, EWRK3_PIR1);
+					outw(PAGE0_HTE + byte, EWRK3_PIR1);
 					tmp = inb(EWRK3_DATA);
 					tmp |= bit;
-					outw((short) ((long) lp->mctbl) + byte, EWRK3_PIR1);
+					outw(PAGE0_HTE + byte, EWRK3_PIR1);
 					outb(tmp, EWRK3_DATA);
 				} else {
-					isa_writeb(isa_readb((int)(lp->mctbl + byte)) | bit, (int)(lp->mctbl + byte));
+					writeb(readb(lp->mctbl + byte) | bit, lp->mctbl + byte);
 				}
 			}
 		}
@@ -1654,8 +1657,7 @@
 
 		/* Wait a little while */
 		spin_unlock_irqrestore(&lp->hw_lock, flags);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HZ>>2);
+		msleep(250);
 		spin_lock_irqsave(&lp->hw_lock, flags);
 
 		/* Exit if we got a signal */
@@ -1784,7 +1786,7 @@
 			}
 		} else {
 			outb(0, EWRK3_MPR);
-			isa_memcpy_fromio(tmp->addr, lp->shmem_base + PAGE0_HTE, (HASH_TABLE_LEN >> 3));
+			memcpy_fromio(tmp->addr, lp->shmem + PAGE0_HTE, (HASH_TABLE_LEN >> 3));
 		}
 		spin_unlock_irqrestore(&lp->hw_lock, flags);
 
@@ -1954,10 +1956,13 @@
 	int i;
 
 	for( i=0; i<ndevs; i++ ) {
-		unregister_netdev(ewrk3_devs[i]);
-		release_region(ewrk3_devs[i]->base_addr, EWRK3_TOTAL_SIZE);
-		free_netdev(ewrk3_devs[i]);
+		struct net_device *dev = ewrk3_devs[i];
+		struct ewrk3_private *lp = netdev_priv(dev);
 		ewrk3_devs[i] = NULL;
+		unregister_netdev(dev);
+		release_region(dev->base_addr, EWRK3_TOTAL_SIZE);
+		iounmap(lp->shmem);
+		free_netdev(dev);
 	}
 }
 
diff -Nru a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
--- a/drivers/net/ioc3-eth.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/ioc3-eth.c	2005-03-09 12:20:51 -05:00
@@ -56,7 +56,6 @@
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/skbuff.h>
-#include <linux/dp83840.h>
 #include <net/ip.h>
 
 #include <asm/byteorder.h>
diff -Nru a/drivers/net/irda/act200l-sir.c b/drivers/net/irda/act200l-sir.c
--- a/drivers/net/irda/act200l-sir.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/irda/act200l-sir.c	2005-03-09 12:20:51 -05:00
@@ -177,8 +177,7 @@
 
 	/* Write control bytes */
 	sirdev_raw_write(dev, control, 3);
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(msecs_to_jiffies(5));
+	msleep(5);
 
 	/* Go back to normal mode */
 	sirdev_set_dtr_rts(dev, TRUE, TRUE);
diff -Nru a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c
--- a/drivers/net/irda/irtty-sir.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/irda/irtty-sir.c	2005-03-09 12:20:51 -05:00
@@ -32,6 +32,7 @@
 #include <linux/init.h>
 #include <asm/uaccess.h>
 #include <linux/smp_lock.h>
+#include <linux/delay.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/irda_device.h>
@@ -97,8 +98,7 @@
 		unlock_kernel();
 	}
 	else {
-		set_task_state(current, TASK_UNINTERRUPTIBLE);
-		schedule_timeout(msecs_to_jiffies(USBSERIAL_TX_DONE_DELAY));
+		msleep(USBSERIAL_TX_DONE_DELAY);
 	}
 }
 
diff -Nru a/drivers/net/irda/ma600-sir.c b/drivers/net/irda/ma600-sir.c
--- a/drivers/net/irda/ma600-sir.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/irda/ma600-sir.c	2005-03-09 12:20:51 -05:00
@@ -191,8 +191,7 @@
 	sirdev_raw_write(dev, &byte, sizeof(byte));
 
 	/* Wait at least 10ms: fake wait_until_sent - 10 bits at 9600 baud*/
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(msecs_to_jiffies(15));		/* old ma600 uses 15ms */
+	msleep(15);					/* old ma600 uses 15ms */
 
 #if 1
 	/* read-back of the control byte. ma600 is the first dongle driver
@@ -215,8 +214,7 @@
 	sirdev_set_dtr_rts(dev, TRUE, TRUE);
 
 	/* Wait at least 10ms */
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(msecs_to_jiffies(10));
+	msleep(10);
 
 	/* dongle is now switched to the new speed */
 	dev->speed = speed;
@@ -245,13 +243,11 @@
 
 	/* Reset the dongle : set DTR low for 10 ms */
 	sirdev_set_dtr_rts(dev, FALSE, TRUE);
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(msecs_to_jiffies(10));
+	msleep(10);
 
 	/* Go back to normal mode */
 	sirdev_set_dtr_rts(dev, TRUE, TRUE);
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(msecs_to_jiffies(10));
+	msleep(10);
 
 	dev->speed = 9600;      /* That's the dongle-default */
 
diff -Nru a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c
--- a/drivers/net/irda/sir_dev.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/irda/sir_dev.c	2005-03-09 12:20:51 -05:00
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/smp_lock.h>
+#include <linux/delay.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/wrapper.h>
@@ -73,8 +74,7 @@
 	spin_lock_irqsave(&dev->tx_lock, flags);	/* serialize with other tx operations */
 	while (dev->tx_buff.len > 0) {			/* wait until tx idle */
 		spin_unlock_irqrestore(&dev->tx_lock, flags);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(msecs_to_jiffies(10));
+		msleep(10);
 		spin_lock_irqsave(&dev->tx_lock, flags);
 	}
 
diff -Nru a/drivers/net/irda/tekram-sir.c b/drivers/net/irda/tekram-sir.c
--- a/drivers/net/irda/tekram-sir.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/irda/tekram-sir.c	2005-03-09 12:20:51 -05:00
@@ -210,8 +210,7 @@
 	sirdev_set_dtr_rts(dev, FALSE, TRUE); 
 
 	/* Should sleep 1 ms */
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(msecs_to_jiffies(1));
+	msleep(1);
 
 	/* Set DTR, Set RTS */
 	sirdev_set_dtr_rts(dev, TRUE, TRUE);
diff -Nru a/drivers/net/loopback.c b/drivers/net/loopback.c
--- a/drivers/net/loopback.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/loopback.c	2005-03-09 12:20:51 -05:00
@@ -184,7 +184,7 @@
 	return stats;
 }
 
-u32 loopback_get_link(struct net_device *dev)
+static u32 loopback_get_link(struct net_device *dev)
 {
 	return 1;
 }
diff -Nru a/drivers/net/lp486e.c b/drivers/net/lp486e.c
--- a/drivers/net/lp486e.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/lp486e.c	2005-03-09 12:20:51 -05:00
@@ -112,8 +112,10 @@
 	CmdDiagnose = 7
 };
 
-char *CUcmdnames[8] = { "NOP", "IASetup", "Configure", "MulticastList",
-			"Tx", "TDR", "Dump", "Diagnose" };
+#if 0
+static const char *CUcmdnames[8] = { "NOP", "IASetup", "Configure", "MulticastList",
+				     "Tx", "TDR", "Dump", "Diagnose" };
+#endif
 
 /* Status word bits */
 #define	STAT_CX		0x8000	/* The CU finished executing a command
@@ -960,7 +962,7 @@
 		(unsigned char) add[12], (unsigned char) add[13]);
 }
 
-int __init lp486e_probe(struct net_device *dev) {
+static int __init lp486e_probe(struct net_device *dev) {
 	struct i596_private *lp;
 	unsigned char eth_addr[6] = { 0, 0xaa, 0, 0, 0, 0 };
 	unsigned char *bios;
diff -Nru a/drivers/net/ni65.c b/drivers/net/ni65.c
--- a/drivers/net/ni65.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/ni65.c	2005-03-09 12:20:51 -05:00
@@ -526,8 +526,7 @@
 			ni65_init_lance(p,dev->dev_addr,0,0);
 			irq_mask = probe_irq_on();
 			writereg(CSR0_INIT|CSR0_INEA,CSR0); /* trigger interrupt */
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(HZ/50);
+			msleep(20);
 			dev->irq = probe_irq_off(irq_mask);
 			if(!dev->irq)
 			{
diff -Nru a/drivers/net/ns83820.c b/drivers/net/ns83820.c
--- a/drivers/net/ns83820.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/ns83820.c	2005-03-09 12:20:51 -05:00
@@ -2007,8 +2007,7 @@
 	if (reset_phy) {
 		printk(KERN_INFO "%s: resetting phy\n", ndev->name);
 		writel(dev->CFG_cache | CFG_PHY_RST, dev->base + CFG);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout((HZ+99)/100);
+		msleep(10);
 		writel(dev->CFG_cache, dev->base + CFG);
 	}
 
diff -Nru a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
--- a/drivers/net/pcmcia/ibmtr_cs.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/pcmcia/ibmtr_cs.c	2005-03-09 12:20:51 -05:00
@@ -343,7 +343,8 @@
     CS_CHECK(MapMemPage, pcmcia_map_mem_page(info->sram_win_handle, &mem));
 
     ti->sram_base = mem.CardOffset >> 12;
-    ti->sram_virt = (u_long)ioremap(req.Base, req.Size);
+    ti->sram_virt = ioremap(req.Base, req.Size);
+    ti->sram_phys = req.Base;
 
     CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
 
@@ -401,7 +402,7 @@
     pcmcia_release_irq(link->handle, &link->irq);
     if (link->win) {
 	struct tok_info *ti = netdev_priv(dev);
-	iounmap((void *)ti->mmio);
+	iounmap(ti->mmio);
 	pcmcia_release_window(link->win);
 	pcmcia_release_window(info->sram_win_handle);
     }
@@ -433,7 +434,7 @@
         if (link->state & DEV_CONFIG) {
 	    /* set flag to bypass normal interrupt code */
 	    struct tok_info *priv = netdev_priv(dev);
-	    priv->sram_virt |= 1;
+	    priv->sram_phys |= 1;
 	    netif_device_detach(dev);
         }
         break;
diff -Nru a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
--- a/drivers/net/pcmcia/xirc2ps_cs.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/pcmcia/xirc2ps_cs.c	2005-03-09 12:20:51 -05:00
@@ -415,11 +415,6 @@
 #define PutByte(reg,value) outb((value), ioaddr+(reg))
 #define PutWord(reg,value) outw((value), ioaddr+(reg))
 
-#define Wait(n) do { \
-	set_current_state(TASK_UNINTERRUPTIBLE); \
-	schedule_timeout(n); \
-} while (0)
-
 /*====== Functions used for debugging =================================*/
 #if defined(PCMCIA_DEBUG) && 0 /* reading regs may change system status */
 static void
@@ -1707,12 +1702,12 @@
     SelectPage(4);
     udelay(1);
     PutByte(XIRCREG4_GPR1, 0);	     /* clear bit 0: power down */
-    Wait(HZ/25);		     /* wait 40 msec */
+    msleep(40);				     /* wait 40 msec */
     if (local->mohawk)
 	PutByte(XIRCREG4_GPR1, 1);	 /* set bit 0: power up */
     else
 	PutByte(XIRCREG4_GPR1, 1 | 4);	 /* set bit 0: power up, bit 2: AIC */
-    Wait(HZ/50);		     /* wait 20 msec */
+    msleep(20);			     /* wait 20 msec */
 }
 
 static void
@@ -1726,9 +1721,9 @@
 
     hardreset(dev);
     PutByte(XIRCREG_CR, SoftReset); /* set */
-    Wait(HZ/50);		     /* wait 20 msec */
+    msleep(20);			     /* wait 20 msec */
     PutByte(XIRCREG_CR, 0);	     /* clear */
-    Wait(HZ/25);		     /* wait 40 msec */
+    msleep(40);			     /* wait 40 msec */
     if (local->mohawk) {
 	SelectPage(4);
 	/* set pin GP1 and GP2 to output  (0x0c)
@@ -1739,7 +1734,7 @@
     }
 
     /* give the circuits some time to power up */
-    Wait(HZ/2);		/* about 500ms */
+    msleep(500);			/* about 500ms */
 
     local->last_ptr_value = 0;
     local->silicon = local->mohawk ? (GetByte(XIRCREG4_BOV) & 0x70) >> 4
@@ -1758,7 +1753,7 @@
 	SelectPage(0x42);
 	PutByte(XIRCREG42_SWC1, 0x80);
     }
-    Wait(HZ/25);		     /* wait 40 msec to let it complete */
+    msleep(40);			     /* wait 40 msec to let it complete */
 
   #ifdef PCMCIA_DEBUG
     if (pc_debug) {
@@ -1817,7 +1812,7 @@
 	    printk(KERN_INFO "%s: MII selected\n", dev->name);
 	    SelectPage(2);
 	    PutByte(XIRCREG2_MSR, GetByte(XIRCREG2_MSR) | 0x08);
-	    Wait(HZ/50);
+	    msleep(20);
 	} else {
 	    printk(KERN_INFO "%s: MII detected; using 10mbs\n",
 		   dev->name);
@@ -1826,7 +1821,7 @@
 		PutByte(XIRCREG42_SWC1, 0xC0);
 	    else  /* enable 10BaseT */
 		PutByte(XIRCREG42_SWC1, 0x80);
-	    Wait(HZ/25);	/* wait 40 msec to let it complete */
+	    msleep(40);			/* wait 40 msec to let it complete */
 	}
 	if (full_duplex)
 	    PutByte(XIRCREG1_ECR, GetByte(XIRCREG1_ECR | FullDuplex));
@@ -1919,7 +1914,7 @@
 	 * Fixme: Better to use a timer here!
 	 */
 	for (i=0; i < 35; i++) {
-	    Wait(HZ/10);	 /* wait 100 msec */
+	    msleep(100);	 /* wait 100 msec */
 	    status = mii_rd(ioaddr,  0, 1);
 	    if ((status & 0x0020) && (status & 0x0004))
 		break;
diff -Nru a/drivers/net/ppp_deflate.c b/drivers/net/ppp_deflate.c
--- a/drivers/net/ppp_deflate.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/ppp_deflate.c	2005-03-09 12:20:51 -05:00
@@ -600,7 +600,7 @@
 /*
  * Procedures exported to if_ppp.c.
  */
-struct compressor ppp_deflate = {
+static struct compressor ppp_deflate = {
 	.compress_proto =	CI_DEFLATE,
 	.comp_alloc =		z_comp_alloc,
 	.comp_free =		z_comp_free,
@@ -618,7 +618,7 @@
 	.owner =		THIS_MODULE
 };
 
-struct compressor ppp_deflate_draft = {
+static struct compressor ppp_deflate_draft = {
 	.compress_proto =	CI_DEFLATE_DRAFT,
 	.comp_alloc =		z_comp_alloc,
 	.comp_free =		z_comp_free,
diff -Nru a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
--- a/drivers/net/ppp_generic.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/ppp_generic.c	2005-03-09 12:20:51 -05:00
@@ -2741,8 +2741,6 @@
 EXPORT_SYMBOL(ppp_output_wakeup);
 EXPORT_SYMBOL(ppp_register_compressor);
 EXPORT_SYMBOL(ppp_unregister_compressor);
-EXPORT_SYMBOL(all_ppp_units); /* for debugging */
-EXPORT_SYMBOL(all_channels); /* for debugging */
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_CHARDEV_MAJOR(PPP_MAJOR);
 MODULE_ALIAS("/dev/ppp");
diff -Nru a/drivers/net/pppoe.c b/drivers/net/pppoe.c
--- a/drivers/net/pppoe.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/pppoe.c	2005-03-09 12:20:51 -05:00
@@ -1036,7 +1036,7 @@
 	read_unlock_bh(&pppoe_hash_lock);
 }
 
-struct seq_operations pppoe_seq_ops = {
+static struct seq_operations pppoe_seq_ops = {
 	.start		= pppoe_seq_start,
 	.next		= pppoe_seq_next,
 	.stop		= pppoe_seq_stop,
diff -Nru a/drivers/net/s2io.c b/drivers/net/s2io.c
--- a/drivers/net/s2io.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/s2io.c	2005-03-09 12:20:51 -05:00
@@ -1350,7 +1350,7 @@
  *
  */
 
-void fix_mac_address(nic_t * sp)
+static void fix_mac_address(nic_t * sp)
 {
 	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64;
@@ -1506,7 +1506,7 @@
  *  Return Value: void 
 */
 
-void free_tx_buffers(struct s2io_nic *nic)
+static void free_tx_buffers(struct s2io_nic *nic)
 {
 	struct net_device *dev = nic->dev;
 	struct sk_buff *skb;
@@ -1597,7 +1597,7 @@
  *  SUCCESS on success or an appropriate -ve value on failure.
  */
 
-int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
+static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
 {
 	struct net_device *dev = nic->dev;
 	struct sk_buff *skb;
@@ -2422,7 +2422,7 @@
  *   SUCCESS on success and FAILURE on failure.
  */
 
-int wait_for_cmd_complete(nic_t * sp)
+static int wait_for_cmd_complete(nic_t * sp)
 {
 	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	int ret = FAILURE, cnt = 0;
@@ -2452,7 +2452,7 @@
  *  void.
  */
 
-void s2io_reset(nic_t * sp)
+static void s2io_reset(nic_t * sp)
 {
 	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64;
@@ -2504,7 +2504,7 @@
  *  SUCCESS on success and FAILURE on failure.
  */
 
-int s2io_set_swapper(nic_t * sp)
+static int s2io_set_swapper(nic_t * sp)
 {
 	struct net_device *dev = sp->dev;
 	XENA_dev_config_t __iomem *bar0 = sp->bar0;
@@ -2598,7 +2598,7 @@
  *   file on failure.
  */
 
-int s2io_open(struct net_device *dev)
+static int s2io_open(struct net_device *dev)
 {
 	nic_t *sp = dev->priv;
 	int err = 0;
@@ -2650,7 +2650,7 @@
  *  file on failure.
  */
 
-int s2io_close(struct net_device *dev)
+static int s2io_close(struct net_device *dev)
 {
 	nic_t *sp = dev->priv;
 
@@ -2677,7 +2677,7 @@
  *  0 on success & 1 on failure.
  */
 
-int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
+static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	nic_t *sp = dev->priv;
 	u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off;
@@ -2897,7 +2897,7 @@
  *  pointer to the updated net_device_stats structure.
  */
 
-struct net_device_stats *s2io_get_stats(struct net_device *dev)
+static struct net_device_stats *s2io_get_stats(struct net_device *dev)
 {
 	nic_t *sp = dev->priv;
 	mac_info_t *mac_control;
@@ -3150,7 +3150,7 @@
  * return 0 on success.
  */
 
-int s2io_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info)
+static int s2io_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info)
 {
 	nic_t *sp = dev->priv;
 	info->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
@@ -3347,8 +3347,8 @@
  * int, returns 0 on Success
  */
 
-int s2io_ethtool_setpause_data(struct net_device *dev,
-			       struct ethtool_pauseparam *ep)
+static int s2io_ethtool_setpause_data(struct net_device *dev,
+				      struct ethtool_pauseparam *ep)
 {
 	u64 val64;
 	nic_t *sp = dev->priv;
@@ -3463,8 +3463,8 @@
  *  int  0 on success
  */
 
-int s2io_ethtool_geeprom(struct net_device *dev,
-			 struct ethtool_eeprom *eeprom, u8 * data_buf)
+static int s2io_ethtool_geeprom(struct net_device *dev,
+				struct ethtool_eeprom *eeprom, u8 * data_buf)
 {
 	u32 data, i, valid;
 	nic_t *sp = dev->priv;
@@ -3961,19 +3961,20 @@
 	tmp_stats[i++] = stat_info->rmac_err_tcp;
 }
 
-int s2io_ethtool_get_regs_len(struct net_device *dev)
+static int s2io_ethtool_get_regs_len(struct net_device *dev)
 {
 	return (XENA_REG_SPACE);
 }
 
 
-u32 s2io_ethtool_get_rx_csum(struct net_device * dev)
+static u32 s2io_ethtool_get_rx_csum(struct net_device * dev)
 {
 	nic_t *sp = dev->priv;
 
 	return (sp->rx_csum);
 }
-int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
+
+static int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
 {
 	nic_t *sp = dev->priv;
 
@@ -3984,17 +3985,19 @@
 
 	return 0;
 }
-int s2io_get_eeprom_len(struct net_device *dev)
+
+static int s2io_get_eeprom_len(struct net_device *dev)
 {
 	return (XENA_EEPROM_SPACE);
 }
 
-int s2io_ethtool_self_test_count(struct net_device *dev)
+static int s2io_ethtool_self_test_count(struct net_device *dev)
 {
 	return (S2IO_TEST_LEN);
 }
-void s2io_ethtool_get_strings(struct net_device *dev,
-			      u32 stringset, u8 * data)
+
+static void s2io_ethtool_get_strings(struct net_device *dev,
+				     u32 stringset, u8 * data)
 {
 	switch (stringset) {
 	case ETH_SS_TEST:
@@ -4005,12 +4008,13 @@
 		       sizeof(ethtool_stats_keys));
 	}
 }
+
 static int s2io_ethtool_get_stats_count(struct net_device *dev)
 {
 	return (S2IO_STAT_LEN);
 }
 
-int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
+static int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
 {
 	if (data)
 		dev->features |= NETIF_F_IP_CSUM;
@@ -4066,7 +4070,7 @@
  *  function returns OP NOT SUPPORTED value.
  */
 
-int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	return -EOPNOTSUPP;
 }
@@ -4082,7 +4086,7 @@
  *   file on failure.
  */
 
-int s2io_change_mtu(struct net_device *dev, int new_mtu)
+static int s2io_change_mtu(struct net_device *dev, int new_mtu)
 {
 	nic_t *sp = dev->priv;
 	XENA_dev_config_t __iomem *bar0 = sp->bar0;
@@ -4476,7 +4480,7 @@
  *  void.
  */
 
-void s2io_link(nic_t * sp, int link)
+static void s2io_link(nic_t * sp, int link)
 {
 	struct net_device *dev = (struct net_device *) sp->dev;
 
@@ -4493,23 +4497,6 @@
 }
 
 /**
- *  get_xena_rev_id - to identify revision ID of xena. 
- *  @pdev : PCI Dev structure
- *  Description:
- *  Function to identify the Revision ID of xena.
- *  Return value:
- *  returns the revision ID of the device.
- */
-
-int get_xena_rev_id(struct pci_dev *pdev)
-{
-	u8 id = 0;
-	int ret;
-	ret = pci_read_config_byte(pdev, PCI_REVISION_ID, (u8 *) & id);
-	return id;
-}
-
-/**
  *  s2io_init_pci -Initialization of PCI and PCI-X configuration registers . 
  *  @sp : private member of the device structure, which is a pointer to the 
  *  s2io_nic structure.
@@ -4962,7 +4949,7 @@
  * Description: This function is the cleanup routine for the driver. It unregist * ers the driver.
  */
 
-void s2io_closer(void)
+static void s2io_closer(void)
 {
 	pci_unregister_driver(&s2io_driver);
 	DBG_PRINT(INIT_DBG, "cleanup done\n");
diff -Nru a/drivers/net/s2io.h b/drivers/net/s2io.h
--- a/drivers/net/s2io.h	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/s2io.h	2005-03-09 12:20:51 -05:00
@@ -848,7 +848,7 @@
 static void alarm_intr_handler(struct s2io_nic *sp);
 
 static int s2io_starter(void);
-void s2io_closer(void);
+static void s2io_closer(void);
 static void s2io_tx_watchdog(struct net_device *dev);
 static void s2io_tasklet(unsigned long dev_addr);
 static void s2io_set_multicast(struct net_device *dev);
@@ -858,13 +858,13 @@
 static int rx_osm_handler(nic_t * sp, RxD_t * rxdp, int ring_no,
 			  buffAdd_t * ba);
 #endif
-void s2io_link(nic_t * sp, int link);
-void s2io_reset(nic_t * sp);
+static void s2io_link(nic_t * sp, int link);
+static void s2io_reset(nic_t * sp);
 #ifdef CONFIG_S2IO_NAPI
 static int s2io_poll(struct net_device *dev, int *budget);
 #endif
 static void s2io_init_pci(nic_t * sp);
-int s2io_set_mac_addr(struct net_device *dev, u8 * addr);
+static int s2io_set_mac_addr(struct net_device *dev, u8 * addr);
 static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs);
 static int verify_xena_quiescence(u64 val64, int flag);
 static struct ethtool_ops netdev_ethtool_ops;
diff -Nru a/drivers/net/sb1000.c b/drivers/net/sb1000.c
--- a/drivers/net/sb1000.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/sb1000.c	2005-03-09 12:20:51 -05:00
@@ -57,9 +57,9 @@
 #include <asm/uaccess.h>
 
 #ifdef SB1000_DEBUG
-int sb1000_debug = SB1000_DEBUG;
+static int sb1000_debug = SB1000_DEBUG;
 #else
-int sb1000_debug = 1;
+static int sb1000_debug = 1;
 #endif
 
 static const int SB1000_IO_EXTENT = 8;
@@ -116,15 +116,15 @@
 static inline int sb1000_end_get_set_command(const int ioaddr[],
 	const char* name);
 static inline int sb1000_activate(const int ioaddr[], const char* name);
-static inline int sb1000_get_firmware_version(const int ioaddr[],
+static int sb1000_get_firmware_version(const int ioaddr[],
 	const char* name, unsigned char version[], int do_end);
-static inline int sb1000_get_frequency(const int ioaddr[], const char* name,
+static int sb1000_get_frequency(const int ioaddr[], const char* name,
 	int* frequency);
-static inline int sb1000_set_frequency(const int ioaddr[], const char* name,
+static int sb1000_set_frequency(const int ioaddr[], const char* name,
 	int frequency);
-static inline int sb1000_get_PIDs(const int ioaddr[], const char* name,
+static int sb1000_get_PIDs(const int ioaddr[], const char* name,
 	short PID[]);
-static inline int sb1000_set_PIDs(const int ioaddr[], const char* name,
+static int sb1000_set_PIDs(const int ioaddr[], const char* name,
 	const short PID[]);
 
 /* SB1000 commands for frame rx interrupt */
@@ -252,7 +252,7 @@
  * SB1000 hardware routines to be used during open/configuration phases
  */
 
-const int TimeOutJiffies = (875 * HZ) / 100;
+static const int TimeOutJiffies = (875 * HZ) / 100;
 
 static inline void nicedelay(unsigned long usecs)
 {
@@ -363,7 +363,7 @@
 /*
  * SB1000 hardware routines to be used during frame rx interrupt
  */
-const int Sb1000TimeOutJiffies = 7 * HZ;
+static const int Sb1000TimeOutJiffies = 7 * HZ;
 
 /* Card Wait For Ready (to be used during frame rx) */
 static inline int
@@ -552,7 +552,7 @@
 }
 
 /* get SB1000 firmware version */
-static inline int
+static int
 sb1000_get_firmware_version(const int ioaddr[], const char* name,
 	unsigned char version[], int do_end)
 {
@@ -575,7 +575,7 @@
 }
 
 /* get SB1000 frequency */
-static inline int
+static int
 sb1000_get_frequency(const int ioaddr[], const char* name, int* frequency)
 {
 	unsigned char st[7];
@@ -592,7 +592,7 @@
 }
 
 /* set SB1000 frequency */
-static inline int
+static int
 sb1000_set_frequency(const int ioaddr[], const char* name, int frequency)
 {
 	unsigned char st[7];
@@ -622,7 +622,7 @@
 }
 
 /* get SB1000 PIDs */
-static inline int
+static int
 sb1000_get_PIDs(const int ioaddr[], const char* name, short PID[])
 {
 	unsigned char st[7];
@@ -656,7 +656,7 @@
 }
 
 /* set SB1000 PIDs */
-static inline int
+static int
 sb1000_set_PIDs(const int ioaddr[], const char* name, const short PID[])
 {
 	unsigned char st[7];
diff -Nru a/drivers/net/shaper.c b/drivers/net/shaper.c
--- a/drivers/net/shaper.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/shaper.c	2005-03-09 12:20:51 -05:00
@@ -96,7 +96,7 @@
 }; 
 #define SHAPERCB(skb) ((struct shaper_cb *) ((skb)->cb))
 
-int sh_debug;		/* Debug flag */
+static int sh_debug;		/* Debug flag */
 
 #define SHAPER_BANNER	"CymruNet Traffic Shaper BETA 0.04 for Linux 2.1\n"
 
diff -Nru a/drivers/net/slhc.c b/drivers/net/slhc.c
--- a/drivers/net/slhc.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/slhc.c	2005-03-09 12:20:51 -05:00
@@ -693,33 +693,6 @@
 }
 
 
-void slhc_i_status(struct slcompress *comp)
-{
-	if (comp != NULLSLCOMPR) {
-		printk("\t%d Cmp, %d Uncmp, %d Bad, %d Tossed\n",
-			comp->sls_i_compressed,
-			comp->sls_i_uncompressed,
-			comp->sls_i_error,
-			comp->sls_i_tossed);
-	}
-}
-
-
-void slhc_o_status(struct slcompress *comp)
-{
-	if (comp != NULLSLCOMPR) {
-		printk("\t%d Cmp, %d Uncmp, %d AsIs, %d NotTCP\n",
-			comp->sls_o_compressed,
-			comp->sls_o_uncompressed,
-			comp->sls_o_tcp,
-			comp->sls_o_nontcp);
-		printk("\t%10d Searches, %10d Misses\n",
-			comp->sls_o_searches,
-			comp->sls_o_misses);
-	}
-}
-
-/* Should this be surrounded with "#ifdef CONFIG_MODULES" ? */
 /* VJ header compression */
 EXPORT_SYMBOL(slhc_init);
 EXPORT_SYMBOL(slhc_free);
diff -Nru a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c
--- a/drivers/net/smc-mca.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/smc-mca.c	2005-03-09 12:20:51 -05:00
@@ -310,9 +310,13 @@
 	ei_status.rx_start_page = START_PG + TX_PAGES;
 	ei_status.stop_page = num_pages;
 
-	ei_status.rmem_start = dev->mem_start + TX_PAGES * 256;
-	dev->mem_end = ei_status.rmem_end =
-	dev->mem_start + (ei_status.stop_page - START_PG) * 256;
+	ei_status.mem = ioremap(dev->mem_start, (ei_status.stop_page - START_PG) * 256);
+	if (!ei_status.mem) {
+		rc = -ENOMEM;
+		goto err_release_region;
+	}
+
+	dev->mem_end = dev->mem_start + (ei_status.stop_page - START_PG) * 256;
 
 	printk(", IRQ %d memory %#lx-%#lx.\n",
 	dev->irq, dev->mem_start, dev->mem_end - 1);
@@ -334,10 +338,12 @@
 
 	rc = register_netdev(dev);
 	if (rc)
-		goto err_release_region;
+		goto err_unmap;
 
 	return 0;
 
+err_unmap:
+	iounmap(ei_status.mem);
 err_release_region:
 	release_region(ioaddr, ULTRA_IO_EXTENT);
 err_unclaim:
@@ -395,13 +401,13 @@
 
 static void ultramca_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
 {
-	unsigned long hdr_start = dev->mem_start + ((ring_page - START_PG) << 8);
+	void __iomem *hdr_start = ei_status.mem + ((ring_page - START_PG) << 8);
 
 #ifdef notdef
 	/* Officially this is what we are doing, but the readl() is faster */
-	isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
+	memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
 #else
-	((unsigned int*)hdr)[0] = isa_readl(hdr_start);
+	((unsigned int*)hdr)[0] = readl(hdr_start);
 #endif
 }
 
@@ -411,17 +417,17 @@
 
 static void ultramca_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
 {
-	unsigned long xfer_start = dev->mem_start + ring_offset - (START_PG << 8);
+	void __iomem *xfer_start = ei_status.mem + ring_offset - START_PG * 256;
 
-	if (xfer_start + count > ei_status.rmem_end) {
+	if (ring_offset + count > ei_status.stop_page * 256) {
 		/* We must wrap the input move. */
-		int semi_count = ei_status.rmem_end - xfer_start;
-		isa_memcpy_fromio(skb->data, xfer_start, semi_count);
+		int semi_count = ei_status.stop_page * 256 - ring_offset;
+		memcpy_fromio(skb->data, xfer_start, semi_count);
 		count -= semi_count;
-		isa_memcpy_fromio(skb->data + semi_count, ei_status.rmem_start, count);
+		memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count);
 	} else {
 		/* Packet is in one chunk -- we can copy + cksum. */
-		isa_eth_io_copy_and_sum(skb, xfer_start, count, 0);
+		eth_io_copy_and_sum(skb, xfer_start, count, 0);
 	}
 
 }
@@ -429,9 +435,9 @@
 static void ultramca_block_output(struct net_device *dev, int count, const unsigned char *buf,
                 int start_page)
 {
-	unsigned long shmem = dev->mem_start + ((start_page - START_PG) << 8);
+	void __iomem *shmem = ei_status.mem + ((start_page - START_PG) << 8);
 
-	isa_memcpy_toio(shmem, buf, count);
+	memcpy_toio(shmem, buf, count);
 }
 
 static int ultramca_close_card(struct net_device *dev)
@@ -466,6 +472,7 @@
 		unregister_netdev(dev);
 		mca_device_set_claim(mca_dev, 0);
 		release_region(ioaddr, ULTRA_IO_EXTENT);
+		iounmap(ei_status.mem);
 		free_netdev(dev);
 	}
 	return 0;
diff -Nru a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c
--- a/drivers/net/smc-ultra.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/smc-ultra.c	2005-03-09 12:20:51 -05:00
@@ -176,6 +176,7 @@
 		pnp_device_detach(idev);
 #endif
 	release_region(dev->base_addr - ULTRA_NIC_OFFSET, ULTRA_IO_EXTENT);
+	iounmap(ei_status.mem);
 }
 
 #ifndef MODULE
@@ -294,9 +295,14 @@
 	ei_status.rx_start_page = START_PG + TX_PAGES;
 	ei_status.stop_page = num_pages;
 
-	ei_status.rmem_start = dev->mem_start + TX_PAGES*256;
-	dev->mem_end = ei_status.rmem_end
-		= dev->mem_start + (ei_status.stop_page - START_PG)*256;
+	ei_status.mem = ioremap(dev->mem_start, (ei_status.stop_page - START_PG)*256);
+	if (!ei_status.mem) {
+		printk(", failed to ioremap.\n");
+		retval =  -ENOMEM;
+		goto out;
+	}
+
+	dev->mem_end = dev->mem_start + (ei_status.stop_page - START_PG)*256;
 
 	if (piomode) {
 		printk(",%s IRQ %d programmed-I/O mode.\n",
@@ -430,16 +436,16 @@
 static void
 ultra_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
 {
-	unsigned long hdr_start = dev->mem_start + ((ring_page - START_PG)<<8);
+	void __iomem *hdr_start = ei_status.mem + ((ring_page - START_PG)<<8);
 
 	outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET);	/* shmem on */
 #ifdef __BIG_ENDIAN
 	/* Officially this is what we are doing, but the readl() is faster */
 	/* unfortunately it isn't endian aware of the struct               */
-	isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
+	memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
 	hdr->count = le16_to_cpu(hdr->count);
 #else
-	((unsigned int*)hdr)[0] = isa_readl(hdr_start);
+	((unsigned int*)hdr)[0] = readl(hdr_start);
 #endif
 	outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* shmem off */
 }
@@ -450,20 +456,20 @@
 static void
 ultra_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
 {
-	unsigned long xfer_start = dev->mem_start + ring_offset - (START_PG<<8);
+	void __iomem *xfer_start = ei_status.mem + ring_offset - (START_PG<<8);
 
 	/* Enable shared memory. */
 	outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET);
 
-	if (xfer_start + count > ei_status.rmem_end) {
+	if (ring_offset + count > ei_status.stop_page*256) {
 		/* We must wrap the input move. */
-		int semi_count = ei_status.rmem_end - xfer_start;
-		isa_memcpy_fromio(skb->data, xfer_start, semi_count);
+		int semi_count = ei_status.stop_page*256 - ring_offset;
+		memcpy_fromio(skb->data, xfer_start, semi_count);
 		count -= semi_count;
-		isa_memcpy_fromio(skb->data + semi_count, ei_status.rmem_start, count);
+		memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count);
 	} else {
 		/* Packet is in one chunk -- we can copy + cksum. */
-		isa_eth_io_copy_and_sum(skb, xfer_start, count, 0);
+		eth_io_copy_and_sum(skb, xfer_start, count, 0);
 	}
 
 	outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET);	/* Disable memory. */
@@ -473,12 +479,12 @@
 ultra_block_output(struct net_device *dev, int count, const unsigned char *buf,
 				int start_page)
 {
-	unsigned long shmem = dev->mem_start + ((start_page - START_PG)<<8);
+	void __iomem *shmem = ei_status.mem + ((start_page - START_PG)<<8);
 
 	/* Enable shared memory. */
 	outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET);
 
-	isa_memcpy_toio(shmem, buf, count);
+	memcpy_toio(shmem, buf, count);
 
 	outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* Disable memory. */
 }
diff -Nru a/drivers/net/smc-ultra32.c b/drivers/net/smc-ultra32.c
--- a/drivers/net/smc-ultra32.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/smc-ultra32.c	2005-03-09 12:20:51 -05:00
@@ -104,6 +104,7 @@
 	int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET;
 	/* NB: ultra32_close_card() does free_irq */
 	release_region(ioaddr, ULTRA32_IO_EXTENT);
+	iounmap(ei_status.mem);
 }
 
 /*	Probe for the Ultra32.  This looks like a 8013 with the station
@@ -259,8 +260,13 @@
 	/* All Ultra32 cards have 32KB memory with an 8KB window. */
 	ei_status.stop_page = 128;
 
-	ei_status.rmem_start = dev->mem_start + TX_PAGES*256;
-	dev->mem_end = ei_status.rmem_end = dev->mem_start + 0x1fff;
+	ei_status.mem = ioremap(dev->mem_start, 0x2000);
+	if (!ei_status.mem) {
+		printk(", failed to ioremap.\n");
+		retval = -ENOMEM;
+		goto out;
+	}
+	dev->mem_end = dev->mem_start + 0x1fff;
 
 	printk(", IRQ %d, 32KB memory, 8KB window at 0x%lx-0x%lx.\n",
 	       dev->irq, dev->mem_start, dev->mem_end);
@@ -345,7 +351,7 @@
 				 struct e8390_pkt_hdr *hdr,
 				 int ring_page)
 {
-	unsigned long hdr_start = dev->mem_start + ((ring_page & 0x1f) << 8);
+	void __iomem *hdr_start = ei_status.mem + ((ring_page & 0x1f) << 8);
 	unsigned int RamReg = dev->base_addr - ULTRA32_NIC_OFFSET + ULTRA32_CFG3;
 
 	/* Select correct 8KB Window. */
@@ -354,10 +360,10 @@
 #ifdef __BIG_ENDIAN
 	/* Officially this is what we are doing, but the readl() is faster */
 	/* unfortunately it isn't endian aware of the struct               */
-	isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
+	memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
 	hdr->count = le16_to_cpu(hdr->count);
 #else
-	((unsigned int*)hdr)[0] = isa_readl(hdr_start);
+	((unsigned int*)hdr)[0] = readl(hdr_start);
 #endif
 }
 
@@ -371,26 +377,26 @@
 				struct sk_buff *skb,
 				int ring_offset)
 {
-	unsigned long xfer_start = dev->mem_start + (ring_offset & 0x1fff);
+	void __iomem *xfer_start = ei_status.mem + (ring_offset & 0x1fff);
 	unsigned int RamReg = dev->base_addr - ULTRA32_NIC_OFFSET + ULTRA32_CFG3;
 
 	if ((ring_offset & ~0x1fff) != ((ring_offset + count - 1) & ~0x1fff)) {
 		int semi_count = 8192 - (ring_offset & 0x1FFF);
-		isa_memcpy_fromio(skb->data, xfer_start, semi_count);
+		memcpy_fromio(skb->data, xfer_start, semi_count);
 		count -= semi_count;
 		if (ring_offset < 96*256) {
 			/* Select next 8KB Window. */
 			ring_offset += semi_count;
 			outb(ei_status.reg0 | ((ring_offset & 0x6000) >> 13), RamReg);
-			isa_memcpy_fromio(skb->data + semi_count, dev->mem_start, count);
+			memcpy_fromio(skb->data + semi_count, ei_status.mem, count);
 		} else {
 			/* Select first 8KB Window. */
 			outb(ei_status.reg0, RamReg);
-			isa_memcpy_fromio(skb->data + semi_count, ei_status.rmem_start, count);
+			memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count);
 		}
 	} else {
 		/* Packet is in one chunk -- we can copy + cksum. */
-		isa_eth_io_copy_and_sum(skb, xfer_start, count, 0);
+		eth_io_copy_and_sum(skb, xfer_start, count, 0);
 	}
 }
 
@@ -399,13 +405,13 @@
 				 const unsigned char *buf,
 				 int start_page)
 {
-	unsigned long xfer_start = dev->mem_start + (start_page<<8);
+	void __iomem *xfer_start = ei_status.mem + (start_page<<8);
 	unsigned int RamReg = dev->base_addr - ULTRA32_NIC_OFFSET + ULTRA32_CFG3;
 
 	/* Select first 8KB Window. */
 	outb(ei_status.reg0, RamReg);
 
-	isa_memcpy_toio(xfer_start, buf, count);
+	memcpy_toio(xfer_start, buf, count);
 }
 \f
 #ifdef MODULE
diff -Nru a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
--- a/drivers/net/tokenring/ibmtr.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/tokenring/ibmtr.c	2005-03-09 12:20:51 -05:00
@@ -227,7 +227,7 @@
 	printk("\n");
 }
 
-static void __devinit HWPrtChanID(void * pcid, short stride)
+static void __devinit HWPrtChanID(void __iomem *pcid, short stride)
 {
 	short i, j;
 	for (i = 0, j = 0; i < 24; i++, j += stride)
@@ -239,15 +239,16 @@
  * going away. 
  */
 
-static void __devinit find_turbo_adapters(int *iolist) {
+static void __devinit find_turbo_adapters(int *iolist)
+{
 	int ram_addr;
 	int index=0;
-	void *chanid;
+	void __iomem *chanid;
 	int found_turbo=0;
 	unsigned char *tchanid, ctemp;
 	int i, j;
 	unsigned long jif;
-	void *ram_mapped ;   
+	void __iomem *ram_mapped ;   
 
 	if (turbo_searched == 1) return;
 	turbo_searched=1;
@@ -328,8 +329,8 @@
 
 	{ 
 		struct tok_info *ti = (struct tok_info *) dev->priv;
-		iounmap((u32 *)ti->mmio);
-		iounmap((u32 *)ti->sram_virt);
+		iounmap(ti->mmio);
+		iounmap(ti->sram_virt);
 	}
 #endif		
 }
@@ -383,9 +384,9 @@
 {
 
 	unsigned char segment, intr=0, irq=0, i, j, cardpresent=NOTOK, temp=0;
-	void * t_mmio = NULL;
+	void __iomem * t_mmio = NULL;
 	struct tok_info *ti = dev->priv;
-	void *cd_chanid;
+	void __iomem *cd_chanid;
 	unsigned char *tchanid, ctemp;
 #ifndef PCMCIA
 	unsigned char t_irq=0;
@@ -428,7 +429,7 @@
 	 */
 #ifdef PCMCIA
 	iounmap(t_mmio);
-	t_mmio = (void *)ti->mmio;	/*BMS to get virtual address */
+	t_mmio = ti->mmio;	/*BMS to get virtual address */
 	irq = ti->irq;		/*BMS to display the irq!   */
 #endif
 	cd_chanid = (CHANNEL_ID + t_mmio);	/* for efficiency */
@@ -515,7 +516,7 @@
 		if (intr == 3) irq = 11;
 		ti->global_int_enable = 0;
 		ti->adapter_int_enable = 0;
-		ti->sram_virt=(__u32)(inb(PIOaddr+ADAPTRESETREL) & 0xfe) << 12;
+		ti->sram_phys=(__u32)(inb(PIOaddr+ADAPTRESETREL) & 0xfe) << 12;
 		break;
 	case TR_ISAPNP:
 		if (!t_irq) {
@@ -533,7 +534,7 @@
 			kfree(ti);
 			return -ENODEV;
 		}
-		ti->sram_virt =
+		ti->sram_phys =
 		     ((__u32)readb(ti->mmio+ACA_OFFSET+ACA_RW+RRR_EVEN)<<12);
 		ti->adapter_int_enable = PIOaddr + ADAPTINTREL;
 		break;
@@ -542,7 +543,7 @@
 
 	if (ibmtr_debug_trace & TRC_INIT) {	/* just report int */
 		DPRINTK("irq=%d", irq);
-		printk(", sram_virt=0x%x", ti->sram_virt);
+		printk(", sram_phys=0x%x", ti->sram_phys);
 		if(ibmtr_debug_trace&TRC_INITV){ /* full chat in verbose only */
 			DPRINTK(", ti->mmio=%p", ti->mmio);
 			printk(", segment=%02X", segment);
@@ -681,7 +682,7 @@
 			ibmtr_mem_base = chk_base;
 		}
 	}
-	else  ti->sram_base = ti->sram_virt >> 12;
+	else  ti->sram_base = ti->sram_phys >> 12;
 
 	/* The PCMCIA has already got the interrupt line and the io port, 
 	   so no chance of anybody else getting it - MLP */
@@ -893,7 +894,7 @@
 	*/
 	dev->flags &= ~IFF_RUNNING;
 
-	ti->sram_virt &= ~1; /* to reverse what we do in tok_close */
+	ti->sram_phys &= ~1; /* to reverse what we do in tok_close */
 	/* init the spinlock */
 	spin_lock_init(&ti->lock);
 	init_timer(&ti->tr_timer);
@@ -1068,7 +1069,7 @@
 	/* unloading the module from memory, and then if a timer pops, ouch */
 	del_timer_sync(&ti->tr_timer);
 	outb(0, dev->base_addr + ADAPTRESET);
-	ti->sram_virt |= 1;
+	ti->sram_phys |= 1;
 	ti->open_status = CLOSED;
 
 	netif_stop_queue(dev);
@@ -1094,30 +1095,33 @@
 		"IMPL force received","Duplicate modifier",
 		"No monitor detected","Monitor contention failed for RPL"};
 
-void dir_open_adapter (struct net_device *dev) {
+static void __iomem *map_address(struct tok_info *ti, unsigned index, __u8 *page)
+{
+	if (ti->page_mask) {
+		*page = (index >> 8) & ti->page_mask;
+		index &= ~(ti->page_mask << 8);
+	}
+	return ti->sram_virt + index;
+}
 
+void dir_open_adapter (struct net_device *dev)
+{
         struct tok_info *ti = (struct tok_info *) dev->priv;
         unsigned char ret_code;
         __u16 err;
 
-        ti->srb = ntohs(readw(ti->init_srb + SRB_ADDRESS_OFST));
-        ti->ssb = ntohs(readw(ti->init_srb + SSB_ADDRESS_OFST));
-        ti->arb = ntohs(readw(ti->init_srb + ARB_ADDRESS_OFST));
-        ti->asb = ntohs(readw(ti->init_srb + ASB_ADDRESS_OFST));
-        if (ti->page_mask) {
-                ti->srb_page = (ti->srb >> 8) & ti->page_mask;
-                ti->srb &= ~(ti->page_mask << 8);
-                ti->ssb_page = (ti->ssb >> 8) & ti->page_mask;
-                ti->ssb &= ~(ti->page_mask << 8);
-                ti->arb_page = (ti->arb >> 8) & ti->page_mask;
-                ti->arb &= ~(ti->page_mask << 8);
-                ti->asb_page = (ti->asb >> 8) & ti->page_mask;
-                ti->asb &= ~(ti->page_mask << 8);
-        }
-        ti->srb += ti->sram_virt;
-        ti->ssb += ti->sram_virt;
-        ti->arb += ti->sram_virt;
-        ti->asb += ti->sram_virt;
+        ti->srb = map_address(ti,
+		ntohs(readw(ti->init_srb + SRB_ADDRESS_OFST)),
+		&ti->srb_page);
+        ti->ssb = map_address(ti,
+		ntohs(readw(ti->init_srb + SSB_ADDRESS_OFST)),
+		&ti->ssb_page);
+        ti->arb = map_address(ti,
+		ntohs(readw(ti->init_srb + ARB_ADDRESS_OFST)),
+		&ti->arb_page);
+        ti->asb = map_address(ti,
+		ntohs(readw(ti->init_srb + ASB_ADDRESS_OFST)),
+		&ti->asb_page);
         ti->current_skb = NULL;
         ret_code = readb(ti->init_srb + RETCODE_OFST);
         err = ntohs(readw(ti->init_srb + OPEN_ERROR_CODE_OFST));
@@ -1188,7 +1192,7 @@
 	DPRINTK("Int from tok_driver, dev : %p irq%d regs=%p\n", dev,irq,regs);
 #endif
 	ti = (struct tok_info *) dev->priv;
-	if (ti->sram_virt & 1)
+	if (ti->sram_phys & 1)
 		return IRQ_NONE;         /* PCMCIA card extraction flag */
 	spin_lock(&(ti->lock));
 #ifdef ENABLE_PAGING
@@ -1220,15 +1224,11 @@
 
 	if (status & ADAP_CHK_INT) {
 		int i;
-		__u32 check_reason;
+		void __iomem *check_reason;
 		__u8 check_reason_page = 0;
-		check_reason =
-			ntohs(readw(ti->mmio+ ACA_OFFSET+ACA_RW + WWCR_EVEN));
-		if (ti->page_mask) {
-			check_reason_page = (check_reason >> 8) & ti->page_mask;
-			check_reason &= ~(ti->page_mask << 8);
-		}
-		check_reason += ti->sram_virt;
+		check_reason = map_address(ti,
+			ntohs(readw(ti->mmio+ ACA_OFFSET+ACA_RW + WWCR_EVEN)),
+			&check_reason_page);
 		SET_PAGE(check_reason_page);
 
 		DPRINTK("Adapter check interrupt\n");
@@ -1517,23 +1517,20 @@
 	/* we assign the shared-ram address for ISA devices */
 	writeb(ti->sram_base, ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN);
 #ifndef PCMCIA
-        ti->sram_virt = (u32)ioremap(((__u32)ti->sram_base << 12), ti->avail_shared_ram);
+        ti->sram_virt = ioremap(((__u32)ti->sram_base << 12), ti->avail_shared_ram);
 #endif
-	ti->init_srb = ntohs(readw(ti->mmio + ACA_OFFSET + WRBR_EVEN));
-	if (ti->page_mask) {
-		ti->init_srb_page = (ti->init_srb >> 8) & ti->page_mask;
-		ti->init_srb &= ~(ti->page_mask << 8);
-	}
-	ti->init_srb += ti->sram_virt;
+	ti->init_srb = map_address(ti,
+		ntohs(readw(ti->mmio + ACA_OFFSET + WRBR_EVEN)),
+		&ti->init_srb_page);
 	if (ti->page_mask && ti->avail_shared_ram == 127) {
-		int last_512 = 0xfe00, i;
-		int last_512_page=0;
-		last_512_page=(last_512>>8)&ti->page_mask;
-		last_512 &= ~(ti->page_mask << 8);
+		void __iomem *last_512;
+		__u8 last_512_page=0;
+		int i;
+		last_512 = map_address(ti, 0xfe00, &last_512_page);
 		/* initialize high section of ram (if necessary) */
 		SET_PAGE(last_512_page);
 		for (i = 0; i < 512; i++)
-			writeb(0, ti->sram_virt + last_512 + i);
+			writeb(0, last_512 + i);
 	}
 	SET_PAGE(ti->init_srb_page);
 
@@ -1542,7 +1539,7 @@
 	int i;
 
 	DPRINTK("ti->init_srb_page=0x%x\n", ti->init_srb_page);
-	DPRINTK("init_srb(%x):", (ti->init_srb) );
+	DPRINTK("init_srb(%p):", ti->init_srb );
 	for (i = 0; i < 20; i++)
 		printk("%02X ", (int) readb(ti->init_srb + i));
 	printk("\n");
@@ -1579,6 +1576,7 @@
 	struct trh_hdr *trhdr = (struct trh_hdr *) ti->current_skb->data;
 	unsigned int hdr_len;
 	__u32 dhb=0,dhb_base;
+	void __iomem *dhbuf = NULL;
 	unsigned char xmit_command;
 	int i,dhb_len=0x4000,src_len,src_offset;
 	struct trllc *llc;
@@ -1600,7 +1598,7 @@
 		dhb_page = (dhb_base >> 8) & ti->page_mask;
 		dhb=dhb_base & ~(ti->page_mask << 8);
 	}
-	dhb += ti->sram_virt;
+	dhbuf = ti->sram_virt + dhb;
 
 	/* Figure out the size of the 802.5 header */
 	if (!(trhdr->saddr[0] & 0x80))	/* RIF present? */
@@ -1626,12 +1624,12 @@
 		writew(htons(0x11), ti->asb + FRAME_LENGTH_OFST);
 		writeb(0x0e, ti->asb + HEADER_LENGTH_OFST);
 		SET_PAGE(dhb_page);
-		writeb(AC, dhb);
-		writeb(LLC_FRAME, dhb + 1);
+		writeb(AC, dhbuf);
+		writeb(LLC_FRAME, dhbuf + 1);
 		for (i = 0; i < TR_ALEN; i++)
-			writeb((int) 0x0FF, dhb + i + 2);
+			writeb((int) 0x0FF, dhbuf + i + 2);
 		for (i = 0; i < TR_ALEN; i++)
-			writeb(0, dhb + i + TR_ALEN + 2);
+			writeb(0, dhbuf + i + TR_ALEN + 2);
 		writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
 		return;
 	}
@@ -1650,10 +1648,10 @@
 			dhb=dhb & ~(ti->page_mask << 8);
 			dhb_len=0x4000-dhb; /* remaining size of this page */
 		}
-		dhb+=ti->sram_virt;
+		dhbuf = ti->sram_virt + dhb;
 		SET_PAGE(dhb_page);
 		if (src_len > dhb_len) {
-			memcpy_toio(dhb,&ti->current_skb->data[src_offset],
+			memcpy_toio(dhbuf,&ti->current_skb->data[src_offset],
 					dhb_len);
 			src_len -= dhb_len;
 			src_offset += dhb_len;
@@ -1661,7 +1659,7 @@
 			dhb=dhb_base;
 			continue;
 		}
-		memcpy_toio(dhb, &ti->current_skb->data[src_offset], src_len);
+		memcpy_toio(dhbuf, &ti->current_skb->data[src_offset], src_len);
 		break;
 	}
 	writeb(RESP_IN_ASB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
@@ -1689,9 +1687,9 @@
 static void tr_rx(struct net_device *dev)
 {
 	struct tok_info *ti = (struct tok_info *) dev->priv;
-	__u32 rbuffer, rbufdata;
+	__u32 rbuffer;
+	void __iomem *rbuf, *rbufdata, *llc;
 	__u8 rbuffer_page = 0;
-	__u32 llc;
 	unsigned char *data;
 	unsigned int rbuffer_len, lan_hdr_len, hdr_len, ip_len, length;
 	unsigned char dlc_hdr_len;
@@ -1705,11 +1703,7 @@
 	SET_PAGE(ti->arb_page);
 	memcpy_fromio(&rarb, ti->arb, sizeof(rarb));
 	rbuffer = ntohs(rarb.rec_buf_addr) ;
-	if (ti->page_mask) {
-		rbuffer_page = (rbuffer >> 8) & ti->page_mask;
-		rbuffer &= ~(ti->page_mask << 8);
-	}
-	rbuffer += ti->sram_virt;
+	rbuf = map_address(ti, rbuffer, &rbuffer_page);
 
 	SET_PAGE(ti->asb_page);
 
@@ -1728,7 +1722,7 @@
 	hdr_len = lan_hdr_len + sizeof(struct trllc) + sizeof(struct iphdr);
 
 	SET_PAGE(rbuffer_page);
-	llc = (rbuffer + offsetof(struct rec_buf, data) + lan_hdr_len);
+	llc = rbuf + offsetof(struct rec_buf, data) + lan_hdr_len;
 
 #if TR_VERBOSE
 	DPRINTK("offsetof data: %02X lan_hdr_len: %02X\n",
@@ -1759,9 +1753,7 @@
 
 	if (!IPv4_p) {
 
-		__u32 trhhdr;
-
-		trhhdr = (rbuffer + offsetof(struct rec_buf, data));
+		void __iomem *trhhdr = rbuf + offsetof(struct rec_buf, data);
 
 		DPRINTK("Probably non-IP frame received.\n");
 		DPRINTK("ssap: %02X dsap: %02X "
@@ -1793,8 +1785,8 @@
 	skb_put(skb, length);
 	skb->dev = dev;
 	data = skb->data;
-	rbuffer_len = ntohs(readw(rbuffer + offsetof(struct rec_buf, buf_len)));
-	rbufdata = rbuffer + offsetof(struct rec_buf, data);
+	rbuffer_len = ntohs(readw(rbuf + offsetof(struct rec_buf, buf_len)));
+	rbufdata = rbuf + offsetof(struct rec_buf, data);
 
 	if (IPv4_p) {
 		/* Copy the headers without checksumming */
@@ -1822,20 +1814,16 @@
 			    data,length<rbuffer_len?length:rbuffer_len,chksum);
 		else
 			memcpy_fromio(data, rbufdata, rbuffer_len);
-		rbuffer = ntohs(readw(rbuffer+BUFFER_POINTER_OFST)) ;
+		rbuffer = ntohs(readw(rbuf+BUFFER_POINTER_OFST)) ;
 		if (!rbuffer)
 			break;
 		rbuffer -= 2;
 		length -= rbuffer_len;
 		data += rbuffer_len;
-		if (ti->page_mask) {
-			rbuffer_page = (rbuffer >> 8) & ti->page_mask;
-			rbuffer &= ~(ti->page_mask << 8);
-		}
-		rbuffer += ti->sram_virt;
+		rbuf = map_address(ti, rbuffer, &rbuffer_page);
 		SET_PAGE(rbuffer_page);
-		rbuffer_len = ntohs(readw(rbuffer + BUFFER_LENGTH_OFST));
-		rbufdata = rbuffer + offsetof(struct rec_buf, data);
+		rbuffer_len = ntohs(readw(rbuf + BUFFER_LENGTH_OFST));
+		rbufdata = rbuf + offsetof(struct rec_buf, data);
 	}
 
 	SET_PAGE(ti->asb_page);
diff -Nru a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c
--- a/drivers/net/tulip/interrupt.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/tulip/interrupt.c	2005-03-09 12:20:51 -05:00
@@ -26,7 +26,7 @@
 #define MIT_SIZE 15
 #define MIT_TABLE 15 /* We use 0 or max */
 
-unsigned int mit_table[MIT_SIZE+1] =
+static unsigned int mit_table[MIT_SIZE+1] =
 {
         /*  CRS11 21143 hardware Mitigation Control Interrupt
             We use only RX mitigation we other techniques for
diff -Nru a/drivers/net/tun.c b/drivers/net/tun.c
--- a/drivers/net/tun.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/tun.c	2005-03-09 12:20:51 -05:00
@@ -843,7 +843,7 @@
 	.set_rx_csum	= tun_set_rx_csum
 };
 
-int __init tun_init(void)
+static int __init tun_init(void)
 {
 	int ret = 0;
 
@@ -856,7 +856,7 @@
 	return ret;
 }
 
-void tun_cleanup(void)
+static void tun_cleanup(void)
 {
 	struct tun_struct *tun, *nxt;
 
diff -Nru a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
--- a/drivers/net/via-rhine.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/via-rhine.c	2005-03-09 12:20:51 -05:00
@@ -390,7 +390,7 @@
 
 #ifdef USE_MMIO
 /* Registers we check that mmio and reg are the same. */
-int mmio_verify_registers[] = {
+static const int mmio_verify_registers[] = {
 	RxConfig, TxConfig, IntrEnable, ConfigA, ConfigB, ConfigC, ConfigD,
 	0
 };
diff -Nru a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
--- a/drivers/net/via-velocity.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/via-velocity.c	2005-03-09 12:20:51 -05:00
@@ -3096,7 +3096,7 @@
  *	we are interested in.
  */
 
-u16 wol_calc_crc(int size, u8 * pattern, u8 *mask_pattern)
+static u16 wol_calc_crc(int size, u8 * pattern, u8 *mask_pattern)
 {
 	u16 crc = 0xFFFF;
 	u8 mask;
diff -Nru a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
--- a/drivers/net/wan/cosa.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/wan/cosa.c	2005-03-09 12:20:51 -05:00
@@ -543,7 +543,7 @@
 		 * FIXME: When this code is not used as module, we should
 		 * probably call udelay() instead of the interruptible sleep.
 		 */
-		current->state = TASK_INTERRUPTIBLE;
+		set_current_state(TASK_INTERRUPTIBLE);
 		cosa_putstatus(cosa, SR_TX_INT_ENA);
 		schedule_timeout(30);
 		irq = probe_irq_off(irqs);
@@ -1564,8 +1564,7 @@
 	cosa_getdata8(cosa);
 	cosa_putstatus(cosa, SR_RST);
 #ifdef MODULE
-	current->state = TASK_INTERRUPTIBLE;
-	schedule_timeout(HZ/2);
+	msleep(500);
 #else
 	udelay(5*100000);
 #endif
@@ -1618,7 +1617,7 @@
 			return r;
 		}
 		/* sleep if not ready to read */
-		current->state = TASK_INTERRUPTIBLE;
+		set_current_state(TASK_INTERRUPTIBLE);
 		schedule_timeout(1);
 	}
 	printk(KERN_INFO "cosa: timeout in get_wait_data (status 0x%x)\n",
diff -Nru a/drivers/net/wd.c b/drivers/net/wd.c
--- a/drivers/net/wd.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/wd.c	2005-03-09 12:20:51 -05:00
@@ -131,6 +131,7 @@
 {
 	free_irq(dev->irq, dev);
 	release_region(dev->base_addr - WD_NIC_OFFSET, WD_IO_EXTENT);
+	iounmap(ei_status.mem);
 }
 
 #ifndef MODULE
@@ -317,16 +318,22 @@
 	ei_status.rx_start_page = WD_START_PG + TX_PAGES;
 
 	/* Don't map in the shared memory until the board is actually opened. */
-	ei_status.rmem_start = dev->mem_start + TX_PAGES*256;
 
 	/* Some cards (eg WD8003EBT) can be jumpered for more (32k!) memory. */
 	if (dev->mem_end != 0) {
 		ei_status.stop_page = (dev->mem_end - dev->mem_start)/256;
+		ei_status.priv = dev->mem_end - dev->mem_start;
 	} else {
 		ei_status.stop_page = word16 ? WD13_STOP_PG : WD03_STOP_PG;
 		dev->mem_end = dev->mem_start + (ei_status.stop_page - WD_START_PG)*256;
+		ei_status.priv = (ei_status.stop_page - WD_START_PG)*256;
+	}
+
+	ei_status.mem = ioremap(dev->mem_start, ei_status.priv);
+	if (!ei_status.mem) {
+		free_irq(dev->irq, dev);
+		return -ENOMEM;
 	}
-	ei_status.rmem_end = dev->mem_end;
 
 	printk(" %s, IRQ %d, shared memory at %#lx-%#lx.\n",
 		   model_name, dev->irq, dev->mem_start, dev->mem_end-1);
@@ -397,7 +404,7 @@
 {
 
 	int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
-	unsigned long hdr_start = dev->mem_start + ((ring_page - WD_START_PG)<<8);
+	void __iomem *hdr_start = ei_status.mem + ((ring_page - WD_START_PG)<<8);
 
 	/* We'll always get a 4 byte header read followed by a packet read, so
 	   we enable 16 bit mode before the header, and disable after the body. */
@@ -407,10 +414,10 @@
 #ifdef __BIG_ENDIAN
 	/* Officially this is what we are doing, but the readl() is faster */
 	/* unfortunately it isn't endian aware of the struct               */
-	isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
+	memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
 	hdr->count = le16_to_cpu(hdr->count);
 #else
-	((unsigned int*)hdr)[0] = isa_readl(hdr_start);
+	((unsigned int*)hdr)[0] = readl(hdr_start);
 #endif
 }
 
@@ -423,17 +430,18 @@
 wd_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
 {
 	int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
-	unsigned long xfer_start = dev->mem_start + ring_offset - (WD_START_PG<<8);
+	unsigned long offset = ring_offset - (WD_START_PG<<8);
+	void __iomem *xfer_start = ei_status.mem + offset;
 
-	if (xfer_start + count > ei_status.rmem_end) {
+	if (offset + count > ei_status.priv) {
 		/* We must wrap the input move. */
-		int semi_count = ei_status.rmem_end - xfer_start;
-		isa_memcpy_fromio(skb->data, xfer_start, semi_count);
+		int semi_count = ei_status.priv - offset;
+		memcpy_fromio(skb->data, xfer_start, semi_count);
 		count -= semi_count;
-		isa_memcpy_fromio(skb->data + semi_count, ei_status.rmem_start, count);
+		memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count);
 	} else {
 		/* Packet is in one chunk -- we can copy + cksum. */
-		isa_eth_io_copy_and_sum(skb, xfer_start, count, 0);
+		eth_io_copy_and_sum(skb, xfer_start, count, 0);
 	}
 
 	/* Turn off 16 bit access so that reboot works.	 ISA brain-damage */
@@ -446,16 +454,16 @@
 				int start_page)
 {
 	int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
-	long shmem = dev->mem_start + ((start_page - WD_START_PG)<<8);
+	void __iomem *shmem = ei_status.mem + ((start_page - WD_START_PG)<<8);
 
 
 	if (ei_status.word16) {
 		/* Turn on and off 16 bit access so that reboot works. */
 		outb(ISA16 | ei_status.reg5, wd_cmdreg+WD_CMDREG5);
-		isa_memcpy_toio(shmem, buf, count);
+		memcpy_toio(shmem, buf, count);
 		outb(ei_status.reg5, wd_cmdreg+WD_CMDREG5);
 	} else
-		isa_memcpy_toio(shmem, buf, count);
+		memcpy_toio(shmem, buf, count);
 }
 
 
diff -Nru a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
--- a/drivers/net/wireless/airo.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/wireless/airo.c	2005-03-09 12:20:51 -05:00
@@ -1698,9 +1698,8 @@
 			issuecommand(ai, &cmd, &rsp);
 			up(&ai->sem);
 			/* Let the command take effect */
-			set_current_state (TASK_INTERRUPTIBLE);
 			ai->task = current;
-			schedule_timeout (3*HZ);
+			ssleep(3);
 			ai->task = NULL;
 		}
 	rc = PC4500_readrid(ai, first ? RID_BSSLISTFIRST : RID_BSSLISTNEXT,
@@ -2685,11 +2684,9 @@
 		return -1;
 	waitbusy (ai);
 	OUT4500(ai,COMMAND,CMD_SOFTRESET);
-	set_current_state (TASK_UNINTERRUPTIBLE);
-	schedule_timeout (HZ/5);
+	msleep(200);
 	waitbusy (ai);
-	set_current_state (TASK_UNINTERRUPTIBLE);
-	schedule_timeout (HZ/5);
+	msleep(200);
 	if (lock)
 		up(&ai->sem);
 	return 0;
@@ -5516,12 +5513,12 @@
 	} else {
 		OUT4500(ai, EVACK, EV_AWAKEN);
 		OUT4500(ai, EVACK, EV_AWAKEN);
-		schedule_timeout(HZ/10);
+		msleep(100);
 	}
 
 	set_bit (FLAG_COMMIT, &ai->flags);
 	disable_MAC(ai, 0);
-        schedule_timeout (HZ/5);
+        msleep(200);
 	if (ai->SSID) {
 		writeSsidRid(ai, ai->SSID, 0);
 		kfree(ai->SSID);
@@ -7470,8 +7467,7 @@
 
 	OUT4500(ai,COMMAND,CMD_SOFTRESET);
 
-	set_current_state (TASK_UNINTERRUPTIBLE);
-	schedule_timeout (HZ);          /* WAS 600 12/7/00 */
+	ssleep(1);			/* WAS 600 12/7/00 */
 
 	if(!waitbusy (ai)){
 		printk(KERN_INFO "Waitbusy hang AFTER RESET\n");
@@ -7498,8 +7494,7 @@
 		OUT4500(ai, SWS3, FLASH_COMMAND);
 		OUT4500(ai, COMMAND,0);
 	}
-	set_current_state (TASK_UNINTERRUPTIBLE);
-	schedule_timeout (HZ/2); /* 500ms delay */
+	msleep(500);		/* 500ms delay */
 
 	if(!waitbusy(ai)) {
 		clear_bit (FLAG_FLASHING, &ai->flags);
@@ -7609,8 +7604,7 @@
 int flashrestart(struct airo_info *ai,struct net_device *dev){
 	int    i,status;
 
-	set_current_state (TASK_UNINTERRUPTIBLE);
-	schedule_timeout (HZ);          /* Added 12/7/00 */
+	ssleep(1);			/* Added 12/7/00 */
 	clear_bit (FLAG_FLASHING, &ai->flags);
 	if (test_bit(FLAG_MPI, &ai->flags)) {
 		status = mpi_init_descriptors(ai);
@@ -7625,8 +7619,7 @@
 				( ai, 2312, i >= MAX_FIDS / 2 );
 		}
 
-	set_current_state (TASK_UNINTERRUPTIBLE);
-	schedule_timeout (HZ);          /* Added 12/7/00 */
+	ssleep(1);			/* Added 12/7/00 */
 	return status;
 }
 #endif /* CISCO_EXT */
diff -Nru a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
--- a/drivers/net/wireless/prism54/isl_ioctl.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/wireless/prism54/isl_ioctl.c	2005-03-09 12:20:51 -05:00
@@ -1750,7 +1750,7 @@
 	u8 wpa_ie[MAX_WPA_IE_LEN];
 	int wpa_ie_len;
 	size_t len = 0; /* u16, better? */
-	u8 *payload = 0, *pos = 0;
+	u8 *payload = NULL, *pos = NULL;
 	int ret;
 
 	/* I think all trapable objects are listed here.
diff -Nru a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
--- a/drivers/net/wireless/ray_cs.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/wireless/ray_cs.c	2005-03-09 12:20:51 -05:00
@@ -1215,6 +1215,9 @@
 #if WIRELESS_EXT > 7
     struct iwreq *wrq = (struct iwreq *) ifr;
 #endif	/* WIRELESS_EXT > 7 */
+#ifdef WIRELESS_SPY
+    struct sockaddr	address[IW_MAX_SPY];
+#endif	/* WIRELESS_SPY */
 
     if (!(link->state & DEV_PRESENT)) {
         DEBUG(2,"ray_dev_ioctl - device not present\n");
@@ -1511,7 +1514,6 @@
       /* If there is some addresses to copy */
       if(local->spy_number > 0)
 	{
-	  struct sockaddr	address[IW_MAX_SPY];
 	  int			i;
 
 	  /* Copy addresses to the driver */
@@ -1551,7 +1553,6 @@
       /* If the user want to have the addresses back... */
       if((local->spy_number > 0) && (wrq->u.data.pointer != (caddr_t) 0))
 	{
-	  struct sockaddr	address[IW_MAX_SPY];
 	  int			i;
 
 	  /* Copy addresses from the lp structure */
diff -Nru a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
--- a/drivers/net/wireless/strip.c	2005-03-09 12:20:51 -05:00
+++ b/drivers/net/wireless/strip.c	2005-03-09 12:20:51 -05:00
@@ -876,7 +876,7 @@
  */
 static int strip_change_mtu(struct net_device *dev, int new_mtu)
 {
-	struct strip *strip_info = dev->priv;
+	struct strip *strip_info = netdev_priv(dev);
 	int old_mtu = strip_info->mtu;
 	unsigned char *orbuff = strip_info->rx_buff;
 	unsigned char *osbuff = strip_info->sx_buff;
@@ -1563,7 +1563,7 @@
 /* Encapsulate a datagram and kick it into a TTY queue. */
 static int strip_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct strip *strip_info = (struct strip *) (dev->priv);
+	struct strip *strip_info = netdev_priv(dev);
 
 	if (!netif_running(dev)) {
 		printk(KERN_ERR "%s: xmit call when iface is down\n",
@@ -1639,7 +1639,7 @@
 			unsigned short type, void *daddr, void *saddr,
 			unsigned len)
 {
-	struct strip *strip_info = (struct strip *) (dev->priv);
+	struct strip *strip_info = netdev_priv(dev);
 	STRIP_Header *header = (STRIP_Header *) skb_push(skb, sizeof(STRIP_Header));
 
 	/*printk(KERN_INFO "%s: strip_header 0x%04X %s\n", dev->name, type,
@@ -1648,7 +1648,7 @@
 	header->src_addr = strip_info->true_dev_addr;
 	header->protocol = htons(type);
 
-	/*HexDump("strip_header", (struct strip *)(dev->priv), skb->data, skb->data + skb->len); */
+	/*HexDump("strip_header", netdev_priv(dev), skb->data, skb->data + skb->len); */
 
 	if (!daddr)
 		return (-dev->hard_header_len);
@@ -2400,7 +2400,7 @@
 
 static int strip_set_mac_address(struct net_device *dev, void *addr)
 {
-	struct strip *strip_info = (struct strip *) (dev->priv);
+	struct strip *strip_info = netdev_priv(dev);
 	struct sockaddr *sa = addr;
 	printk(KERN_INFO "%s: strip_set_dev_mac_address called\n", dev->name);
 	set_mac_address(strip_info, (MetricomAddress *) sa->sa_data);
@@ -2409,8 +2409,8 @@
 
 static struct net_device_stats *strip_get_stats(struct net_device *dev)
 {
+	struct strip *strip_info = netdev_priv(dev);
 	static struct net_device_stats stats;
-	struct strip *strip_info = (struct strip *) (dev->priv);
 
 	memset(&stats, 0, sizeof(struct net_device_stats));
 
@@ -2454,7 +2454,7 @@
 
 static int strip_open_low(struct net_device *dev)
 {
-	struct strip *strip_info = (struct strip *) (dev->priv);
+	struct strip *strip_info = netdev_priv(dev);
 
 	if (strip_info->tty == NULL)
 		return (-ENODEV);
@@ -2487,7 +2487,7 @@
 
 static int strip_close_low(struct net_device *dev)
 {
-	struct strip *strip_info = (struct strip *) (dev->priv);
+	struct strip *strip_info = netdev_priv(dev);
 
 	if (strip_info->tty == NULL)
 		return -EBUSY;
diff -Nru a/include/linux/dp83840.h b/include/linux/dp83840.h
--- a/include/linux/dp83840.h	2005-03-09 12:20:51 -05:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,41 +0,0 @@
-/*
- * linux/dp83840.h: definitions for DP83840 MII-compatible transceivers
- *
- * Copyright (C) 1996, 1999 David S. Miller (davem@redhat.com)
- */
-#ifndef __LINUX_DP83840_H
-#define __LINUX_DP83840_H
-
-#include <linux/mii.h>
-
-/*
- * Data sheets and programming docs for the DP83840 are available at
- * from http://www.national.com/
- *
- * The DP83840 is capable of both 10 and 100Mbps ethernet, in both
- * half and full duplex mode.  It also supports auto negotiation.
- *
- * But.... THIS THING IS A PAIN IN THE ASS TO PROGRAM!
- * Debugging eeprom burnt code is more fun than programming this chip!
- */
-
-/* First, the MII register numbers (actually DP83840 register numbers). */
-#define MII_CSCONFIG        0x17        /* CS configuration            */
-
-/* The Carrier Sense config register. */
-#define CSCONFIG_RESV1          0x0001  /* Unused...                   */
-#define CSCONFIG_LED4           0x0002  /* Pin for full-dplx LED4      */
-#define CSCONFIG_LED1           0x0004  /* Pin for conn-status LED1    */
-#define CSCONFIG_RESV2          0x0008  /* Unused...                   */
-#define CSCONFIG_TCVDISAB       0x0010  /* Turns off the transceiver   */
-#define CSCONFIG_DFBYPASS       0x0020  /* Bypass disconnect function  */
-#define CSCONFIG_GLFORCE        0x0040  /* Good link force for 100mbps */
-#define CSCONFIG_CLKTRISTATE    0x0080  /* Tristate 25m clock          */
-#define CSCONFIG_RESV3          0x0700  /* Unused...                   */
-#define CSCONFIG_ENCODE         0x0800  /* 1=MLT-3, 0=binary           */
-#define CSCONFIG_RENABLE        0x1000  /* Repeater mode enable        */
-#define CSCONFIG_TCDISABLE      0x2000  /* Disable timeout counter     */
-#define CSCONFIG_RESV4          0x4000  /* Unused...                   */
-#define CSCONFIG_NDISABLE       0x8000  /* Disable NRZI                */
-
-#endif /* __LINUX_DP83840_H */
diff -Nru a/include/linux/ibmtr.h b/include/linux/ibmtr.h
--- a/include/linux/ibmtr.h	2005-03-09 12:20:51 -05:00
+++ b/include/linux/ibmtr.h	2005-03-09 12:20:51 -05:00
@@ -169,7 +169,7 @@
 
 struct tok_info {
 	unsigned char irq;
-	void *mmio;
+	void __iomem *mmio;
 	unsigned char hw_address[32];
 	unsigned char adapter_type;
 	unsigned char data_rate;
@@ -192,12 +192,13 @@
 	/* Additions by Peter De Schrijver */
 	unsigned char page_mask;          /* mask to select RAM page to Map*/
 	unsigned char mapped_ram_size;    /* size of RAM page */
-	__u32 sram_virt;                  /* Shared memory base address */
-	__u32 init_srb;               /* Initial System Request Block address */
-	__u32 srb;                        /* System Request Block address */
-	__u32 ssb;                        /* System Status Block address */
-	__u32 arb;                        /* Adapter Request Block address */
-	__u32 asb;                        /* Adapter Status Block address */
+	__u32 sram_phys;          /* Shared memory base address */
+	void __iomem *sram_virt;          /* Shared memory base address */
+	void __iomem *init_srb;   /* Initial System Request Block address */
+	void __iomem *srb;                /* System Request Block address */
+	void __iomem *ssb;                /* System Status Block address */
+	void __iomem *arb;                /* Adapter Request Block address */
+	void __iomem *asb;                /* Adapter Status Block address */
         __u8  init_srb_page;
         __u8  srb_page;
         __u8  ssb_page;
diff -Nru a/include/net/slhc_vj.h b/include/net/slhc_vj.h
--- a/include/net/slhc_vj.h	2005-03-09 12:20:51 -05:00
+++ b/include/net/slhc_vj.h	2005-03-09 12:20:51 -05:00
@@ -185,7 +185,4 @@
 			  int isize));
 int slhc_toss __ARGS((struct slcompress *comp));
 
-void slhc_i_status __ARGS((struct slcompress *comp));
-void slhc_o_status __ARGS((struct slcompress *comp));
-
 #endif	/* _SLHC_H */

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [BK PATCHES] 2.6.x net driver updates
@ 2005-03-08 19:31 Jeff Garzik
  0 siblings, 0 replies; 28+ messages in thread
From: Jeff Garzik @ 2005-03-08 19:31 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: Netdev, Linux Kernel

[-- Attachment #1: Type: text/plain, Size: 98 bytes --]

Changes:
* viro's iomap/iomem updates
* ham, mv643xx, orinoco updates
* sis900, via-rhine updates

[-- Attachment #2: changelog.txt --]
[-- Type: text/plain, Size: 7257 bytes --]

Please do a

	bk pull bk://gkernel.bkbits.net/net-drivers-2.6

This will update the following files:

 drivers/net/Kconfig                   |    5 
 drivers/net/fealnx.c                  |  275 +--
 drivers/net/hamradio/6pack.c          |    4 
 drivers/net/hamradio/baycom_epp.c     |   53 
 drivers/net/hamradio/baycom_par.c     |    8 
 drivers/net/hamradio/baycom_ser_fdx.c |    7 
 drivers/net/hamradio/baycom_ser_hdx.c |    7 
 drivers/net/hamradio/bpqether.c       |   19 
 drivers/net/hamradio/dmascc.c         | 2073 +++++++++++++-------------
 drivers/net/hamradio/hdlcdrv.c        |   48 
 drivers/net/hamradio/mkiss.c          |   12 
 drivers/net/hamradio/yam.c            |   38 
 drivers/net/mv643xx_eth.c             | 2687 +++++++++++++++++++---------------
 drivers/net/mv643xx_eth.h             |  641 +++-----
 drivers/net/sis900.c                  |  216 +-
 drivers/net/via-rhine.c               |    4 
 drivers/net/wireless/airport.c        |   22 
 drivers/net/wireless/hermes.c         |   72 
 drivers/net/wireless/hermes.h         |   64 
 drivers/net/wireless/orinoco.c        |  419 +++--
 drivers/net/wireless/orinoco.h        |   37 
 drivers/net/wireless/orinoco_cs.c     |   49 
 drivers/net/wireless/orinoco_pci.c    |  124 -
 drivers/net/wireless/orinoco_plx.c    |  235 +-
 drivers/net/wireless/orinoco_tmd.c    |  150 +
 include/linux/mv643xx.h               |  448 ++++-
 26 files changed, 4187 insertions(+), 3530 deletions(-)

through these ChangeSets:

<dfarnsworth:mvista.com>:
  o [netdrvr mv643xx] Big rename
  o [netdrvr mv643xx] Rename MV_READ => mv_read and MV_WRITE => mv_write
  o [netdrvr mv643xx] Additional whitespace cleanups, mostly changing spaces to tabs in comments
  o [netdrvr mv643xx] Run mv643xx_eth.[ch] through scripts/Lindent
  o [netdrvr mv643xx] Add a function to detect at runtime whether a PHY is attached to the specified port, and use it to cause the probe routine to fail when there is no PHY.
  o [netdrvr mv643xx] This one liner removes a spurious left paren fixing an obvious syntax error in the #ifndef MV64340_NAPI case
  o [netdrvr mv643xx] Add support for PHYs/boards that don't support autonegotiation
  o [netdrvr mv643xx] With this patch, the driver now calls netif_carrier_off/netif_carrier_on
  o [netdrvr mv643xx] This patch cleans up the handling of receive skb sizing

<mbrancaleoni:tiscali.it>:
  o sis900.c net poll support

<takis:lumumba.luc.ac.be>:
  o Possible VIA-Rhine free irq issue

Alexander Viro:
  o fealnx iomem annotations, switch to io{read,write}
  o wireless iomem annotations and fixes, switch to io{read,write}

Andrew Morton:
  o VIA-Rhine: undork whitespace

Dale Farnsworth:
  o mv643xx: remove superfluous function, mv643xx_set_ethtool_ops
  o mv643xx: raise size of receive skbs to allow for an optional VLAN tag
  o [netdrvr mv643xx] Remove call to msleep() while locks are held.  We don't really need to wait for the link to come up.  It was a workaround to avoid a transient error message, "Virtual device %s asks to queue packet!\n", in dev_queue_xmit() when called by ic_bootp_send_if().  This happens because right after opening the network device, there is a pending PHY status change interrupt causing the driver to call netif_stop_queue().  A half second later, the link comes up and all is well.  We could have moved the call to msleep() to mv643xx_eth_open() to perpetuate the workaround, but I think it's best to remove it entirely.
  o [netdrvr mv643xx] Ensure that we only change the Port Serial Control Reg while the port is disabled.
  o [netdrvr mv643xx] Add ethtool support to the mv643xx ethernet driver
  o [netdrvr mv643xx] Enable the mv643xx ethernet support on platforms using the MV64360 chip
  o [netdrvr mv643xx] Disable tcp/udp checksum offload to hardware.  It generally works, but the hardware appears to generate the wrong checksum if the hw checksum generation wasn't used in the previous packet sent.
  o [netdrvr mv643xx] We already set ETH_TX_ENABLE_INTERRUPT whenever we set ETH_TX_LAST_DESC
  o [netdrvr mv643xx] Update tx_bytes statistic when using hw tcp/udp checksum generation
  o [netdrvr mv643xx] Call netif_carrier_off when closing the driver
  o [netdrvr mv643xx] Trivial.  Remove repeated comment
  o [netdrvr mv643xx] Clear transmit l4i_chk even when the hardware ignores it
  o [netdrvr mv643xx] Increment tx_ring_skbs before calling eth_port_send, since
  o [netdrvr mv643xx] Fix handling of unaligned tiny fragments not handled by hardware Check all fragments instead of just the last.
  o [netdrvr mv643xx] Fix a few places I missed in the previous rename patch
  o [netdrvr mv643xx] This patch simplifies the mv64340_eth_set_rx_mode function without changing its behavior.
  o [netdrvr mv643xx] This patch makes the use of the MV64340_RX_QUEUE_FILL_ON_TASK config macro more consistent, though the macro remains undefined, since the feature still does not work properly.
  o [netdrvr mv643xx] This patch adds support for passing additional parameters via the platform_device interface.  These additional parameters are:
  o [netdrvr mv643xx] This patch adds device driver model support to the mv643xx_eth driver
  o [netdrvr mv643xx] This patch replaces the use of the pci_map_* functions with the corresponding dma_map_* functions.
  o [netdrvr mv643xx] This patch fixes the code that enables hardware checksum generation
  o [netdrvr mv643xx] This patch removes spin delays (count to 1000000, ugh) and instead waits with udelay or msleep for hardware flags to change.
  o [netdrvr mv643xx] This patch removes code that is redundant or useless

Daniele Venzano:
  o sis900: chiprev i/o cleanups
  o sis900: debugging output update
  o sis900 printk audit
  o sis900: version bump; remove broken URL
  o sis900: add infrastructure needed for standard netif messages

David Gibson:
  o Orinoco driver updates - cleanup PCI initialization
  o Orinoco driver updates - PCMCIA initialization cleanups
  o Orinoco driver updates - update version and changelog
  o Orinoco driver updates - update firmware detection
  o Orinoco driver updates - WEP updates
  o Orinoco driver updates - delay Tx wake
  o Orinoco driver updates - prohibit IBSS with no ESSID
  o Orinoco driver updates - update is_ethersnap()
  o Orinoco driver updates - PCMCIA initialization cleanups
  o Orinoco driver updates - use modern module_parm()
  o Orinoco driver updates - cleanup PCI initialization
  o Orinoco driver updates - cleanup low-level code
  o Orinoco driver updates - add free_orinocodev()
  o Orinoco driver updates - use mdelay()/ssleep() more
  o Orinoco driver updates - update printk()s
  o Orinoco driver updates - use netif_carrier_*()

Ralf Bächle:
  o Remove unused MAXBPQDEV definition
  o Sparse fixes for drivers/net/hamradio
  o Reformat DMASCC driver
  o Use netdev_priv in baycom_epp driver
  o Use netdev_priv in baycom_ser_fdx driver
  o Use netdev_priv in hdlcdrv driver
  o Use netdev_priv in baycom_ser_hdx driver
  o Use netdev_priv in baycom_par driver
  o Use netdev_priv in bpqether driver
  o Use netdev_priv in mkiss driver
  o Use netdev_priv in YAM driver


[-- Attachment #3: patch --]
[-- Type: text/plain, Size: 383168 bytes --]

diff -Nru a/drivers/net/Kconfig b/drivers/net/Kconfig
--- a/drivers/net/Kconfig	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/Kconfig	2005-03-08 14:29:45 -05:00
@@ -2066,10 +2066,11 @@
 
 config MV643XX_ETH
 	tristate "MV-643XX Ethernet support"
-	depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX || MOMENCO_OCELOT_3
+	depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX || MV64360 || MOMENCO_OCELOT_3
 	help
 	  This driver supports the gigabit Ethernet on the Marvell MV643XX
-	  chipset which is used in the Momenco Ocelot C and Jaguar ATX.
+	  chipset which is used in the Momenco Ocelot C and Jaguar ATX and
+	  Pegasos II, amongst other PPC and MIPS boards.
 
 config MV643XX_ETH_0
 	bool "MV-643XX Port 0"
diff -Nru a/drivers/net/fealnx.c b/drivers/net/fealnx.c
--- a/drivers/net/fealnx.c	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/fealnx.c	2005-03-08 14:29:45 -05:00
@@ -102,21 +102,6 @@
 #define USE_IO_OPS
 #endif
 
-#ifdef USE_IO_OPS
-#undef readb
-#undef readw
-#undef readl
-#undef writeb
-#undef writew
-#undef writel
-#define readb inb
-#define readw inw
-#define readl inl
-#define writeb outb
-#define writew outw
-#define writel outl
-#endif
-
 /* Kernel compatibility defines, some common to David Hinds' PCMCIA package. */
 /* This is only in the support-all-kernels source code. */
 
@@ -444,6 +429,7 @@
 	int mii_cnt;		/* MII device addresses. */
 	unsigned char phys[2];	/* MII device addresses. */
 	struct mii_if_info mii;
+	void __iomem *mem;
 };
 
 
@@ -468,23 +454,23 @@
 static void reset_rx_descriptors(struct net_device *dev);
 static void reset_tx_descriptors(struct net_device *dev);
 
-static void stop_nic_rx(long ioaddr, long crvalue)
+static void stop_nic_rx(void __iomem *ioaddr, long crvalue)
 {
 	int delay = 0x1000;
-	writel(crvalue & ~(CR_W_RXEN), ioaddr + TCRRCR);
+	iowrite32(crvalue & ~(CR_W_RXEN), ioaddr + TCRRCR);
 	while (--delay) {
-		if ( (readl(ioaddr + TCRRCR) & CR_R_RXSTOP) == CR_R_RXSTOP)
+		if ( (ioread32(ioaddr + TCRRCR) & CR_R_RXSTOP) == CR_R_RXSTOP)
 			break;
 	}
 }
 
 
-static void stop_nic_rxtx(long ioaddr, long crvalue)
+static void stop_nic_rxtx(void __iomem *ioaddr, long crvalue)
 {
 	int delay = 0x1000;
-	writel(crvalue & ~(CR_W_RXEN+CR_W_TXEN), ioaddr + TCRRCR);
+	iowrite32(crvalue & ~(CR_W_RXEN+CR_W_TXEN), ioaddr + TCRRCR);
 	while (--delay) {
-		if ( (readl(ioaddr + TCRRCR) & (CR_R_RXSTOP+CR_R_TXSTOP))
+		if ( (ioread32(ioaddr + TCRRCR) & (CR_R_RXSTOP+CR_R_TXSTOP))
 					    == (CR_R_RXSTOP+CR_R_TXSTOP) )
 			break;
 	}
@@ -498,11 +484,17 @@
 	int i, option, err, irq;
 	static int card_idx = -1;
 	char boardname[12];
-	long ioaddr;
+	void __iomem *ioaddr;
+	unsigned long len;
 	unsigned int chip_id = ent->driver_data;
 	struct net_device *dev;
 	void *ring_space;
 	dma_addr_t ring_dma;
+#ifdef USE_IO_OPS
+	int bar = 0;
+#else
+	int bar = 1;
+#endif
 	
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
@@ -520,14 +512,10 @@
 	if (i) return i;
 	pci_set_master(pdev);
 	
-#ifdef USE_IO_OPS
-	ioaddr = pci_resource_len(pdev, 0);
-#else
-	ioaddr = pci_resource_len(pdev, 1);
-#endif
-	if (ioaddr < MIN_REGION_SIZE) {
+	len = pci_resource_len(pdev, bar);
+	if (len < MIN_REGION_SIZE) {
 		printk(KERN_ERR "%s: region size %ld too small, aborting\n",
-		       boardname, ioaddr);
+		       boardname, len);
 		return -ENODEV;
 	}
 
@@ -536,17 +524,12 @@
 	
 	irq = pdev->irq;
 
-#ifdef USE_IO_OPS
-	ioaddr = pci_resource_start(pdev, 0);
-#else
-	ioaddr = (long) ioremap(pci_resource_start(pdev, 1),
-				pci_resource_len(pdev, 1));
+	ioaddr = pci_iomap(pdev, bar, len);
 	if (!ioaddr) {
 		err = -ENOMEM;
 		goto err_out_res;
 	}
-#endif
-	
+
 	dev = alloc_etherdev(sizeof(struct netdev_private));
 	if (!dev) {
 		err = -ENOMEM;
@@ -557,16 +540,17 @@
 
 	/* read ethernet id */
 	for (i = 0; i < 6; ++i)
-		dev->dev_addr[i] = readb(ioaddr + PAR0 + i);
+		dev->dev_addr[i] = ioread8(ioaddr + PAR0 + i);
 
 	/* Reset the chip to erase previous misconfiguration. */
-	writel(0x00000001, ioaddr + BCR);
+	iowrite32(0x00000001, ioaddr + BCR);
 
-	dev->base_addr = ioaddr;
+	dev->base_addr = (unsigned long)ioaddr;
 	dev->irq = irq;
 
 	/* Make certain the descriptor lists are aligned. */
-	np = dev->priv;
+	np = netdev_priv(dev);
+	np->mem = ioaddr;
 	spin_lock_init(&np->lock);
 	np->pci_dev = pdev;
 	np->flags = skel_netdrv_tbl[chip_id].flags;
@@ -635,7 +619,7 @@
 		np->phys[0] = 32;
 /* 89/6/23 add, (begin) */
 		/* get phy type */
-		if (readl(ioaddr + PHYIDENTIFIER) == MysonPHYID)
+		if (ioread32(ioaddr + PHYIDENTIFIER) == MysonPHYID)
 			np->PHYType = MysonPHY;
 		else
 			np->PHYType = OtherPHY;
@@ -670,7 +654,7 @@
 		if (np->flags == HAS_MII_XCVR)
 			mdio_write(dev, np->phys[0], MII_ADVERTISE, ADVERTISE_FULL);
 		else
-			writel(ADVERTISE_FULL, ioaddr + ANARANLPAR);
+			iowrite32(ADVERTISE_FULL, ioaddr + ANARANLPAR);
 		np->mii.force_media = 1;
 	}
 
@@ -689,7 +673,7 @@
 	if (err)
 		goto err_out_free_tx;
 
-	printk(KERN_INFO "%s: %s at 0x%lx, ",
+	printk(KERN_INFO "%s: %s at %p, ",
 	       dev->name, skel_netdrv_tbl[chip_id].chip_name, ioaddr);
 	for (i = 0; i < 5; i++)
 		printk("%2.2x:", dev->dev_addr[i]);
@@ -704,10 +688,8 @@
 err_out_free_dev:
 	free_netdev(dev);
 err_out_unmap:
-#ifndef USE_IO_OPS
-	iounmap((void *)ioaddr);
+	pci_iounmap(pdev, ioaddr);
 err_out_res:
-#endif
 	pci_release_regions(pdev);
 	return err;
 }
@@ -718,16 +700,14 @@
 	struct net_device *dev = pci_get_drvdata(pdev);
 
 	if (dev) {
-		struct netdev_private *np = dev->priv;
+		struct netdev_private *np = netdev_priv(dev);
 
 		pci_free_consistent(pdev, TX_TOTAL_SIZE, np->tx_ring,
 			np->tx_ring_dma);
 		pci_free_consistent(pdev, RX_TOTAL_SIZE, np->rx_ring,
 			np->rx_ring_dma);
 		unregister_netdev(dev);
-#ifndef USE_IO_OPS
-		iounmap((void *)dev->base_addr);
-#endif
+		pci_iounmap(pdev, np->mem);
 		free_netdev(dev);
 		pci_release_regions(pdev);
 		pci_set_drvdata(pdev, NULL);
@@ -736,14 +716,14 @@
 }
 
 
-static ulong m80x_send_cmd_to_phy(long miiport, int opcode, int phyad, int regad)
+static ulong m80x_send_cmd_to_phy(void __iomem *miiport, int opcode, int phyad, int regad)
 {
 	ulong miir;
 	int i;
 	unsigned int mask, data;
 
 	/* enable MII output */
-	miir = (ulong) readl(miiport);
+	miir = (ulong) ioread32(miiport);
 	miir &= 0xfffffff0;
 
 	miir |= MASK_MIIR_MII_WRITE + MASK_MIIR_MII_MDO;
@@ -752,11 +732,11 @@
 	for (i = 0; i < 32; i++) {
 		/* low MDC; MDO is already high (miir) */
 		miir &= ~MASK_MIIR_MII_MDC;
-		writel(miir, miiport);
+		iowrite32(miir, miiport);
 
 		/* high MDC */
 		miir |= MASK_MIIR_MII_MDC;
-		writel(miir, miiport);
+		iowrite32(miir, miiport);
 	}
 
 	/* calculate ST+OP+PHYAD+REGAD+TA */
@@ -770,10 +750,10 @@
 		if (mask & data)
 			miir |= MASK_MIIR_MII_MDO;
 
-		writel(miir, miiport);
+		iowrite32(miir, miiport);
 		/* high MDC */
 		miir |= MASK_MIIR_MII_MDC;
-		writel(miir, miiport);
+		iowrite32(miir, miiport);
 		udelay(30);
 
 		/* next */
@@ -787,7 +767,8 @@
 
 static int mdio_read(struct net_device *dev, int phyad, int regad)
 {
-	long miiport = dev->base_addr + MANAGEMENT;
+	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *miiport = np->mem + MANAGEMENT;
 	ulong miir;
 	unsigned int mask, data;
 
@@ -799,16 +780,16 @@
 	while (mask) {
 		/* low MDC */
 		miir &= ~MASK_MIIR_MII_MDC;
-		writel(miir, miiport);
+		iowrite32(miir, miiport);
 
 		/* read MDI */
-		miir = readl(miiport);
+		miir = ioread32(miiport);
 		if (miir & MASK_MIIR_MII_MDI)
 			data |= mask;
 
 		/* high MDC, and wait */
 		miir |= MASK_MIIR_MII_MDC;
-		writel(miir, miiport);
+		iowrite32(miir, miiport);
 		udelay(30);
 
 		/* next */
@@ -817,7 +798,7 @@
 
 	/* low MDC */
 	miir &= ~MASK_MIIR_MII_MDC;
-	writel(miir, miiport);
+	iowrite32(miir, miiport);
 
 	return data & 0xffff;
 }
@@ -825,7 +806,8 @@
 
 static void mdio_write(struct net_device *dev, int phyad, int regad, int data)
 {
-	long miiport = dev->base_addr + MANAGEMENT;
+	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *miiport = np->mem + MANAGEMENT;
 	ulong miir;
 	unsigned int mask;
 
@@ -838,11 +820,11 @@
 		miir &= ~(MASK_MIIR_MII_MDC + MASK_MIIR_MII_MDO);
 		if (mask & data)
 			miir |= MASK_MIIR_MII_MDO;
-		writel(miir, miiport);
+		iowrite32(miir, miiport);
 
 		/* high MDC */
 		miir |= MASK_MIIR_MII_MDC;
-		writel(miir, miiport);
+		iowrite32(miir, miiport);
 
 		/* next */
 		mask >>= 1;
@@ -850,29 +832,29 @@
 
 	/* low MDC */
 	miir &= ~MASK_MIIR_MII_MDC;
-	writel(miir, miiport);
+	iowrite32(miir, miiport);
 }
 
 
 static int netdev_open(struct net_device *dev)
 {
-	struct netdev_private *np = dev->priv;
-	long ioaddr = dev->base_addr;
+	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *ioaddr = np->mem;
 	int i;
 
-	writel(0x00000001, ioaddr + BCR);	/* Reset */
+	iowrite32(0x00000001, ioaddr + BCR);	/* Reset */
 
 	if (request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev))
 		return -EAGAIN;
 
 	for (i = 0; i < 3; i++)
-		writew(((unsigned short*)dev->dev_addr)[i],
+		iowrite16(((unsigned short*)dev->dev_addr)[i],
 				ioaddr + PAR0 + i*2);
 
 	init_ring(dev);
 
-	writel(np->rx_ring_dma, ioaddr + RXLBA);
-	writel(np->tx_ring_dma, ioaddr + TXLBA);
+	iowrite32(np->rx_ring_dma, ioaddr + RXLBA);
+	iowrite32(np->tx_ring_dma, ioaddr + TXLBA);
 
 	/* Initialize other registers. */
 	/* Configure the PCI bus bursts and FIFO thresholds.
@@ -933,12 +915,12 @@
 		np->crvalue |= CR_W_ENH;	/* set enhanced bit */
 		np->imrvalue |= ETI;
 	}
-	writel(np->bcrvalue, ioaddr + BCR);
+	iowrite32(np->bcrvalue, ioaddr + BCR);
 
 	if (dev->if_port == 0)
 		dev->if_port = np->default_port;
 
-	writel(0, ioaddr + RXPDR);
+	iowrite32(0, ioaddr + RXPDR);
 // 89/9/1 modify,
 //   np->crvalue = 0x00e40001;    /* tx store and forward, tx/rx enable */
 	np->crvalue |= 0x00e40001;	/* tx store and forward, tx/rx enable */
@@ -951,8 +933,8 @@
 	netif_start_queue(dev);
 
 	/* Clear and Enable interrupts by setting the interrupt mask. */
-	writel(FBE | TUNF | CNTOVF | RBU | TI | RI, ioaddr + ISR);
-	writel(np->imrvalue, ioaddr + IMR);
+	iowrite32(FBE | TUNF | CNTOVF | RBU | TI | RI, ioaddr + ISR);
+	iowrite32(np->imrvalue, ioaddr + IMR);
 
 	if (debug)
 		printk(KERN_DEBUG "%s: Done netdev_open().\n", dev->name);
@@ -980,14 +962,14 @@
 /* input   : dev... pointer to the adapter block.                            */
 /* output  : none.                                                           */
 {
-	struct netdev_private *np = dev->priv;
+	struct netdev_private *np = netdev_priv(dev);
 	unsigned int i, DelayTime = 0x1000;
 
 	np->linkok = 0;
 
 	if (np->PHYType == MysonPHY) {
 		for (i = 0; i < DelayTime; ++i) {
-			if (readl(dev->base_addr + BMCRSR) & LinkIsUp2) {
+			if (ioread32(np->mem + BMCRSR) & LinkIsUp2) {
 				np->linkok = 1;
 				return;
 			}
@@ -1007,14 +989,14 @@
 
 static void getlinktype(struct net_device *dev)
 {
-	struct netdev_private *np = dev->priv;
+	struct netdev_private *np = netdev_priv(dev);
 
 	if (np->PHYType == MysonPHY) {	/* 3-in-1 case */
-		if (readl(dev->base_addr + TCRRCR) & CR_R_FD)
+		if (ioread32(np->mem + TCRRCR) & CR_R_FD)
 			np->duplexmode = 2;	/* full duplex */
 		else
 			np->duplexmode = 1;	/* half duplex */
-		if (readl(dev->base_addr + TCRRCR) & CR_R_PS10)
+		if (ioread32(np->mem + TCRRCR) & CR_R_PS10)
 			np->line_speed = 1;	/* 10M */
 		else
 			np->line_speed = 2;	/* 100M */
@@ -1110,7 +1092,7 @@
 /* Take lock before calling this */
 static void allocate_rx_buffers(struct net_device *dev)
 {
-	struct netdev_private *np = dev->priv;
+	struct netdev_private *np = netdev_priv(dev);
 
 	/*  allocate skb for rx buffers */
 	while (np->really_rx_count != RX_RING_SIZE) {
@@ -1136,16 +1118,16 @@
 static void netdev_timer(unsigned long data)
 {
 	struct net_device *dev = (struct net_device *) data;
-	struct netdev_private *np = dev->priv;
-	long ioaddr = dev->base_addr;
+	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *ioaddr = np->mem;
 	int old_crvalue = np->crvalue;
 	unsigned int old_linkok = np->linkok;
 	unsigned long flags;
 
 	if (debug)
 		printk(KERN_DEBUG "%s: Media selection timer tick, status %8.8x "
-		       "config %8.8x.\n", dev->name, readl(ioaddr + ISR),
-		       readl(ioaddr + TCRRCR));
+		       "config %8.8x.\n", dev->name, ioread32(ioaddr + ISR),
+		       ioread32(ioaddr + TCRRCR));
 
 	spin_lock_irqsave(&np->lock, flags);
 
@@ -1155,7 +1137,7 @@
 			getlinktype(dev);
 			if (np->crvalue != old_crvalue) {
 				stop_nic_rxtx(ioaddr, np->crvalue);
-				writel(np->crvalue, ioaddr + TCRRCR);
+				iowrite32(np->crvalue, ioaddr + TCRRCR);
 			}
 		}
 	}
@@ -1173,22 +1155,23 @@
 /* Reset chip and disable rx, tx and interrupts */
 static void reset_and_disable_rxtx(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
+	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *ioaddr = np->mem;
 	int delay=51;
 
 	/* Reset the chip's Tx and Rx processes. */
 	stop_nic_rxtx(ioaddr, 0);
 
 	/* Disable interrupts by clearing the interrupt mask. */
-	writel(0, ioaddr + IMR);
+	iowrite32(0, ioaddr + IMR);
 
 	/* Reset the chip to erase previous misconfiguration. */
-	writel(0x00000001, ioaddr + BCR);
+	iowrite32(0x00000001, ioaddr + BCR);
 
 	/* Ueimor: wait for 50 PCI cycles (and flush posted writes btw). 
 	   We surely wait too long (address+data phase). Who cares? */
 	while (--delay) {
-		readl(ioaddr + BCR);
+		ioread32(ioaddr + BCR);
 		rmb();
 	}
 }
@@ -1198,33 +1181,33 @@
 /* Restore chip after reset */
 static void enable_rxtx(struct net_device *dev)
 {
-	struct netdev_private *np = dev->priv;
-	long ioaddr = dev->base_addr;
+	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *ioaddr = np->mem;
 
 	reset_rx_descriptors(dev);
 
-	writel(np->tx_ring_dma + ((char*)np->cur_tx - (char*)np->tx_ring),
+	iowrite32(np->tx_ring_dma + ((char*)np->cur_tx - (char*)np->tx_ring),
 		ioaddr + TXLBA);
-	writel(np->rx_ring_dma + ((char*)np->cur_rx - (char*)np->rx_ring),
+	iowrite32(np->rx_ring_dma + ((char*)np->cur_rx - (char*)np->rx_ring),
 		ioaddr + RXLBA);
 
-	writel(np->bcrvalue, ioaddr + BCR);
+	iowrite32(np->bcrvalue, ioaddr + BCR);
 
-	writel(0, ioaddr + RXPDR);
+	iowrite32(0, ioaddr + RXPDR);
 	__set_rx_mode(dev); /* changes np->crvalue, writes it into TCRRCR */
 
 	/* Clear and Enable interrupts by setting the interrupt mask. */
-	writel(FBE | TUNF | CNTOVF | RBU | TI | RI, ioaddr + ISR);
-	writel(np->imrvalue, ioaddr + IMR);
+	iowrite32(FBE | TUNF | CNTOVF | RBU | TI | RI, ioaddr + ISR);
+	iowrite32(np->imrvalue, ioaddr + IMR);
 
-	writel(0, ioaddr + TXPDR);
+	iowrite32(0, ioaddr + TXPDR);
 }
 
 
 static void reset_timer(unsigned long data)
 {
 	struct net_device *dev = (struct net_device *) data;
-	struct netdev_private *np = dev->priv;
+	struct netdev_private *np = netdev_priv(dev);
 	unsigned long flags;
 
 	printk(KERN_WARNING "%s: resetting tx and rx machinery\n", dev->name);
@@ -1247,13 +1230,13 @@
 
 static void tx_timeout(struct net_device *dev)
 {
-	struct netdev_private *np = dev->priv;
-	long ioaddr = dev->base_addr;
+	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *ioaddr = np->mem;
 	unsigned long flags;
 	int i;
 
 	printk(KERN_WARNING "%s: Transmit timed out, status %8.8x,"
-	       " resetting...\n", dev->name, readl(ioaddr + ISR));
+	       " resetting...\n", dev->name, ioread32(ioaddr + ISR));
 
 	{
 		printk(KERN_DEBUG "  Rx ring %p: ", np->rx_ring);
@@ -1282,7 +1265,7 @@
 /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
 static void init_ring(struct net_device *dev)
 {
-	struct netdev_private *np = dev->priv;
+	struct netdev_private *np = netdev_priv(dev);
 	int i;
 
 	/* initialize rx variables */
@@ -1346,7 +1329,7 @@
 
 static int start_tx(struct sk_buff *skb, struct net_device *dev)
 {
-	struct netdev_private *np = dev->priv;
+	struct netdev_private *np = netdev_priv(dev);
 	unsigned long flags;
 
 	spin_lock_irqsave(&np->lock, flags);
@@ -1413,7 +1396,7 @@
 	if (np->free_tx_count < 2)
 		netif_stop_queue(dev);
 	++np->really_tx_count;
-	writel(0, dev->base_addr + TXPDR);
+	iowrite32(0, np->mem + TXPDR);
 	dev->trans_start = jiffies;
 
 	spin_unlock_irqrestore(&np->lock, flags);
@@ -1425,7 +1408,7 @@
 /* Chip probably hosed tx ring. Clean up. */
 static void reset_tx_descriptors(struct net_device *dev)
 {
-	struct netdev_private *np = dev->priv;
+	struct netdev_private *np = netdev_priv(dev);
 	struct fealnx_desc *cur;
 	int i;
 
@@ -1460,7 +1443,7 @@
 /* Take lock and stop rx before calling this */
 static void reset_rx_descriptors(struct net_device *dev)
 {
-	struct netdev_private *np = dev->priv;
+	struct netdev_private *np = netdev_priv(dev);
 	struct fealnx_desc *cur = np->cur_rx;
 	int i;
 
@@ -1472,8 +1455,8 @@
 		cur = cur->next_desc_logical;
 	}
 
-	writel(np->rx_ring_dma + ((char*)np->cur_rx - (char*)np->rx_ring),
-		dev->base_addr + RXLBA);
+	iowrite32(np->rx_ring_dma + ((char*)np->cur_rx - (char*)np->rx_ring),
+		np->mem + RXLBA);
 }
 
 
@@ -1482,21 +1465,21 @@
 static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
 {
 	struct net_device *dev = (struct net_device *) dev_instance;
-	struct netdev_private *np = dev->priv;
-	long ioaddr = dev->base_addr;
+	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *ioaddr = np->mem;
 	long boguscnt = max_interrupt_work;
 	unsigned int num_tx = 0;
 	int handled = 0;
 
 	spin_lock(&np->lock);
 
-	writel(0, ioaddr + IMR);
+	iowrite32(0, ioaddr + IMR);
 
 	do {
-		u32 intr_status = readl(ioaddr + ISR);
+		u32 intr_status = ioread32(ioaddr + ISR);
 
 		/* Acknowledge all of the current interrupt sources ASAP. */
-		writel(intr_status, ioaddr + ISR);
+		iowrite32(intr_status, ioaddr + ISR);
 
 		if (debug)
 			printk(KERN_DEBUG "%s: Interrupt, status %4.4x.\n", dev->name,
@@ -1517,15 +1500,15 @@
 //      };
 
 		if (intr_status & TUNF)
-			writel(0, ioaddr + TXPDR);
+			iowrite32(0, ioaddr + TXPDR);
 
 		if (intr_status & CNTOVF) {
 			/* missed pkts */
-			np->stats.rx_missed_errors += readl(ioaddr + TALLY) & 0x7fff;
+			np->stats.rx_missed_errors += ioread32(ioaddr + TALLY) & 0x7fff;
 
 			/* crc error */
 			np->stats.rx_crc_errors +=
-			    (readl(ioaddr + TALLY) & 0x7fff0000) >> 16;
+			    (ioread32(ioaddr + TALLY) & 0x7fff0000) >> 16;
 		}
 
 		if (intr_status & (RI | RBU)) {
@@ -1534,7 +1517,7 @@
 			else {
 				stop_nic_rx(ioaddr, np->crvalue);
 				reset_rx_descriptors(dev);
-				writel(np->crvalue, ioaddr + TCRRCR);
+				iowrite32(np->crvalue, ioaddr + TCRRCR);
 			}				
 		}
 
@@ -1605,7 +1588,7 @@
 		if (np->crvalue & CR_W_ENH) {
 			long data;
 
-			data = readl(ioaddr + TSR);
+			data = ioread32(ioaddr + TSR);
 			np->stats.tx_errors += (data & 0xff000000) >> 24;
 			np->stats.tx_aborted_errors += (data & 0xff000000) >> 24;
 			np->stats.tx_window_errors += (data & 0x00ff0000) >> 16;
@@ -1635,16 +1618,16 @@
 
 	/* read the tally counters */
 	/* missed pkts */
-	np->stats.rx_missed_errors += readl(ioaddr + TALLY) & 0x7fff;
+	np->stats.rx_missed_errors += ioread32(ioaddr + TALLY) & 0x7fff;
 
 	/* crc error */
-	np->stats.rx_crc_errors += (readl(ioaddr + TALLY) & 0x7fff0000) >> 16;
+	np->stats.rx_crc_errors += (ioread32(ioaddr + TALLY) & 0x7fff0000) >> 16;
 
 	if (debug)
 		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
-		       dev->name, readl(ioaddr + ISR));
+		       dev->name, ioread32(ioaddr + ISR));
 
-	writel(np->imrvalue, ioaddr + IMR);
+	iowrite32(np->imrvalue, ioaddr + IMR);
 
 	spin_unlock(&np->lock);
 
@@ -1656,8 +1639,8 @@
    for clarity and better register allocation. */
 static int netdev_rx(struct net_device *dev)
 {
-	struct netdev_private *np = dev->priv;
-	long ioaddr = dev->base_addr;
+	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *ioaddr = np->mem;
 
 	/* If EOP is set on the next entry, it's a new packet. Send it up. */
 	while (!(np->cur_rx->status & RXOWN) && np->cur_rx->skbuff) {
@@ -1725,7 +1708,7 @@
 				} else {        /* rx error, need to reset this chip */
 					stop_nic_rx(ioaddr, np->crvalue);
 					reset_rx_descriptors(dev);
-					writel(np->crvalue, ioaddr + TCRRCR);
+					iowrite32(np->crvalue, ioaddr + TCRRCR);
 				}
 				break;	/* exit the while loop */
 			}
@@ -1793,13 +1776,13 @@
 
 static struct net_device_stats *get_stats(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
-	struct netdev_private *np = dev->priv;
+	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *ioaddr = np->mem;
 
 	/* The chip only need report frame silently dropped. */
 	if (netif_running(dev)) {
-		np->stats.rx_missed_errors += readl(ioaddr + TALLY) & 0x7fff;
-		np->stats.rx_crc_errors += (readl(ioaddr + TALLY) & 0x7fff0000) >> 16;
+		np->stats.rx_missed_errors += ioread32(ioaddr + TALLY) & 0x7fff;
+		np->stats.rx_crc_errors += (ioread32(ioaddr + TALLY) & 0x7fff0000) >> 16;
 	}
 
 	return &np->stats;
@@ -1809,7 +1792,7 @@
 /* for dev->set_multicast_list */
 static void set_rx_mode(struct net_device *dev)
 {
-	spinlock_t *lp = &((struct netdev_private *)dev->priv)->lock;
+	spinlock_t *lp = &((struct netdev_private *)netdev_priv(dev))->lock;
 	unsigned long flags;
 	spin_lock_irqsave(lp, flags);
 	__set_rx_mode(dev);
@@ -1820,8 +1803,8 @@
 /* Take lock before calling */
 static void __set_rx_mode(struct net_device *dev)
 {
-	struct netdev_private *np = dev->priv;
-	long ioaddr = dev->base_addr;
+	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *ioaddr = np->mem;
 	u32 mc_filter[2];	/* Multicast hash filter */
 	u32 rx_mode;
 
@@ -1851,16 +1834,16 @@
 
 	stop_nic_rxtx(ioaddr, np->crvalue);
 
-	writel(mc_filter[0], ioaddr + MAR0);
-	writel(mc_filter[1], ioaddr + MAR1);
+	iowrite32(mc_filter[0], ioaddr + MAR0);
+	iowrite32(mc_filter[1], ioaddr + MAR1);
 	np->crvalue &= ~CR_W_RXMODEMASK;
 	np->crvalue |= rx_mode;
-	writel(np->crvalue, ioaddr + TCRRCR);
+	iowrite32(np->crvalue, ioaddr + TCRRCR);
 }
 
 static void netdev_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
-	struct netdev_private *np = dev->priv;
+	struct netdev_private *np = netdev_priv(dev);
 
 	strcpy(info->driver, DRV_NAME);
 	strcpy(info->version, DRV_VERSION);
@@ -1869,7 +1852,7 @@
 
 static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-	struct netdev_private *np = dev->priv;
+	struct netdev_private *np = netdev_priv(dev);
 	int rc;
 
 	spin_lock_irq(&np->lock);
@@ -1881,7 +1864,7 @@
 
 static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-	struct netdev_private *np = dev->priv;
+	struct netdev_private *np = netdev_priv(dev);
 	int rc;
 
 	spin_lock_irq(&np->lock);
@@ -1893,13 +1876,13 @@
 
 static int netdev_nway_reset(struct net_device *dev)
 {
-	struct netdev_private *np = dev->priv;
+	struct netdev_private *np = netdev_priv(dev);
 	return mii_nway_restart(&np->mii);
 }
 
 static u32 netdev_get_link(struct net_device *dev)
 {
-	struct netdev_private *np = dev->priv;
+	struct netdev_private *np = netdev_priv(dev);
 	return mii_link_ok(&np->mii);
 }
 
@@ -1927,7 +1910,7 @@
 
 static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-	struct netdev_private *np = dev->priv;
+	struct netdev_private *np = netdev_priv(dev);
 	int rc;
 
 	if (!netif_running(dev))
@@ -1943,14 +1926,14 @@
 
 static int netdev_close(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
-	struct netdev_private *np = dev->priv;
+	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *ioaddr = np->mem;
 	int i;
 
 	netif_stop_queue(dev);
 
 	/* Disable interrupts by clearing the interrupt mask. */
-	writel(0x0000, ioaddr + IMR);
+	iowrite32(0x0000, ioaddr + IMR);
 
 	/* Stop the chip's Tx and Rx processes. */
 	stop_nic_rxtx(ioaddr, 0);
diff -Nru a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
--- a/drivers/net/hamradio/6pack.c	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/hamradio/6pack.c	2005-03-08 14:29:45 -05:00
@@ -756,12 +756,12 @@
 
 	switch(cmd) {
 	case SIOCGIFNAME:
-		err = copy_to_user((void *) arg, dev->name,
+		err = copy_to_user((void __user *) arg, dev->name,
 		                   strlen(dev->name) + 1) ? -EFAULT : 0;
 		break;
 
 	case SIOCGIFENCAP:
-		err = put_user(0, (int __user *)arg);
+		err = put_user(0, (int __user *) arg);
 		break;
 
 	case SIOCSIFENCAP:
diff -Nru a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
--- a/drivers/net/hamradio/baycom_epp.c	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/hamradio/baycom_epp.c	2005-03-08 14:29:45 -05:00
@@ -68,25 +68,7 @@
 /* --------------------------------------------------------------------- */
 
 static const char paranoia_str[] = KERN_ERR 
-"baycom_epp: bad magic number for hdlcdrv_state struct in routine %s\n";
-
-#define baycom_paranoia_check(dev,routine,retval)                                              \
-({                                                                                             \
-	if (!dev || !dev->priv || ((struct baycom_state *)dev->priv)->magic != BAYCOM_MAGIC) { \
-		printk(paranoia_str, routine);                                                 \
-		return retval;                                                                 \
-	}                                                                                      \
-})
-
-#define baycom_paranoia_check_void(dev,routine)                                                \
-({                                                                                             \
-	if (!dev || !dev->priv || ((struct baycom_state *)dev->priv)->magic != BAYCOM_MAGIC) { \
-		printk(paranoia_str, routine);                                                 \
-		return;                                                                        \
-	}                                                                                      \
-})
-
-/* --------------------------------------------------------------------- */
+	"baycom_epp: bad magic number for hdlcdrv_state struct in routine %s\n";
 
 static const char bc_drvname[] = "baycom_epp";
 static const char bc_drvinfo[] = KERN_INFO "baycom_epp: (C) 1998-2000 Thomas Sailer, HB9JNX/AE4WA\n"
@@ -747,7 +729,6 @@
 	unsigned int time1 = 0, time2 = 0, time3 = 0;
 	int cnt, cnt2;
 	
-	baycom_paranoia_check_void(dev, "epp_bh");
 	bc = netdev_priv(dev);
 	if (!bc->work_running)
 		return;
@@ -863,10 +844,8 @@
 
 static int baycom_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
-	struct baycom_state *bc;
+	struct baycom_state *bc = netdev_priv(dev);
 
-	baycom_paranoia_check(dev, "baycom_send_packet", 0);
-	bc = netdev_priv(dev);
 	if (skb->data[0] != 0) {
 		do_kiss_params(bc, skb->data, skb->len);
 		dev_kfree_skb(skb);
@@ -899,10 +878,8 @@
 
 static struct net_device_stats *baycom_get_stats(struct net_device *dev)
 {
-	struct baycom_state *bc;
+	struct baycom_state *bc = netdev_priv(dev);
 
-	baycom_paranoia_check(dev, "baycom_get_stats", NULL);
-	bc = netdev_priv(dev);
 	/* 
 	 * Get the current statistics.  This may be called with the
 	 * card open or closed. 
@@ -915,10 +892,8 @@
 static void epp_wakeup(void *handle)
 {
         struct net_device *dev = (struct net_device *)handle;
-        struct baycom_state *bc;
+        struct baycom_state *bc = netdev_priv(dev);
 
-	baycom_paranoia_check_void(dev, "epp_wakeup");
-        bc = netdev_priv(dev);
         printk(KERN_DEBUG "baycom_epp: %s: why am I being woken up?\n", dev->name);
         if (!parport_claim(bc->pdev))
                 printk(KERN_DEBUG "baycom_epp: %s: I'm broken.\n", dev->name);
@@ -937,16 +912,13 @@
 
 static int epp_open(struct net_device *dev)
 {
-	struct baycom_state *bc;
-        struct parport *pp;
+	struct baycom_state *bc = netdev_priv(dev);
+        struct parport *pp = parport_find_base(dev->base_addr);
 	unsigned int i, j;
 	unsigned char tmp[128];
 	unsigned char stat;
 	unsigned long tstart;
 	
-	baycom_paranoia_check(dev, "epp_open", -ENXIO);
-	bc = netdev_priv(dev);
-        pp = parport_find_base(dev->base_addr);
         if (!pp) {
                 printk(KERN_ERR "%s: parport at 0x%lx unknown\n", bc_drvname, dev->base_addr);
                 return -ENXIO;
@@ -1055,13 +1027,10 @@
 
 static int epp_close(struct net_device *dev)
 {
-	struct baycom_state *bc;
-	struct parport *pp;
+	struct baycom_state *bc = netdev_priv(dev);
+	struct parport *pp = bc->pdev->port;
 	unsigned char tmp[1];
 
-	baycom_paranoia_check(dev, "epp_close", -EINVAL);
-	bc = netdev_priv(dev);
-	pp = bc->pdev->port;
 	bc->work_running = 0;
 	flush_scheduled_work();
 	bc->stat = EPP_DCDBIT;
@@ -1117,11 +1086,9 @@
 
 static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
-	struct baycom_state *bc;
+	struct baycom_state *bc = netdev_priv(dev);
 	struct hdlcdrv_ioctl hi;
 
-	baycom_paranoia_check(dev, "baycom_ioctl", -EINVAL);
-	bc = netdev_priv(dev);
 	if (cmd != SIOCDEVPRIVATE)
 		return -ENOIOCTLCMD;
 
@@ -1354,7 +1321,7 @@
 			free_netdev(dev);
 			break;
 		}
-		if (set_hw && baycom_setmode(dev->priv, mode[i]))
+		if (set_hw && baycom_setmode(netdev_priv(dev), mode[i]))
 			set_hw = 0;
 		baycom_device[i] = dev;
 		found++;
diff -Nru a/drivers/net/hamradio/baycom_par.c b/drivers/net/hamradio/baycom_par.c
--- a/drivers/net/hamradio/baycom_par.c	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/hamradio/baycom_par.c	2005-03-08 14:29:45 -05:00
@@ -85,6 +85,7 @@
 #include <linux/parport.h>
 #include <linux/bitops.h>
 
+#include <asm/bug.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
@@ -415,12 +416,11 @@
 	struct baycom_state *bc;
 	struct baycom_ioctl bi;
 
-	if (!dev || !dev->priv ||
-	    ((struct baycom_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
-		printk(KERN_ERR "bc_ioctl: invalid device struct\n");
+	if (!dev)
 		return -EINVAL;
-	}
+
 	bc = netdev_priv(dev);
+	BUG_ON(bc->hdrv.magic != HDLCDRV_MAGIC);
 
 	if (cmd != SIOCDEVPRIVATE)
 		return -ENOIOCTLCMD;
diff -Nru a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c
--- a/drivers/net/hamradio/baycom_ser_fdx.c	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/hamradio/baycom_ser_fdx.c	2005-03-08 14:29:45 -05:00
@@ -530,12 +530,11 @@
 	struct baycom_state *bc;
 	struct baycom_ioctl bi;
 
-	if (!dev || !dev->priv ||
-	    ((struct baycom_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
-		printk(KERN_ERR "bc_ioctl: invalid device struct\n");
+	if (!dev)
 		return -EINVAL;
-	}
+
 	bc = netdev_priv(dev);
+	BUG_ON(bc->hdrv.magic != HDLCDRV_MAGIC);
 
 	if (cmd != SIOCDEVPRIVATE)
 		return -ENOIOCTLCMD;
diff -Nru a/drivers/net/hamradio/baycom_ser_hdx.c b/drivers/net/hamradio/baycom_ser_hdx.c
--- a/drivers/net/hamradio/baycom_ser_hdx.c	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/hamradio/baycom_ser_hdx.c	2005-03-08 14:29:45 -05:00
@@ -570,12 +570,11 @@
 	struct baycom_state *bc;
 	struct baycom_ioctl bi;
 
-	if (!dev || !dev->priv ||
-	    ((struct baycom_state *)dev->priv)->hdrv.magic != HDLCDRV_MAGIC) {
-		printk(KERN_ERR "bc_ioctl: invalid device struct\n");
+	if (!dev)
 		return -EINVAL;
-	}
+
 	bc = netdev_priv(dev);
+	BUG_ON(bc->hdrv.magic != HDLCDRV_MAGIC);
 
 	if (cmd != SIOCDEVPRIVATE)
 		return -ENOIOCTLCMD;
diff -Nru a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
--- a/drivers/net/hamradio/bpqether.c	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/hamradio/bpqether.c	2005-03-08 14:29:45 -05:00
@@ -112,8 +112,6 @@
 };
 
 
-#define MAXBPQDEV 100
-
 struct bpqdev {
 	struct list_head bpq_list;	/* list of bpq devices chain */
 	struct net_device *ethdev;	/* link to ethernet device */
@@ -134,7 +132,7 @@
  */
 static inline struct net_device *bpq_get_ether_dev(struct net_device *dev)
 {
-	struct bpqdev *bpq = (struct bpqdev *) dev->priv;
+	struct bpqdev *bpq = netdev_priv(dev);
 
 	return bpq ? bpq->ethdev : NULL;
 }
@@ -191,7 +189,7 @@
 	 * we check the source address of the sender.
 	 */
 
-	bpq = (struct bpqdev *)dev->priv;
+	bpq = netdev_priv(dev);
 
 	eth = eth_hdr(skb);
 
@@ -281,7 +279,7 @@
 	*ptr++ = (size + 5) % 256;
 	*ptr++ = (size + 5) / 256;
 
-	bpq = (struct bpqdev *)dev->priv;
+	bpq = netdev_priv(dev);
 
 	if ((dev = bpq_get_ether_dev(dev)) == NULL) {
 		bpq->stats.tx_dropped++;
@@ -305,7 +303,7 @@
  */
 static struct net_device_stats *bpq_get_stats(struct net_device *dev)
 {
-	struct bpqdev *bpq = (struct bpqdev *) dev->priv;
+	struct bpqdev *bpq = netdev_priv(dev);
 
 	return &bpq->stats;
 }
@@ -332,15 +330,12 @@
 static int bpq_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
 	struct bpq_ethaddr __user *ethaddr = ifr->ifr_data;
-	struct bpqdev *bpq = dev->priv;
+	struct bpqdev *bpq = netdev_priv(dev);
 	struct bpq_req req;
 
 	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
 
-	if (bpq == NULL)		/* woops! */
-		return -ENODEV;
-
 	switch (cmd) {
 		case SIOCSBPQETHOPT:
 			if (copy_from_user(&req, ifr->ifr_data, sizeof(struct bpq_req)))
@@ -525,7 +520,7 @@
 		return -ENOMEM;
 
 		
-	bpq = ndev->priv;
+	bpq = netdev_priv(ndev);
 	dev_hold(edev);
 	bpq->ethdev = edev;
 	bpq->axdev = ndev;
@@ -554,7 +549,7 @@
 
 static void bpq_free_device(struct net_device *ndev)
 {
-	struct bpqdev *bpq = ndev->priv;
+	struct bpqdev *bpq = netdev_priv(ndev);
 
 	dev_put(bpq->ethdev);
 	list_del_rcu(&bpq->bpq_list);
diff -Nru a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
--- a/drivers/net/hamradio/dmascc.c	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/hamradio/dmascc.c	2005-03-08 14:29:45 -05:00
@@ -1,6 +1,4 @@
 /*
- * $Id: dmascc.c,v 1.27 2000/06/01 14:46:23 oe1kib Exp $
- *
  * Driver for high-speed SCC boards (those with DMA support)
  * Copyright (C) 1997-2000 Klaus Kudielka
  *
@@ -19,7 +17,6 @@
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
  */
 
 
@@ -49,9 +46,9 @@
 
 /* Number of buffers per channel */
 
-#define NUM_TX_BUF      2          /* NUM_TX_BUF >= 1 (min. 2 recommended) */
-#define NUM_RX_BUF      6          /* NUM_RX_BUF >= 1 (min. 2 recommended) */
-#define BUF_SIZE        1576       /* BUF_SIZE >= mtu + hard_header_len */
+#define NUM_TX_BUF      2	/* NUM_TX_BUF >= 1 (min. 2 recommended) */
+#define NUM_RX_BUF      6	/* NUM_RX_BUF >= 1 (min. 2 recommended) */
+#define BUF_SIZE        1576	/* BUF_SIZE >= mtu + hard_header_len */
 
 
 /* Cards supported */
@@ -67,7 +64,7 @@
 
 #define HARDWARE        { HW_PI, HW_PI2, HW_TWIN, HW_S5 }
 
-#define TMR_0_HZ        25600      /* Frequency of timer 0 */
+#define TMR_0_HZ        25600	/* Frequency of timer 0 */
 
 #define TYPE_PI         0
 #define TYPE_PI2        1
@@ -164,69 +161,69 @@
 /* Data types */
 
 struct scc_param {
-  int pclk_hz;    /* frequency of BRG input (don't change) */
-  int brg_tc;     /* BRG terminal count; BRG disabled if < 0 */
-  int nrzi;       /* 0 (nrz), 1 (nrzi) */
-  int clocks;     /* see dmascc_cfg documentation */
-  int txdelay;    /* [1/TMR_0_HZ] */
-  int txtimeout;  /* [1/HZ] */
-  int txtail;     /* [1/TMR_0_HZ] */
-  int waittime;   /* [1/TMR_0_HZ] */
-  int slottime;   /* [1/TMR_0_HZ] */
-  int persist;    /* 1 ... 256 */
-  int dma;        /* -1 (disable), 0, 1, 3 */
-  int txpause;    /* [1/TMR_0_HZ] */
-  int rtsoff;     /* [1/TMR_0_HZ] */
-  int dcdon;      /* [1/TMR_0_HZ] */
-  int dcdoff;     /* [1/TMR_0_HZ] */
+	int pclk_hz;		/* frequency of BRG input (don't change) */
+	int brg_tc;		/* BRG terminal count; BRG disabled if < 0 */
+	int nrzi;		/* 0 (nrz), 1 (nrzi) */
+	int clocks;		/* see dmascc_cfg documentation */
+	int txdelay;		/* [1/TMR_0_HZ] */
+	int txtimeout;		/* [1/HZ] */
+	int txtail;		/* [1/TMR_0_HZ] */
+	int waittime;		/* [1/TMR_0_HZ] */
+	int slottime;		/* [1/TMR_0_HZ] */
+	int persist;		/* 1 ... 256 */
+	int dma;		/* -1 (disable), 0, 1, 3 */
+	int txpause;		/* [1/TMR_0_HZ] */
+	int rtsoff;		/* [1/TMR_0_HZ] */
+	int dcdon;		/* [1/TMR_0_HZ] */
+	int dcdoff;		/* [1/TMR_0_HZ] */
 };
 
 struct scc_hardware {
-  char *name;
-  int io_region;
-  int io_delta;
-  int io_size;
-  int num_devs;
-  int scc_offset;
-  int tmr_offset;
-  int tmr_hz;
-  int pclk_hz;
+	char *name;
+	int io_region;
+	int io_delta;
+	int io_size;
+	int num_devs;
+	int scc_offset;
+	int tmr_offset;
+	int tmr_hz;
+	int pclk_hz;
 };
 
 struct scc_priv {
-  int type;
-  int chip;
-  struct net_device *dev;
-  struct scc_info *info;
-  struct net_device_stats stats;
-  int channel;
-  int card_base, scc_cmd, scc_data;
-  int tmr_cnt, tmr_ctrl, tmr_mode;
-  struct scc_param param;
-  char rx_buf[NUM_RX_BUF][BUF_SIZE];
-  int rx_len[NUM_RX_BUF];
-  int rx_ptr;
-  struct work_struct rx_work;
-  int rx_head, rx_tail, rx_count;
-  int rx_over;
-  char tx_buf[NUM_TX_BUF][BUF_SIZE];
-  int tx_len[NUM_TX_BUF];
-  int tx_ptr;
-  int tx_head, tx_tail, tx_count;
-  int state;
-  unsigned long tx_start;
-  int rr0;
-  spinlock_t *register_lock;	/* Per scc_info */
-  spinlock_t ring_lock;
+	int type;
+	int chip;
+	struct net_device *dev;
+	struct scc_info *info;
+	struct net_device_stats stats;
+	int channel;
+	int card_base, scc_cmd, scc_data;
+	int tmr_cnt, tmr_ctrl, tmr_mode;
+	struct scc_param param;
+	char rx_buf[NUM_RX_BUF][BUF_SIZE];
+	int rx_len[NUM_RX_BUF];
+	int rx_ptr;
+	struct work_struct rx_work;
+	int rx_head, rx_tail, rx_count;
+	int rx_over;
+	char tx_buf[NUM_TX_BUF][BUF_SIZE];
+	int tx_len[NUM_TX_BUF];
+	int tx_ptr;
+	int tx_head, tx_tail, tx_count;
+	int state;
+	unsigned long tx_start;
+	int rr0;
+	spinlock_t *register_lock;	/* Per scc_info */
+	spinlock_t ring_lock;
 };
 
 struct scc_info {
-  int irq_used;
-  int twin_serial_cfg;
-  struct net_device *dev[2];
-  struct scc_priv priv[2];
-  struct scc_info *next;
-  spinlock_t register_lock;	/* Per device register lock */
+	int irq_used;
+	int twin_serial_cfg;
+	struct net_device *dev[2];
+	struct scc_priv priv[2];
+	struct scc_info *next;
+	spinlock_t register_lock;	/* Per device register lock */
 };
 
 
@@ -252,7 +249,7 @@
 static inline unsigned char random(void);
 
 static inline void z8530_isr(struct scc_info *info);
-static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs * regs);
+static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs *regs);
 static void rx_isr(struct scc_priv *priv);
 static void special_condition(struct scc_priv *priv, int rc);
 static void rx_bh(void *arg);
@@ -264,12 +261,15 @@
 /* Initialization variables */
 
 static int io[MAX_NUM_DEVS] __initdata = { 0, };
+
 /* Beware! hw[] is also used in cleanup_module(). */
 static struct scc_hardware hw[NUM_TYPES] __initdata_or_module = HARDWARE;
 static char ax25_broadcast[7] __initdata =
-  { 'Q'<<1, 'S'<<1, 'T'<<1, ' '<<1, ' '<<1, ' '<<1, '0'<<1 };
+    { 'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1,
+'0' << 1 };
 static char ax25_test[7] __initdata =
-  { 'L'<<1, 'I'<<1, 'N'<<1, 'U'<<1, 'X'<<1, ' '<<1, '1'<<1 };
+    { 'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1,
+'1' << 1 };
 
 
 /* Global variables */
@@ -283,143 +283,164 @@
 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NUM_DEVS) "i");
 MODULE_LICENSE("GPL");
 
-static void __exit dmascc_exit(void) {
-  int i;
-  struct scc_info *info;
-
-  while (first) {
-    info = first;
-
-    /* Unregister devices */
-    for (i = 0; i < 2; i++)
-	unregister_netdev(info->dev[i]);
-
-    /* Reset board */
-    if (info->priv[0].type == TYPE_TWIN)
-      outb(0, info->dev[0]->base_addr + TWIN_SERIAL_CFG);
-    write_scc(&info->priv[0], R9, FHWRES);
-    release_region(info->dev[0]->base_addr,
-		   hw[info->priv[0].type].io_size);
-
-    for (i = 0; i < 2; i++)
-	free_netdev(info->dev[i]);
-
-    /* Free memory */
-    first = info->next;
-    kfree(info);
-  }
+static void __exit dmascc_exit(void)
+{
+	int i;
+	struct scc_info *info;
+
+	while (first) {
+		info = first;
+
+		/* Unregister devices */
+		for (i = 0; i < 2; i++)
+			unregister_netdev(info->dev[i]);
+
+		/* Reset board */
+		if (info->priv[0].type == TYPE_TWIN)
+			outb(0, info->dev[0]->base_addr + TWIN_SERIAL_CFG);
+		write_scc(&info->priv[0], R9, FHWRES);
+		release_region(info->dev[0]->base_addr,
+			       hw[info->priv[0].type].io_size);
+
+		for (i = 0; i < 2; i++)
+			free_netdev(info->dev[i]);
+
+		/* Free memory */
+		first = info->next;
+		kfree(info);
+	}
 }
 
 #ifndef MODULE
-void __init dmascc_setup(char *str, int *ints) {
-   int i;
+void __init dmascc_setup(char *str, int *ints)
+{
+	int i;
 
-   for (i = 0; i < MAX_NUM_DEVS && i < ints[0]; i++)
-      io[i] = ints[i+1];
+	for (i = 0; i < MAX_NUM_DEVS && i < ints[0]; i++)
+		io[i] = ints[i + 1];
 }
 #endif
 
-static int __init dmascc_init(void) {
-  int h, i, j, n;
-  int base[MAX_NUM_DEVS], tcmd[MAX_NUM_DEVS], t0[MAX_NUM_DEVS],
-    t1[MAX_NUM_DEVS];
-  unsigned t_val;
-  unsigned long time, start[MAX_NUM_DEVS], delay[MAX_NUM_DEVS],
-    counting[MAX_NUM_DEVS];
-
-  /* Initialize random number generator */
-  rand = jiffies;
-  /* Cards found = 0 */
-  n = 0;
-  /* Warning message */
-  if (!io[0]) printk(KERN_INFO "dmascc: autoprobing (dangerous)\n");
-
-  /* Run autodetection for each card type */
-  for (h = 0; h < NUM_TYPES; h++) {
-
-    if (io[0]) {
-      /* User-specified I/O address regions */
-      for (i = 0; i < hw[h].num_devs; i++) base[i] = 0;
-      for (i = 0; i < MAX_NUM_DEVS && io[i]; i++) {
-	j = (io[i] - hw[h].io_region) / hw[h].io_delta;
-	if (j >= 0 &&
-	    j < hw[h].num_devs && 
-	    hw[h].io_region + j * hw[h].io_delta == io[i]) {
-	  base[j] = io[i];
-	}
-      }
-    } else {
-      /* Default I/O address regions */
-      for (i = 0; i < hw[h].num_devs; i++) {
-	base[i] = hw[h].io_region + i * hw[h].io_delta;
-      }
-    }
-
-    /* Check valid I/O address regions */
-    for (i = 0; i < hw[h].num_devs; i++)
-      if (base[i]) {
-	if (!request_region(base[i], hw[h].io_size, "dmascc"))
-	  base[i] = 0;
-	else {
-	  tcmd[i] = base[i] + hw[h].tmr_offset + TMR_CTRL;
-	  t0[i]   = base[i] + hw[h].tmr_offset + TMR_CNT0;
-	  t1[i]   = base[i] + hw[h].tmr_offset + TMR_CNT1;
-	}
-      }
-
-    /* Start timers */
-    for (i = 0; i < hw[h].num_devs; i++)
-      if (base[i]) {
-	/* Timer 0: LSB+MSB, Mode 3, TMR_0_HZ */
-	outb(0x36, tcmd[i]);
-	outb((hw[h].tmr_hz/TMR_0_HZ) & 0xFF, t0[i]);
-	outb((hw[h].tmr_hz/TMR_0_HZ) >> 8, t0[i]);
-	/* Timer 1: LSB+MSB, Mode 0, HZ/10 */
-	outb(0x70, tcmd[i]);
-	outb((TMR_0_HZ/HZ*10) & 0xFF, t1[i]);
-	outb((TMR_0_HZ/HZ*10) >> 8, t1[i]);
-	start[i] = jiffies;
-	delay[i] = 0;
-	counting[i] = 1;
-	/* Timer 2: LSB+MSB, Mode 0 */
-	outb(0xb0, tcmd[i]);
-      }
-    time = jiffies;
-    /* Wait until counter registers are loaded */
-    udelay(2000000/TMR_0_HZ);
-
-    /* Timing loop */
-    while (jiffies - time < 13) {
-      for (i = 0; i < hw[h].num_devs; i++)
-	if (base[i] && counting[i]) {
-	  /* Read back Timer 1: latch; read LSB; read MSB */
-	  outb(0x40, tcmd[i]);
-	  t_val = inb(t1[i]) + (inb(t1[i]) << 8);
-	  /* Also check whether counter did wrap */
-	  if (t_val == 0 || t_val > TMR_0_HZ/HZ*10) counting[i] = 0;
-	  delay[i] = jiffies - start[i];
-	}
-    }
-
-    /* Evaluate measurements */
-    for (i = 0; i < hw[h].num_devs; i++)
-      if (base[i]) {
-	if ((delay[i] >= 9 && delay[i] <= 11)&& 
-	    /* Ok, we have found an adapter */
-	    (setup_adapter(base[i], h, n) == 0))
-	  n++;
-	else
-	  release_region(base[i], hw[h].io_size);
-      }
-
-  } /* NUM_TYPES */
+static int __init dmascc_init(void)
+{
+	int h, i, j, n;
+	int base[MAX_NUM_DEVS], tcmd[MAX_NUM_DEVS], t0[MAX_NUM_DEVS],
+	    t1[MAX_NUM_DEVS];
+	unsigned t_val;
+	unsigned long time, start[MAX_NUM_DEVS], delay[MAX_NUM_DEVS],
+	    counting[MAX_NUM_DEVS];
+
+	/* Initialize random number generator */
+	rand = jiffies;
+	/* Cards found = 0 */
+	n = 0;
+	/* Warning message */
+	if (!io[0])
+		printk(KERN_INFO "dmascc: autoprobing (dangerous)\n");
+
+	/* Run autodetection for each card type */
+	for (h = 0; h < NUM_TYPES; h++) {
+
+		if (io[0]) {
+			/* User-specified I/O address regions */
+			for (i = 0; i < hw[h].num_devs; i++)
+				base[i] = 0;
+			for (i = 0; i < MAX_NUM_DEVS && io[i]; i++) {
+				j = (io[i] -
+				     hw[h].io_region) / hw[h].io_delta;
+				if (j >= 0 && j < hw[h].num_devs
+				    && hw[h].io_region +
+				    j * hw[h].io_delta == io[i]) {
+					base[j] = io[i];
+				}
+			}
+		} else {
+			/* Default I/O address regions */
+			for (i = 0; i < hw[h].num_devs; i++) {
+				base[i] =
+				    hw[h].io_region + i * hw[h].io_delta;
+			}
+		}
 
-  /* If any adapter was successfully initialized, return ok */
-  if (n) return 0;
+		/* Check valid I/O address regions */
+		for (i = 0; i < hw[h].num_devs; i++)
+			if (base[i]) {
+				if (!request_region
+				    (base[i], hw[h].io_size, "dmascc"))
+					base[i] = 0;
+				else {
+					tcmd[i] =
+					    base[i] + hw[h].tmr_offset +
+					    TMR_CTRL;
+					t0[i] =
+					    base[i] + hw[h].tmr_offset +
+					    TMR_CNT0;
+					t1[i] =
+					    base[i] + hw[h].tmr_offset +
+					    TMR_CNT1;
+				}
+			}
+
+		/* Start timers */
+		for (i = 0; i < hw[h].num_devs; i++)
+			if (base[i]) {
+				/* Timer 0: LSB+MSB, Mode 3, TMR_0_HZ */
+				outb(0x36, tcmd[i]);
+				outb((hw[h].tmr_hz / TMR_0_HZ) & 0xFF,
+				     t0[i]);
+				outb((hw[h].tmr_hz / TMR_0_HZ) >> 8,
+				     t0[i]);
+				/* Timer 1: LSB+MSB, Mode 0, HZ/10 */
+				outb(0x70, tcmd[i]);
+				outb((TMR_0_HZ / HZ * 10) & 0xFF, t1[i]);
+				outb((TMR_0_HZ / HZ * 10) >> 8, t1[i]);
+				start[i] = jiffies;
+				delay[i] = 0;
+				counting[i] = 1;
+				/* Timer 2: LSB+MSB, Mode 0 */
+				outb(0xb0, tcmd[i]);
+			}
+		time = jiffies;
+		/* Wait until counter registers are loaded */
+		udelay(2000000 / TMR_0_HZ);
+
+		/* Timing loop */
+		while (jiffies - time < 13) {
+			for (i = 0; i < hw[h].num_devs; i++)
+				if (base[i] && counting[i]) {
+					/* Read back Timer 1: latch; read LSB; read MSB */
+					outb(0x40, tcmd[i]);
+					t_val =
+					    inb(t1[i]) + (inb(t1[i]) << 8);
+					/* Also check whether counter did wrap */
+					if (t_val == 0
+					    || t_val > TMR_0_HZ / HZ * 10)
+						counting[i] = 0;
+					delay[i] = jiffies - start[i];
+				}
+		}
 
-  /* If no adapter found, return error */
-  printk(KERN_INFO "dmascc: no adapters found\n");
-  return -EIO;
+		/* Evaluate measurements */
+		for (i = 0; i < hw[h].num_devs; i++)
+			if (base[i]) {
+				if ((delay[i] >= 9 && delay[i] <= 11) &&
+				    /* Ok, we have found an adapter */
+				    (setup_adapter(base[i], h, n) == 0))
+					n++;
+				else
+					release_region(base[i],
+						       hw[h].io_size);
+			}
+
+	}			/* NUM_TYPES */
+
+	/* If any adapter was successfully initialized, return ok */
+	if (n)
+		return 0;
+
+	/* If no adapter found, return error */
+	printk(KERN_INFO "dmascc: no adapters found\n");
+	return -EIO;
 }
 
 module_init(dmascc_init);
@@ -452,8 +473,8 @@
 	info = kmalloc(sizeof(struct scc_info), GFP_KERNEL | GFP_DMA);
 	if (!info) {
 		printk(KERN_ERR "dmascc: "
-			"could not allocate memory for %s at %#3x\n",
-			hw[type].name, card_base);
+		       "could not allocate memory for %s at %#3x\n",
+		       hw[type].name, card_base);
 		goto out;
 	}
 
@@ -463,16 +484,16 @@
 	info->dev[0] = alloc_netdev(0, "", dev_setup);
 	if (!info->dev[0]) {
 		printk(KERN_ERR "dmascc: "
-			"could not allocate memory for %s at %#3x\n",
-			hw[type].name, card_base);
+		       "could not allocate memory for %s at %#3x\n",
+		       hw[type].name, card_base);
 		goto out1;
 	}
 
 	info->dev[1] = alloc_netdev(0, "", dev_setup);
 	if (!info->dev[1]) {
 		printk(KERN_ERR "dmascc: "
-			"could not allocate memory for %s at %#3x\n",
-			hw[type].name, card_base);
+		       "could not allocate memory for %s at %#3x\n",
+		       hw[type].name, card_base);
 		goto out2;
 	}
 	spin_lock_init(&info->register_lock);
@@ -526,7 +547,8 @@
 	outb(0, tmr_base + TMR_CNT1);
 
 	/* Wait and detect IRQ */
-	time = jiffies; while (jiffies - time < 2 + HZ / TMR_0_HZ);
+	time = jiffies;
+	while (jiffies - time < 2 + HZ / TMR_0_HZ);
 	irq = probe_irq_off(irqs);
 
 	/* Clear pending interrupt, disable interrupts */
@@ -539,8 +561,9 @@
 	}
 
 	if (irq <= 0) {
-		printk(KERN_ERR "dmascc: could not find irq of %s at %#3x (irq=%d)\n",
-			hw[type].name, card_base, irq);
+		printk(KERN_ERR
+		       "dmascc: could not find irq of %s at %#3x (irq=%d)\n",
+		       hw[type].name, card_base, irq);
 		goto out3;
 	}
 
@@ -568,7 +591,7 @@
 		priv->param.dma = -1;
 		INIT_WORK(&priv->rx_work, rx_bh, priv);
 		dev->priv = priv;
-		sprintf(dev->name, "dmascc%i", 2*n+i);
+		sprintf(dev->name, "dmascc%i", 2 * n + i);
 		SET_MODULE_OWNER(dev);
 		dev->base_addr = card_base;
 		dev->irq = irq;
@@ -583,820 +606,888 @@
 	}
 	if (register_netdev(info->dev[0])) {
 		printk(KERN_ERR "dmascc: could not register %s\n",
-				info->dev[0]->name);
+		       info->dev[0]->name);
 		goto out3;
 	}
 	if (register_netdev(info->dev[1])) {
 		printk(KERN_ERR "dmascc: could not register %s\n",
-				info->dev[1]->name);
+		       info->dev[1]->name);
 		goto out4;
 	}
 
 
 	info->next = first;
 	first = info;
-	printk(KERN_INFO "dmascc: found %s (%s) at %#3x, irq %d\n", hw[type].name,
-	chipnames[chip], card_base, irq);
+	printk(KERN_INFO "dmascc: found %s (%s) at %#3x, irq %d\n",
+	       hw[type].name, chipnames[chip], card_base, irq);
 	return 0;
 
-out4:
+      out4:
 	unregister_netdev(info->dev[0]);
-out3:
+      out3:
 	if (info->priv[0].type == TYPE_TWIN)
 		outb(0, info->dev[0]->base_addr + TWIN_SERIAL_CFG);
 	write_scc(&info->priv[0], R9, FHWRES);
 	free_netdev(info->dev[1]);
-out2:
+      out2:
 	free_netdev(info->dev[0]);
-out1:
+      out1:
 	kfree(info);
-out:
+      out:
 	return -1;
 }
 
 
 /* Driver functions */
 
-static void write_scc(struct scc_priv *priv, int reg, int val) {
-  unsigned long flags;
-  switch (priv->type) {
-  case TYPE_S5:
-    if (reg) outb(reg, priv->scc_cmd);
-    outb(val, priv->scc_cmd);
-    return;
-  case TYPE_TWIN:
-    if (reg) outb_p(reg, priv->scc_cmd);
-    outb_p(val, priv->scc_cmd);
-    return;
-  default:
-    spin_lock_irqsave(priv->register_lock, flags);
-    outb_p(0, priv->card_base + PI_DREQ_MASK);
-    if (reg) outb_p(reg, priv->scc_cmd);
-    outb_p(val, priv->scc_cmd);
-    outb(1, priv->card_base + PI_DREQ_MASK);
-    spin_unlock_irqrestore(priv->register_lock, flags);
-    return;
-  }
-}
-
-
-static void write_scc_data(struct scc_priv *priv, int val, int fast) {
-  unsigned long flags;
-  switch (priv->type) {
-  case TYPE_S5:
-    outb(val, priv->scc_data);
-    return;
-  case TYPE_TWIN:
-    outb_p(val, priv->scc_data);
-    return;
-  default:
-    if (fast) outb_p(val, priv->scc_data);
-    else {
-      spin_lock_irqsave(priv->register_lock, flags);
-      outb_p(0, priv->card_base + PI_DREQ_MASK);
-      outb_p(val, priv->scc_data);
-      outb(1, priv->card_base + PI_DREQ_MASK);
-      spin_unlock_irqrestore(priv->register_lock, flags);
-    }
-    return;
-  }
-}
-
-
-static int read_scc(struct scc_priv *priv, int reg) {
-  int rc;
-  unsigned long flags;
-  switch (priv->type) {
-  case TYPE_S5:
-    if (reg) outb(reg, priv->scc_cmd);
-    return inb(priv->scc_cmd);
-  case TYPE_TWIN:
-    if (reg) outb_p(reg, priv->scc_cmd);
-    return inb_p(priv->scc_cmd);
-  default:
-    spin_lock_irqsave(priv->register_lock, flags);
-    outb_p(0, priv->card_base + PI_DREQ_MASK);
-    if (reg) outb_p(reg, priv->scc_cmd);
-    rc = inb_p(priv->scc_cmd);
-    outb(1, priv->card_base + PI_DREQ_MASK);
-    spin_unlock_irqrestore(priv->register_lock, flags);
-    return rc;
-  }
-}
-
-
-static int read_scc_data(struct scc_priv *priv) {
-  int rc;
-  unsigned long flags;
-  switch (priv->type) {
-  case TYPE_S5:
-    return inb(priv->scc_data);
-  case TYPE_TWIN:
-    return inb_p(priv->scc_data);
-  default:
-    spin_lock_irqsave(priv->register_lock, flags);
-    outb_p(0, priv->card_base + PI_DREQ_MASK);
-    rc = inb_p(priv->scc_data);
-    outb(1, priv->card_base + PI_DREQ_MASK);
-    spin_unlock_irqrestore(priv->register_lock, flags);
-    return rc;
-  }
-}
-
-
-static int scc_open(struct net_device *dev) {
-  struct scc_priv *priv = dev->priv;
-  struct scc_info *info = priv->info;
-  int card_base = priv->card_base;
-
-  /* Request IRQ if not already used by other channel */
-  if (!info->irq_used) {
-    if (request_irq(dev->irq, scc_isr, 0, "dmascc", info)) {
-      return -EAGAIN;
-    }
-  }
-  info->irq_used++;
-
-  /* Request DMA if required */
-  if (priv->param.dma >= 0) {
-    if (request_dma(priv->param.dma, "dmascc")) {
-      if (--info->irq_used == 0) free_irq(dev->irq, info);
-      return -EAGAIN;
-    } else {
-      unsigned long flags = claim_dma_lock();
-      clear_dma_ff(priv->param.dma);
-      release_dma_lock(flags);
-    }
-  }
-
-  /* Initialize local variables */
-  priv->rx_ptr = 0;
-  priv->rx_over = 0;
-  priv->rx_head = priv->rx_tail = priv->rx_count = 0;
-  priv->state = IDLE;
-  priv->tx_head = priv->tx_tail = priv->tx_count = 0;
-  priv->tx_ptr = 0;
-
-  /* Reset channel */
-  write_scc(priv, R9, (priv->channel ? CHRB : CHRA) | MIE | NV);
-  /* X1 clock, SDLC mode */
-  write_scc(priv, R4, SDLC | X1CLK);
-  /* DMA */
-  write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN);
-  /* 8 bit RX char, RX disable */
-  write_scc(priv, R3, Rx8);
-  /* 8 bit TX char, TX disable */
-  write_scc(priv, R5, Tx8);
-  /* SDLC address field */
-  write_scc(priv, R6, 0);
-  /* SDLC flag */
-  write_scc(priv, R7, FLAG);
-  switch (priv->chip) {
-  case Z85C30:
-    /* Select WR7' */
-    write_scc(priv, R15, SHDLCE);
-    /* Auto EOM reset */
-    write_scc(priv, R7, AUTOEOM);
-    write_scc(priv, R15, 0);
-    break;
-  case Z85230:
-    /* Select WR7' */
-    write_scc(priv, R15, SHDLCE);
-    /* The following bits are set (see 2.5.2.1):
-       - Automatic EOM reset
-       - Interrupt request if RX FIFO is half full
-         This bit should be ignored in DMA mode (according to the
-         documentation), but actually isn't. The receiver doesn't work if
-         it is set. Thus, we have to clear it in DMA mode.
-       - Interrupt/DMA request if TX FIFO is completely empty
-         a) If set, the ESCC behaves as if it had no TX FIFO (Z85C30
-            compatibility).
-         b) If cleared, DMA requests may follow each other very quickly,
-            filling up the TX FIFO.
-            Advantage: TX works even in case of high bus latency.
-            Disadvantage: Edge-triggered DMA request circuitry may miss
-                          a request. No more data is delivered, resulting
-                          in a TX FIFO underrun.
-         Both PI2 and S5SCC/DMA seem to work fine with TXFIFOE cleared.
-         The PackeTwin doesn't. I don't know about the PI, but let's
-	 assume it behaves like the PI2.
-    */
-    if (priv->param.dma >= 0) {
-      if (priv->type == TYPE_TWIN) write_scc(priv, R7, AUTOEOM | TXFIFOE);
-      else write_scc(priv, R7, AUTOEOM);
-    } else {
-      write_scc(priv, R7, AUTOEOM | RXFIFOH);
-    }
-    write_scc(priv, R15, 0);
-    break;
-  }
-  /* Preset CRC, NRZ(I) encoding */
-  write_scc(priv, R10, CRCPS | (priv->param.nrzi ? NRZI : NRZ));
-
-  /* Configure baud rate generator */
-  if (priv->param.brg_tc >= 0) {
-    /* Program BR generator */
-    write_scc(priv, R12, priv->param.brg_tc & 0xFF);
-    write_scc(priv, R13, (priv->param.brg_tc>>8) & 0xFF);
-    /* BRG source = SYS CLK; enable BRG; DTR REQ function (required by
-       PackeTwin, not connected on the PI2); set DPLL source to BRG */
-    write_scc(priv, R14, SSBR | DTRREQ | BRSRC | BRENABL);
-    /* Enable DPLL */
-    write_scc(priv, R14, SEARCH | DTRREQ | BRSRC | BRENABL);
-  } else {
-    /* Disable BR generator */
-    write_scc(priv, R14, DTRREQ | BRSRC);
-  }
-
-  /* Configure clocks */
-  if (priv->type == TYPE_TWIN) {
-    /* Disable external TX clock receiver */
-    outb((info->twin_serial_cfg &=
-	    ~(priv->channel ? TWIN_EXTCLKB : TWIN_EXTCLKA)), 
-	   card_base + TWIN_SERIAL_CFG);
-  }
-  write_scc(priv, R11, priv->param.clocks);
-  if ((priv->type == TYPE_TWIN) && !(priv->param.clocks & TRxCOI)) {
-    /* Enable external TX clock receiver */
-    outb((info->twin_serial_cfg |=
-	    (priv->channel ? TWIN_EXTCLKB : TWIN_EXTCLKA)),
-	   card_base + TWIN_SERIAL_CFG);
-  }
-
-  /* Configure PackeTwin */
-  if (priv->type == TYPE_TWIN) {
-    /* Assert DTR, enable interrupts */
-    outb((info->twin_serial_cfg |= TWIN_EI |
-	    (priv->channel ? TWIN_DTRB_ON : TWIN_DTRA_ON)),
-	   card_base + TWIN_SERIAL_CFG);
-  }
-
-  /* Read current status */
-  priv->rr0 = read_scc(priv, R0);
-  /* Enable DCD interrupt */
-  write_scc(priv, R15, DCDIE);
-
-  netif_start_queue(dev);
-
-  return 0;
-}
-
-
-static int scc_close(struct net_device *dev) {
-  struct scc_priv *priv = dev->priv;
-  struct scc_info *info = priv->info;
-  int card_base = priv->card_base;
-
-  netif_stop_queue(dev);
-
-  if (priv->type == TYPE_TWIN) {
-    /* Drop DTR */
-    outb((info->twin_serial_cfg &=
-	    (priv->channel ? ~TWIN_DTRB_ON : ~TWIN_DTRA_ON)),
-	   card_base + TWIN_SERIAL_CFG);
-  }
-
-  /* Reset channel, free DMA and IRQ */
-  write_scc(priv, R9, (priv->channel ? CHRB : CHRA) | MIE | NV);
-  if (priv->param.dma >= 0) {
-    if (priv->type == TYPE_TWIN) outb(0, card_base + TWIN_DMA_CFG);
-    free_dma(priv->param.dma);
-  }
-  if (--info->irq_used == 0) free_irq(dev->irq, info);
-
-  return 0;
-}
-
-
-static int scc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) {
-  struct scc_priv *priv = dev->priv;
-  
-  switch (cmd) {
-  case SIOCGSCCPARAM:
-    if (copy_to_user(ifr->ifr_data, &priv->param, sizeof(struct scc_param)))
-      return -EFAULT;
-    return 0;
-  case SIOCSSCCPARAM:
-    if (!capable(CAP_NET_ADMIN)) return -EPERM;
-    if (netif_running(dev)) return -EAGAIN;
-    if (copy_from_user(&priv->param, ifr->ifr_data, sizeof(struct scc_param)))
-      return -EFAULT;
-    return 0;
-  default:
-    return -EINVAL;
-  }
-}
-
-
-static int scc_send_packet(struct sk_buff *skb, struct net_device *dev) {
-  struct scc_priv *priv = dev->priv;
-  unsigned long flags;
-  int i;
-
-  /* Temporarily stop the scheduler feeding us packets */
-  netif_stop_queue(dev);
-
-  /* Transfer data to DMA buffer */
-  i = priv->tx_head;
-  memcpy(priv->tx_buf[i], skb->data+1, skb->len-1);
-  priv->tx_len[i] = skb->len-1;
-
-  /* Clear interrupts while we touch our circular buffers */
-
-  spin_lock_irqsave(&priv->ring_lock, flags);
-  /* Move the ring buffer's head */
-  priv->tx_head = (i + 1) % NUM_TX_BUF;
-  priv->tx_count++;
-
-  /* If we just filled up the last buffer, leave queue stopped.
-     The higher layers must wait until we have a DMA buffer
-     to accept the data. */
-  if (priv->tx_count < NUM_TX_BUF) netif_wake_queue(dev);
-
-  /* Set new TX state */
-  if (priv->state == IDLE) {
-    /* Assert RTS, start timer */
-    priv->state = TX_HEAD;
-    priv->tx_start = jiffies;
-    write_scc(priv, R5, TxCRC_ENAB | RTS | TxENAB | Tx8);
-    write_scc(priv, R15, 0);
-    start_timer(priv, priv->param.txdelay, 0);
-  }
-
-  /* Turn interrupts back on and free buffer */
-  spin_unlock_irqrestore(&priv->ring_lock, flags);
-  dev_kfree_skb(skb);
-
-  return 0;
-}
-
-
-static struct net_device_stats *scc_get_stats(struct net_device *dev) {
-  struct scc_priv *priv = dev->priv;
-
-  return &priv->stats;
-}
-
-
-static int scc_set_mac_address(struct net_device *dev, void *sa) {
-  memcpy(dev->dev_addr, ((struct sockaddr *)sa)->sa_data, dev->addr_len);
-  return 0;
-}
-
-
-static inline void tx_on(struct scc_priv *priv) {
-  int i, n;
-  unsigned long flags;
-
-  if (priv->param.dma >= 0) {
-    n = (priv->chip == Z85230) ? 3 : 1;
-    /* Program DMA controller */
-    flags = claim_dma_lock();
-    set_dma_mode(priv->param.dma, DMA_MODE_WRITE);
-    set_dma_addr(priv->param.dma, (int) priv->tx_buf[priv->tx_tail]+n);
-    set_dma_count(priv->param.dma, priv->tx_len[priv->tx_tail]-n);
-    release_dma_lock(flags);
-    /* Enable TX underrun interrupt */
-    write_scc(priv, R15, TxUIE);
-    /* Configure DREQ */
-    if (priv->type == TYPE_TWIN)
-      outb((priv->param.dma == 1) ? TWIN_DMA_HDX_T1 : TWIN_DMA_HDX_T3,
-	   priv->card_base + TWIN_DMA_CFG);
-    else
-      write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN | WT_RDY_ENAB);
-    /* Write first byte(s) */
-    spin_lock_irqsave(priv->register_lock, flags);
-    for (i = 0; i < n; i++)
-      write_scc_data(priv, priv->tx_buf[priv->tx_tail][i], 1);
-    enable_dma(priv->param.dma);
-    spin_unlock_irqrestore(priv->register_lock, flags);
-  } else {
-    write_scc(priv, R15, TxUIE);
-    write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN | TxINT_ENAB);
-    tx_isr(priv);
-  }
-  /* Reset EOM latch if we do not have the AUTOEOM feature */
-  if (priv->chip == Z8530) write_scc(priv, R0, RES_EOM_L);
-}
-
-
-static inline void rx_on(struct scc_priv *priv) {
-  unsigned long flags;
-
-  /* Clear RX FIFO */
-  while (read_scc(priv, R0) & Rx_CH_AV) read_scc_data(priv);
-  priv->rx_over = 0;
-  if (priv->param.dma >= 0) {
-    /* Program DMA controller */
-    flags = claim_dma_lock();
-    set_dma_mode(priv->param.dma, DMA_MODE_READ);
-    set_dma_addr(priv->param.dma, (int) priv->rx_buf[priv->rx_head]);
-    set_dma_count(priv->param.dma, BUF_SIZE);
-    release_dma_lock(flags);
-    enable_dma(priv->param.dma);
-    /* Configure PackeTwin DMA */
-    if (priv->type == TYPE_TWIN) {
-      outb((priv->param.dma == 1) ? TWIN_DMA_HDX_R1 : TWIN_DMA_HDX_R3,
-	   priv->card_base + TWIN_DMA_CFG);
-    }
-    /* Sp. cond. intr. only, ext int enable, RX DMA enable */
-    write_scc(priv, R1, EXT_INT_ENAB | INT_ERR_Rx |
-	      WT_RDY_RT | WT_FN_RDYFN | WT_RDY_ENAB);
-  } else {
-    /* Reset current frame */
-    priv->rx_ptr = 0;
-    /* Intr. on all Rx characters and Sp. cond., ext int enable */
-    write_scc(priv, R1, EXT_INT_ENAB | INT_ALL_Rx | WT_RDY_RT |
-	      WT_FN_RDYFN);
-  }
-  write_scc(priv, R0, ERR_RES);
-  write_scc(priv, R3, RxENABLE | Rx8 | RxCRC_ENAB);
-}
-
-
-static inline void rx_off(struct scc_priv *priv) {
-  /* Disable receiver */
-  write_scc(priv, R3, Rx8);
-  /* Disable DREQ / RX interrupt */
-  if (priv->param.dma >= 0 && priv->type == TYPE_TWIN)
-    outb(0, priv->card_base + TWIN_DMA_CFG);
-  else
-    write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN);
-  /* Disable DMA */
-  if (priv->param.dma >= 0) disable_dma(priv->param.dma);
-}
-
-
-static void start_timer(struct scc_priv *priv, int t, int r15) {
-  unsigned long flags;
-
-  outb(priv->tmr_mode, priv->tmr_ctrl);
-  if (t == 0) {
-    tm_isr(priv);
-  } else if (t > 0) {
-    save_flags(flags);
-    cli();
-    outb(t & 0xFF, priv->tmr_cnt);
-    outb((t >> 8) & 0xFF, priv->tmr_cnt);
-    if (priv->type != TYPE_TWIN) {
-      write_scc(priv, R15, r15 | CTSIE);
-      priv->rr0 |= CTS;
-    }
-    restore_flags(flags);
-  }
-}
-
-
-static inline unsigned char random(void) {
-  /* See "Numerical Recipes in C", second edition, p. 284 */
-  rand = rand * 1664525L + 1013904223L;
-  return (unsigned char) (rand >> 24);
-}
-
-static inline void z8530_isr(struct scc_info *info) {
-  int is, i = 100;
-
-  while ((is = read_scc(&info->priv[0], R3)) && i--) {
-    if (is & CHARxIP) {
-      rx_isr(&info->priv[0]);
-    } else if (is & CHATxIP) {
-      tx_isr(&info->priv[0]);
-    } else if (is & CHAEXT) {
-      es_isr(&info->priv[0]);
-    } else if (is & CHBRxIP) {
-      rx_isr(&info->priv[1]);
-    } else if (is & CHBTxIP) {
-      tx_isr(&info->priv[1]);
-    } else {
-      es_isr(&info->priv[1]);
-    }
-    write_scc(&info->priv[0], R0, RES_H_IUS);
-    i++;
-  }
-  if (i < 0) {
-    printk(KERN_ERR "dmascc: stuck in ISR with RR3=0x%02x.\n", is);
-  }
-  /* Ok, no interrupts pending from this 8530. The INT line should
-     be inactive now. */
-}
-
-
-static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs * regs) {
-  struct scc_info *info = dev_id;
-
-  spin_lock(info->priv[0].register_lock);
-  /* At this point interrupts are enabled, and the interrupt under service
-     is already acknowledged, but masked off.
-
-     Interrupt processing: We loop until we know that the IRQ line is
-     low. If another positive edge occurs afterwards during the ISR,
-     another interrupt will be triggered by the interrupt controller
-     as soon as the IRQ level is enabled again (see asm/irq.h).
-
-     Bottom-half handlers will be processed after scc_isr(). This is
-     important, since we only have small ringbuffers and want new data
-     to be fetched/delivered immediately. */
-
-  if (info->priv[0].type == TYPE_TWIN) {
-    int is, card_base = info->priv[0].card_base;
-    while ((is = ~inb(card_base + TWIN_INT_REG)) &
-	   TWIN_INT_MSK) {
-      if (is & TWIN_SCC_MSK) {
-	z8530_isr(info);
-      } else if (is & TWIN_TMR1_MSK) {
-	inb(card_base + TWIN_CLR_TMR1);
-	tm_isr(&info->priv[0]);
-      } else {
-	inb(card_base + TWIN_CLR_TMR2);
-	tm_isr(&info->priv[1]);
-      }
-    }
-  } else z8530_isr(info);
-  spin_unlock(info->priv[0].register_lock);
-  return IRQ_HANDLED;
-}
-
-
-static void rx_isr(struct scc_priv *priv) {
-  if (priv->param.dma >= 0) {
-    /* Check special condition and perform error reset. See 2.4.7.5. */
-    special_condition(priv, read_scc(priv, R1));
-    write_scc(priv, R0, ERR_RES);
-  } else {
-    /* Check special condition for each character. Error reset not necessary.
-       Same algorithm for SCC and ESCC. See 2.4.7.1 and 2.4.7.4. */
-    int rc;
-    while (read_scc(priv, R0) & Rx_CH_AV) {
-      rc = read_scc(priv, R1);
-      if (priv->rx_ptr < BUF_SIZE)
-	priv->rx_buf[priv->rx_head][priv->rx_ptr++] =
-	  read_scc_data(priv);
-      else {
-	priv->rx_over = 2;
-	read_scc_data(priv);
-      }
-      special_condition(priv, rc);
-    }
-  }
-}
-
-
-static void special_condition(struct scc_priv *priv, int rc) {
-  int cb;
-  unsigned long flags;
-
-  /* See Figure 2-15. Only overrun and EOF need to be checked. */
-  
-  if (rc & Rx_OVR) {
-    /* Receiver overrun */
-    priv->rx_over = 1;
-    if (priv->param.dma < 0) write_scc(priv, R0, ERR_RES);
-  } else if (rc & END_FR) {
-    /* End of frame. Get byte count */
-    if (priv->param.dma >= 0) {
-      flags = claim_dma_lock();
-      cb = BUF_SIZE - get_dma_residue(priv->param.dma) - 2;
-      release_dma_lock(flags);
-    } else {
-      cb = priv->rx_ptr - 2;
-    }
-    if (priv->rx_over) {
-      /* We had an overrun */
-      priv->stats.rx_errors++;
-      if (priv->rx_over == 2) priv->stats.rx_length_errors++;
-      else priv->stats.rx_fifo_errors++;
-      priv->rx_over = 0;
-    } else if (rc & CRC_ERR) {
-      /* Count invalid CRC only if packet length >= minimum */
-      if (cb >= 15) {
-	priv->stats.rx_errors++;
-	priv->stats.rx_crc_errors++;
-      }
-    } else {
-      if (cb >= 15) {
-	if (priv->rx_count < NUM_RX_BUF - 1) {
-	  /* Put good frame in FIFO */
-	  priv->rx_len[priv->rx_head] = cb;
-	  priv->rx_head = (priv->rx_head + 1) % NUM_RX_BUF;
-	  priv->rx_count++;
-	  schedule_work(&priv->rx_work);
+static void write_scc(struct scc_priv *priv, int reg, int val)
+{
+	unsigned long flags;
+	switch (priv->type) {
+	case TYPE_S5:
+		if (reg)
+			outb(reg, priv->scc_cmd);
+		outb(val, priv->scc_cmd);
+		return;
+	case TYPE_TWIN:
+		if (reg)
+			outb_p(reg, priv->scc_cmd);
+		outb_p(val, priv->scc_cmd);
+		return;
+	default:
+		spin_lock_irqsave(priv->register_lock, flags);
+		outb_p(0, priv->card_base + PI_DREQ_MASK);
+		if (reg)
+			outb_p(reg, priv->scc_cmd);
+		outb_p(val, priv->scc_cmd);
+		outb(1, priv->card_base + PI_DREQ_MASK);
+		spin_unlock_irqrestore(priv->register_lock, flags);
+		return;
+	}
+}
+
+
+static void write_scc_data(struct scc_priv *priv, int val, int fast)
+{
+	unsigned long flags;
+	switch (priv->type) {
+	case TYPE_S5:
+		outb(val, priv->scc_data);
+		return;
+	case TYPE_TWIN:
+		outb_p(val, priv->scc_data);
+		return;
+	default:
+		if (fast)
+			outb_p(val, priv->scc_data);
+		else {
+			spin_lock_irqsave(priv->register_lock, flags);
+			outb_p(0, priv->card_base + PI_DREQ_MASK);
+			outb_p(val, priv->scc_data);
+			outb(1, priv->card_base + PI_DREQ_MASK);
+			spin_unlock_irqrestore(priv->register_lock, flags);
+		}
+		return;
+	}
+}
+
+
+static int read_scc(struct scc_priv *priv, int reg)
+{
+	int rc;
+	unsigned long flags;
+	switch (priv->type) {
+	case TYPE_S5:
+		if (reg)
+			outb(reg, priv->scc_cmd);
+		return inb(priv->scc_cmd);
+	case TYPE_TWIN:
+		if (reg)
+			outb_p(reg, priv->scc_cmd);
+		return inb_p(priv->scc_cmd);
+	default:
+		spin_lock_irqsave(priv->register_lock, flags);
+		outb_p(0, priv->card_base + PI_DREQ_MASK);
+		if (reg)
+			outb_p(reg, priv->scc_cmd);
+		rc = inb_p(priv->scc_cmd);
+		outb(1, priv->card_base + PI_DREQ_MASK);
+		spin_unlock_irqrestore(priv->register_lock, flags);
+		return rc;
+	}
+}
+
+
+static int read_scc_data(struct scc_priv *priv)
+{
+	int rc;
+	unsigned long flags;
+	switch (priv->type) {
+	case TYPE_S5:
+		return inb(priv->scc_data);
+	case TYPE_TWIN:
+		return inb_p(priv->scc_data);
+	default:
+		spin_lock_irqsave(priv->register_lock, flags);
+		outb_p(0, priv->card_base + PI_DREQ_MASK);
+		rc = inb_p(priv->scc_data);
+		outb(1, priv->card_base + PI_DREQ_MASK);
+		spin_unlock_irqrestore(priv->register_lock, flags);
+		return rc;
+	}
+}
+
+
+static int scc_open(struct net_device *dev)
+{
+	struct scc_priv *priv = dev->priv;
+	struct scc_info *info = priv->info;
+	int card_base = priv->card_base;
+
+	/* Request IRQ if not already used by other channel */
+	if (!info->irq_used) {
+		if (request_irq(dev->irq, scc_isr, 0, "dmascc", info)) {
+			return -EAGAIN;
+		}
+	}
+	info->irq_used++;
+
+	/* Request DMA if required */
+	if (priv->param.dma >= 0) {
+		if (request_dma(priv->param.dma, "dmascc")) {
+			if (--info->irq_used == 0)
+				free_irq(dev->irq, info);
+			return -EAGAIN;
+		} else {
+			unsigned long flags = claim_dma_lock();
+			clear_dma_ff(priv->param.dma);
+			release_dma_lock(flags);
+		}
+	}
+
+	/* Initialize local variables */
+	priv->rx_ptr = 0;
+	priv->rx_over = 0;
+	priv->rx_head = priv->rx_tail = priv->rx_count = 0;
+	priv->state = IDLE;
+	priv->tx_head = priv->tx_tail = priv->tx_count = 0;
+	priv->tx_ptr = 0;
+
+	/* Reset channel */
+	write_scc(priv, R9, (priv->channel ? CHRB : CHRA) | MIE | NV);
+	/* X1 clock, SDLC mode */
+	write_scc(priv, R4, SDLC | X1CLK);
+	/* DMA */
+	write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN);
+	/* 8 bit RX char, RX disable */
+	write_scc(priv, R3, Rx8);
+	/* 8 bit TX char, TX disable */
+	write_scc(priv, R5, Tx8);
+	/* SDLC address field */
+	write_scc(priv, R6, 0);
+	/* SDLC flag */
+	write_scc(priv, R7, FLAG);
+	switch (priv->chip) {
+	case Z85C30:
+		/* Select WR7' */
+		write_scc(priv, R15, SHDLCE);
+		/* Auto EOM reset */
+		write_scc(priv, R7, AUTOEOM);
+		write_scc(priv, R15, 0);
+		break;
+	case Z85230:
+		/* Select WR7' */
+		write_scc(priv, R15, SHDLCE);
+		/* The following bits are set (see 2.5.2.1):
+		   - Automatic EOM reset
+		   - Interrupt request if RX FIFO is half full
+		   This bit should be ignored in DMA mode (according to the
+		   documentation), but actually isn't. The receiver doesn't work if
+		   it is set. Thus, we have to clear it in DMA mode.
+		   - Interrupt/DMA request if TX FIFO is completely empty
+		   a) If set, the ESCC behaves as if it had no TX FIFO (Z85C30
+		   compatibility).
+		   b) If cleared, DMA requests may follow each other very quickly,
+		   filling up the TX FIFO.
+		   Advantage: TX works even in case of high bus latency.
+		   Disadvantage: Edge-triggered DMA request circuitry may miss
+		   a request. No more data is delivered, resulting
+		   in a TX FIFO underrun.
+		   Both PI2 and S5SCC/DMA seem to work fine with TXFIFOE cleared.
+		   The PackeTwin doesn't. I don't know about the PI, but let's
+		   assume it behaves like the PI2.
+		 */
+		if (priv->param.dma >= 0) {
+			if (priv->type == TYPE_TWIN)
+				write_scc(priv, R7, AUTOEOM | TXFIFOE);
+			else
+				write_scc(priv, R7, AUTOEOM);
+		} else {
+			write_scc(priv, R7, AUTOEOM | RXFIFOH);
+		}
+		write_scc(priv, R15, 0);
+		break;
+	}
+	/* Preset CRC, NRZ(I) encoding */
+	write_scc(priv, R10, CRCPS | (priv->param.nrzi ? NRZI : NRZ));
+
+	/* Configure baud rate generator */
+	if (priv->param.brg_tc >= 0) {
+		/* Program BR generator */
+		write_scc(priv, R12, priv->param.brg_tc & 0xFF);
+		write_scc(priv, R13, (priv->param.brg_tc >> 8) & 0xFF);
+		/* BRG source = SYS CLK; enable BRG; DTR REQ function (required by
+		   PackeTwin, not connected on the PI2); set DPLL source to BRG */
+		write_scc(priv, R14, SSBR | DTRREQ | BRSRC | BRENABL);
+		/* Enable DPLL */
+		write_scc(priv, R14, SEARCH | DTRREQ | BRSRC | BRENABL);
 	} else {
-	  priv->stats.rx_errors++;
-	  priv->stats.rx_over_errors++;
+		/* Disable BR generator */
+		write_scc(priv, R14, DTRREQ | BRSRC);
+	}
+
+	/* Configure clocks */
+	if (priv->type == TYPE_TWIN) {
+		/* Disable external TX clock receiver */
+		outb((info->twin_serial_cfg &=
+		      ~(priv->channel ? TWIN_EXTCLKB : TWIN_EXTCLKA)),
+		     card_base + TWIN_SERIAL_CFG);
+	}
+	write_scc(priv, R11, priv->param.clocks);
+	if ((priv->type == TYPE_TWIN) && !(priv->param.clocks & TRxCOI)) {
+		/* Enable external TX clock receiver */
+		outb((info->twin_serial_cfg |=
+		      (priv->channel ? TWIN_EXTCLKB : TWIN_EXTCLKA)),
+		     card_base + TWIN_SERIAL_CFG);
+	}
+
+	/* Configure PackeTwin */
+	if (priv->type == TYPE_TWIN) {
+		/* Assert DTR, enable interrupts */
+		outb((info->twin_serial_cfg |= TWIN_EI |
+		      (priv->channel ? TWIN_DTRB_ON : TWIN_DTRA_ON)),
+		     card_base + TWIN_SERIAL_CFG);
+	}
+
+	/* Read current status */
+	priv->rr0 = read_scc(priv, R0);
+	/* Enable DCD interrupt */
+	write_scc(priv, R15, DCDIE);
+
+	netif_start_queue(dev);
+
+	return 0;
+}
+
+
+static int scc_close(struct net_device *dev)
+{
+	struct scc_priv *priv = dev->priv;
+	struct scc_info *info = priv->info;
+	int card_base = priv->card_base;
+
+	netif_stop_queue(dev);
+
+	if (priv->type == TYPE_TWIN) {
+		/* Drop DTR */
+		outb((info->twin_serial_cfg &=
+		      (priv->channel ? ~TWIN_DTRB_ON : ~TWIN_DTRA_ON)),
+		     card_base + TWIN_SERIAL_CFG);
+	}
+
+	/* Reset channel, free DMA and IRQ */
+	write_scc(priv, R9, (priv->channel ? CHRB : CHRA) | MIE | NV);
+	if (priv->param.dma >= 0) {
+		if (priv->type == TYPE_TWIN)
+			outb(0, card_base + TWIN_DMA_CFG);
+		free_dma(priv->param.dma);
+	}
+	if (--info->irq_used == 0)
+		free_irq(dev->irq, info);
+
+	return 0;
+}
+
+
+static int scc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	struct scc_priv *priv = dev->priv;
+
+	switch (cmd) {
+	case SIOCGSCCPARAM:
+		if (copy_to_user
+		    (ifr->ifr_data, &priv->param,
+		     sizeof(struct scc_param)))
+			return -EFAULT;
+		return 0;
+	case SIOCSSCCPARAM:
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+		if (netif_running(dev))
+			return -EAGAIN;
+		if (copy_from_user
+		    (&priv->param, ifr->ifr_data,
+		     sizeof(struct scc_param)))
+			return -EFAULT;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+
+static int scc_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
+	struct scc_priv *priv = dev->priv;
+	unsigned long flags;
+	int i;
+
+	/* Temporarily stop the scheduler feeding us packets */
+	netif_stop_queue(dev);
+
+	/* Transfer data to DMA buffer */
+	i = priv->tx_head;
+	memcpy(priv->tx_buf[i], skb->data + 1, skb->len - 1);
+	priv->tx_len[i] = skb->len - 1;
+
+	/* Clear interrupts while we touch our circular buffers */
+
+	spin_lock_irqsave(&priv->ring_lock, flags);
+	/* Move the ring buffer's head */
+	priv->tx_head = (i + 1) % NUM_TX_BUF;
+	priv->tx_count++;
+
+	/* If we just filled up the last buffer, leave queue stopped.
+	   The higher layers must wait until we have a DMA buffer
+	   to accept the data. */
+	if (priv->tx_count < NUM_TX_BUF)
+		netif_wake_queue(dev);
+
+	/* Set new TX state */
+	if (priv->state == IDLE) {
+		/* Assert RTS, start timer */
+		priv->state = TX_HEAD;
+		priv->tx_start = jiffies;
+		write_scc(priv, R5, TxCRC_ENAB | RTS | TxENAB | Tx8);
+		write_scc(priv, R15, 0);
+		start_timer(priv, priv->param.txdelay, 0);
+	}
+
+	/* Turn interrupts back on and free buffer */
+	spin_unlock_irqrestore(&priv->ring_lock, flags);
+	dev_kfree_skb(skb);
+
+	return 0;
+}
+
+
+static struct net_device_stats *scc_get_stats(struct net_device *dev)
+{
+	struct scc_priv *priv = dev->priv;
+
+	return &priv->stats;
+}
+
+
+static int scc_set_mac_address(struct net_device *dev, void *sa)
+{
+	memcpy(dev->dev_addr, ((struct sockaddr *) sa)->sa_data,
+	       dev->addr_len);
+	return 0;
+}
+
+
+static inline void tx_on(struct scc_priv *priv)
+{
+	int i, n;
+	unsigned long flags;
+
+	if (priv->param.dma >= 0) {
+		n = (priv->chip == Z85230) ? 3 : 1;
+		/* Program DMA controller */
+		flags = claim_dma_lock();
+		set_dma_mode(priv->param.dma, DMA_MODE_WRITE);
+		set_dma_addr(priv->param.dma,
+			     (int) priv->tx_buf[priv->tx_tail] + n);
+		set_dma_count(priv->param.dma,
+			      priv->tx_len[priv->tx_tail] - n);
+		release_dma_lock(flags);
+		/* Enable TX underrun interrupt */
+		write_scc(priv, R15, TxUIE);
+		/* Configure DREQ */
+		if (priv->type == TYPE_TWIN)
+			outb((priv->param.dma ==
+			      1) ? TWIN_DMA_HDX_T1 : TWIN_DMA_HDX_T3,
+			     priv->card_base + TWIN_DMA_CFG);
+		else
+			write_scc(priv, R1,
+				  EXT_INT_ENAB | WT_FN_RDYFN |
+				  WT_RDY_ENAB);
+		/* Write first byte(s) */
+		spin_lock_irqsave(priv->register_lock, flags);
+		for (i = 0; i < n; i++)
+			write_scc_data(priv,
+				       priv->tx_buf[priv->tx_tail][i], 1);
+		enable_dma(priv->param.dma);
+		spin_unlock_irqrestore(priv->register_lock, flags);
+	} else {
+		write_scc(priv, R15, TxUIE);
+		write_scc(priv, R1,
+			  EXT_INT_ENAB | WT_FN_RDYFN | TxINT_ENAB);
+		tx_isr(priv);
+	}
+	/* Reset EOM latch if we do not have the AUTOEOM feature */
+	if (priv->chip == Z8530)
+		write_scc(priv, R0, RES_EOM_L);
+}
+
+
+static inline void rx_on(struct scc_priv *priv)
+{
+	unsigned long flags;
+
+	/* Clear RX FIFO */
+	while (read_scc(priv, R0) & Rx_CH_AV)
+		read_scc_data(priv);
+	priv->rx_over = 0;
+	if (priv->param.dma >= 0) {
+		/* Program DMA controller */
+		flags = claim_dma_lock();
+		set_dma_mode(priv->param.dma, DMA_MODE_READ);
+		set_dma_addr(priv->param.dma,
+			     (int) priv->rx_buf[priv->rx_head]);
+		set_dma_count(priv->param.dma, BUF_SIZE);
+		release_dma_lock(flags);
+		enable_dma(priv->param.dma);
+		/* Configure PackeTwin DMA */
+		if (priv->type == TYPE_TWIN) {
+			outb((priv->param.dma ==
+			      1) ? TWIN_DMA_HDX_R1 : TWIN_DMA_HDX_R3,
+			     priv->card_base + TWIN_DMA_CFG);
+		}
+		/* Sp. cond. intr. only, ext int enable, RX DMA enable */
+		write_scc(priv, R1, EXT_INT_ENAB | INT_ERR_Rx |
+			  WT_RDY_RT | WT_FN_RDYFN | WT_RDY_ENAB);
+	} else {
+		/* Reset current frame */
+		priv->rx_ptr = 0;
+		/* Intr. on all Rx characters and Sp. cond., ext int enable */
+		write_scc(priv, R1, EXT_INT_ENAB | INT_ALL_Rx | WT_RDY_RT |
+			  WT_FN_RDYFN);
+	}
+	write_scc(priv, R0, ERR_RES);
+	write_scc(priv, R3, RxENABLE | Rx8 | RxCRC_ENAB);
+}
+
+
+static inline void rx_off(struct scc_priv *priv)
+{
+	/* Disable receiver */
+	write_scc(priv, R3, Rx8);
+	/* Disable DREQ / RX interrupt */
+	if (priv->param.dma >= 0 && priv->type == TYPE_TWIN)
+		outb(0, priv->card_base + TWIN_DMA_CFG);
+	else
+		write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN);
+	/* Disable DMA */
+	if (priv->param.dma >= 0)
+		disable_dma(priv->param.dma);
+}
+
+
+static void start_timer(struct scc_priv *priv, int t, int r15)
+{
+	unsigned long flags;
+
+	outb(priv->tmr_mode, priv->tmr_ctrl);
+	if (t == 0) {
+		tm_isr(priv);
+	} else if (t > 0) {
+		save_flags(flags);
+		cli();
+		outb(t & 0xFF, priv->tmr_cnt);
+		outb((t >> 8) & 0xFF, priv->tmr_cnt);
+		if (priv->type != TYPE_TWIN) {
+			write_scc(priv, R15, r15 | CTSIE);
+			priv->rr0 |= CTS;
+		}
+		restore_flags(flags);
+	}
+}
+
+
+static inline unsigned char random(void)
+{
+	/* See "Numerical Recipes in C", second edition, p. 284 */
+	rand = rand * 1664525L + 1013904223L;
+	return (unsigned char) (rand >> 24);
+}
+
+static inline void z8530_isr(struct scc_info *info)
+{
+	int is, i = 100;
+
+	while ((is = read_scc(&info->priv[0], R3)) && i--) {
+		if (is & CHARxIP) {
+			rx_isr(&info->priv[0]);
+		} else if (is & CHATxIP) {
+			tx_isr(&info->priv[0]);
+		} else if (is & CHAEXT) {
+			es_isr(&info->priv[0]);
+		} else if (is & CHBRxIP) {
+			rx_isr(&info->priv[1]);
+		} else if (is & CHBTxIP) {
+			tx_isr(&info->priv[1]);
+		} else {
+			es_isr(&info->priv[1]);
+		}
+		write_scc(&info->priv[0], R0, RES_H_IUS);
+		i++;
+	}
+	if (i < 0) {
+		printk(KERN_ERR "dmascc: stuck in ISR with RR3=0x%02x.\n",
+		       is);
+	}
+	/* Ok, no interrupts pending from this 8530. The INT line should
+	   be inactive now. */
+}
+
+
+static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct scc_info *info = dev_id;
+
+	spin_lock(info->priv[0].register_lock);
+	/* At this point interrupts are enabled, and the interrupt under service
+	   is already acknowledged, but masked off.
+
+	   Interrupt processing: We loop until we know that the IRQ line is
+	   low. If another positive edge occurs afterwards during the ISR,
+	   another interrupt will be triggered by the interrupt controller
+	   as soon as the IRQ level is enabled again (see asm/irq.h).
+
+	   Bottom-half handlers will be processed after scc_isr(). This is
+	   important, since we only have small ringbuffers and want new data
+	   to be fetched/delivered immediately. */
+
+	if (info->priv[0].type == TYPE_TWIN) {
+		int is, card_base = info->priv[0].card_base;
+		while ((is = ~inb(card_base + TWIN_INT_REG)) &
+		       TWIN_INT_MSK) {
+			if (is & TWIN_SCC_MSK) {
+				z8530_isr(info);
+			} else if (is & TWIN_TMR1_MSK) {
+				inb(card_base + TWIN_CLR_TMR1);
+				tm_isr(&info->priv[0]);
+			} else {
+				inb(card_base + TWIN_CLR_TMR2);
+				tm_isr(&info->priv[1]);
+			}
+		}
+	} else
+		z8530_isr(info);
+	spin_unlock(info->priv[0].register_lock);
+	return IRQ_HANDLED;
+}
+
+
+static void rx_isr(struct scc_priv *priv)
+{
+	if (priv->param.dma >= 0) {
+		/* Check special condition and perform error reset. See 2.4.7.5. */
+		special_condition(priv, read_scc(priv, R1));
+		write_scc(priv, R0, ERR_RES);
+	} else {
+		/* Check special condition for each character. Error reset not necessary.
+		   Same algorithm for SCC and ESCC. See 2.4.7.1 and 2.4.7.4. */
+		int rc;
+		while (read_scc(priv, R0) & Rx_CH_AV) {
+			rc = read_scc(priv, R1);
+			if (priv->rx_ptr < BUF_SIZE)
+				priv->rx_buf[priv->rx_head][priv->
+							    rx_ptr++] =
+				    read_scc_data(priv);
+			else {
+				priv->rx_over = 2;
+				read_scc_data(priv);
+			}
+			special_condition(priv, rc);
+		}
+	}
+}
+
+
+static void special_condition(struct scc_priv *priv, int rc)
+{
+	int cb;
+	unsigned long flags;
+
+	/* See Figure 2-15. Only overrun and EOF need to be checked. */
+
+	if (rc & Rx_OVR) {
+		/* Receiver overrun */
+		priv->rx_over = 1;
+		if (priv->param.dma < 0)
+			write_scc(priv, R0, ERR_RES);
+	} else if (rc & END_FR) {
+		/* End of frame. Get byte count */
+		if (priv->param.dma >= 0) {
+			flags = claim_dma_lock();
+			cb = BUF_SIZE - get_dma_residue(priv->param.dma) -
+			    2;
+			release_dma_lock(flags);
+		} else {
+			cb = priv->rx_ptr - 2;
+		}
+		if (priv->rx_over) {
+			/* We had an overrun */
+			priv->stats.rx_errors++;
+			if (priv->rx_over == 2)
+				priv->stats.rx_length_errors++;
+			else
+				priv->stats.rx_fifo_errors++;
+			priv->rx_over = 0;
+		} else if (rc & CRC_ERR) {
+			/* Count invalid CRC only if packet length >= minimum */
+			if (cb >= 15) {
+				priv->stats.rx_errors++;
+				priv->stats.rx_crc_errors++;
+			}
+		} else {
+			if (cb >= 15) {
+				if (priv->rx_count < NUM_RX_BUF - 1) {
+					/* Put good frame in FIFO */
+					priv->rx_len[priv->rx_head] = cb;
+					priv->rx_head =
+					    (priv->rx_head +
+					     1) % NUM_RX_BUF;
+					priv->rx_count++;
+					schedule_work(&priv->rx_work);
+				} else {
+					priv->stats.rx_errors++;
+					priv->stats.rx_over_errors++;
+				}
+			}
+		}
+		/* Get ready for new frame */
+		if (priv->param.dma >= 0) {
+			flags = claim_dma_lock();
+			set_dma_addr(priv->param.dma,
+				     (int) priv->rx_buf[priv->rx_head]);
+			set_dma_count(priv->param.dma, BUF_SIZE);
+			release_dma_lock(flags);
+		} else {
+			priv->rx_ptr = 0;
+		}
+	}
+}
+
+
+static void rx_bh(void *arg)
+{
+	struct scc_priv *priv = arg;
+	int i = priv->rx_tail;
+	int cb;
+	unsigned long flags;
+	struct sk_buff *skb;
+	unsigned char *data;
+
+	spin_lock_irqsave(&priv->ring_lock, flags);
+	while (priv->rx_count) {
+		spin_unlock_irqrestore(&priv->ring_lock, flags);
+		cb = priv->rx_len[i];
+		/* Allocate buffer */
+		skb = dev_alloc_skb(cb + 1);
+		if (skb == NULL) {
+			/* Drop packet */
+			priv->stats.rx_dropped++;
+		} else {
+			/* Fill buffer */
+			data = skb_put(skb, cb + 1);
+			data[0] = 0;
+			memcpy(&data[1], priv->rx_buf[i], cb);
+			skb->dev = priv->dev;
+			skb->protocol = ntohs(ETH_P_AX25);
+			skb->mac.raw = skb->data;
+			netif_rx(skb);
+			priv->dev->last_rx = jiffies;
+			priv->stats.rx_packets++;
+			priv->stats.rx_bytes += cb;
+		}
+		spin_lock_irqsave(&priv->ring_lock, flags);
+		/* Move tail */
+		priv->rx_tail = i = (i + 1) % NUM_RX_BUF;
+		priv->rx_count--;
+	}
+	spin_unlock_irqrestore(&priv->ring_lock, flags);
+}
+
+
+static void tx_isr(struct scc_priv *priv)
+{
+	int i = priv->tx_tail, p = priv->tx_ptr;
+
+	/* Suspend TX interrupts if we don't want to send anything.
+	   See Figure 2-22. */
+	if (p == priv->tx_len[i]) {
+		write_scc(priv, R0, RES_Tx_P);
+		return;
+	}
+
+	/* Write characters */
+	while ((read_scc(priv, R0) & Tx_BUF_EMP) && p < priv->tx_len[i]) {
+		write_scc_data(priv, priv->tx_buf[i][p++], 0);
+	}
+
+	/* Reset EOM latch of Z8530 */
+	if (!priv->tx_ptr && p && priv->chip == Z8530)
+		write_scc(priv, R0, RES_EOM_L);
+
+	priv->tx_ptr = p;
+}
+
+
+static void es_isr(struct scc_priv *priv)
+{
+	int i, rr0, drr0, res;
+	unsigned long flags;
+
+	/* Read status, reset interrupt bit (open latches) */
+	rr0 = read_scc(priv, R0);
+	write_scc(priv, R0, RES_EXT_INT);
+	drr0 = priv->rr0 ^ rr0;
+	priv->rr0 = rr0;
+
+	/* Transmit underrun (2.4.9.6). We can't check the TxEOM flag, since
+	   it might have already been cleared again by AUTOEOM. */
+	if (priv->state == TX_DATA) {
+		/* Get remaining bytes */
+		i = priv->tx_tail;
+		if (priv->param.dma >= 0) {
+			disable_dma(priv->param.dma);
+			flags = claim_dma_lock();
+			res = get_dma_residue(priv->param.dma);
+			release_dma_lock(flags);
+		} else {
+			res = priv->tx_len[i] - priv->tx_ptr;
+			priv->tx_ptr = 0;
+		}
+		/* Disable DREQ / TX interrupt */
+		if (priv->param.dma >= 0 && priv->type == TYPE_TWIN)
+			outb(0, priv->card_base + TWIN_DMA_CFG);
+		else
+			write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN);
+		if (res) {
+			/* Update packet statistics */
+			priv->stats.tx_errors++;
+			priv->stats.tx_fifo_errors++;
+			/* Other underrun interrupts may already be waiting */
+			write_scc(priv, R0, RES_EXT_INT);
+			write_scc(priv, R0, RES_EXT_INT);
+		} else {
+			/* Update packet statistics */
+			priv->stats.tx_packets++;
+			priv->stats.tx_bytes += priv->tx_len[i];
+			/* Remove frame from FIFO */
+			priv->tx_tail = (i + 1) % NUM_TX_BUF;
+			priv->tx_count--;
+			/* Inform upper layers */
+			netif_wake_queue(priv->dev);
+		}
+		/* Switch state */
+		write_scc(priv, R15, 0);
+		if (priv->tx_count &&
+		    (jiffies - priv->tx_start) < priv->param.txtimeout) {
+			priv->state = TX_PAUSE;
+			start_timer(priv, priv->param.txpause, 0);
+		} else {
+			priv->state = TX_TAIL;
+			start_timer(priv, priv->param.txtail, 0);
+		}
+	}
+
+	/* DCD transition */
+	if (drr0 & DCD) {
+		if (rr0 & DCD) {
+			switch (priv->state) {
+			case IDLE:
+			case WAIT:
+				priv->state = DCD_ON;
+				write_scc(priv, R15, 0);
+				start_timer(priv, priv->param.dcdon, 0);
+			}
+		} else {
+			switch (priv->state) {
+			case RX_ON:
+				rx_off(priv);
+				priv->state = DCD_OFF;
+				write_scc(priv, R15, 0);
+				start_timer(priv, priv->param.dcdoff, 0);
+			}
+		}
+	}
+
+	/* CTS transition */
+	if ((drr0 & CTS) && (~rr0 & CTS) && priv->type != TYPE_TWIN)
+		tm_isr(priv);
+
+}
+
+
+static void tm_isr(struct scc_priv *priv)
+{
+	switch (priv->state) {
+	case TX_HEAD:
+	case TX_PAUSE:
+		tx_on(priv);
+		priv->state = TX_DATA;
+		break;
+	case TX_TAIL:
+		write_scc(priv, R5, TxCRC_ENAB | Tx8);
+		priv->state = RTS_OFF;
+		if (priv->type != TYPE_TWIN)
+			write_scc(priv, R15, 0);
+		start_timer(priv, priv->param.rtsoff, 0);
+		break;
+	case RTS_OFF:
+		write_scc(priv, R15, DCDIE);
+		priv->rr0 = read_scc(priv, R0);
+		if (priv->rr0 & DCD) {
+			priv->stats.collisions++;
+			rx_on(priv);
+			priv->state = RX_ON;
+		} else {
+			priv->state = WAIT;
+			start_timer(priv, priv->param.waittime, DCDIE);
+		}
+		break;
+	case WAIT:
+		if (priv->tx_count) {
+			priv->state = TX_HEAD;
+			priv->tx_start = jiffies;
+			write_scc(priv, R5,
+				  TxCRC_ENAB | RTS | TxENAB | Tx8);
+			write_scc(priv, R15, 0);
+			start_timer(priv, priv->param.txdelay, 0);
+		} else {
+			priv->state = IDLE;
+			if (priv->type != TYPE_TWIN)
+				write_scc(priv, R15, DCDIE);
+		}
+		break;
+	case DCD_ON:
+	case DCD_OFF:
+		write_scc(priv, R15, DCDIE);
+		priv->rr0 = read_scc(priv, R0);
+		if (priv->rr0 & DCD) {
+			rx_on(priv);
+			priv->state = RX_ON;
+		} else {
+			priv->state = WAIT;
+			start_timer(priv,
+				    random() / priv->param.persist *
+				    priv->param.slottime, DCDIE);
+		}
+		break;
 	}
-      }
-    }
-    /* Get ready for new frame */
-    if (priv->param.dma >= 0) {
-      flags = claim_dma_lock();
-      set_dma_addr(priv->param.dma, (int) priv->rx_buf[priv->rx_head]);
-      set_dma_count(priv->param.dma, BUF_SIZE);
-      release_dma_lock(flags);
-    } else {
-      priv->rx_ptr = 0;
-    }
-  }
-}
-
-
-static void rx_bh(void *arg) {
-  struct scc_priv *priv = arg;
-  int i = priv->rx_tail;
-  int cb;
-  unsigned long flags;
-  struct sk_buff *skb;
-  unsigned char *data;
-
-  spin_lock_irqsave(&priv->ring_lock, flags);
-  while (priv->rx_count) {
-    spin_unlock_irqrestore(&priv->ring_lock, flags);
-    cb = priv->rx_len[i];
-    /* Allocate buffer */
-    skb = dev_alloc_skb(cb+1);
-    if (skb == NULL) {
-      /* Drop packet */
-      priv->stats.rx_dropped++;
-    } else {
-      /* Fill buffer */
-      data = skb_put(skb, cb+1);
-      data[0] = 0;
-      memcpy(&data[1], priv->rx_buf[i], cb);
-      skb->dev = priv->dev;
-      skb->protocol = ntohs(ETH_P_AX25);
-      skb->mac.raw = skb->data;
-      netif_rx(skb);
-      priv->dev->last_rx = jiffies;
-      priv->stats.rx_packets++;
-      priv->stats.rx_bytes += cb;
-    }
-    spin_lock_irqsave(&priv->ring_lock, flags);
-    /* Move tail */
-    priv->rx_tail = i = (i + 1) % NUM_RX_BUF;
-    priv->rx_count--;
-  }
-  spin_unlock_irqrestore(&priv->ring_lock, flags);
-}
-
-
-static void tx_isr(struct scc_priv *priv) {
-  int i = priv->tx_tail, p = priv->tx_ptr;
-
-  /* Suspend TX interrupts if we don't want to send anything.
-     See Figure 2-22. */
-  if (p ==  priv->tx_len[i]) {
-    write_scc(priv, R0, RES_Tx_P);
-    return;
-  }
-
-  /* Write characters */
-  while ((read_scc(priv, R0) & Tx_BUF_EMP) && p < priv->tx_len[i]) {
-    write_scc_data(priv, priv->tx_buf[i][p++], 0);
-  }
-
-  /* Reset EOM latch of Z8530 */
-  if (!priv->tx_ptr && p && priv->chip == Z8530)
-    write_scc(priv, R0, RES_EOM_L);
-
-  priv->tx_ptr = p;
-}
-
-
-static void es_isr(struct scc_priv *priv) {
-  int i, rr0, drr0, res;
-  unsigned long flags;
-
-  /* Read status, reset interrupt bit (open latches) */
-  rr0 = read_scc(priv, R0);
-  write_scc(priv, R0, RES_EXT_INT);
-  drr0 = priv->rr0 ^ rr0;
-  priv->rr0 = rr0;
-
-  /* Transmit underrun (2.4.9.6). We can't check the TxEOM flag, since
-     it might have already been cleared again by AUTOEOM. */
-  if (priv->state == TX_DATA) {
-    /* Get remaining bytes */
-    i = priv->tx_tail;
-    if (priv->param.dma >= 0) {
-      disable_dma(priv->param.dma);
-      flags = claim_dma_lock();
-      res = get_dma_residue(priv->param.dma);
-      release_dma_lock(flags);
-    } else {
-      res = priv->tx_len[i] - priv->tx_ptr;
-      priv->tx_ptr = 0;
-    }
-    /* Disable DREQ / TX interrupt */
-    if (priv->param.dma >= 0 && priv->type == TYPE_TWIN)
-      outb(0, priv->card_base + TWIN_DMA_CFG);
-    else
-      write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN);
-    if (res) {
-      /* Update packet statistics */
-      priv->stats.tx_errors++;
-      priv->stats.tx_fifo_errors++;
-      /* Other underrun interrupts may already be waiting */
-      write_scc(priv, R0, RES_EXT_INT);
-      write_scc(priv, R0, RES_EXT_INT);
-    } else {
-      /* Update packet statistics */
-      priv->stats.tx_packets++;
-      priv->stats.tx_bytes += priv->tx_len[i];
-      /* Remove frame from FIFO */
-      priv->tx_tail = (i + 1) % NUM_TX_BUF;
-      priv->tx_count--;
-      /* Inform upper layers */
-      netif_wake_queue(priv->dev);
-    }
-    /* Switch state */
-    write_scc(priv, R15, 0);
-    if (priv->tx_count &&
-	(jiffies - priv->tx_start) < priv->param.txtimeout) {
-      priv->state = TX_PAUSE;
-      start_timer(priv, priv->param.txpause, 0);
-    } else {
-      priv->state = TX_TAIL;
-      start_timer(priv, priv->param.txtail, 0);
-    }
-  }
-
-  /* DCD transition */
-  if (drr0 & DCD) {
-    if (rr0 & DCD) {
-      switch (priv->state) {
-      case IDLE:
-      case WAIT:
-	priv->state = DCD_ON;
-	write_scc(priv, R15, 0);
-	start_timer(priv, priv->param.dcdon, 0);
-      }
-    } else {
-      switch (priv->state) {
-      case RX_ON:
-	rx_off(priv);
-	priv->state = DCD_OFF;
-	write_scc(priv, R15, 0);
-	start_timer(priv, priv->param.dcdoff, 0);
-      }
-    }
-  }
-
-  /* CTS transition */
-  if ((drr0 & CTS) && (~rr0 & CTS) && priv->type != TYPE_TWIN)
-    tm_isr(priv);
-
-}
-
-
-static void tm_isr(struct scc_priv *priv) {
-  switch (priv->state) {
-  case TX_HEAD:
-  case TX_PAUSE:
-    tx_on(priv);
-    priv->state = TX_DATA;
-    break;
-  case TX_TAIL:
-    write_scc(priv, R5, TxCRC_ENAB | Tx8);
-    priv->state = RTS_OFF;
-    if (priv->type != TYPE_TWIN) write_scc(priv, R15, 0);
-    start_timer(priv, priv->param.rtsoff, 0);
-    break;
-  case RTS_OFF:
-    write_scc(priv, R15, DCDIE);
-    priv->rr0 = read_scc(priv, R0);
-    if (priv->rr0 & DCD) {
-      priv->stats.collisions++;
-      rx_on(priv);
-      priv->state = RX_ON;
-    } else {
-      priv->state = WAIT;
-      start_timer(priv, priv->param.waittime, DCDIE);
-    }
-    break;
-  case WAIT:
-    if (priv->tx_count) {
-      priv->state = TX_HEAD;
-      priv->tx_start = jiffies;
-      write_scc(priv, R5, TxCRC_ENAB | RTS | TxENAB | Tx8);
-      write_scc(priv, R15, 0);
-      start_timer(priv, priv->param.txdelay, 0);
-    } else {
-      priv->state = IDLE;
-      if (priv->type != TYPE_TWIN) write_scc(priv, R15, DCDIE);
-    }
-    break;
-  case DCD_ON:
-  case DCD_OFF:
-    write_scc(priv, R15, DCDIE);
-    priv->rr0 = read_scc(priv, R0);
-    if (priv->rr0 & DCD) {
-      rx_on(priv);
-      priv->state = RX_ON;
-    } else {
-      priv->state = WAIT;
-      start_timer(priv,
-		  random()/priv->param.persist*priv->param.slottime,
-		  DCDIE);
-    }
-    break;
-  }
 }
diff -Nru a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c
--- a/drivers/net/hamradio/hdlcdrv.c	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/hamradio/hdlcdrv.c	2005-03-08 14:29:45 -05:00
@@ -427,27 +427,10 @@
  * ===================== network driver interface =========================
  */
 
-static inline int hdlcdrv_paranoia_check(struct net_device *dev,
-					const char *routine)
-{
-	if (!dev || !dev->priv || 
-	    ((struct hdlcdrv_state *)dev->priv)->magic != HDLCDRV_MAGIC) {
-		printk(KERN_ERR "hdlcdrv: bad magic number for hdlcdrv_state "
-		       "struct in routine %s\n", routine);
-		return 1;
-	}
-	return 0;
-}
-
-/* --------------------------------------------------------------------- */
-
 static int hdlcdrv_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
-	struct hdlcdrv_state *sm;
+	struct hdlcdrv_state *sm = netdev_priv(dev);
 
-	if (hdlcdrv_paranoia_check(dev, "hdlcdrv_send_packet"))
-		return 0;
-	sm = (struct hdlcdrv_state *)dev->priv;
 	if (skb->data[0] != 0) {
 		do_kiss_params(sm, skb->data, skb->len);
 		dev_kfree_skb(skb);
@@ -475,11 +458,8 @@
 
 static struct net_device_stats *hdlcdrv_get_stats(struct net_device *dev)
 {
-	struct hdlcdrv_state *sm;
+	struct hdlcdrv_state *sm = netdev_priv(dev);
 
-	if (hdlcdrv_paranoia_check(dev, "hdlcdrv_get_stats"))
-		return NULL;
-	sm = (struct hdlcdrv_state *)dev->priv;
 	/* 
 	 * Get the current statistics.  This may be called with the
 	 * card open or closed. 
@@ -499,13 +479,9 @@
 
 static int hdlcdrv_open(struct net_device *dev)
 {
-	struct hdlcdrv_state *s;
+	struct hdlcdrv_state *s = netdev_priv(dev);
 	int i;
 
-	if (hdlcdrv_paranoia_check(dev, "hdlcdrv_open"))
-		return -EINVAL;
-	s = (struct hdlcdrv_state *)dev->priv;
-
 	if (!s->ops || !s->ops->open)
 		return -ENODEV;
 
@@ -540,13 +516,9 @@
 
 static int hdlcdrv_close(struct net_device *dev)
 {
-	struct hdlcdrv_state *s;
+	struct hdlcdrv_state *s = netdev_priv(dev);
 	int i = 0;
 
-	if (hdlcdrv_paranoia_check(dev, "hdlcdrv_close"))
-		return -EINVAL;
-	s = (struct hdlcdrv_state *)dev->priv;
-
 	netif_stop_queue(dev);
 
 	if (s->ops && s->ops->close)
@@ -562,12 +534,8 @@
 
 static int hdlcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
-	struct hdlcdrv_state *s;
+	struct hdlcdrv_state *s = netdev_priv(dev);
 	struct hdlcdrv_ioctl bi;
-		
-	if (hdlcdrv_paranoia_check(dev, "hdlcdrv_ioctl"))
-		return -EINVAL;
-	s = (struct hdlcdrv_state *)dev->priv;
 
 	if (cmd != SIOCDEVPRIVATE) {
 		if (s->ops && s->ops->ioctl)
@@ -698,7 +666,7 @@
 	static const struct hdlcdrv_channel_params dflt_ch_params = { 
 		20, 2, 10, 40, 0 
 	};
-	struct hdlcdrv_state *s = dev->priv;
+	struct hdlcdrv_state *s = netdev_priv(dev);
 
 	/*
 	 * initialize the hdlcdrv_state struct
@@ -782,7 +750,7 @@
 	/*
 	 * initialize part of the hdlcdrv_state struct
 	 */
-	s = dev->priv;
+	s = netdev_priv(dev);
 	s->magic = HDLCDRV_MAGIC;
 	s->ops = ops;
 	dev->base_addr = baseaddr;
@@ -803,7 +771,7 @@
 
 void hdlcdrv_unregister(struct net_device *dev) 
 {
-	struct hdlcdrv_state *s = dev->priv;
+	struct hdlcdrv_state *s = netdev_priv(dev);
 
 	BUG_ON(s->magic != HDLCDRV_MAGIC);
 
diff -Nru a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
--- a/drivers/net/hamradio/mkiss.c	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/hamradio/mkiss.c	2005-03-08 14:29:45 -05:00
@@ -419,7 +419,7 @@
 /* Encapsulate an AX.25 packet and kick it into a TTY queue. */
 static int ax_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct ax_disp *ax = (struct ax_disp *) dev->priv;
+	struct ax_disp *ax = netdev_priv(dev);
 
 	if (!netif_running(dev))  {
 		printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name);
@@ -483,7 +483,7 @@
 /* Open the low-level part of the AX25 channel. Easy! */
 static int ax_open(struct net_device *dev)
 {
-	struct ax_disp *ax = (struct ax_disp *) dev->priv;
+	struct ax_disp *ax = netdev_priv(dev);
 	unsigned long len;
 
 	if (ax->tty == NULL)
@@ -534,7 +534,7 @@
 /* Close the low-level part of the AX25 channel. Easy! */
 static int ax_close(struct net_device *dev)
 {
-	struct ax_disp *ax = (struct ax_disp *) dev->priv;
+	struct ax_disp *ax = netdev_priv(dev);
 
 	if (ax->tty == NULL)
 		return -EBUSY;
@@ -634,7 +634,7 @@
 static struct net_device_stats *ax_get_stats(struct net_device *dev)
 {
 	static struct net_device_stats stats;
-	struct ax_disp *ax = (struct ax_disp *) dev->priv;
+	struct ax_disp *ax = netdev_priv(dev);
 
 	memset(&stats, 0, sizeof(struct net_device_stats));
 
@@ -827,7 +827,7 @@
 
 static int ax_open_dev(struct net_device *dev)
 {
-	struct ax_disp *ax = (struct ax_disp *) dev->priv;
+	struct ax_disp *ax = netdev_priv(dev);
 
 	if (ax->tty == NULL)
 		return -ENODEV;
@@ -839,7 +839,7 @@
 /* Initialize the driver.  Called by network startup. */
 static int ax25_init(struct net_device *dev)
 {
-	struct ax_disp *ax = (struct ax_disp *) dev->priv;
+	struct ax_disp *ax = netdev_priv(dev);
 
 	static char ax25_bcast[AX25_ADDR_LEN] =
 		{'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1};
diff -Nru a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
--- a/drivers/net/hamradio/yam.c	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/hamradio/yam.c	2005-03-08 14:29:45 -05:00
@@ -442,7 +442,7 @@
 
 static void yam_set_uart(struct net_device *dev)
 {
-	struct yam_port *yp = (struct yam_port *) dev->priv;
+	struct yam_port *yp = netdev_priv(dev);
 	int divisor = 115200 / yp->baudrate;
 
 	outb(0, IER(dev->base_addr));
@@ -565,7 +565,7 @@
 
 static int yam_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
-	struct yam_port *yp = dev->priv;
+	struct yam_port *yp = netdev_priv(dev);
 
 	skb_queue_tail(&yp->send_queue, skb);
 	dev->trans_start = jiffies;
@@ -592,12 +592,11 @@
 
 static void yam_arbitrate(struct net_device *dev)
 {
-	struct yam_port *yp = dev->priv;
+	struct yam_port *yp = netdev_priv(dev);
 
-	if (!yp || yp->magic != YAM_MAGIC
-		|| yp->tx_state != TX_OFF || skb_queue_empty(&yp->send_queue)) {
+	if (yp->magic != YAM_MAGIC || yp->tx_state != TX_OFF ||
+	    skb_queue_empty(&yp->send_queue))
 		return;
-	}
 	/* tx_state is TX_OFF and there is data to send */
 
 	if (yp->dupmode) {
@@ -725,7 +724,7 @@
 
 	for (i = 0; i < NR_PORTS; i++) {
 		dev = yam_devs[i];
-		yp = dev->priv;
+		yp = netdev_priv(dev);
 
 		if (!netif_running(dev))
 			continue;
@@ -784,8 +783,8 @@
 
 static int yam_seq_show(struct seq_file *seq, void *v)
 {
-	const struct net_device *dev = v;
-	const struct yam_port *yp = dev->priv;
+	struct net_device *dev = v;
+	const struct yam_port *yp = netdev_priv(dev);
 
 	seq_printf(seq, "Device %s\n", dev->name);
 	seq_printf(seq, "  Up       %d\n", netif_running(dev));
@@ -838,10 +837,10 @@
 {
 	struct yam_port *yp;
 
-	if (!dev || !dev->priv)
+	if (!dev)
 		return NULL;
 
-	yp = (struct yam_port *) dev->priv;
+	yp = netdev_priv(dev);
 	if (yp->magic != YAM_MAGIC)
 		return NULL;
 
@@ -856,14 +855,14 @@
 
 static int yam_open(struct net_device *dev)
 {
-	struct yam_port *yp = (struct yam_port *) dev->priv;
+	struct yam_port *yp = netdev_priv(dev);
 	enum uart u;
 	int i;
 	int ret=0;
 
 	printk(KERN_INFO "Trying %s at iobase 0x%lx irq %u\n", dev->name, dev->base_addr, dev->irq);
 
-	if (!dev || !yp || !yp->bitrate)
+	if (!dev || !yp->bitrate)
 		return -ENXIO;
 	if (!dev->base_addr || dev->base_addr > 0x1000 - YAM_EXTENT ||
 		dev->irq < 2 || dev->irq > 15) {
@@ -900,7 +899,7 @@
 	/* Reset overruns for all ports - FPGA programming makes overruns */
 	for (i = 0; i < NR_PORTS; i++) {
 		struct net_device *dev = yam_devs[i];
-		struct yam_port *yp = dev->priv;
+		struct yam_port *yp = netdev_priv(dev);
 		inb(LSR(dev->base_addr));
 		yp->stats.rx_fifo_errors = 0;
 	}
@@ -919,10 +918,11 @@
 static int yam_close(struct net_device *dev)
 {
 	struct sk_buff *skb;
-	struct yam_port *yp = (struct yam_port *) dev->priv;
+	struct yam_port *yp = netdev_priv(dev);
 
-	if (!dev || !yp)
+	if (!dev)
 		return -EINVAL;
+
 	/*
 	 * disable interrupts
 	 */
@@ -944,7 +944,7 @@
 
 static int yam_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
-	struct yam_port *yp = (struct yam_port *) dev->priv;
+	struct yam_port *yp = netdev_priv(dev);
 	struct yamdrv_ioctl_cfg yi;
 	struct yamdrv_ioctl_mcs *ym;
 	int ioctl_cmd;
@@ -952,7 +952,7 @@
 	if (copy_from_user(&ioctl_cmd, ifr->ifr_data, sizeof(int)))
 		 return -EFAULT;
 
-	if (yp == NULL || yp->magic != YAM_MAGIC)
+	if (yp->magic != YAM_MAGIC)
 		return -EINVAL;
 
 	if (!capable(CAP_NET_ADMIN))
@@ -1091,7 +1091,7 @@
 
 static void yam_setup(struct net_device *dev)
 {
-	struct yam_port *yp = dev->priv;
+	struct yam_port *yp = netdev_priv(dev);
 
 	yp->magic = YAM_MAGIC;
 	yp->bitrate = DEFAULT_BITRATE;
diff -Nru a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
--- a/drivers/net/mv643xx_eth.c	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/mv643xx_eth.c	2005-03-08 14:29:45 -05:00
@@ -1,5 +1,5 @@
 /*
- * drivers/net/mv64340_eth.c - Driver for MV64340X ethernet ports
+ * drivers/net/mv643xx_eth.c - Driver for MV643XX ethernet ports
  * Copyright (C) 2002 Matthew Dharm <mdharm@momenco.com>
  *
  * Based on the 64360 driver from:
@@ -10,6 +10,12 @@
  *
  * Copyright (C) 2003 Ralf Baechle <ralf@linux-mips.org>
  *
+ * Copyright (C) 2004-2005 MontaVista Software, Inc.
+ *			   Dale Farnsworth <dale@farnsworth.org>
+ *
+ * Copyright (C) 2004 Steven J. Hill <sjhill1@rockwellcollins.com>
+ *				     <sjhill@realitydiluted.com>
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
@@ -24,80 +30,100 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
-#include <linux/config.h>
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/config.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/fcntl.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/ip.h>
 #include <linux/init.h>
-#include <linux/in.h>
-#include <linux/pci.h>
-#include <linux/workqueue.h>
-#include <asm/smp.h>
-#include <linux/skbuff.h>
+#include <linux/dma-mapping.h>
 #include <linux/tcp.h>
-#include <linux/netdevice.h>
+#include <linux/udp.h>
 #include <linux/etherdevice.h>
-#include <net/ip.h>
 
 #include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/ethtool.h>
 #include <asm/io.h>
 #include <asm/types.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
+#include <asm/delay.h>
 #include "mv643xx_eth.h"
 
 /*
- * The first part is the high level driver of the gigE ethernet ports. 
+ * The first part is the high level driver of the gigE ethernet ports.
  */
 
-/* Definition for configuring driver */
-#undef MV64340_RX_QUEUE_FILL_ON_TASK
-
 /* Constants */
-#define EXTRA_BYTES 32
-#define WRAP       ETH_HLEN + 2 + 4 + 16
-#define BUFFER_MTU dev->mtu + WRAP
+#define VLAN_HLEN		4
+#define FCS_LEN			4
+#define WRAP			NET_IP_ALIGN + ETH_HLEN + VLAN_HLEN + FCS_LEN
+#define RX_SKB_SIZE		((dev->mtu + WRAP + 7) & ~0x7)
+
 #define INT_CAUSE_UNMASK_ALL		0x0007ffff
 #define INT_CAUSE_UNMASK_ALL_EXT	0x0011ffff
-#ifdef MV64340_RX_FILL_ON_TASK
+#ifdef MV643XX_RX_QUEUE_FILL_ON_TASK
 #define INT_CAUSE_MASK_ALL		0x00000000
 #define INT_CAUSE_CHECK_BITS		INT_CAUSE_UNMASK_ALL
 #define INT_CAUSE_CHECK_BITS_EXT	INT_CAUSE_UNMASK_ALL_EXT
 #endif
 
+#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
+#define MAX_DESCS_PER_SKB	(MAX_SKB_FRAGS + 1)
+#else
+#define MAX_DESCS_PER_SKB	1
+#endif
+
+#define PHY_WAIT_ITERATIONS	1000	/* 1000 iterations * 10uS = 10mS max */
+#define PHY_WAIT_MICRO_SECONDS	10
+
 /* Static function declarations */
-static int mv64340_eth_real_open(struct net_device *);
-static int mv64340_eth_real_stop(struct net_device *);
-static int mv64340_eth_change_mtu(struct net_device *, int);
-static struct net_device_stats *mv64340_eth_get_stats(struct net_device *);
+static int eth_port_link_is_up(unsigned int eth_port_num);
+static void eth_port_uc_addr_get(struct net_device *dev,
+						unsigned char *MacAddr);
+static int mv643xx_eth_real_open(struct net_device *);
+static int mv643xx_eth_real_stop(struct net_device *);
+static int mv643xx_eth_change_mtu(struct net_device *, int);
+static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *);
 static void eth_port_init_mac_tables(unsigned int eth_port_num);
-#ifdef MV64340_NAPI
-static int mv64340_poll(struct net_device *dev, int *budget);
+#ifdef MV643XX_NAPI
+static int mv643xx_poll(struct net_device *dev, int *budget);
 #endif
+static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr);
+static int ethernet_phy_detect(unsigned int eth_port_num);
+static struct ethtool_ops mv643xx_ethtool_ops;
+
+static char mv643xx_driver_name[] = "mv643xx_eth";
+static char mv643xx_driver_version[] = "1.0";
+
+static void __iomem *mv643xx_eth_shared_base;
+
+/* used to protect MV643XX_ETH_SMI_REG, which is shared across ports */
+static spinlock_t mv643xx_eth_phy_lock = SPIN_LOCK_UNLOCKED;
+
+static inline u32 mv_read(int offset)
+{
+	void *__iomem reg_base;
+
+	reg_base = mv643xx_eth_shared_base - MV643XX_ETH_SHARED_REGS;
+
+	return readl(reg_base + offset);
+}
+
+static inline void mv_write(int offset, u32 data)
+{
+	void * __iomem reg_base;
 
-unsigned char prom_mac_addr_base[6];
-unsigned long mv64340_sram_base;
+	reg_base = mv643xx_eth_shared_base - MV643XX_ETH_SHARED_REGS;
+	writel(data, reg_base + offset);
+}
 
 /*
  * Changes MTU (maximum transfer unit) of the gigabit ethenret port
  *
- * Input : pointer to ethernet interface network device structure
- *         new mtu size 
- * Output : 0 upon success, -EINVAL upon failure
+ * Input :	pointer to ethernet interface network device structure
+ *		new mtu size
+ * Output :	0 upon success, -EINVAL upon failure
  */
-static int mv64340_eth_change_mtu(struct net_device *dev, int new_mtu)
+static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu)
 {
-	struct mv64340_private *mp = netdev_priv(dev);
+	struct mv643xx_private *mp = netdev_priv(dev);
 	unsigned long flags;
 
 	spin_lock_irqsave(&mp->lock, flags);
@@ -108,21 +134,21 @@
 	}
 
 	dev->mtu = new_mtu;
-	/* 
+	/*
 	 * Stop then re-open the interface. This will allocate RX skb's with
 	 * the new MTU.
 	 * There is a possible danger that the open will not successed, due
 	 * to memory is full, which might fail the open function.
 	 */
 	if (netif_running(dev)) {
-		if (mv64340_eth_real_stop(dev))
+		if (mv643xx_eth_real_stop(dev))
 			printk(KERN_ERR
-			       "%s: Fatal error on stopping device\n",
-			       dev->name);
-		if (mv64340_eth_real_open(dev))
+				"%s: Fatal error on stopping device\n",
+				dev->name);
+		if (mv643xx_eth_real_open(dev))
 			printk(KERN_ERR
-			       "%s: Fatal error on opening device\n",
-			       dev->name);
+				"%s: Fatal error on opening device\n",
+				dev->name);
 	}
 
 	spin_unlock_irqrestore(&mp->lock, flags);
@@ -130,17 +156,17 @@
 }
 
 /*
- * mv64340_eth_rx_task
- *								       
+ * mv643xx_eth_rx_task
+ *
  * Fills / refills RX queue on a certain gigabit ethernet port
  *
- * Input : pointer to ethernet interface network device structure
- * Output : N/A
+ * Input :	pointer to ethernet interface network device structure
+ * Output :	N/A
  */
-static void mv64340_eth_rx_task(void *data)
+static void mv643xx_eth_rx_task(void *data)
 {
-	struct net_device *dev = (struct net_device *) data;
-	struct mv64340_private *mp = netdev_priv(dev);
+	struct net_device *dev = (struct net_device *)data;
+	struct mv643xx_private *mp = netdev_priv(dev);
 	struct pkt_info pkt_info;
 	struct sk_buff *skb;
 
@@ -148,28 +174,18 @@
 		panic("%s: Error in test_set_bit / clear_bit", dev->name);
 
 	while (mp->rx_ring_skbs < (mp->rx_ring_size - 5)) {
-		/* The +8 for buffer allignment and another 32 byte extra */
-
-		skb = dev_alloc_skb(BUFFER_MTU + 8 + EXTRA_BYTES);
+		skb = dev_alloc_skb(RX_SKB_SIZE);
 		if (!skb)
-			/* Better luck next time */
 			break;
 		mp->rx_ring_skbs++;
 		pkt_info.cmd_sts = ETH_RX_ENABLE_INTERRUPT;
-		pkt_info.byte_cnt = dev->mtu + ETH_HLEN + 4 + 2 + EXTRA_BYTES;
-		/* Allign buffer to 8 bytes */
-		if (pkt_info.byte_cnt & ~0x7) {
-			pkt_info.byte_cnt &= ~0x7;
-			pkt_info.byte_cnt += 8;
-		}
-		pkt_info.buf_ptr =
-		    pci_map_single(0, skb->data,
-				   dev->mtu + ETH_HLEN + 4 + 2 + EXTRA_BYTES,
-				   PCI_DMA_FROMDEVICE);
+		pkt_info.byte_cnt = RX_SKB_SIZE;
+		pkt_info.buf_ptr = dma_map_single(NULL, skb->data, RX_SKB_SIZE,
+							DMA_FROM_DEVICE);
 		pkt_info.return_info = skb;
 		if (eth_rx_return_buff(mp, &pkt_info) != ETH_OK) {
 			printk(KERN_ERR
-			       "%s: Error allocating RX Ring\n", dev->name);
+				"%s: Error allocating RX Ring\n", dev->name);
 			break;
 		}
 		skb_reserve(skb, 2);
@@ -186,46 +202,45 @@
 		add_timer(&mp->timeout);
 		mp->rx_timer_flag = 1;
 	}
-#if MV64340_RX_QUEUE_FILL_ON_TASK
+#ifdef MV643XX_RX_QUEUE_FILL_ON_TASK
 	else {
 		/* Return interrupts */
-		MV_WRITE(MV64340_ETH_INTERRUPT_MASK_REG(mp->port_num),
-			 INT_CAUSE_UNMASK_ALL);
+		mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(mp->port_num),
+							INT_CAUSE_UNMASK_ALL);
 	}
 #endif
 }
 
 /*
- * mv64340_eth_rx_task_timer_wrapper
- *								       
+ * mv643xx_eth_rx_task_timer_wrapper
+ *
  * Timer routine to wake up RX queue filling task. This function is
  * used only in case the RX queue is empty, and all alloc_skb has
  * failed (due to out of memory event).
  *
- * Input : pointer to ethernet interface network device structure
- * Output : N/A
+ * Input :	pointer to ethernet interface network device structure
+ * Output :	N/A
  */
-static void mv64340_eth_rx_task_timer_wrapper(unsigned long data)
+static void mv643xx_eth_rx_task_timer_wrapper(unsigned long data)
 {
-	struct net_device *dev = (struct net_device *) data;
-	struct mv64340_private *mp = netdev_priv(dev);
+	struct net_device *dev = (struct net_device *)data;
+	struct mv643xx_private *mp = netdev_priv(dev);
 
 	mp->rx_timer_flag = 0;
-	mv64340_eth_rx_task((void *) data);
+	mv643xx_eth_rx_task((void *)data);
 }
 
-
 /*
- * mv64340_eth_update_mac_address
- *								       
+ * mv643xx_eth_update_mac_address
+ *
  * Update the MAC address of the port in the address table
  *
- * Input : pointer to ethernet interface network device structure
- * Output : N/A
+ * Input :	pointer to ethernet interface network device structure
+ * Output :	N/A
  */
-static void mv64340_eth_update_mac_address(struct net_device *dev)
+static void mv643xx_eth_update_mac_address(struct net_device *dev)
 {
-	struct mv64340_private *mp = netdev_priv(dev);
+	struct mv643xx_private *mp = netdev_priv(dev);
 	unsigned int port_num = mp->port_num;
 
 	eth_port_init_mac_tables(port_num);
@@ -234,64 +249,59 @@
 }
 
 /*
- * mv64340_eth_set_rx_mode
- *								       
+ * mv643xx_eth_set_rx_mode
+ *
  * Change from promiscuos to regular rx mode
  *
- * Input : pointer to ethernet interface network device structure
- * Output : N/A
+ * Input :	pointer to ethernet interface network device structure
+ * Output :	N/A
  */
-static void mv64340_eth_set_rx_mode(struct net_device *dev)
+static void mv643xx_eth_set_rx_mode(struct net_device *dev)
 {
-	struct mv64340_private *mp = netdev_priv(dev);
+	struct mv643xx_private *mp = netdev_priv(dev);
+	u32 config_reg;
 
-	if (dev->flags & IFF_PROMISC) {
-		ethernet_set_config_reg
-		    (mp->port_num,
-		     ethernet_get_config_reg(mp->port_num) |
-		     ETH_UNICAST_PROMISCUOUS_MODE);
-	} else {
-		ethernet_set_config_reg
-		    (mp->port_num,
-		     ethernet_get_config_reg(mp->port_num) &
-		     ~(unsigned int) ETH_UNICAST_PROMISCUOUS_MODE);
-	}
+	config_reg = ethernet_get_config_reg(mp->port_num);
+	if (dev->flags & IFF_PROMISC)
+		config_reg |= (u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
+	else
+		config_reg &= ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
+	ethernet_set_config_reg(mp->port_num, config_reg);
 }
 
-
 /*
- * mv64340_eth_set_mac_address
- *								       
+ * mv643xx_eth_set_mac_address
+ *
  * Change the interface's mac address.
  * No special hardware thing should be done because interface is always
  * put in promiscuous mode.
  *
- * Input : pointer to ethernet interface network device structure and
- *         a pointer to the designated entry to be added to the cache.
- * Output : zero upon success, negative upon failure
+ * Input :	pointer to ethernet interface network device structure and
+ *		a pointer to the designated entry to be added to the cache.
+ * Output :	zero upon success, negative upon failure
  */
-static int mv64340_eth_set_mac_address(struct net_device *dev, void *addr)
+static int mv643xx_eth_set_mac_address(struct net_device *dev, void *addr)
 {
 	int i;
 
 	for (i = 0; i < 6; i++)
 		/* +2 is for the offset of the HW addr type */
-		dev->dev_addr[i] = ((unsigned char *) addr)[i + 2];
-	mv64340_eth_update_mac_address(dev);
+		dev->dev_addr[i] = ((unsigned char *)addr)[i + 2];
+	mv643xx_eth_update_mac_address(dev);
 	return 0;
 }
 
 /*
- * mv64340_eth_tx_timeout
- *								       
+ * mv643xx_eth_tx_timeout
+ *
  * Called upon a timeout on transmitting a packet
  *
- * Input : pointer to ethernet interface network device structure.
- * Output : N/A
+ * Input :	pointer to ethernet interface network device structure.
+ * Output :	N/A
  */
-static void mv64340_eth_tx_timeout(struct net_device *dev)
+static void mv643xx_eth_tx_timeout(struct net_device *dev)
 {
-	struct mv64340_private *mp = netdev_priv(dev);
+	struct mv643xx_private *mp = netdev_priv(dev);
 
 	printk(KERN_INFO "%s: TX timeout  ", dev->name);
 
@@ -300,31 +310,31 @@
 }
 
 /*
- * mv64340_eth_tx_timeout_task
+ * mv643xx_eth_tx_timeout_task
  *
  * Actual routine to reset the adapter when a timeout on Tx has occurred
  */
-static void mv64340_eth_tx_timeout_task(struct net_device *dev)
+static void mv643xx_eth_tx_timeout_task(struct net_device *dev)
 {
-        struct mv64340_private *mp = netdev_priv(dev);
+	struct mv643xx_private *mp = netdev_priv(dev);
 
-        netif_device_detach(dev);
-        eth_port_reset(mp->port_num);
-        eth_port_start(mp);
-        netif_device_attach(dev);
+	netif_device_detach(dev);
+	eth_port_reset(mp->port_num);
+	eth_port_start(mp);
+	netif_device_attach(dev);
 }
 
 /*
- * mv64340_eth_free_tx_queue
+ * mv643xx_eth_free_tx_queue
  *
- * Input : dev - a pointer to the required interface
+ * Input :	dev - a pointer to the required interface
  *
- * Output : 0 if was able to release skb , nonzero otherwise
+ * Output :	0 if was able to release skb , nonzero otherwise
  */
-static int mv64340_eth_free_tx_queue(struct net_device *dev,
-			      unsigned int eth_int_cause_ext)
+static int mv643xx_eth_free_tx_queue(struct net_device *dev,
+					unsigned int eth_int_cause_ext)
 {
-	struct mv64340_private *mp = netdev_priv(dev);
+	struct mv643xx_private *mp = netdev_priv(dev);
 	struct net_device_stats *stats = &mp->stats;
 	struct pkt_info pkt_info;
 	int released = 1;
@@ -341,33 +351,36 @@
 			stats->tx_errors++;
 		}
 
-		/* 
+		/*
 		 * If return_info is different than 0, release the skb.
 		 * The case where return_info is not 0 is only in case
 		 * when transmitted a scatter/gather packet, where only
 		 * last skb releases the whole chain.
 		 */
 		if (pkt_info.return_info) {
-			dev_kfree_skb_irq((struct sk_buff *)
-					  pkt_info.return_info);
-			released = 0;
 			if (skb_shinfo(pkt_info.return_info)->nr_frags)
-				pci_unmap_page(NULL, pkt_info.buf_ptr,
-					pkt_info.byte_cnt, PCI_DMA_TODEVICE);
+				dma_unmap_page(NULL, pkt_info.buf_ptr,
+						pkt_info.byte_cnt,
+						DMA_TO_DEVICE);
+			else
+				dma_unmap_single(NULL, pkt_info.buf_ptr,
+						pkt_info.byte_cnt,
+						DMA_TO_DEVICE);
 
-			if (mp->tx_ring_skbs != 1)
-				mp->tx_ring_skbs--;
-		} else 
-			pci_unmap_page(NULL, pkt_info.buf_ptr,
-					pkt_info.byte_cnt, PCI_DMA_TODEVICE);
-
-		/* 
-		 * Decrement the number of outstanding skbs counter on
-		 * the TX queue.
-		 */
-		if (mp->tx_ring_skbs == 0)
-			panic("ERROR - TX outstanding SKBs counter is corrupted");
+			dev_kfree_skb_irq(pkt_info.return_info);
+			released = 0;
 
+			/*
+			 * Decrement the number of outstanding skbs counter on
+			 * the TX queue.
+			 */
+			if (mp->tx_ring_skbs == 0)
+				panic("ERROR - TX outstanding SKBs"
+						" counter is corrupted");
+			mp->tx_ring_skbs--;
+		} else
+			dma_unmap_page(NULL, pkt_info.buf_ptr,
+					pkt_info.byte_cnt, DMA_TO_DEVICE);
 	}
 
 	spin_unlock(&mp->lock);
@@ -376,60 +389,59 @@
 }
 
 /*
- * mv64340_eth_receive
+ * mv643xx_eth_receive
  *
  * This function is forward packets that are received from the port's
  * queues toward kernel core or FastRoute them to another interface.
  *
- * Input : dev - a pointer to the required interface
- *         max - maximum number to receive (0 means unlimted)
+ * Input :	dev - a pointer to the required interface
+ *		max - maximum number to receive (0 means unlimted)
  *
- * Output : number of served packets
+ * Output :	number of served packets
  */
-#ifdef MV64340_NAPI
-static int mv64340_eth_receive_queue(struct net_device *dev, unsigned int max,
-								int budget)
+#ifdef MV643XX_NAPI
+static int mv643xx_eth_receive_queue(struct net_device *dev, int budget)
 #else
-static int mv64340_eth_receive_queue(struct net_device *dev, unsigned int max)
+static int mv643xx_eth_receive_queue(struct net_device *dev)
 #endif
 {
-	struct mv64340_private *mp = netdev_priv(dev);
+	struct mv643xx_private *mp = netdev_priv(dev);
 	struct net_device_stats *stats = &mp->stats;
 	unsigned int received_packets = 0;
 	struct sk_buff *skb;
 	struct pkt_info pkt_info;
 
-#ifdef MV64340_NAPI
+#ifdef MV643XX_NAPI
 	while (eth_port_receive(mp, &pkt_info) == ETH_OK && budget > 0) {
 #else
-	while ((--max) && eth_port_receive(mp, &pkt_info) == ETH_OK) {
+	while (eth_port_receive(mp, &pkt_info) == ETH_OK) {
 #endif
 		mp->rx_ring_skbs--;
 		received_packets++;
-#ifdef MV64340_NAPI
+#ifdef MV643XX_NAPI
 		budget--;
 #endif
 		/* Update statistics. Note byte count includes 4 byte CRC count */
 		stats->rx_packets++;
 		stats->rx_bytes += pkt_info.byte_cnt;
-		skb = (struct sk_buff *) pkt_info.return_info;
+		skb = pkt_info.return_info;
 		/*
 		 * In case received a packet without first / last bits on OR
 		 * the error summary bit is on, the packets needs to be dropeed.
 		 */
 		if (((pkt_info.cmd_sts
-		      & (ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC)) !=
-		     (ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC))
-		    || (pkt_info.cmd_sts & ETH_ERROR_SUMMARY)) {
+				& (ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC)) !=
+					(ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC))
+				|| (pkt_info.cmd_sts & ETH_ERROR_SUMMARY)) {
 			stats->rx_dropped++;
 			if ((pkt_info.cmd_sts & (ETH_RX_FIRST_DESC |
-						 ETH_RX_LAST_DESC)) !=
-			    (ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC)) {
+							ETH_RX_LAST_DESC)) !=
+				(ETH_RX_FIRST_DESC | ETH_RX_LAST_DESC)) {
 				if (net_ratelimit())
 					printk(KERN_ERR
-					       "%s: Received packet spread on multiple"
-					       " descriptors\n",
-					       dev->name);
+						"%s: Received packet spread "
+						"on multiple descriptors\n",
+						dev->name);
 			}
 			if (pkt_info.cmd_sts & ETH_ERROR_SUMMARY)
 				stats->rx_errors++;
@@ -445,11 +457,11 @@
 
 			if (pkt_info.cmd_sts & ETH_LAYER_4_CHECKSUM_OK) {
 				skb->ip_summed = CHECKSUM_UNNECESSARY;
-				skb->csum = htons((pkt_info.cmd_sts
-							& 0x0007fff8) >> 3);
+				skb->csum = htons(
+					(pkt_info.cmd_sts & 0x0007fff8) >> 3);
 			}
 			skb->protocol = eth_type_trans(skb, dev);
-#ifdef MV64340_NAPI
+#ifdef MV643XX_NAPI
 			netif_receive_skb(skb);
 #else
 			netif_rx(skb);
@@ -461,74 +473,74 @@
 }
 
 /*
- * mv64340_eth_int_handler
+ * mv643xx_eth_int_handler
  *
  * Main interrupt handler for the gigbit ethernet ports
  *
- * Input : irq - irq number (not used)
- *         dev_id - a pointer to the required interface's data structure
- *         regs   - not used
- * Output : N/A
+ * Input :	irq	- irq number (not used)
+ *		dev_id	- a pointer to the required interface's data structure
+ *		regs	- not used
+ * Output :	N/A
  */
 
-static irqreturn_t mv64340_eth_int_handler(int irq, void *dev_id,
-	struct pt_regs *regs)
+static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id,
+							struct pt_regs *regs)
 {
-	struct net_device *dev = (struct net_device *) dev_id;
-	struct mv64340_private *mp = netdev_priv(dev);
+	struct net_device *dev = (struct net_device *)dev_id;
+	struct mv643xx_private *mp = netdev_priv(dev);
 	u32 eth_int_cause, eth_int_cause_ext = 0;
 	unsigned int port_num = mp->port_num;
 
 	/* Read interrupt cause registers */
-	eth_int_cause = MV_READ(MV64340_ETH_INTERRUPT_CAUSE_REG(port_num)) &
-			INT_CAUSE_UNMASK_ALL;
+	eth_int_cause = mv_read(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num)) &
+						INT_CAUSE_UNMASK_ALL;
 
 	if (eth_int_cause & BIT1)
-		eth_int_cause_ext =
-		MV_READ(MV64340_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num)) &
-		INT_CAUSE_UNMASK_ALL_EXT;
+		eth_int_cause_ext = mv_read(
+			MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num)) &
+						INT_CAUSE_UNMASK_ALL_EXT;
 
-#ifdef MV64340_NAPI
+#ifdef MV643XX_NAPI
 	if (!(eth_int_cause & 0x0007fffd)) {
-	/* Dont ack the Rx interrupt */
+		/* Dont ack the Rx interrupt */
 #endif
 		/*
-	 	 * Clear specific ethernet port intrerrupt registers by
+		 * Clear specific ethernet port intrerrupt registers by
 		 * acknowleding relevant bits.
 		 */
-		MV_WRITE(MV64340_ETH_INTERRUPT_CAUSE_REG(port_num),
-			 ~eth_int_cause);
+		mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num),
+							~eth_int_cause);
 		if (eth_int_cause_ext != 0x0)
-			MV_WRITE(MV64340_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num),
-				 ~eth_int_cause_ext);
+			mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG
+					(port_num), ~eth_int_cause_ext);
 
 		/* UDP change : We may need this */
 		if ((eth_int_cause_ext & 0x0000ffff) &&
-		    (mv64340_eth_free_tx_queue(dev, eth_int_cause_ext) == 0) &&
-		    (MV64340_TX_QUEUE_SIZE > mp->tx_ring_skbs + 1))
-                                         netif_wake_queue(dev);
-#ifdef MV64340_NAPI
+		    (mv643xx_eth_free_tx_queue(dev, eth_int_cause_ext) == 0) &&
+		    (mp->tx_ring_size > mp->tx_ring_skbs + MAX_DESCS_PER_SKB))
+			netif_wake_queue(dev);
+#ifdef MV643XX_NAPI
 	} else {
 		if (netif_rx_schedule_prep(dev)) {
 			/* Mask all the interrupts */
-			MV_WRITE(MV64340_ETH_INTERRUPT_MASK_REG(port_num),0);
-			MV_WRITE(MV64340_ETH_INTERRUPT_EXTEND_MASK_REG(port_num), 0);
+			mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), 0);
+			mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG
+								(port_num), 0);
 			__netif_rx_schedule(dev);
 		}
 #else
-		{
 		if (eth_int_cause & (BIT2 | BIT11))
-			mv64340_eth_receive_queue(dev, 0);
+			mv643xx_eth_receive_queue(dev, 0);
 
 		/*
-		 * After forwarded received packets to upper layer,  add a task
+		 * After forwarded received packets to upper layer, add a task
 		 * in an interrupts enabled context that refills the RX ring
 		 * with skb's.
 		 */
-#if MV64340_RX_QUEUE_FILL_ON_TASK
+#ifdef MV643XX_RX_QUEUE_FILL_ON_TASK
 		/* Unmask all interrupts on ethernet port */
-		MV_WRITE(MV64340_ETH_INTERRUPT_MASK_REG(port_num),
-		         INT_CAUSE_MASK_ALL);
+		mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
+							INT_CAUSE_MASK_ALL);
 		queue_task(&mp->rx_task, &tq_immediate);
 		mark_bh(IMMEDIATE_BH);
 #else
@@ -538,25 +550,15 @@
 	}
 	/* PHY status changed */
 	if (eth_int_cause_ext & (BIT16 | BIT20)) {
-		unsigned int phy_reg_data;
-
-		/* Check Link status on ethernet port */
-		eth_port_read_smi_reg(port_num, 1, &phy_reg_data);
-		if (!(phy_reg_data & 0x20)) {
-			netif_stop_queue(dev);
-		} else {
+		if (eth_port_link_is_up(port_num)) {
+			netif_carrier_on(dev);
 			netif_wake_queue(dev);
-
-			/*
-			 * Start all TX queues on ethernet port. This is good in
-			 * case of previous packets where not transmitted, due
-			 * to link down and this command re-enables all TX
-			 * queues.
-			 * Note that it is possible to get a TX resource error
-			 * interrupt after issuing this, since not all TX queues
-			 * are enabled, or has anything to send.
-			 */
-			MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), 1);
+			/* Start TX queue */
+			mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG
+								(port_num), 1);
+		} else {
+			netif_carrier_off(dev);
+			netif_stop_queue(dev);
 		}
 	}
 
@@ -570,7 +572,7 @@
 	return IRQ_HANDLED;
 }
 
-#ifdef MV64340_COAL
+#ifdef MV643XX_COAL
 
 /*
  * eth_port_set_rx_coal - Sets coalescing interrupt mechanism on RX path
@@ -584,9 +586,9 @@
  *	, and the required delay of the interrupt in usec.
  *
  * INPUT:
- *	unsigned int eth_port_num      Ethernet port number
- *	unsigned int t_clk        t_clk of the MV-643xx chip in HZ units
- *	unsigned int delay       Delay in usec
+ *	unsigned int eth_port_num	Ethernet port number
+ *	unsigned int t_clk		t_clk of the MV-643xx chip in HZ units
+ *	unsigned int delay		Delay in usec
  *
  * OUTPUT:
  *	Interrupt coalescing mechanism value is set in MV-643xx chip.
@@ -596,15 +598,15 @@
  *
  */
 static unsigned int eth_port_set_rx_coal(unsigned int eth_port_num,
-	unsigned int t_clk, unsigned int delay)
+					unsigned int t_clk, unsigned int delay)
 {
 	unsigned int coal = ((t_clk / 1000000) * delay) / 64;
 
 	/* Set RX Coalescing mechanism */
-	MV_WRITE(MV64340_ETH_SDMA_CONFIG_REG(eth_port_num),
-		 ((coal & 0x3fff) << 8) |
-		 (MV_READ(MV64340_ETH_SDMA_CONFIG_REG(eth_port_num))
-		  & 0xffc000ff));
+	mv_write(MV643XX_ETH_SDMA_CONFIG_REG(eth_port_num),
+		((coal & 0x3fff) << 8) |
+		(mv_read(MV643XX_ETH_SDMA_CONFIG_REG(eth_port_num))
+			& 0xffc000ff));
 
 	return coal;
 }
@@ -618,13 +620,13 @@
  *	This parameter is a timeout counter, that counts in 64 t_clk
  *	chunks ; that when timeout event occurs a maskable interrupt
  *	occurs.
- *	The parameter is calculated using the t_cLK frequency of the 
+ *	The parameter is calculated using the t_cLK frequency of the
  *	MV-643xx chip and the required delay in the interrupt in uSec
  *
  * INPUT:
- *	unsigned int eth_port_num      Ethernet port number
- *	unsigned int t_clk        t_clk of the MV-643xx chip in HZ units
- *	unsigned int delay       Delay in uSeconds
+ *	unsigned int eth_port_num	Ethernet port number
+ *	unsigned int t_clk		t_clk of the MV-643xx chip in HZ units
+ *	unsigned int delay		Delay in uSeconds
  *
  * OUTPUT:
  *	Interrupt coalescing mechanism value is set in MV-643xx chip.
@@ -634,48 +636,48 @@
  *
  */
 static unsigned int eth_port_set_tx_coal(unsigned int eth_port_num,
-	unsigned int t_clk, unsigned int delay)
+					unsigned int t_clk, unsigned int delay)
 {
 	unsigned int coal;
 	coal = ((t_clk / 1000000) * delay) / 64;
 	/* Set TX Coalescing mechanism */
-	MV_WRITE(MV64340_ETH_TX_FIFO_URGENT_THRESHOLD_REG(eth_port_num),
-		 coal << 4);
+	mv_write(MV643XX_ETH_TX_FIFO_URGENT_THRESHOLD_REG(eth_port_num),
+								coal << 4);
 	return coal;
 }
 
 /*
- * mv64340_eth_open
+ * mv643xx_eth_open
  *
  * This function is called when openning the network device. The function
  * should initialize all the hardware, initialize cyclic Rx/Tx
  * descriptors chain and buffers and allocate an IRQ to the network
  * device.
  *
- * Input : a pointer to the network device structure
+ * Input :	a pointer to the network device structure
  *
- * Output : zero of success , nonzero if fails.
+ * Output :	zero of success , nonzero if fails.
  */
 
-static int mv64340_eth_open(struct net_device *dev)
+static int mv643xx_eth_open(struct net_device *dev)
 {
-	struct mv64340_private *mp = netdev_priv(dev);
+	struct mv643xx_private *mp = netdev_priv(dev);
 	unsigned int port_num = mp->port_num;
-	int err = err;
+	int err;
 
 	spin_lock_irq(&mp->lock);
 
-	err = request_irq(dev->irq, mv64340_eth_int_handler,
-	                  SA_INTERRUPT | SA_SAMPLE_RANDOM, dev->name, dev);
+	err = request_irq(dev->irq, mv643xx_eth_int_handler,
+			SA_INTERRUPT | SA_SAMPLE_RANDOM, dev->name, dev);
 
 	if (err) {
-		printk(KERN_ERR "Can not assign IRQ number to MV64340_eth%d\n",
-		       port_num);
+		printk(KERN_ERR "Can not assign IRQ number to MV643XX_eth%d\n",
+								port_num);
 		err = -EAGAIN;
 		goto out;
 	}
 
-	if (mv64340_eth_real_open(dev)) {
+	if (mv643xx_eth_real_open(dev)) {
 		printk("%s: Error opening interface\n", dev->name);
 		err = -EBUSY;
 		goto out_free;
@@ -698,66 +700,35 @@
  * ether_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory.
  *
  * DESCRIPTION:
- *       This function prepares a Rx chained list of descriptors and packet 
- *       buffers in a form of a ring. The routine must be called after port 
- *       initialization routine and before port start routine. 
- *       The Ethernet SDMA engine uses CPU bus addresses to access the various 
- *       devices in the system (i.e. DRAM). This function uses the ethernet 
- *       struct 'virtual to physical' routine (set by the user) to set the ring 
- *       with physical addresses.
+ *	This function prepares a Rx chained list of descriptors and packet
+ *	buffers in a form of a ring. The routine must be called after port
+ *	initialization routine and before port start routine.
+ *	The Ethernet SDMA engine uses CPU bus addresses to access the various
+ *	devices in the system (i.e. DRAM). This function uses the ethernet
+ *	struct 'virtual to physical' routine (set by the user) to set the ring
+ *	with physical addresses.
  *
  * INPUT:
- *	struct mv64340_private   *mp   Ethernet Port Control srtuct. 
- *      int 			rx_desc_num       Number of Rx descriptors
- *      int 			rx_buff_size      Size of Rx buffer
- *      unsigned int    rx_desc_base_addr  Rx descriptors memory area base addr.
- *      unsigned int    rx_buff_base_addr  Rx buffer memory area base addr.
+ *	struct mv643xx_private *mp	Ethernet Port Control srtuct.
  *
  * OUTPUT:
- *      The routine updates the Ethernet port control struct with information 
- *      regarding the Rx descriptors and buffers.
+ *	The routine updates the Ethernet port control struct with information
+ *	regarding the Rx descriptors and buffers.
  *
  * RETURN:
- *      false if the given descriptors memory area is not aligned according to
- *      Ethernet SDMA specifications.
- *      true otherwise.
+ *	None.
  */
-static int ether_init_rx_desc_ring(struct mv64340_private * mp,
-	unsigned long rx_buff_base_addr)
+static void ether_init_rx_desc_ring(struct mv643xx_private *mp)
 {
-	unsigned long buffer_addr = rx_buff_base_addr;
 	volatile struct eth_rx_desc *p_rx_desc;
 	int rx_desc_num = mp->rx_ring_size;
-	unsigned long rx_desc_base_addr = (unsigned long) mp->p_rx_desc_area;
-	int rx_buff_size = 1536;	/* Dummy, will be replaced later */
 	int i;
 
-	p_rx_desc = (struct eth_rx_desc *) rx_desc_base_addr;
-
-	/* Rx desc Must be 4LW aligned (i.e. Descriptor_Address[3:0]=0000). */
-	if (rx_buff_base_addr & 0xf)
-		return 0;
-
-	/* Rx buffers are limited to 64K bytes and Minimum size is 8 bytes  */
-	if ((rx_buff_size < 8) || (rx_buff_size > RX_BUFFER_MAX_SIZE))
-		return 0;
-
-	/* Rx buffers must be 64-bit aligned.       */
-	if ((rx_buff_base_addr + rx_buff_size) & 0x7)
-		return 0;
-
-	/* initialize the Rx descriptors ring */
+	/* initialize the next_desc_ptr links in the Rx descriptors ring */
+	p_rx_desc = (struct eth_rx_desc *)mp->p_rx_desc_area;
 	for (i = 0; i < rx_desc_num; i++) {
-		p_rx_desc[i].buf_size = rx_buff_size;
-		p_rx_desc[i].byte_cnt = 0x0000;
-		p_rx_desc[i].cmd_sts =
-			ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT;
 		p_rx_desc[i].next_desc_ptr = mp->rx_desc_dma +
 			((i + 1) % rx_desc_num) * sizeof(struct eth_rx_desc);
-		p_rx_desc[i].buf_ptr = buffer_addr;
-
-		mp->rx_skb[i] = NULL;
-		buffer_addr += rx_buff_size;
 	}
 
 	/* Save Rx desc pointer to driver struct. */
@@ -766,293 +737,288 @@
 
 	mp->rx_desc_area_size = rx_desc_num * sizeof(struct eth_rx_desc);
 
+	/* Add the queue to the list of RX queues of this port */
 	mp->port_rx_queue_command |= 1;
-
-	return 1;
 }
 
 /*
  * ether_init_tx_desc_ring - Curve a Tx chain desc list and buffer in memory.
  *
  * DESCRIPTION:
- *       This function prepares a Tx chained list of descriptors and packet 
- *       buffers in a form of a ring. The routine must be called after port 
- *       initialization routine and before port start routine. 
- *       The Ethernet SDMA engine uses CPU bus addresses to access the various 
- *       devices in the system (i.e. DRAM). This function uses the ethernet 
- *       struct 'virtual to physical' routine (set by the user) to set the ring 
- *       with physical addresses.
+ *	This function prepares a Tx chained list of descriptors and packet
+ *	buffers in a form of a ring. The routine must be called after port
+ *	initialization routine and before port start routine.
+ *	The Ethernet SDMA engine uses CPU bus addresses to access the various
+ *	devices in the system (i.e. DRAM). This function uses the ethernet
+ *	struct 'virtual to physical' routine (set by the user) to set the ring
+ *	with physical addresses.
  *
  * INPUT:
- *	struct mv64340_private   *mp   Ethernet Port Control srtuct. 
- *      int 		tx_desc_num        Number of Tx descriptors
- *      int 		tx_buff_size	   Size of Tx buffer
- *      unsigned int    tx_desc_base_addr  Tx descriptors memory area base addr.
+ *	struct mv643xx_private *mp	Ethernet Port Control srtuct.
  *
  * OUTPUT:
- *      The routine updates the Ethernet port control struct with information 
- *      regarding the Tx descriptors and buffers.
+ *	The routine updates the Ethernet port control struct with information
+ *	regarding the Tx descriptors and buffers.
  *
  * RETURN:
- *      false if the given descriptors memory area is not aligned according to
- *      Ethernet SDMA specifications.
- *      true otherwise.
+ *	None.
  */
-static int ether_init_tx_desc_ring(struct mv64340_private *mp)
+static void ether_init_tx_desc_ring(struct mv643xx_private *mp)
 {
-	unsigned long tx_desc_base_addr = (unsigned long) mp->p_tx_desc_area;
 	int tx_desc_num = mp->tx_ring_size;
 	struct eth_tx_desc *p_tx_desc;
 	int i;
 
-	/* Tx desc Must be 4LW aligned (i.e. Descriptor_Address[3:0]=0000). */
-	if (tx_desc_base_addr & 0xf)
-		return 0;
-
-	/* save the first desc pointer to link with the last descriptor */
-	p_tx_desc = (struct eth_tx_desc *) tx_desc_base_addr;
-
-	/* Initialize the Tx descriptors ring */
+	/* Initialize the next_desc_ptr links in the Tx descriptors ring */
+	p_tx_desc = (struct eth_tx_desc *)mp->p_tx_desc_area;
 	for (i = 0; i < tx_desc_num; i++) {
-		p_tx_desc[i].byte_cnt	= 0x0000;
-		p_tx_desc[i].l4i_chk	= 0x0000;
-		p_tx_desc[i].cmd_sts	= 0x00000000;
 		p_tx_desc[i].next_desc_ptr = mp->tx_desc_dma +
 			((i + 1) % tx_desc_num) * sizeof(struct eth_tx_desc);
-		p_tx_desc[i].buf_ptr	= 0x00000000;
-		mp->tx_skb[i]		= NULL;
 	}
 
-	/* Set Tx desc pointer in driver struct. */
 	mp->tx_curr_desc_q = 0;
 	mp->tx_used_desc_q = 0;
-#ifdef MV64340_CHECKSUM_OFFLOAD_TX
-        mp->tx_first_desc_q = 0;
+#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
+	mp->tx_first_desc_q = 0;
 #endif
-	/* Init Tx ring base and size parameters */
-	mp->tx_desc_area_size	= tx_desc_num * sizeof(struct eth_tx_desc);
+
+	mp->tx_desc_area_size = tx_desc_num * sizeof(struct eth_tx_desc);
 
 	/* Add the queue to the list of Tx queues of this port */
 	mp->port_tx_queue_command |= 1;
-
-	return 1;
 }
 
-/* Helper function for mv64340_eth_open */
-static int mv64340_eth_real_open(struct net_device *dev)
+/* Helper function for mv643xx_eth_open */
+static int mv643xx_eth_real_open(struct net_device *dev)
 {
-	struct mv64340_private *mp = netdev_priv(dev);
+	struct mv643xx_private *mp = netdev_priv(dev);
 	unsigned int port_num = mp->port_num;
-	u32 phy_reg_data;
 	unsigned int size;
 
 	/* Stop RX Queues */
-	MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num),
-		 0x0000ff00);
+	mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), 0x0000ff00);
 
 	/* Clear the ethernet port interrupts */
-	MV_WRITE(MV64340_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
-	MV_WRITE(MV64340_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
+	mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
+	mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
 
 	/* Unmask RX buffer and TX end interrupt */
-	MV_WRITE(MV64340_ETH_INTERRUPT_MASK_REG(port_num),
-		 INT_CAUSE_UNMASK_ALL);
+	mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
+						INT_CAUSE_UNMASK_ALL);
 
 	/* Unmask phy and link status changes interrupts */
-	MV_WRITE(MV64340_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
-		 INT_CAUSE_UNMASK_ALL_EXT);
+	mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
+						INT_CAUSE_UNMASK_ALL_EXT);
 
 	/* Set the MAC Address */
 	memcpy(mp->port_mac_addr, dev->dev_addr, 6);
 
 	eth_port_init(mp);
 
-	INIT_WORK(&mp->rx_task, (void (*)(void *)) mv64340_eth_rx_task, dev);
+	INIT_WORK(&mp->rx_task, (void (*)(void *))mv643xx_eth_rx_task, dev);
 
 	memset(&mp->timeout, 0, sizeof(struct timer_list));
-	mp->timeout.function = mv64340_eth_rx_task_timer_wrapper;
-	mp->timeout.data = (unsigned long) dev;
+	mp->timeout.function = mv643xx_eth_rx_task_timer_wrapper;
+	mp->timeout.data = (unsigned long)dev;
 
 	mp->rx_task_busy = 0;
 	mp->rx_timer_flag = 0;
 
+	/* Allocate RX and TX skb rings */
+	mp->rx_skb = kmalloc(sizeof(*mp->rx_skb) * mp->rx_ring_size,
+								GFP_KERNEL);
+	if (!mp->rx_skb) {
+		printk(KERN_ERR "%s: Cannot allocate Rx skb ring\n", dev->name);
+		return -ENOMEM;
+	}
+	mp->tx_skb = kmalloc(sizeof(*mp->tx_skb) * mp->tx_ring_size,
+								GFP_KERNEL);
+	if (!mp->tx_skb) {
+		printk(KERN_ERR "%s: Cannot allocate Tx skb ring\n", dev->name);
+		kfree(mp->rx_skb);
+		return -ENOMEM;
+	}
+
 	/* Allocate TX ring */
 	mp->tx_ring_skbs = 0;
-	mp->tx_ring_size = MV64340_TX_QUEUE_SIZE;
 	size = mp->tx_ring_size * sizeof(struct eth_tx_desc);
 	mp->tx_desc_area_size = size;
 
-	/* Assumes allocated ring is 16 bytes alligned */
-	mp->p_tx_desc_area = pci_alloc_consistent(NULL, size, &mp->tx_desc_dma);
+	if (mp->tx_sram_size) {
+		mp->p_tx_desc_area = ioremap(mp->tx_sram_addr,
+							mp->tx_sram_size);
+		mp->tx_desc_dma = mp->tx_sram_addr;
+	} else
+		mp->p_tx_desc_area = dma_alloc_coherent(NULL, size,
+							&mp->tx_desc_dma,
+							GFP_KERNEL);
+
 	if (!mp->p_tx_desc_area) {
 		printk(KERN_ERR "%s: Cannot allocate Tx Ring (size %d bytes)\n",
-		       dev->name, size);
+							dev->name, size);
+		kfree(mp->rx_skb);
+		kfree(mp->tx_skb);
 		return -ENOMEM;
 	}
-	memset((void *) mp->p_tx_desc_area, 0, mp->tx_desc_area_size);
+	BUG_ON((u32) mp->p_tx_desc_area & 0xf);	/* check 16-byte alignment */
+	memset((void *)mp->p_tx_desc_area, 0, mp->tx_desc_area_size);
 
-	/* Dummy will be replaced upon real tx */
 	ether_init_tx_desc_ring(mp);
 
 	/* Allocate RX ring */
-	/* Meantime RX Ring are fixed - but must be configurable by user */
-	mp->rx_ring_size = MV64340_RX_QUEUE_SIZE;
 	mp->rx_ring_skbs = 0;
 	size = mp->rx_ring_size * sizeof(struct eth_rx_desc);
 	mp->rx_desc_area_size = size;
 
-	/* Assumes allocated ring is 16 bytes aligned */
-
-	mp->p_rx_desc_area = pci_alloc_consistent(NULL, size, &mp->rx_desc_dma);
+	if (mp->rx_sram_size) {
+		mp->p_rx_desc_area = ioremap(mp->rx_sram_addr,
+							mp->rx_sram_size);
+		mp->rx_desc_dma = mp->rx_sram_addr;
+	} else
+		mp->p_rx_desc_area = dma_alloc_coherent(NULL, size,
+							&mp->rx_desc_dma,
+							GFP_KERNEL);
 
 	if (!mp->p_rx_desc_area) {
 		printk(KERN_ERR "%s: Cannot allocate Rx ring (size %d bytes)\n",
-		       dev->name, size);
+							dev->name, size);
 		printk(KERN_ERR "%s: Freeing previously allocated TX queues...",
-		       dev->name);
-		pci_free_consistent(0, mp->tx_desc_area_size,
-				    (void *) mp->p_tx_desc_area,
-				    mp->tx_desc_dma);
+							dev->name);
+		if (mp->rx_sram_size)
+			iounmap(mp->p_rx_desc_area);
+		else
+			dma_free_coherent(NULL, mp->tx_desc_area_size,
+					mp->p_tx_desc_area, mp->tx_desc_dma);
+		kfree(mp->rx_skb);
+		kfree(mp->tx_skb);
 		return -ENOMEM;
 	}
-	memset(mp->p_rx_desc_area, 0, size);
+	memset((void *)mp->p_rx_desc_area, 0, size);
 
-	if (!(ether_init_rx_desc_ring(mp, 0)))
-		panic("%s: Error initializing RX Ring", dev->name);
+	ether_init_rx_desc_ring(mp);
 
-	mv64340_eth_rx_task(dev);	/* Fill RX ring with skb's */
+	mv643xx_eth_rx_task(dev);	/* Fill RX ring with skb's */
 
 	eth_port_start(mp);
 
 	/* Interrupt Coalescing */
 
-#ifdef MV64340_COAL
+#ifdef MV643XX_COAL
 	mp->rx_int_coal =
-		eth_port_set_rx_coal(port_num, 133000000, MV64340_RX_COAL);
+		eth_port_set_rx_coal(port_num, 133000000, MV643XX_RX_COAL);
 #endif
 
 	mp->tx_int_coal =
-		eth_port_set_tx_coal (port_num, 133000000, MV64340_TX_COAL);  
+		eth_port_set_tx_coal(port_num, 133000000, MV643XX_TX_COAL);
 
-	/* Increase the Rx side buffer size */
-
-	MV_WRITE (MV64340_ETH_PORT_SERIAL_CONTROL_REG(port_num), (0x5 << 17) |
-			(MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(port_num))
-					& 0xfff1ffff));
-
-	/* Check Link status on phy */
-	eth_port_read_smi_reg(port_num, 1, &phy_reg_data);
-	if (!(phy_reg_data & 0x20))
-		netif_stop_queue(dev);
-	else
-		netif_start_queue(dev);
+	netif_start_queue(dev);
 
 	return 0;
 }
 
-static void mv64340_eth_free_tx_rings(struct net_device *dev)
+static void mv643xx_eth_free_tx_rings(struct net_device *dev)
 {
-	struct mv64340_private *mp = netdev_priv(dev);
+	struct mv643xx_private *mp = netdev_priv(dev);
 	unsigned int port_num = mp->port_num;
 	unsigned int curr;
 
 	/* Stop Tx Queues */
-	MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num),
-		 0x0000ff00);
+	mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), 0x0000ff00);
 
-	/* Free TX rings */
 	/* Free outstanding skb's on TX rings */
-	for (curr = 0;
-	     (mp->tx_ring_skbs) && (curr < MV64340_TX_QUEUE_SIZE);
-	     curr++) {
+	for (curr = 0; mp->tx_ring_skbs && curr < mp->tx_ring_size; curr++) {
 		if (mp->tx_skb[curr]) {
 			dev_kfree_skb(mp->tx_skb[curr]);
 			mp->tx_ring_skbs--;
 		}
 	}
-	if (mp->tx_ring_skbs != 0)
+	if (mp->tx_ring_skbs)
 		printk("%s: Error on Tx descriptor free - could not free %d"
-		     " descriptors\n", dev->name,
-		     mp->tx_ring_skbs);
-	pci_free_consistent(0, mp->tx_desc_area_size,
-			    (void *) mp->p_tx_desc_area, mp->tx_desc_dma);
+				" descriptors\n", dev->name, mp->tx_ring_skbs);
+
+	/* Free TX ring */
+	if (mp->tx_sram_size)
+		iounmap(mp->p_tx_desc_area);
+	else
+		dma_free_coherent(NULL, mp->tx_desc_area_size,
+				mp->p_tx_desc_area, mp->tx_desc_dma);
 }
 
-static void mv64340_eth_free_rx_rings(struct net_device *dev)
+static void mv643xx_eth_free_rx_rings(struct net_device *dev)
 {
-	struct mv64340_private *mp = netdev_priv(dev);
+	struct mv643xx_private *mp = netdev_priv(dev);
 	unsigned int port_num = mp->port_num;
 	int curr;
 
 	/* Stop RX Queues */
-	MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num),
-		 0x0000ff00);
+	mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), 0x0000ff00);
 
-	/* Free RX rings */
 	/* Free preallocated skb's on RX rings */
-	for (curr = 0;
-		mp->rx_ring_skbs && (curr < MV64340_RX_QUEUE_SIZE);
-		curr++) {
+	for (curr = 0; mp->rx_ring_skbs && curr < mp->rx_ring_size; curr++) {
 		if (mp->rx_skb[curr]) {
 			dev_kfree_skb(mp->rx_skb[curr]);
 			mp->rx_ring_skbs--;
 		}
 	}
 
-	if (mp->rx_ring_skbs != 0)
+	if (mp->rx_ring_skbs)
 		printk(KERN_ERR
-		       "%s: Error in freeing Rx Ring. %d skb's still"
-		       " stuck in RX Ring - ignoring them\n", dev->name,
-		       mp->rx_ring_skbs);
-	pci_free_consistent(0, mp->rx_desc_area_size,
-			    (void *) mp->p_rx_desc_area,
-			    mp->rx_desc_dma);
+			"%s: Error in freeing Rx Ring. %d skb's still"
+			" stuck in RX Ring - ignoring them\n", dev->name,
+			mp->rx_ring_skbs);
+	/* Free RX ring */
+	if (mp->rx_sram_size)
+		iounmap(mp->p_rx_desc_area);
+	else
+		dma_free_coherent(NULL, mp->rx_desc_area_size,
+				mp->p_rx_desc_area, mp->rx_desc_dma);
 }
 
 /*
- * mv64340_eth_stop
+ * mv643xx_eth_stop
  *
- * This function is used when closing the network device. 
- * It updates the hardware, 
+ * This function is used when closing the network device.
+ * It updates the hardware,
  * release all memory that holds buffers and descriptors and release the IRQ.
- * Input : a pointer to the device structure
- * Output : zero if success , nonzero if fails
+ * Input :	a pointer to the device structure
+ * Output :	zero if success , nonzero if fails
  */
 
-/* Helper function for mv64340_eth_stop */
+/* Helper function for mv643xx_eth_stop */
 
-static int mv64340_eth_real_stop(struct net_device *dev)
+static int mv643xx_eth_real_stop(struct net_device *dev)
 {
-	struct mv64340_private *mp = netdev_priv(dev);
+	struct mv643xx_private *mp = netdev_priv(dev);
 	unsigned int port_num = mp->port_num;
 
+	netif_carrier_off(dev);
 	netif_stop_queue(dev);
 
-	mv64340_eth_free_tx_rings(dev);
-	mv64340_eth_free_rx_rings(dev);
+	mv643xx_eth_free_tx_rings(dev);
+	mv643xx_eth_free_rx_rings(dev);
 
 	eth_port_reset(mp->port_num);
 
 	/* Disable ethernet port interrupts */
-	MV_WRITE(MV64340_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
-	MV_WRITE(MV64340_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
+	mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
+	mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
 
 	/* Mask RX buffer and TX end interrupt */
-	MV_WRITE(MV64340_ETH_INTERRUPT_MASK_REG(port_num), 0);
+	mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), 0);
 
 	/* Mask phy and link status changes interrupts */
-	MV_WRITE(MV64340_ETH_INTERRUPT_EXTEND_MASK_REG(port_num), 0);
+	mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num), 0);
 
 	return 0;
 }
 
-static int mv64340_eth_stop(struct net_device *dev)
+static int mv643xx_eth_stop(struct net_device *dev)
 {
-	struct mv64340_private *mp = netdev_priv(dev);
+	struct mv643xx_private *mp = netdev_priv(dev);
 
 	spin_lock_irq(&mp->lock);
 
-	mv64340_eth_real_stop(dev);
+	mv643xx_eth_real_stop(dev);
 
 	free_irq(dev->irq, dev);
 	spin_unlock_irq(&mp->lock);
@@ -1060,59 +1026,64 @@
 	return 0;
 }
 
-#ifdef MV64340_NAPI
-static void mv64340_tx(struct net_device *dev)
+#ifdef MV643XX_NAPI
+static void mv643xx_tx(struct net_device *dev)
 {
-	struct mv64340_private *mp = netdev_priv(dev);
-        struct pkt_info pkt_info;
+	struct mv643xx_private *mp = netdev_priv(dev);
+	struct pkt_info pkt_info;
 
 	while (eth_tx_return_desc(mp, &pkt_info) == ETH_OK) {
 		if (pkt_info.return_info) {
-			dev_kfree_skb_irq((struct sk_buff *)
-                                                  pkt_info.return_info);
-			if (skb_shinfo(pkt_info.return_info)->nr_frags) 
-                                 pci_unmap_page(NULL, pkt_info.buf_ptr,
-                                             pkt_info.byte_cnt,
-                                             PCI_DMA_TODEVICE);
-
-                         if (mp->tx_ring_skbs != 1)
-                                  mp->tx_ring_skbs--;
-                } else 
-                       pci_unmap_page(NULL, pkt_info.buf_ptr, pkt_info.byte_cnt,
-                                      PCI_DMA_TODEVICE);
+			if (skb_shinfo(pkt_info.return_info)->nr_frags)
+				dma_unmap_page(NULL, pkt_info.buf_ptr,
+						pkt_info.byte_cnt,
+						DMA_TO_DEVICE);
+			else
+				dma_unmap_single(NULL, pkt_info.buf_ptr,
+						pkt_info.byte_cnt,
+						DMA_TO_DEVICE);
+
+			dev_kfree_skb_irq(pkt_info.return_info);
+
+			if (mp->tx_ring_skbs)
+				mp->tx_ring_skbs--;
+		} else
+			dma_unmap_page(NULL, pkt_info.buf_ptr,
+					pkt_info.byte_cnt, DMA_TO_DEVICE);
 	}
 
 	if (netif_queue_stopped(dev) &&
-            MV64340_TX_QUEUE_SIZE > mp->tx_ring_skbs + 1)
-                       netif_wake_queue(dev);
+			mp->tx_ring_size > mp->tx_ring_skbs + MAX_DESCS_PER_SKB)
+		netif_wake_queue(dev);
 }
 
 /*
- * mv64340_poll
+ * mv643xx_poll
  *
  * This function is used in case of NAPI
  */
-static int mv64340_poll(struct net_device *dev, int *budget)
+static int mv643xx_poll(struct net_device *dev, int *budget)
 {
-	struct mv64340_private *mp = netdev_priv(dev);
-	int	done = 1, orig_budget, work_done;
+	struct mv643xx_private *mp = netdev_priv(dev);
+	int done = 1, orig_budget, work_done;
 	unsigned int port_num = mp->port_num;
 	unsigned long flags;
 
-#ifdef MV64340_TX_FAST_REFILL
+#ifdef MV643XX_TX_FAST_REFILL
 	if (++mp->tx_clean_threshold > 5) {
 		spin_lock_irqsave(&mp->lock, flags);
-		mv64340_tx(dev);
+		mv643xx_tx(dev);
 		mp->tx_clean_threshold = 0;
 		spin_unlock_irqrestore(&mp->lock, flags);
 	}
 #endif
 
-	if ((u32)(MV_READ(MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_0(port_num)))                                      != (u32)mp->rx_used_desc_q) {
+	if ((mv_read(MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_0(port_num)))
+						!= (u32) mp->rx_used_desc_q) {
 		orig_budget = *budget;
 		if (orig_budget > dev->quota)
 			orig_budget = dev->quota;
-		work_done = mv64340_eth_receive_queue(dev, 0, orig_budget);
+		work_done = mv643xx_eth_receive_queue(dev, orig_budget);
 		mp->rx_task.func(dev);
 		*budget -= work_done;
 		dev->quota -= work_done;
@@ -1123,12 +1094,12 @@
 	if (done) {
 		spin_lock_irqsave(&mp->lock, flags);
 		__netif_rx_complete(dev);
-		MV_WRITE(MV64340_ETH_INTERRUPT_CAUSE_REG(port_num),0);
-                MV_WRITE(MV64340_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num),0);
-		MV_WRITE(MV64340_ETH_INTERRUPT_MASK_REG(port_num), 
+		mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
+		mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
+		mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
 						INT_CAUSE_UNMASK_ALL);
-		MV_WRITE(MV64340_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
-				                 INT_CAUSE_UNMASK_ALL_EXT);
+		mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
+						INT_CAUSE_UNMASK_ALL_EXT);
 		spin_unlock_irqrestore(&mp->lock, flags);
 	}
 
@@ -1137,19 +1108,19 @@
 #endif
 
 /*
- * mv64340_eth_start_xmit
+ * mv643xx_eth_start_xmit
  *
- * This function is queues a packet in the Tx descriptor for 
+ * This function is queues a packet in the Tx descriptor for
  * required port.
  *
- * Input : skb - a pointer to socket buffer
- *         dev - a pointer to the required port
+ * Input :	skb - a pointer to socket buffer
+ *		dev - a pointer to the required port
  *
- * Output : zero upon success
+ * Output :	zero upon success
  */
-static int mv64340_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct mv64340_private *mp = netdev_priv(dev);
+	struct mv643xx_private *mp = netdev_priv(dev);
 	struct net_device_stats *stats = &mp->stats;
 	ETH_FUNC_RET_STATUS status;
 	unsigned long flags;
@@ -1157,119 +1128,195 @@
 
 	if (netif_queue_stopped(dev)) {
 		printk(KERN_ERR
-		       "%s: Tried sending packet when interface is stopped\n",
-		       dev->name);
+			"%s: Tried sending packet when interface is stopped\n",
+			dev->name);
 		return 1;
 	}
 
 	/* This is a hard error, log it. */
-	if ((MV64340_TX_QUEUE_SIZE - mp->tx_ring_skbs) <=
-	    (skb_shinfo(skb)->nr_frags + 1)) {
+	if ((mp->tx_ring_size - mp->tx_ring_skbs) <=
+					(skb_shinfo(skb)->nr_frags + 1)) {
 		netif_stop_queue(dev);
 		printk(KERN_ERR
-		       "%s: Bug in mv64340_eth - Trying to transmit when"
-		       " queue full !\n", dev->name);
+			"%s: Bug in mv643xx_eth - Trying to transmit when"
+			" queue full !\n", dev->name);
 		return 1;
 	}
 
 	/* Paranoid check - this shouldn't happen */
 	if (skb == NULL) {
 		stats->tx_dropped++;
+		printk(KERN_ERR "mv64320_eth paranoid check failed\n");
 		return 1;
 	}
 
 	spin_lock_irqsave(&mp->lock, flags);
 
 	/* Update packet info data structure -- DMA owned, first last */
-#ifdef MV64340_CHECKSUM_OFFLOAD_TX
-	if (!skb_shinfo(skb)->nr_frags || (skb_shinfo(skb)->nr_frags > 3)) {
-#endif
-		pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT |
-	    	                   ETH_TX_FIRST_DESC | ETH_TX_LAST_DESC;
+#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
+	if (!skb_shinfo(skb)->nr_frags) {
+linear:
+		if (skb->ip_summed != CHECKSUM_HW) {
+			pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT |
+					ETH_TX_FIRST_DESC | ETH_TX_LAST_DESC;
+			pkt_info.l4i_chk = 0;
+		} else {
+			u32 ipheader = skb->nh.iph->ihl << 11;
 
+			pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT |
+					ETH_TX_FIRST_DESC | ETH_TX_LAST_DESC |
+					ETH_GEN_TCP_UDP_CHECKSUM |
+					ETH_GEN_IP_V_4_CHECKSUM | ipheader;
+			/* CPU already calculated pseudo header checksum. */
+			if (skb->nh.iph->protocol == IPPROTO_UDP) {
+				pkt_info.cmd_sts |= ETH_UDP_FRAME;
+				pkt_info.l4i_chk = skb->h.uh->check;
+			} else if (skb->nh.iph->protocol == IPPROTO_TCP)
+				pkt_info.l4i_chk = skb->h.th->check;
+			else {
+				printk(KERN_ERR
+					"%s: chksum proto != TCP or UDP\n",
+					dev->name);
+				spin_unlock_irqrestore(&mp->lock, flags);
+				return 1;
+			}
+		}
 		pkt_info.byte_cnt = skb->len;
-		pkt_info.buf_ptr = pci_map_single(0, skb->data, skb->len,
-		                                  PCI_DMA_TODEVICE);
-
-
+		pkt_info.buf_ptr = dma_map_single(NULL, skb->data, skb->len,
+							DMA_TO_DEVICE);
 		pkt_info.return_info = skb;
+		mp->tx_ring_skbs++;
 		status = eth_port_send(mp, &pkt_info);
 		if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL))
 			printk(KERN_ERR "%s: Error on transmitting packet\n",
-				       dev->name);
-		mp->tx_ring_skbs++;
-#ifdef MV64340_CHECKSUM_OFFLOAD_TX
+								dev->name);
+		stats->tx_bytes += pkt_info.byte_cnt;
 	} else {
-		unsigned int    frag;
-		u32		ipheader;
+		unsigned int frag;
+		u32 ipheader;
 
-                /* first frag which is skb header */
-                pkt_info.byte_cnt = skb_headlen(skb);
-                pkt_info.buf_ptr = pci_map_single(0, skb->data,
-                                        skb_headlen(skb), PCI_DMA_TODEVICE);
-                pkt_info.return_info = 0;
-                ipheader = skb->nh.iph->ihl << 11;
-                pkt_info.cmd_sts = ETH_TX_FIRST_DESC | 
-					ETH_GEN_TCP_UDP_CHECKSUM |
-					ETH_GEN_IP_V_4_CHECKSUM |
-                                        ipheader;
-		/* CPU already calculated pseudo header checksum. So, use it */
-                pkt_info.l4i_chk = skb->h.th->check;
-                status = eth_port_send(mp, &pkt_info);
+		/* Since hardware can't handle unaligned fragments smaller
+		 * than 9 bytes, if we find any, we linearize the skb
+		 * and start again.  When I've seen it, it's always been
+		 * the first frag (probably near the end of the page),
+		 * but we check all frags to be safe.
+		 */
+		for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
+			skb_frag_t *fragp;
+
+			fragp = &skb_shinfo(skb)->frags[frag];
+			if (fragp->size <= 8 && fragp->page_offset & 0x7) {
+				skb_linearize(skb, GFP_ATOMIC);
+				printk(KERN_DEBUG "%s: unaligned tiny fragment"
+						"%d of %d, fixed\n",
+						dev->name, frag,
+						skb_shinfo(skb)->nr_frags);
+				goto linear;
+			}
+		}
+
+		/* first frag which is skb header */
+		pkt_info.byte_cnt = skb_headlen(skb);
+		pkt_info.buf_ptr = dma_map_single(NULL, skb->data,
+							skb_headlen(skb),
+							DMA_TO_DEVICE);
+		pkt_info.l4i_chk = 0;
+		pkt_info.return_info = 0;
+		pkt_info.cmd_sts = ETH_TX_FIRST_DESC;
+
+		if (skb->ip_summed == CHECKSUM_HW) {
+			ipheader = skb->nh.iph->ihl << 11;
+			pkt_info.cmd_sts |= ETH_GEN_TCP_UDP_CHECKSUM |
+					ETH_GEN_IP_V_4_CHECKSUM | ipheader;
+			/* CPU already calculated pseudo header checksum. */
+			if (skb->nh.iph->protocol == IPPROTO_UDP) {
+				pkt_info.cmd_sts |= ETH_UDP_FRAME;
+				pkt_info.l4i_chk = skb->h.uh->check;
+			} else if (skb->nh.iph->protocol == IPPROTO_TCP)
+				pkt_info.l4i_chk = skb->h.th->check;
+			else {
+				printk(KERN_ERR
+					"%s: chksum proto != TCP or UDP\n",
+					dev->name);
+				spin_unlock_irqrestore(&mp->lock, flags);
+				return 1;
+			}
+		}
+
+		status = eth_port_send(mp, &pkt_info);
 		if (status != ETH_OK) {
-	                if ((status == ETH_ERROR))
-        	                printk(KERN_ERR "%s: Error on transmitting packet\n", dev->name);
-	                if (status == ETH_QUEUE_FULL)
-        	                printk("Error on Queue Full \n");
-                	if (status == ETH_QUEUE_LAST_RESOURCE)
-                        	printk("Tx resource error \n");
+			if ((status == ETH_ERROR))
+				printk(KERN_ERR
+					"%s: Error on transmitting packet\n",
+					dev->name);
+			if (status == ETH_QUEUE_FULL)
+				printk("Error on Queue Full \n");
+			if (status == ETH_QUEUE_LAST_RESOURCE)
+				printk("Tx resource error \n");
 		}
+		stats->tx_bytes += pkt_info.byte_cnt;
+
+		/* Check for the remaining frags */
+		for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
+			skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag];
+			pkt_info.l4i_chk = 0x0000;
+			pkt_info.cmd_sts = 0x00000000;
+
+			/* Last Frag enables interrupt and frees the skb */
+			if (frag == (skb_shinfo(skb)->nr_frags - 1)) {
+				pkt_info.cmd_sts |= ETH_TX_ENABLE_INTERRUPT |
+							ETH_TX_LAST_DESC;
+				pkt_info.return_info = skb;
+				mp->tx_ring_skbs++;
+			} else {
+				pkt_info.return_info = 0;
+			}
+			pkt_info.l4i_chk = 0;
+			pkt_info.byte_cnt = this_frag->size;
 
-                /* Check for the remaining frags */
-                for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
-                        skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag];
-                        pkt_info.l4i_chk = 0x0000;
-                        pkt_info.cmd_sts = 0x00000000;
-
-                        /* Last Frag enables interrupt and frees the skb */
-                        if (frag == (skb_shinfo(skb)->nr_frags - 1)) {
-                                pkt_info.cmd_sts |= ETH_TX_ENABLE_INTERRUPT |
-                                                        ETH_TX_LAST_DESC;
-                                pkt_info.return_info = skb;
-                                mp->tx_ring_skbs++;
-                        }
-                        else {
-                                pkt_info.return_info = 0;
-                        }
-                        pkt_info.byte_cnt = this_frag->size;
-                        if (this_frag->size < 8)
-                                printk("%d : \n", skb_shinfo(skb)->nr_frags);
-
-                        pkt_info.buf_ptr = pci_map_page(NULL, this_frag->page,
-                                        this_frag->page_offset,
-                                        this_frag->size, PCI_DMA_TODEVICE);
+			pkt_info.buf_ptr = dma_map_page(NULL, this_frag->page,
+							this_frag->page_offset,
+							this_frag->size,
+							DMA_TO_DEVICE);
 
-                        status = eth_port_send(mp, &pkt_info);
+			status = eth_port_send(mp, &pkt_info);
 
 			if (status != ETH_OK) {
-	                        if ((status == ETH_ERROR))
-        	                        printk(KERN_ERR "%s: Error on transmitting packet\n", dev->name);
+				if ((status == ETH_ERROR))
+					printk(KERN_ERR "%s: Error on "
+							"transmitting packet\n",
+							dev->name);
 
-       		                 if (status == ETH_QUEUE_LAST_RESOURCE)
-                	                printk("Tx resource error \n");
+				if (status == ETH_QUEUE_LAST_RESOURCE)
+					printk("Tx resource error \n");
 
-                        	if (status == ETH_QUEUE_FULL)
-                                	printk("Queue is full \n");
+				if (status == ETH_QUEUE_FULL)
+					printk("Queue is full \n");
 			}
-                }
-        }
+			stats->tx_bytes += pkt_info.byte_cnt;
+		}
+	}
+#else
+	pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | ETH_TX_FIRST_DESC |
+							ETH_TX_LAST_DESC;
+	pkt_info.l4i_chk = 0;
+	pkt_info.byte_cnt = skb->len;
+	pkt_info.buf_ptr = dma_map_single(NULL, skb->data, skb->len,
+								DMA_TO_DEVICE);
+	pkt_info.return_info = skb;
+	mp->tx_ring_skbs++;
+	status = eth_port_send(mp, &pkt_info);
+	if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL))
+		printk(KERN_ERR "%s: Error on transmitting packet\n",
+								dev->name);
+	stats->tx_bytes += pkt_info.byte_cnt;
 #endif
 
 	/* Check if TX queue can handle another skb. If not, then
 	 * signal higher layers to stop requesting TX
 	 */
-	if (MV64340_TX_QUEUE_SIZE <= (mp->tx_ring_skbs + 1))
-		/* 
+	if (mp->tx_ring_size <= (mp->tx_ring_skbs + MAX_DESCS_PER_SKB))
+		/*
 		 * Stop getting skb's from upper layers.
 		 * Getting skb's from upper layers will be enabled again after
 		 * packets are released.
@@ -1277,7 +1324,6 @@
 		netif_stop_queue(dev);
 
 	/* Update statistics and start of transmittion time */
-	stats->tx_bytes += skb->len;
 	stats->tx_packets++;
 	dev->trans_start = jiffies;
 
@@ -1287,212 +1333,302 @@
 }
 
 /*
- * mv64340_eth_get_stats
+ * mv643xx_eth_get_stats
  *
  * Returns a pointer to the interface statistics.
  *
- * Input : dev - a pointer to the required interface
+ * Input :	dev - a pointer to the required interface
  *
- * Output : a pointer to the interface's statistics
+ * Output :	a pointer to the interface's statistics
  */
 
-static struct net_device_stats *mv64340_eth_get_stats(struct net_device *dev)
+static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *dev)
 {
-	struct mv64340_private *mp = netdev_priv(dev);
+	struct mv643xx_private *mp = netdev_priv(dev);
 
 	return &mp->stats;
 }
 
 /*/
- * mv64340_eth_init
- *								       
- * First function called after registering the network device. 
- * It's purpose is to initialize the device as an ethernet device, 
- * fill the structure that was given in registration with pointers
- * to functions, and setting the MAC address of the interface
+ * mv643xx_eth_probe
  *
- * Input : number of port to initialize
- * Output : -ENONMEM if failed , 0 if success
- */
-static struct net_device *mv64340_eth_init(int port_num)
-{
-	struct mv64340_private *mp;
+ * First function called after registering the network device.
+ * It's purpose is to initialize the device as an ethernet device,
+ * fill the ethernet device structure with pointers * to functions,
+ * and set the MAC address of the interface
+ *
+ * Input :	struct device *
+ * Output :	-ENOMEM if failed , 0 if success
+ */
+static int mv643xx_eth_probe(struct device *ddev)
+{
+	struct platform_device *pdev = to_platform_device(ddev);
+	struct mv643xx_eth_platform_data *pd;
+	int port_num = pdev->id;
+	struct mv643xx_private *mp;
 	struct net_device *dev;
+	u8 *p;
+	struct resource *res;
 	int err;
 
-	dev = alloc_etherdev(sizeof(struct mv64340_private));
+	dev = alloc_etherdev(sizeof(struct mv643xx_private));
 	if (!dev)
-		return NULL;
+		return -ENOMEM;
+
+	dev_set_drvdata(ddev, dev);
 
 	mp = netdev_priv(dev);
 
-	dev->irq = ETH_PORT0_IRQ_NUM + port_num;
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	BUG_ON(!res);
+	dev->irq = res->start;
 
-	dev->open = mv64340_eth_open;
-	dev->stop = mv64340_eth_stop;
-	dev->hard_start_xmit = mv64340_eth_start_xmit;
-	dev->get_stats = mv64340_eth_get_stats;
-	dev->set_mac_address = mv64340_eth_set_mac_address;
-	dev->set_multicast_list = mv64340_eth_set_rx_mode;
+	mp->port_num = port_num;
+
+	dev->open = mv643xx_eth_open;
+	dev->stop = mv643xx_eth_stop;
+	dev->hard_start_xmit = mv643xx_eth_start_xmit;
+	dev->get_stats = mv643xx_eth_get_stats;
+	dev->set_mac_address = mv643xx_eth_set_mac_address;
+	dev->set_multicast_list = mv643xx_eth_set_rx_mode;
 
 	/* No need to Tx Timeout */
-	dev->tx_timeout = mv64340_eth_tx_timeout;
-#ifdef MV64340_NAPI
-        dev->poll = mv64340_poll;
-        dev->weight = 64;
+	dev->tx_timeout = mv643xx_eth_tx_timeout;
+#ifdef MV643XX_NAPI
+	dev->poll = mv643xx_poll;
+	dev->weight = 64;
 #endif
 
 	dev->watchdog_timeo = 2 * HZ;
-	dev->tx_queue_len = MV64340_TX_QUEUE_SIZE;
+	dev->tx_queue_len = mp->tx_ring_size;
 	dev->base_addr = 0;
-	dev->change_mtu = mv64340_eth_change_mtu;
+	dev->change_mtu = mv643xx_eth_change_mtu;
+	SET_ETHTOOL_OPS(dev, &mv643xx_ethtool_ops);
 
-#ifdef MV64340_CHECKSUM_OFFLOAD_TX
+#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
 #ifdef MAX_SKB_FRAGS
-        /*
-         * Zero copy can only work if we use Discovery II memory. Else, we will
-         * have to map the buffers to ISA memory which is only 16 MB
-         */
-        dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_HW_CSUM;
+	/*
+	 * Zero copy can only work if we use Discovery II memory. Else, we will
+	 * have to map the buffers to ISA memory which is only 16 MB
+	 */
+	dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_HW_CSUM;
 #endif
 #endif
 
-	mp->port_num = port_num;
-
 	/* Configure the timeout task */
-        INIT_WORK(&mp->tx_timeout_task,
-                  (void (*)(void *))mv64340_eth_tx_timeout_task, dev);
+	INIT_WORK(&mp->tx_timeout_task,
+			(void (*)(void *))mv643xx_eth_tx_timeout_task, dev);
 
 	spin_lock_init(&mp->lock);
 
-	/* set MAC addresses */
-	memcpy(dev->dev_addr, prom_mac_addr_base, 6);
-	dev->dev_addr[5] += port_num;
+	/* set default config values */
+	eth_port_uc_addr_get(dev, dev->dev_addr);
+	mp->port_config = MV643XX_ETH_PORT_CONFIG_DEFAULT_VALUE;
+	mp->port_config_extend = MV643XX_ETH_PORT_CONFIG_EXTEND_DEFAULT_VALUE;
+	mp->port_sdma_config = MV643XX_ETH_PORT_SDMA_CONFIG_DEFAULT_VALUE;
+	mp->port_serial_control = MV643XX_ETH_PORT_SERIAL_CONTROL_DEFAULT_VALUE;
+	mp->rx_ring_size = MV643XX_ETH_PORT_DEFAULT_RECEIVE_QUEUE_SIZE;
+	mp->tx_ring_size = MV643XX_ETH_PORT_DEFAULT_TRANSMIT_QUEUE_SIZE;
+
+	pd = pdev->dev.platform_data;
+	if (pd) {
+		if (pd->mac_addr != NULL)
+			memcpy(dev->dev_addr, pd->mac_addr, 6);
+
+		if (pd->phy_addr || pd->force_phy_addr)
+			ethernet_phy_set(port_num, pd->phy_addr);
+
+		if (pd->port_config || pd->force_port_config)
+			mp->port_config = pd->port_config;
+
+		if (pd->port_config_extend || pd->force_port_config_extend)
+			mp->port_config_extend = pd->port_config_extend;
+
+		if (pd->port_sdma_config || pd->force_port_sdma_config)
+			mp->port_sdma_config = pd->port_sdma_config;
+
+		if (pd->port_serial_control || pd->force_port_serial_control)
+			mp->port_serial_control = pd->port_serial_control;
+
+		if (pd->rx_queue_size)
+			mp->rx_ring_size = pd->rx_queue_size;
+
+		if (pd->tx_queue_size)
+			mp->tx_ring_size = pd->tx_queue_size;
+
+		if (pd->tx_sram_size) {
+			mp->tx_sram_size = pd->tx_sram_size;
+			mp->tx_sram_addr = pd->tx_sram_addr;
+		}
+
+		if (pd->rx_sram_size) {
+			mp->rx_sram_size = pd->rx_sram_size;
+			mp->rx_sram_addr = pd->rx_sram_addr;
+		}
+	}
+
+	err = ethernet_phy_detect(port_num);
+	if (err) {
+		pr_debug("MV643xx ethernet port %d: "
+					"No PHY detected at addr %d\n",
+					port_num, ethernet_phy_get(port_num));
+		return err;
+	}
 
 	err = register_netdev(dev);
 	if (err)
-		goto out_free_dev;
+		goto out;
 
-	printk(KERN_NOTICE "%s: port %d with MAC address %02x:%02x:%02x:%02x:%02x:%02x\n",
-		dev->name, port_num,
-		dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
-		dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+	p = dev->dev_addr;
+	printk(KERN_NOTICE
+		"%s: port %d with MAC address %02x:%02x:%02x:%02x:%02x:%02x\n",
+		dev->name, port_num, p[0], p[1], p[2], p[3], p[4], p[5]);
 
 	if (dev->features & NETIF_F_SG)
-		printk("Scatter Gather Enabled  ");
+		printk(KERN_NOTICE "%s: Scatter Gather Enabled\n", dev->name);
 
 	if (dev->features & NETIF_F_IP_CSUM)
-		printk("TX TCP/IP Checksumming Supported  \n");
+		printk(KERN_NOTICE "%s: TX TCP/IP Checksumming Supported\n",
+								dev->name);
+
+#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
+	printk(KERN_NOTICE "%s: RX TCP/UDP Checksum Offload ON \n", dev->name);
+#endif
 
-	printk("RX TCP/UDP Checksum Offload ON, \n");
-	printk("TX and RX Interrupt Coalescing ON \n");
+#ifdef MV643XX_COAL
+	printk(KERN_NOTICE "%s: TX and RX Interrupt Coalescing ON \n",
+								dev->name);
+#endif
 
-#ifdef MV64340_NAPI
-	printk("RX NAPI Enabled \n");
+#ifdef MV643XX_NAPI
+	printk(KERN_NOTICE "%s: RX NAPI Enabled \n", dev->name);
 #endif
 
-	return dev;
+	return 0;
 
-out_free_dev:
+out:
 	free_netdev(dev);
 
-	return NULL;
+	return err;
 }
 
-static void mv64340_eth_remove(struct net_device *dev)
+static int mv643xx_eth_remove(struct device *ddev)
 {
-	struct mv64340_private *mp = netdev_priv(dev);
+	struct net_device *dev = dev_get_drvdata(ddev);
 
 	unregister_netdev(dev);
 	flush_scheduled_work();
+
 	free_netdev(dev);
+	dev_set_drvdata(ddev, NULL);
+	return 0;
+}
+
+static int mv643xx_eth_shared_probe(struct device *ddev)
+{
+	struct platform_device *pdev = to_platform_device(ddev);
+	struct resource *res;
+
+	printk(KERN_NOTICE "MV-643xx 10/100/1000 Ethernet Driver\n");
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL)
+		return -ENODEV;
+
+	mv643xx_eth_shared_base = ioremap(res->start,
+						MV643XX_ETH_SHARED_REGS_SIZE);
+	if (mv643xx_eth_shared_base == NULL)
+		return -ENOMEM;
+
+	return 0;
+
+}
+
+static int mv643xx_eth_shared_remove(struct device *ddev)
+{
+	iounmap(mv643xx_eth_shared_base);
+	mv643xx_eth_shared_base = NULL;
+
+	return 0;
 }
 
-static struct net_device *mv64340_dev0;
-static struct net_device *mv64340_dev1;
-static struct net_device *mv64340_dev2;
+static struct device_driver mv643xx_eth_driver = {
+	.name = MV643XX_ETH_NAME,
+	.bus = &platform_bus_type,
+	.probe = mv643xx_eth_probe,
+	.remove = mv643xx_eth_remove,
+};
+
+static struct device_driver mv643xx_eth_shared_driver = {
+	.name = MV643XX_ETH_SHARED_NAME,
+	.bus = &platform_bus_type,
+	.probe = mv643xx_eth_shared_probe,
+	.remove = mv643xx_eth_shared_remove,
+};
 
 /*
- * mv64340_init_module
+ * mv643xx_init_module
  *
  * Registers the network drivers into the Linux kernel
  *
- * Input : N/A
+ * Input :	N/A
  *
- * Output : N/A
+ * Output :	N/A
  */
-static int __init mv64340_init_module(void)
+static int __init mv643xx_init_module(void)
 {
-	printk(KERN_NOTICE "MV-643xx 10/100/1000 Ethernet Driver\n");
+	int rc;
 
-#ifdef CONFIG_MV643XX_ETH_0
-	mv64340_dev0 = mv64340_eth_init(0);
-	if (!mv64340_dev0) {
-		printk(KERN_ERR
-		       "Error registering MV-64360 ethernet port 0\n");
-	}
-#endif
-#ifdef CONFIG_MV643XX_ETH_1
-	mv64340_dev1 = mv64340_eth_init(1);
-	if (!mv64340_dev1) {
-		printk(KERN_ERR
-		       "Error registering MV-64360 ethernet port 1\n");
-	}
-#endif
-#ifdef CONFIG_MV643XX_ETH_2
-	mv64340_dev2 = mv64340_eth_init(2);
-	if (!mv64340_dev2) {
-		printk(KERN_ERR
-		       "Error registering MV-64360 ethernet port 2\n");
+	rc = driver_register(&mv643xx_eth_shared_driver);
+	if (!rc) {
+		rc = driver_register(&mv643xx_eth_driver);
+		if (rc)
+			driver_unregister(&mv643xx_eth_shared_driver);
 	}
-#endif
-	return 0;
+	return rc;
 }
 
 /*
- * mv64340_cleanup_module
+ * mv643xx_cleanup_module
  *
  * Registers the network drivers into the Linux kernel
  *
- * Input : N/A
+ * Input :	N/A
  *
- * Output : N/A
+ * Output :	N/A
  */
-static void __exit mv64340_cleanup_module(void)
+static void __exit mv643xx_cleanup_module(void)
 {
-	if (mv64340_dev2)
-		mv64340_eth_remove(mv64340_dev2);
-	if (mv64340_dev1)
-		mv64340_eth_remove(mv64340_dev1);
-	if (mv64340_dev0)
-		mv64340_eth_remove(mv64340_dev0);
+	driver_unregister(&mv643xx_eth_driver);
+	driver_unregister(&mv643xx_eth_shared_driver);
 }
 
-module_init(mv64340_init_module);
-module_exit(mv64340_cleanup_module);
+module_init(mv643xx_init_module);
+module_exit(mv643xx_cleanup_module);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Rabeeh Khoury, Assaf Hoffman, Matthew Dharm and Manish Lachwani");
-MODULE_DESCRIPTION("Ethernet driver for Marvell MV64340");
+MODULE_AUTHOR(	"Rabeeh Khoury, Assaf Hoffman, Matthew Dharm, Manish Lachwani"
+		" and Dale Farnsworth");
+MODULE_DESCRIPTION("Ethernet driver for Marvell MV643XX");
 
 /*
- *  The second part is the low level driver of the gigE ethernet ports.
+ * The second part is the low level driver of the gigE ethernet ports.
  */
 
 /*
  * Marvell's Gigabit Ethernet controller low level driver
  *
  * DESCRIPTION:
- *       This file introduce low level API to Marvell's Gigabit Ethernet
+ *	This file introduce low level API to Marvell's Gigabit Ethernet
  *		controller. This Gigabit Ethernet Controller driver API controls
  *		1) Operations (i.e. port init, start, reset etc').
  *		2) Data flow (i.e. port send, receive etc').
  *		Each Gigabit Ethernet port is controlled via
- *              struct mv64340_private.
+ *		struct mv643xx_private.
  *		This struct includes user configuration information as well as
  *		driver internal data needed for its operations.
  *
- *		Supported Features:  
+ *		Supported Features:
  *		- This low level driver is OS independent. Allocating memory for
  *		  the descriptor rings and buffers are not within the scope of
  *		  this driver.
@@ -1509,12 +1645,12 @@
  *		- PHY access and control API.
  *		- Port control register configuration API.
  *		- Full control over Unicast and Multicast MAC configurations.
- *								   
+ *
  *		Operation flow:
  *
  *		Initialization phase
- *		This phase complete the initialization of the the mv64340_private
- *		struct. 
+ *		This phase complete the initialization of the the
+ *		mv643xx_private struct.
  *		User information regarding port configuration has to be set
  *		prior to calling the port initialization routine.
  *
@@ -1523,7 +1659,7 @@
  *		access to DRAM and internal SRAM memory spaces.
  *
  *		Driver ring initialization
- *		Allocating memory for the descriptor rings and buffers is not 
+ *		Allocating memory for the descriptor rings and buffers is not
  *		within the scope of this driver. Thus, the user is required to
  *		allocate memory for the descriptors ring and buffers. Those
  *		memory parameters are used by the Rx and Tx ring initialization
@@ -1531,49 +1667,50 @@
  *		of a ring.
  *		Note: Pay special attention to alignment issues when using
  *		cached descriptors/buffers. In this phase the driver store
- *		information in the mv64340_private struct regarding each queue
+ *		information in the mv643xx_private struct regarding each queue
  *		ring.
  *
- *		Driver start 
+ *		Driver start
  *		This phase prepares the Ethernet port for Rx and Tx activity.
- *		It uses the information stored in the mv64340_private struct to 
+ *		It uses the information stored in the mv643xx_private struct to
  *		initialize the various port registers.
  *
  *		Data flow:
  *		All packet references to/from the driver are done using
- *              struct pkt_info.
- *		This struct is a unified struct used with Rx and Tx operations. 
+ *		struct pkt_info.
+ *		This struct is a unified struct used with Rx and Tx operations.
  *		This way the user is not required to be familiar with neither
  *		Tx nor Rx descriptors structures.
  *		The driver's descriptors rings are management by indexes.
  *		Those indexes controls the ring resources and used to indicate
  *		a SW resource error:
- *		'current' 
- *		This index points to the current available resource for use. For 
- *		example in Rx process this index will point to the descriptor  
- *		that will be passed to the user upon calling the receive routine.
- *		In Tx process, this index will point to the descriptor
+ *		'current'
+ *		This index points to the current available resource for use. For
+ *		example in Rx process this index will point to the descriptor
+ *		that will be passed to the user upon calling the receive
+ *		routine.  In Tx process, this index will point to the descriptor
  *		that will be assigned with the user packet info and transmitted.
- *		'used'    
- *		This index points to the descriptor that need to restore its 
+ *		'used'
+ *		This index points to the descriptor that need to restore its
  *		resources. For example in Rx process, using the Rx buffer return
  *		API will attach the buffer returned in packet info to the
  *		descriptor pointed by 'used'. In Tx process, using the Tx
  *		descriptor return will merely return the user packet info with
- *		the command status of  the transmitted buffer pointed by the
+ *		the command status of the transmitted buffer pointed by the
  *		'used' index. Nevertheless, it is essential to use this routine
  *		to update the 'used' index.
  *		'first'
- *		This index supports Tx Scatter-Gather. It points to the first 
- *		descriptor of a packet assembled of multiple buffers. For example
- *		when in middle of Such packet we have a Tx resource error the 
- *		'curr' index get the value of 'first' to indicate that the ring 
- *		returned to its state before trying to transmit this packet.
+ *		This index supports Tx Scatter-Gather. It points to the first
+ *		descriptor of a packet assembled of multiple buffers. For
+ *		example when in middle of Such packet we have a Tx resource
+ *		error the 'curr' index get the value of 'first' to indicate
+ *		that the ring returned to its state before trying to transmit
+ *		this packet.
  *
  *		Receive operation:
  *		The eth_port_receive API set the packet information struct,
- *		passed by the caller, with received information from the 
- *		'current' SDMA descriptor. 
+ *		passed by the caller, with received information from the
+ *		'current' SDMA descriptor.
  *		It is the user responsibility to return this resource back
  *		to the Rx descriptor ring to enable the reuse of this source.
  *		Return Rx resource is done using the eth_rx_return_buff API.
@@ -1594,27 +1731,21 @@
  *
  *		EXTERNAL INTERFACE
  *
- *       Prior to calling the initialization routine eth_port_init() the user
- *	 must set the following fields under mv64340_private struct:
- *       port_num             User Ethernet port number.
- *       port_mac_addr[6]	    User defined port MAC address.
- *       port_config          User port configuration value.
- *       port_config_extend    User port config extend value.
- *       port_sdma_config      User port SDMA config value.
- *       port_serial_control   User port serial control value.
- *
- *       This driver introduce a set of default values:
- *       PORT_CONFIG_VALUE           Default port configuration value
- *       PORT_CONFIG_EXTEND_VALUE    Default port extend configuration value
- *       PORT_SDMA_CONFIG_VALUE      Default sdma control value
- *       PORT_SERIAL_CONTROL_VALUE   Default port serial control value
+ *	Prior to calling the initialization routine eth_port_init() the user
+ *	must set the following fields under mv643xx_private struct:
+ *	port_num		User Ethernet port number.
+ *	port_mac_addr[6]	User defined port MAC address.
+ *	port_config		User port configuration value.
+ *	port_config_extend	User port config extend value.
+ *	port_sdma_config	User port SDMA config value.
+ *	port_serial_control	User port serial control value.
  *
  *		This driver data flow is done using the struct pkt_info which
- *              is a unified struct for Rx and Tx operations:
+ *		is a unified struct for Rx and Tx operations:
  *
  *		byte_cnt	Tx/Rx descriptor buffer byte count.
  *		l4i_chk		CPU provided TCP Checksum. For Tx operation
- *                              only.
+ *				only.
  *		cmd_sts		Tx/Rx descriptor command status.
  *		buf_ptr		Tx/Rx descriptor buffer pointer.
  *		return_info	Tx/Rx user resource return information.
@@ -1623,70 +1754,44 @@
 /* defines */
 /* SDMA command macros */
 #define ETH_ENABLE_TX_QUEUE(eth_port) \
-	MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(eth_port), 1)
-
-#define ETH_DISABLE_TX_QUEUE(eth_port) \
-	MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(eth_port),	\
-	         (1 << 8))
-
-#define ETH_ENABLE_RX_QUEUE(rx_queue, eth_port) \
-	MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(eth_port),	\
-	         (1 << rx_queue))
-
-#define ETH_DISABLE_RX_QUEUE(rx_queue, eth_port) \
-	MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(eth_port),	\
-	         (1 << (8 + rx_queue)))
-
-#define LINK_UP_TIMEOUT		100000
-#define PHY_BUSY_TIMEOUT	10000000
+	mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(eth_port), 1)
 
 /* locals */
 
 /* PHY routines */
 static int ethernet_phy_get(unsigned int eth_port_num);
+static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr);
 
 /* Ethernet Port routines */
 static int eth_port_uc_addr(unsigned int eth_port_num, unsigned char uc_nibble,
-	int option);
+								int option);
 
 /*
  * eth_port_init - Initialize the Ethernet port driver
  *
  * DESCRIPTION:
- *       This function prepares the ethernet port to start its activity:
- *       1) Completes the ethernet port driver struct initialization toward port
- *           start routine.
- *       2) Resets the device to a quiescent state in case of warm reboot.
- *       3) Enable SDMA access to all four DRAM banks as well as internal SRAM.
- *       4) Clean MAC tables. The reset status of those tables is unknown.
- *       5) Set PHY address. 
- *       Note: Call this routine prior to eth_port_start routine and after
- *       setting user values in the user fields of Ethernet port control
- *       struct.
+ *	This function prepares the ethernet port to start its activity:
+ *	1) Completes the ethernet port driver struct initialization toward port
+ *		start routine.
+ *	2) Resets the device to a quiescent state in case of warm reboot.
+ *	3) Enable SDMA access to all four DRAM banks as well as internal SRAM.
+ *	4) Clean MAC tables. The reset status of those tables is unknown.
+ *	5) Set PHY address.
+ *	Note: Call this routine prior to eth_port_start routine and after
+ *	setting user values in the user fields of Ethernet port control
+ *	struct.
  *
  * INPUT:
- *       struct mv64340_private *mp   Ethernet port control struct
+ *	struct mv643xx_private *mp	Ethernet port control struct
  *
  * OUTPUT:
- *       See description.
+ *	See description.
  *
  * RETURN:
- *       None.
+ *	None.
  */
-static void eth_port_init(struct mv64340_private * mp)
+static void eth_port_init(struct mv643xx_private *mp)
 {
-	mp->port_config = PORT_CONFIG_VALUE;
-	mp->port_config_extend = PORT_CONFIG_EXTEND_VALUE;
-#if defined(__BIG_ENDIAN)
-	mp->port_sdma_config = PORT_SDMA_CONFIG_VALUE;
-#elif defined(__LITTLE_ENDIAN)
-	mp->port_sdma_config = PORT_SDMA_CONFIG_VALUE |
-		ETH_BLM_RX_NO_SWAP | ETH_BLM_TX_NO_SWAP;
-#else
-#error One of __LITTLE_ENDIAN or __BIG_ENDIAN must be defined!
-#endif
-	mp->port_serial_control = PORT_SERIAL_CONTROL_VALUE;
-
 	mp->port_rx_queue_command = 0;
 	mp->port_tx_queue_command = 0;
 
@@ -1704,77 +1809,73 @@
  * eth_port_start - Start the Ethernet port activity.
  *
  * DESCRIPTION:
- *       This routine prepares the Ethernet port for Rx and Tx activity:
- *       1. Initialize Tx and Rx Current Descriptor Pointer for each queue that
- *          has been initialized a descriptor's ring (using
- *          ether_init_tx_desc_ring for Tx and ether_init_rx_desc_ring for Rx)
- *       2. Initialize and enable the Ethernet configuration port by writing to
- *          the port's configuration and command registers.
- *       3. Initialize and enable the SDMA by writing to the SDMA's 
- *          configuration and command registers.  After completing these steps,
- *          the ethernet port SDMA can starts to perform Rx and Tx activities.
+ *	This routine prepares the Ethernet port for Rx and Tx activity:
+ *	 1. Initialize Tx and Rx Current Descriptor Pointer for each queue that
+ *	    has been initialized a descriptor's ring (using
+ *	    ether_init_tx_desc_ring for Tx and ether_init_rx_desc_ring for Rx)
+ *	 2. Initialize and enable the Ethernet configuration port by writing to
+ *	    the port's configuration and command registers.
+ *	 3. Initialize and enable the SDMA by writing to the SDMA's
+ *	    configuration and command registers.  After completing these steps,
+ *	    the ethernet port SDMA can starts to perform Rx and Tx activities.
  *
- *       Note: Each Rx and Tx queue descriptor's list must be initialized prior
- *       to calling this function (use ether_init_tx_desc_ring for Tx queues
- *       and ether_init_rx_desc_ring for Rx queues).
+ *	Note: Each Rx and Tx queue descriptor's list must be initialized prior
+ *	to calling this function (use ether_init_tx_desc_ring for Tx queues
+ *	and ether_init_rx_desc_ring for Rx queues).
  *
  * INPUT:
- *       struct mv64340_private 	*mp   Ethernet port control struct
+ *	struct mv643xx_private *mp	Ethernet port control struct
  *
  * OUTPUT:
- *       Ethernet port is ready to receive and transmit.
+ *	Ethernet port is ready to receive and transmit.
  *
  * RETURN:
- *       false if the port PHY is not up.
- *       true otherwise.
+ *	None.
  */
-static int eth_port_start(struct mv64340_private *mp)
+static void eth_port_start(struct mv643xx_private *mp)
 {
-	unsigned int eth_port_num = mp->port_num;
+	unsigned int port_num = mp->port_num;
 	int tx_curr_desc, rx_curr_desc;
-	unsigned int phy_reg_data;
 
 	/* Assignment of Tx CTRP of given queue */
 	tx_curr_desc = mp->tx_curr_desc_q;
-	MV_WRITE(MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_0(eth_port_num),
-	         (struct eth_tx_desc *) mp->tx_desc_dma + tx_curr_desc);
+	mv_write(MV643XX_ETH_TX_CURRENT_QUEUE_DESC_PTR_0(port_num),
+		(u32)((struct eth_tx_desc *)mp->tx_desc_dma + tx_curr_desc));
 
 	/* Assignment of Rx CRDP of given queue */
 	rx_curr_desc = mp->rx_curr_desc_q;
-	MV_WRITE(MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_0(eth_port_num),
-		 (struct eth_rx_desc *) mp->rx_desc_dma + rx_curr_desc);
+	mv_write(MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_0(port_num),
+		(u32)((struct eth_rx_desc *)mp->rx_desc_dma + rx_curr_desc));
 
 	/* Add the assigned Ethernet address to the port's address table */
-	eth_port_uc_addr_set(mp->port_num, mp->port_mac_addr);
+	eth_port_uc_addr_set(port_num, mp->port_mac_addr);
 
 	/* Assign port configuration and command. */
-	MV_WRITE(MV64340_ETH_PORT_CONFIG_REG(eth_port_num),
-		 mp->port_config);
+	mv_write(MV643XX_ETH_PORT_CONFIG_REG(port_num), mp->port_config);
 
-	MV_WRITE(MV64340_ETH_PORT_CONFIG_EXTEND_REG(eth_port_num),
-		 mp->port_config_extend);
+	mv_write(MV643XX_ETH_PORT_CONFIG_EXTEND_REG(port_num),
+						mp->port_config_extend);
 
-	MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(eth_port_num),
-		 mp->port_serial_control);
 
-	MV_SET_REG_BITS(MV64340_ETH_PORT_SERIAL_CONTROL_REG(eth_port_num),
-			ETH_SERIAL_PORT_ENABLE);
+	/* Increase the Rx side buffer size if supporting GigE */
+	if (mp->port_serial_control & MV643XX_ETH_SET_GMII_SPEED_TO_1000)
+		mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
+			(mp->port_serial_control & 0xfff1ffff) | (0x5 << 17));
+	else
+		mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
+						mp->port_serial_control);
+
+	mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
+		mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num)) |
+						MV643XX_ETH_SERIAL_PORT_ENABLE);
 
 	/* Assign port SDMA configuration */
-	MV_WRITE(MV64340_ETH_SDMA_CONFIG_REG(eth_port_num),
-		 mp->port_sdma_config);
+	mv_write(MV643XX_ETH_SDMA_CONFIG_REG(port_num),
+							mp->port_sdma_config);
 
 	/* Enable port Rx. */
-	MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(eth_port_num),
-		 mp->port_rx_queue_command);
-
-	/* Check if link is up */
-	eth_port_read_smi_reg(eth_port_num, 1, &phy_reg_data);
-
-	if (!(phy_reg_data & 0x20))
-		return 0;
-
-	return 1;
+	mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num),
+						mp->port_rx_queue_command);
 }
 
 /*
@@ -1784,29 +1885,29 @@
  *		This function Set the port Ethernet MAC address.
  *
  * INPUT:
- *	unsigned int eth_port_num     Port number.
- *	char *        p_addr		Address to be set 
+ *	unsigned int	eth_port_num	Port number.
+ *	char *		p_addr		Address to be set
  *
  * OUTPUT:
- *	Set MAC address low and high registers. also calls eth_port_uc_addr() 
- *       To set the unicast table with the proper information.
+ *	Set MAC address low and high registers. also calls eth_port_uc_addr()
+ *	To set the unicast table with the proper information.
  *
  * RETURN:
  *	N/A.
  *
  */
 static void eth_port_uc_addr_set(unsigned int eth_port_num,
-				 unsigned char *p_addr)
+							unsigned char *p_addr)
 {
 	unsigned int mac_h;
 	unsigned int mac_l;
 
 	mac_l = (p_addr[4] << 8) | (p_addr[5]);
-	mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) |
-	    (p_addr[2] << 8) | (p_addr[3] << 0);
+	mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) | (p_addr[2] << 8) |
+							(p_addr[3] << 0);
 
-	MV_WRITE(MV64340_ETH_MAC_ADDR_LOW(eth_port_num), mac_l);
-	MV_WRITE(MV64340_ETH_MAC_ADDR_HIGH(eth_port_num), mac_h);
+	mv_write(MV643XX_ETH_MAC_ADDR_LOW(eth_port_num), mac_l);
+	mv_write(MV643XX_ETH_MAC_ADDR_HIGH(eth_port_num), mac_h);
 
 	/* Accept frames of this address */
 	eth_port_uc_addr(eth_port_num, p_addr[5], ACCEPT_MAC_ADDR);
@@ -1815,29 +1916,64 @@
 }
 
 /*
+ * eth_port_uc_addr_get - This function retrieves the port Unicast address
+ * (MAC address) from the ethernet hw registers.
+ *
+ * DESCRIPTION:
+ *		This function retrieves the port Ethernet MAC address.
+ *
+ * INPUT:
+ *	unsigned int	eth_port_num	Port number.
+ *	char		*MacAddr	pointer where the MAC address is stored
+ *
+ * OUTPUT:
+ *	Copy the MAC address to the location pointed to by MacAddr
+ *
+ * RETURN:
+ *	N/A.
+ *
+ */
+static void eth_port_uc_addr_get(struct net_device *dev, unsigned char *p_addr)
+{
+	struct mv643xx_private *mp = netdev_priv(dev);
+	unsigned int mac_h;
+	unsigned int mac_l;
+
+	mac_h = mv_read(MV643XX_ETH_MAC_ADDR_HIGH(mp->port_num));
+	mac_l = mv_read(MV643XX_ETH_MAC_ADDR_LOW(mp->port_num));
+
+	p_addr[0] = (mac_h >> 24) & 0xff;
+	p_addr[1] = (mac_h >> 16) & 0xff;
+	p_addr[2] = (mac_h >> 8) & 0xff;
+	p_addr[3] = mac_h & 0xff;
+	p_addr[4] = (mac_l >> 8) & 0xff;
+	p_addr[5] = mac_l & 0xff;
+}
+
+/*
  * eth_port_uc_addr - This function Set the port unicast address table
  *
  * DESCRIPTION:
- *	This function locates the proper entry in the Unicast table for the 
- *	specified MAC nibble and sets its properties according to function 
+ *	This function locates the proper entry in the Unicast table for the
+ *	specified MAC nibble and sets its properties according to function
  *	parameters.
  *
  * INPUT:
- *	unsigned int 	eth_port_num      Port number.
- *	unsigned char uc_nibble		Unicast MAC Address last nibble. 
- *	int 			option      0 = Add, 1 = remove address.
+ *	unsigned int	eth_port_num	Port number.
+ *	unsigned char	uc_nibble	Unicast MAC Address last nibble.
+ *	int 		option		0 = Add, 1 = remove address.
  *
  * OUTPUT:
  *	This function add/removes MAC addresses from the port unicast address
- *	table. 
+ *	table.
  *
  * RETURN:
  *	true is output succeeded.
  *	false if option parameter is invalid.
  *
  */
-static int eth_port_uc_addr(unsigned int eth_port_num,
-	unsigned char uc_nibble, int option)
+static int eth_port_uc_addr(unsigned int eth_port_num, unsigned char uc_nibble,
+								int option)
 {
 	unsigned int unicast_reg;
 	unsigned int tbl_offset;
@@ -1850,29 +1986,26 @@
 
 	switch (option) {
 	case REJECT_MAC_ADDR:
-		/* Clear accepts frame bit at specified unicast DA table entry */
-		unicast_reg = MV_READ((MV64340_ETH_DA_FILTER_UNICAST_TABLE_BASE
-				  (eth_port_num) + tbl_offset));
+		/* Clear accepts frame bit at given unicast DA table entry */
+		unicast_reg = mv_read((MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE
+						(eth_port_num) + tbl_offset));
 
 		unicast_reg &= (0x0E << (8 * reg_offset));
 
-		MV_WRITE(
-			 (MV64340_ETH_DA_FILTER_UNICAST_TABLE_BASE
-			  (eth_port_num) + tbl_offset), unicast_reg);
+		mv_write((MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE
+				(eth_port_num) + tbl_offset), unicast_reg);
 		break;
 
 	case ACCEPT_MAC_ADDR:
 		/* Set accepts frame bit at unicast DA filter table entry */
 		unicast_reg =
-		    MV_READ(
-				 (MV64340_ETH_DA_FILTER_UNICAST_TABLE_BASE
-				  (eth_port_num) + tbl_offset));
+			mv_read((MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE
+						(eth_port_num) + tbl_offset));
 
 		unicast_reg |= (0x01 << (8 * reg_offset));
 
-		MV_WRITE(
-			 (MV64340_ETH_DA_FILTER_UNICAST_TABLE_BASE
-			  (eth_port_num) + tbl_offset), unicast_reg);
+		mv_write((MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE
+				(eth_port_num) + tbl_offset), unicast_reg);
 
 		break;
 
@@ -1887,17 +2020,17 @@
  * eth_port_init_mac_tables - Clear all entrance in the UC, SMC and OMC tables
  *
  * DESCRIPTION:
- *       Go through all the DA filter tables (Unicast, Special Multicast &
- *       Other Multicast) and set each entry to 0.
+ *	Go through all the DA filter tables (Unicast, Special Multicast &
+ *	Other Multicast) and set each entry to 0.
  *
  * INPUT:
- *	unsigned int    eth_port_num   Ethernet Port number.
+ *	unsigned int	eth_port_num	Ethernet Port number.
  *
  * OUTPUT:
- *       Multicast and Unicast packets are rejected.
+ *	Multicast and Unicast packets are rejected.
  *
  * RETURN:
- *       None.
+ *	None.
  */
 static void eth_port_init_mac_tables(unsigned int eth_port_num)
 {
@@ -1905,18 +2038,16 @@
 
 	/* Clear DA filter unicast table (Ex_dFUT) */
 	for (table_index = 0; table_index <= 0xC; table_index += 4)
-		MV_WRITE(
-			 (MV64340_ETH_DA_FILTER_UNICAST_TABLE_BASE
-			  (eth_port_num) + table_index), 0);
+		mv_write((MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE
+					(eth_port_num) + table_index), 0);
 
 	for (table_index = 0; table_index <= 0xFC; table_index += 4) {
 		/* Clear DA filter special multicast table (Ex_dFSMT) */
-		MV_WRITE(
-			 (MV64340_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE
-			  (eth_port_num) + table_index), 0);
+		mv_write((MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE
+					(eth_port_num) + table_index), 0);
 		/* Clear DA filter other multicast table (Ex_dFOMT) */
-		MV_WRITE((MV64340_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE
-			  (eth_port_num) + table_index), 0);
+		mv_write((MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE
+					(eth_port_num) + table_index), 0);
 	}
 }
 
@@ -1924,17 +2055,17 @@
  * eth_clear_mib_counters - Clear all MIB counters
  *
  * DESCRIPTION:
- *       This function clears all MIB counters of a specific ethernet port.
- *       A read from the MIB counter will reset the counter.
+ *	This function clears all MIB counters of a specific ethernet port.
+ *	A read from the MIB counter will reset the counter.
  *
  * INPUT:
- *	unsigned int    eth_port_num   Ethernet Port number.
+ *	unsigned int	eth_port_num	Ethernet Port number.
  *
  * OUTPUT:
- *       After reading all MIB counters, the counters resets.
+ *	After reading all MIB counters, the counters resets.
  *
  * RETURN:
- *       MIB counter value.
+ *	MIB counter value.
  *
  */
 static void eth_clear_mib_counters(unsigned int eth_port_num)
@@ -1942,72 +2073,155 @@
 	int i;
 
 	/* Perform dummy reads from MIB counters */
-	for (i = ETH_MIB_GOOD_OCTETS_RECEIVED_LOW; i < ETH_MIB_LATE_COLLISION; i += 4)
-		MV_READ(MV64340_ETH_MIB_COUNTERS_BASE(eth_port_num) + i);
+	for (i = ETH_MIB_GOOD_OCTETS_RECEIVED_LOW; i < ETH_MIB_LATE_COLLISION;
+									i += 4)
+		mv_read(MV643XX_ETH_MIB_COUNTERS_BASE(eth_port_num) + i);
+}
+
+static inline u32 read_mib(struct mv643xx_private *mp, int offset)
+{
+	return mv_read(MV643XX_ETH_MIB_COUNTERS_BASE(mp->port_num) + offset);
 }
 
+static void eth_update_mib_counters(struct mv643xx_private *mp)
+{
+	struct mv643xx_mib_counters *p = &mp->mib_counters;
+	int offset;
+
+	p->good_octets_received +=
+		read_mib(mp, ETH_MIB_GOOD_OCTETS_RECEIVED_LOW);
+	p->good_octets_received +=
+		(u64)read_mib(mp, ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH) << 32;
+
+	for (offset = ETH_MIB_BAD_OCTETS_RECEIVED;
+			offset <= ETH_MIB_FRAMES_1024_TO_MAX_OCTETS;
+			offset += 4)
+		*(u32 *)((char *)p + offset) = read_mib(mp, offset);
+
+	p->good_octets_sent += read_mib(mp, ETH_MIB_GOOD_OCTETS_SENT_LOW);
+	p->good_octets_sent +=
+		(u64)read_mib(mp, ETH_MIB_GOOD_OCTETS_SENT_HIGH) << 32;
+
+	for (offset = ETH_MIB_GOOD_FRAMES_SENT;
+			offset <= ETH_MIB_LATE_COLLISION;
+			offset += 4)
+		*(u32 *)((char *)p + offset) = read_mib(mp, offset);
+}
+
+/*
+ * ethernet_phy_detect - Detect whether a phy is present
+ *
+ * DESCRIPTION:
+ *	This function tests whether there is a PHY present on
+ *	the specified port.
+ *
+ * INPUT:
+ *	unsigned int	eth_port_num	Ethernet Port number.
+ *
+ * OUTPUT:
+ *	None
+ *
+ * RETURN:
+ *	0 on success
+ *	-ENODEV on failure
+ *
+ */
+static int ethernet_phy_detect(unsigned int port_num)
+{
+	unsigned int phy_reg_data0;
+	int auto_neg;
+
+	eth_port_read_smi_reg(port_num, 0, &phy_reg_data0);
+	auto_neg = phy_reg_data0 & 0x1000;
+	phy_reg_data0 ^= 0x1000;	/* invert auto_neg */
+	eth_port_write_smi_reg(port_num, 0, phy_reg_data0);
+
+	eth_port_read_smi_reg(port_num, 0, &phy_reg_data0);
+	if ((phy_reg_data0 & 0x1000) == auto_neg)
+		return -ENODEV;				/* change didn't take */
+
+	phy_reg_data0 ^= 0x1000;
+	eth_port_write_smi_reg(port_num, 0, phy_reg_data0);
+	return 0;
+}
 
 /*
  * ethernet_phy_get - Get the ethernet port PHY address.
  *
  * DESCRIPTION:
- *       This routine returns the given ethernet port PHY address.
+ *	This routine returns the given ethernet port PHY address.
  *
  * INPUT:
- *		unsigned int   eth_port_num   Ethernet Port number.
+ *	unsigned int	eth_port_num	Ethernet Port number.
  *
  * OUTPUT:
- *       None.
+ *	None.
  *
  * RETURN:
- *       PHY address.
+ *	PHY address.
  *
  */
 static int ethernet_phy_get(unsigned int eth_port_num)
 {
 	unsigned int reg_data;
 
-	reg_data = MV_READ(MV64340_ETH_PHY_ADDR_REG);
+	reg_data = mv_read(MV643XX_ETH_PHY_ADDR_REG);
 
 	return ((reg_data >> (5 * eth_port_num)) & 0x1f);
 }
 
 /*
+ * ethernet_phy_set - Set the ethernet port PHY address.
+ *
+ * DESCRIPTION:
+ *	This routine sets the given ethernet port PHY address.
+ *
+ * INPUT:
+ *	unsigned int	eth_port_num	Ethernet Port number.
+ *	int		phy_addr	PHY address.
+ *
+ * OUTPUT:
+ *	None.
+ *
+ * RETURN:
+ *	None.
+ *
+ */
+static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr)
+{
+	u32 reg_data;
+	int addr_shift = 5 * eth_port_num;
+
+	reg_data = mv_read(MV643XX_ETH_PHY_ADDR_REG);
+	reg_data &= ~(0x1f << addr_shift);
+	reg_data |= (phy_addr & 0x1f) << addr_shift;
+	mv_write(MV643XX_ETH_PHY_ADDR_REG, reg_data);
+}
+
+/*
  * ethernet_phy_reset - Reset Ethernet port PHY.
  *
  * DESCRIPTION:
- *       This routine utilize the SMI interface to reset the ethernet port PHY.
- *       The routine waits until the link is up again or link up is timeout.
+ *	This routine utilizes the SMI interface to reset the ethernet port PHY.
  *
  * INPUT:
- *	unsigned int   eth_port_num   Ethernet Port number.
+ *	unsigned int	eth_port_num	Ethernet Port number.
  *
  * OUTPUT:
- *       The ethernet port PHY renew its link.
+ *	The PHY is reset.
  *
  * RETURN:
- *       None.
+ *	None.
  *
  */
-static int ethernet_phy_reset(unsigned int eth_port_num)
+static void ethernet_phy_reset(unsigned int eth_port_num)
 {
-	unsigned int time_out = 50;
 	unsigned int phy_reg_data;
 
 	/* Reset the PHY */
 	eth_port_read_smi_reg(eth_port_num, 0, &phy_reg_data);
 	phy_reg_data |= 0x8000;	/* Set bit 15 to reset the PHY */
 	eth_port_write_smi_reg(eth_port_num, 0, phy_reg_data);
-
-	/* Poll on the PHY LINK */
-	do {
-		eth_port_read_smi_reg(eth_port_num, 1, &phy_reg_data);
-
-		if (time_out-- == 0)
-			return 0;
-	} while (!(phy_reg_data & 0x20));
-
-	return 1;
 }
 
 /*
@@ -2015,381 +2229,358 @@
  *
  * DESCRIPTION:
  * 	This routine resets the chip by aborting any SDMA engine activity and
- *      clearing the MIB counters. The Receiver and the Transmit unit are in 
- *      idle state after this command is performed and the port is disabled.
+ *	clearing the MIB counters. The Receiver and the Transmit unit are in
+ *	idle state after this command is performed and the port is disabled.
  *
  * INPUT:
- *	unsigned int   eth_port_num   Ethernet Port number.
+ *	unsigned int	eth_port_num	Ethernet Port number.
  *
  * OUTPUT:
- *       Channel activity is halted.
+ *	Channel activity is halted.
  *
  * RETURN:
- *       None.
+ *	None.
  *
  */
-static void eth_port_reset(unsigned int eth_port_num)
+static void eth_port_reset(unsigned int port_num)
 {
 	unsigned int reg_data;
 
 	/* Stop Tx port activity. Check port Tx activity. */
-	reg_data =
-	    MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(eth_port_num));
+	reg_data = mv_read(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num));
 
 	if (reg_data & 0xFF) {
 		/* Issue stop command for active channels only */
-		MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG
-			 (eth_port_num), (reg_data << 8));
+		mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num),
+							(reg_data << 8));
 
 		/* Wait for all Tx activity to terminate. */
-		do {
-			/* Check port cause register that all Tx queues are stopped */
-			reg_data =
-			    MV_READ
-			    (MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG
-			     (eth_port_num));
-		}
-		while (reg_data & 0xFF);
+		/* Check port cause register that all Tx queues are stopped */
+		while (mv_read(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num))
+									& 0xFF)
+			udelay(10);
 	}
 
 	/* Stop Rx port activity. Check port Rx activity. */
-	reg_data =
-	    MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG
-			 (eth_port_num));
+	reg_data = mv_read(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num));
 
 	if (reg_data & 0xFF) {
 		/* Issue stop command for active channels only */
-		MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG
-			 (eth_port_num), (reg_data << 8));
+		mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num),
+							(reg_data << 8));
 
 		/* Wait for all Rx activity to terminate. */
-		do {
-			/* Check port cause register that all Rx queues are stopped */
-			reg_data =
-			    MV_READ
-			    (MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG
-			     (eth_port_num));
-		}
-		while (reg_data & 0xFF);
+		/* Check port cause register that all Rx queues are stopped */
+		while (mv_read(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num))
+									& 0xFF)
+			udelay(10);
 	}
 
-
 	/* Clear all MIB counters */
-	eth_clear_mib_counters(eth_port_num);
+	eth_clear_mib_counters(port_num);
 
 	/* Reset the Enable bit in the Configuration Register */
-	reg_data =
-	    MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG (eth_port_num));
-	reg_data &= ~ETH_SERIAL_PORT_ENABLE;
-	MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(eth_port_num), reg_data);
-
-	return;
+	reg_data = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num));
+	reg_data &= ~MV643XX_ETH_SERIAL_PORT_ENABLE;
+	mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), reg_data);
 }
 
 /*
  * ethernet_set_config_reg - Set specified bits in configuration register.
  *
  * DESCRIPTION:
- *       This function sets specified bits in the given ethernet 
- *       configuration register. 
+ *	This function sets specified bits in the given ethernet
+ *	configuration register.
  *
  * INPUT:
- *	unsigned int   eth_port_num   Ethernet Port number.
- *      unsigned int    value   32 bit value.
+ *	unsigned int	eth_port_num	Ethernet Port number.
+ *	unsigned int	value		32 bit value.
  *
  * OUTPUT:
- *      The set bits in the value parameter are set in the configuration 
- *      register.
+ *	The set bits in the value parameter are set in the configuration
+ *	register.
  *
  * RETURN:
- *      None.
+ *	None.
  *
  */
 static void ethernet_set_config_reg(unsigned int eth_port_num,
-				    unsigned int value)
+							unsigned int value)
 {
 	unsigned int eth_config_reg;
 
-	eth_config_reg =
-	    MV_READ(MV64340_ETH_PORT_CONFIG_REG(eth_port_num));
+	eth_config_reg = mv_read(MV643XX_ETH_PORT_CONFIG_REG(eth_port_num));
 	eth_config_reg |= value;
-	MV_WRITE(MV64340_ETH_PORT_CONFIG_REG(eth_port_num),
-		 eth_config_reg);
+	mv_write(MV643XX_ETH_PORT_CONFIG_REG(eth_port_num), eth_config_reg);
+}
+
+static int eth_port_autoneg_supported(unsigned int eth_port_num)
+{
+	unsigned int phy_reg_data0;
+
+	eth_port_read_smi_reg(eth_port_num, 0, &phy_reg_data0);
+
+	return phy_reg_data0 & 0x1000;
+}
+
+static int eth_port_link_is_up(unsigned int eth_port_num)
+{
+	unsigned int phy_reg_data1;
+
+	eth_port_read_smi_reg(eth_port_num, 1, &phy_reg_data1);
+
+	if (eth_port_autoneg_supported(eth_port_num)) {
+		if (phy_reg_data1 & 0x20)	/* auto-neg complete */
+			return 1;
+	} else if (phy_reg_data1 & 0x4)		/* link up */
+		return 1;
+
+	return 0;
 }
 
 /*
  * ethernet_get_config_reg - Get the port configuration register
  *
  * DESCRIPTION:
- *       This function returns the configuration register value of the given 
- *       ethernet port.
+ *	This function returns the configuration register value of the given
+ *	ethernet port.
  *
  * INPUT:
- *	unsigned int   eth_port_num   Ethernet Port number.
+ *	unsigned int	eth_port_num	Ethernet Port number.
  *
  * OUTPUT:
- *       None.
+ *	None.
  *
  * RETURN:
- *       Port configuration register value.
+ *	Port configuration register value.
  */
 static unsigned int ethernet_get_config_reg(unsigned int eth_port_num)
 {
 	unsigned int eth_config_reg;
 
-	eth_config_reg = MV_READ(MV64340_ETH_PORT_CONFIG_EXTEND_REG
-				      (eth_port_num));
+	eth_config_reg = mv_read(MV643XX_ETH_PORT_CONFIG_EXTEND_REG
+								(eth_port_num));
 	return eth_config_reg;
 }
 
-
 /*
  * eth_port_read_smi_reg - Read PHY registers
  *
  * DESCRIPTION:
- *       This routine utilize the SMI interface to interact with the PHY in 
- *       order to perform PHY register read.
+ *	This routine utilize the SMI interface to interact with the PHY in
+ *	order to perform PHY register read.
  *
  * INPUT:
- *	unsigned int   eth_port_num   Ethernet Port number.
- *       unsigned int   phy_reg   PHY register address offset.
- *       unsigned int   *value   Register value buffer.
+ *	unsigned int	port_num	Ethernet Port number.
+ *	unsigned int	phy_reg		PHY register address offset.
+ *	unsigned int	*value		Register value buffer.
  *
  * OUTPUT:
- *       Write the value of a specified PHY register into given buffer.
+ *	Write the value of a specified PHY register into given buffer.
  *
  * RETURN:
- *       false if the PHY is busy or read data is not in valid state.
- *       true otherwise.
+ *	false if the PHY is busy or read data is not in valid state.
+ *	true otherwise.
  *
  */
-static int eth_port_read_smi_reg(unsigned int eth_port_num,
-	unsigned int phy_reg, unsigned int *value)
+static void eth_port_read_smi_reg(unsigned int port_num,
+				unsigned int phy_reg, unsigned int *value)
 {
-	int phy_addr = ethernet_phy_get(eth_port_num);
-	unsigned int time_out = PHY_BUSY_TIMEOUT;
-	unsigned int reg_value;
-
-	/* first check that it is not busy */
-	do {
-		reg_value = MV_READ(MV64340_ETH_SMI_REG);
-		if (time_out-- == 0)
-			return 0;
-	} while (reg_value & ETH_SMI_BUSY);
-
-	/* not busy */
-
-	MV_WRITE(MV64340_ETH_SMI_REG,
-		 (phy_addr << 16) | (phy_reg << 21) | ETH_SMI_OPCODE_READ);
-
-	time_out = PHY_BUSY_TIMEOUT;	/* initialize the time out var again */
+	int phy_addr = ethernet_phy_get(port_num);
+	unsigned long flags;
+	int i;
 
-	do {
-		reg_value = MV_READ(MV64340_ETH_SMI_REG);
-		if (time_out-- == 0)
-			return 0;
-	} while (reg_value & ETH_SMI_READ_VALID);
+	/* the SMI register is a shared resource */
+	spin_lock_irqsave(&mv643xx_eth_phy_lock, flags);
 
-	/* Wait for the data to update in the SMI register */
-	for (time_out = 0; time_out < PHY_BUSY_TIMEOUT; time_out++);
+	/* wait for the SMI register to become available */
+	for (i = 0; mv_read(MV643XX_ETH_SMI_REG) & ETH_SMI_BUSY; i++) {
+		if (i == PHY_WAIT_ITERATIONS) {
+			printk("mv643xx PHY busy timeout, port %d\n", port_num);
+			goto out;
+		}
+		udelay(PHY_WAIT_MICRO_SECONDS);
+	}
 
-	reg_value = MV_READ(MV64340_ETH_SMI_REG);
+	mv_write(MV643XX_ETH_SMI_REG,
+		(phy_addr << 16) | (phy_reg << 21) | ETH_SMI_OPCODE_READ);
 
-	*value = reg_value & 0xffff;
+	/* now wait for the data to be valid */
+	for (i = 0; !(mv_read(MV643XX_ETH_SMI_REG) & ETH_SMI_READ_VALID); i++) {
+		if (i == PHY_WAIT_ITERATIONS) {
+			printk("mv643xx PHY read timeout, port %d\n", port_num);
+			goto out;
+		}
+		udelay(PHY_WAIT_MICRO_SECONDS);
+	}
 
-	return 1;
+	*value = mv_read(MV643XX_ETH_SMI_REG) & 0xffff;
+out:
+	spin_unlock_irqrestore(&mv643xx_eth_phy_lock, flags);
 }
 
 /*
  * eth_port_write_smi_reg - Write to PHY registers
  *
  * DESCRIPTION:
- *       This routine utilize the SMI interface to interact with the PHY in 
- *       order to perform writes to PHY registers.
+ *	This routine utilize the SMI interface to interact with the PHY in
+ *	order to perform writes to PHY registers.
  *
  * INPUT:
- *	unsigned int   eth_port_num   Ethernet Port number.
- *      unsigned int   phy_reg   PHY register address offset.
- *      unsigned int    value   Register value.
+ *	unsigned int	eth_port_num	Ethernet Port number.
+ *	unsigned int	phy_reg		PHY register address offset.
+ *	unsigned int	value		Register value.
  *
  * OUTPUT:
- *      Write the given value to the specified PHY register.
+ *	Write the given value to the specified PHY register.
  *
  * RETURN:
- *      false if the PHY is busy.
- *      true otherwise.
+ *	false if the PHY is busy.
+ *	true otherwise.
  *
  */
-static int eth_port_write_smi_reg(unsigned int eth_port_num,
-	unsigned int phy_reg, unsigned int value)
+static void eth_port_write_smi_reg(unsigned int eth_port_num,
+				   unsigned int phy_reg, unsigned int value)
 {
-	unsigned int time_out = PHY_BUSY_TIMEOUT;
-	unsigned int reg_value;
 	int phy_addr;
+	int i;
+	unsigned long flags;
 
 	phy_addr = ethernet_phy_get(eth_port_num);
 
-	/* first check that it is not busy */
-	do {
-		reg_value = MV_READ(MV64340_ETH_SMI_REG);
-		if (time_out-- == 0)
-			return 0;
-	} while (reg_value & ETH_SMI_BUSY);
-
-	/* not busy */
-	MV_WRITE(MV64340_ETH_SMI_REG, (phy_addr << 16) | (phy_reg << 21) |
-		 ETH_SMI_OPCODE_WRITE | (value & 0xffff));
+	/* the SMI register is a shared resource */
+	spin_lock_irqsave(&mv643xx_eth_phy_lock, flags);
 
-	return 1;
+	/* wait for the SMI register to become available */
+	for (i = 0; mv_read(MV643XX_ETH_SMI_REG) & ETH_SMI_BUSY; i++) {
+		if (i == PHY_WAIT_ITERATIONS) {
+			printk("mv643xx PHY busy timeout, port %d\n",
+								eth_port_num);
+			goto out;
+		}
+		udelay(PHY_WAIT_MICRO_SECONDS);
+	}
+
+	mv_write(MV643XX_ETH_SMI_REG, (phy_addr << 16) | (phy_reg << 21) |
+				ETH_SMI_OPCODE_WRITE | (value & 0xffff));
+out:
+	spin_unlock_irqrestore(&mv643xx_eth_phy_lock, flags);
 }
 
 /*
  * eth_port_send - Send an Ethernet packet
  *
  * DESCRIPTION:
- *	This routine send a given packet described by p_pktinfo parameter. It 
- *      supports transmitting of a packet spaned over multiple buffers. The 
- *      routine updates 'curr' and 'first' indexes according to the packet 
- *      segment passed to the routine. In case the packet segment is first, 
- *      the 'first' index is update. In any case, the 'curr' index is updated. 
- *      If the routine get into Tx resource error it assigns 'curr' index as 
- *      'first'. This way the function can abort Tx process of multiple 
- *      descriptors per packet.
+ *	This routine send a given packet described by p_pktinfo parameter. It
+ *	supports transmitting of a packet spaned over multiple buffers. The
+ *	routine updates 'curr' and 'first' indexes according to the packet
+ *	segment passed to the routine. In case the packet segment is first,
+ *	the 'first' index is update. In any case, the 'curr' index is updated.
+ *	If the routine get into Tx resource error it assigns 'curr' index as
+ *	'first'. This way the function can abort Tx process of multiple
+ *	descriptors per packet.
  *
  * INPUT:
- *	struct mv64340_private   *mp   Ethernet Port Control srtuct. 
- *	struct pkt_info        *p_pkt_info       User packet buffer.
+ *	struct mv643xx_private	*mp		Ethernet Port Control srtuct.
+ *	struct pkt_info		*p_pkt_info	User packet buffer.
  *
  * OUTPUT:
- *	Tx ring 'curr' and 'first' indexes are updated. 
+ *	Tx ring 'curr' and 'first' indexes are updated.
  *
  * RETURN:
- *      ETH_QUEUE_FULL in case of Tx resource error.
+ *	ETH_QUEUE_FULL in case of Tx resource error.
  *	ETH_ERROR in case the routine can not access Tx desc ring.
  *	ETH_QUEUE_LAST_RESOURCE if the routine uses the last Tx resource.
- *      ETH_OK otherwise.
+ *	ETH_OK otherwise.
  *
  */
-#ifdef  MV64340_CHECKSUM_OFFLOAD_TX
+#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
 /*
  * Modified to include the first descriptor pointer in case of SG
  */
-static ETH_FUNC_RET_STATUS eth_port_send(struct mv64340_private * mp,
-                                         struct pkt_info * p_pkt_info)
+static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
+					 struct pkt_info *p_pkt_info)
 {
 	int tx_desc_curr, tx_desc_used, tx_first_desc, tx_next_desc;
-	volatile struct eth_tx_desc *current_descriptor;
-	volatile struct eth_tx_desc *first_descriptor;
-	u32 command_status, first_chip_ptr;
+	struct eth_tx_desc *current_descriptor;
+	struct eth_tx_desc *first_descriptor;
+	u32 command;
 
 	/* Do not process Tx ring in case of Tx ring resource error */
 	if (mp->tx_resource_err)
 		return ETH_QUEUE_FULL;
 
+	/*
+	 * The hardware requires that each buffer that is <= 8 bytes
+	 * in length must be aligned on an 8 byte boundary.
+	 */
+	if (p_pkt_info->byte_cnt <= 8 && p_pkt_info->buf_ptr & 0x7) {
+		printk(KERN_ERR
+			"mv643xx_eth port %d: packet size <= 8 problem\n",
+			mp->port_num);
+		return ETH_ERROR;
+	}
+
 	/* Get the Tx Desc ring indexes */
 	tx_desc_curr = mp->tx_curr_desc_q;
 	tx_desc_used = mp->tx_used_desc_q;
 
 	current_descriptor = &mp->p_tx_desc_area[tx_desc_curr];
-	if (current_descriptor == NULL)
-		return ETH_ERROR;
 
-	tx_next_desc = (tx_desc_curr + 1) % MV64340_TX_QUEUE_SIZE;
-	command_status = p_pkt_info->cmd_sts | ETH_ZERO_PADDING | ETH_GEN_CRC;
+	tx_next_desc = (tx_desc_curr + 1) % mp->tx_ring_size;
+
+	current_descriptor->buf_ptr = p_pkt_info->buf_ptr;
+	current_descriptor->byte_cnt = p_pkt_info->byte_cnt;
+	current_descriptor->l4i_chk = p_pkt_info->l4i_chk;
+	mp->tx_skb[tx_desc_curr] = p_pkt_info->return_info;
 
-	if (command_status & ETH_TX_FIRST_DESC) {
+	command = p_pkt_info->cmd_sts | ETH_ZERO_PADDING | ETH_GEN_CRC |
+							ETH_BUFFER_OWNED_BY_DMA;
+	if (command & ETH_TX_FIRST_DESC) {
 		tx_first_desc = tx_desc_curr;
 		mp->tx_first_desc_q = tx_first_desc;
+		first_descriptor = current_descriptor;
+		mp->tx_first_command = command;
+	} else {
+		tx_first_desc = mp->tx_first_desc_q;
+		first_descriptor = &mp->p_tx_desc_area[tx_first_desc];
+		BUG_ON(first_descriptor == NULL);
+		current_descriptor->cmd_sts = command;
+	}
 
-                /* fill first descriptor */
-                first_descriptor = &mp->p_tx_desc_area[tx_desc_curr];
-                first_descriptor->l4i_chk = p_pkt_info->l4i_chk;
-                first_descriptor->cmd_sts = command_status;
-                first_descriptor->byte_cnt = p_pkt_info->byte_cnt;
-                first_descriptor->buf_ptr = p_pkt_info->buf_ptr;
-                first_descriptor->next_desc_ptr = mp->tx_desc_dma +
-			tx_next_desc * sizeof(struct eth_tx_desc);
+	if (command & ETH_TX_LAST_DESC) {
 		wmb();
-        } else {
-                tx_first_desc = mp->tx_first_desc_q;
-                first_descriptor = &mp->p_tx_desc_area[tx_first_desc];
-                if (first_descriptor == NULL) {
-                        printk("First desc is NULL !!\n");
-                        return ETH_ERROR;
-                }
-                if (command_status & ETH_TX_LAST_DESC)
-                        current_descriptor->next_desc_ptr = 0x00000000;
-                else {
-                        command_status |= ETH_BUFFER_OWNED_BY_DMA;
-                        current_descriptor->next_desc_ptr = mp->tx_desc_dma +
-				tx_next_desc * sizeof(struct eth_tx_desc);
-                }
-        }
-
-        if (p_pkt_info->byte_cnt < 8) {
-                printk(" < 8 problem \n");
-                return ETH_ERROR;
-        }
-
-        current_descriptor->buf_ptr = p_pkt_info->buf_ptr;
-        current_descriptor->byte_cnt = p_pkt_info->byte_cnt;
-        current_descriptor->l4i_chk = p_pkt_info->l4i_chk;
-        current_descriptor->cmd_sts = command_status;
-
-        mp->tx_skb[tx_desc_curr] = (struct sk_buff*) p_pkt_info->return_info;
-
-        wmb();
-
-        /* Set last desc with DMA ownership and interrupt enable. */
-        if (command_status & ETH_TX_LAST_DESC) {
-                current_descriptor->cmd_sts = command_status |
-                                        ETH_TX_ENABLE_INTERRUPT |
-                                        ETH_BUFFER_OWNED_BY_DMA;
+		first_descriptor->cmd_sts = mp->tx_first_command;
 
-		if (!(command_status & ETH_TX_FIRST_DESC))
-			first_descriptor->cmd_sts |= ETH_BUFFER_OWNED_BY_DMA;
 		wmb();
-
-		first_chip_ptr = MV_READ(MV64340_ETH_CURRENT_SERVED_TX_DESC_PTR(mp->port_num));
-
-		/* Apply send command */
-		if (first_chip_ptr == 0x00000000)
-			MV_WRITE(MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_0(mp->port_num), (struct eth_tx_desc *) mp->tx_desc_dma + tx_first_desc);
-
-                ETH_ENABLE_TX_QUEUE(mp->port_num);
+		ETH_ENABLE_TX_QUEUE(mp->port_num);
 
 		/*
 		 * Finish Tx packet. Update first desc in case of Tx resource
 		 * error */
-                tx_first_desc = tx_next_desc;
-                mp->tx_first_desc_q = tx_first_desc;
-	} else {
-		if (! (command_status & ETH_TX_FIRST_DESC) ) {
-			current_descriptor->cmd_sts = command_status;
-			wmb();
-		}
+		tx_first_desc = tx_next_desc;
+		mp->tx_first_desc_q = tx_first_desc;
 	}
 
-        /* Check for ring index overlap in the Tx desc ring */
-        if (tx_next_desc == tx_desc_used) {
-                mp->tx_resource_err = 1;
-                mp->tx_curr_desc_q = tx_first_desc;
+	/* Check for ring index overlap in the Tx desc ring */
+	if (tx_next_desc == tx_desc_used) {
+		mp->tx_resource_err = 1;
+		mp->tx_curr_desc_q = tx_first_desc;
 
-                return ETH_QUEUE_LAST_RESOURCE;
+		return ETH_QUEUE_LAST_RESOURCE;
 	}
 
-        mp->tx_curr_desc_q = tx_next_desc;
-        wmb();
+	mp->tx_curr_desc_q = tx_next_desc;
 
-        return ETH_OK;
+	return ETH_OK;
 }
 #else
-static ETH_FUNC_RET_STATUS eth_port_send(struct mv64340_private * mp,
-					 struct pkt_info * p_pkt_info)
+static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
+					 struct pkt_info *p_pkt_info)
 {
 	int tx_desc_curr;
 	int tx_desc_used;
-	volatile struct eth_tx_desc* current_descriptor;
+	struct eth_tx_desc *current_descriptor;
 	unsigned int command_status;
 
 	/* Do not process Tx ring in case of Tx ring resource error */
@@ -2401,39 +2592,24 @@
 	tx_desc_used = mp->tx_used_desc_q;
 	current_descriptor = &mp->p_tx_desc_area[tx_desc_curr];
 
-	if (current_descriptor == NULL)
-		return ETH_ERROR;
-
 	command_status = p_pkt_info->cmd_sts | ETH_ZERO_PADDING | ETH_GEN_CRC;
-
-/* XXX Is this for real ?!?!? */
-	/* Buffers with a payload smaller than 8 bytes must be aligned to a
-	 * 64-bit boundary. We use the memory allocated for Tx descriptor.
-	 * This memory is located in TX_BUF_OFFSET_IN_DESC offset within the
-	 * Tx descriptor. */
-	if (p_pkt_info->byte_cnt <= 8) {
-		printk(KERN_ERR
-		       "You have failed in the < 8 bytes errata - fixme\n");
-		return ETH_ERROR;
-	}
 	current_descriptor->buf_ptr = p_pkt_info->buf_ptr;
 	current_descriptor->byte_cnt = p_pkt_info->byte_cnt;
-	mp->tx_skb[tx_desc_curr] = (struct sk_buff *) p_pkt_info->return_info;
-
-	mb();
+	mp->tx_skb[tx_desc_curr] = p_pkt_info->return_info;
 
 	/* Set last desc with DMA ownership and interrupt enable. */
+	wmb();
 	current_descriptor->cmd_sts = command_status |
 			ETH_BUFFER_OWNED_BY_DMA | ETH_TX_ENABLE_INTERRUPT;
 
-	/* Apply send command */
+	wmb();
 	ETH_ENABLE_TX_QUEUE(mp->port_num);
 
 	/* Finish Tx packet. Update first desc in case of Tx resource error */
-	tx_desc_curr = (tx_desc_curr + 1) % MV64340_TX_QUEUE_SIZE;
+	tx_desc_curr = (tx_desc_curr + 1) % mp->tx_ring_size;
 
 	/* Update the current descriptor */
- 	mp->tx_curr_desc_q = tx_desc_curr;
+	mp->tx_curr_desc_q = tx_desc_curr;
 
 	/* Check for ring index overlap in the Tx desc ring */
 	if (tx_desc_curr == tx_desc_used) {
@@ -2450,62 +2626,55 @@
  *
  * DESCRIPTION:
  *	This routine returns the transmitted packet information to the caller.
- *      It uses the 'first' index to support Tx desc return in case a transmit 
- *      of a packet spanned over multiple buffer still in process.
- *      In case the Tx queue was in "resource error" condition, where there are 
- *      no available Tx resources, the function resets the resource error flag.
+ *	It uses the 'first' index to support Tx desc return in case a transmit
+ *	of a packet spanned over multiple buffer still in process.
+ *	In case the Tx queue was in "resource error" condition, where there are
+ *	no available Tx resources, the function resets the resource error flag.
  *
  * INPUT:
- *	struct mv64340_private   *mp   Ethernet Port Control srtuct. 
- *	struct pkt_info        *p_pkt_info       User packet buffer.
+ *	struct mv643xx_private	*mp		Ethernet Port Control srtuct.
+ *	struct pkt_info		*p_pkt_info	User packet buffer.
  *
  * OUTPUT:
- *	Tx ring 'first' and 'used' indexes are updated. 
+ *	Tx ring 'first' and 'used' indexes are updated.
  *
  * RETURN:
  *	ETH_ERROR in case the routine can not access Tx desc ring.
- *      ETH_RETRY in case there is transmission in process.
+ *	ETH_RETRY in case there is transmission in process.
  *	ETH_END_OF_JOB if the routine has nothing to release.
- *      ETH_OK otherwise.
+ *	ETH_OK otherwise.
  *
  */
-static ETH_FUNC_RET_STATUS eth_tx_return_desc(struct mv64340_private * mp,
-					      struct pkt_info * p_pkt_info)
+static ETH_FUNC_RET_STATUS eth_tx_return_desc(struct mv643xx_private *mp,
+						struct pkt_info *p_pkt_info)
 {
-	int tx_desc_used, tx_desc_curr;
-#ifdef MV64340_CHECKSUM_OFFLOAD_TX
-        int tx_first_desc;
+	int tx_desc_used;
+#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
+	int tx_busy_desc = mp->tx_first_desc_q;
+#else
+	int tx_busy_desc = mp->tx_curr_desc_q;
 #endif
-	volatile struct eth_tx_desc *p_tx_desc_used;
+	struct eth_tx_desc *p_tx_desc_used;
 	unsigned int command_status;
 
 	/* Get the Tx Desc ring indexes */
-	tx_desc_curr = mp->tx_curr_desc_q;
 	tx_desc_used = mp->tx_used_desc_q;
-#ifdef MV64340_CHECKSUM_OFFLOAD_TX
-        tx_first_desc = mp->tx_first_desc_q;
-#endif
+
 	p_tx_desc_used = &mp->p_tx_desc_area[tx_desc_used];
 
-	/* XXX Sanity check */
+	/* Sanity check */
 	if (p_tx_desc_used == NULL)
 		return ETH_ERROR;
 
+	/* Stop release. About to overlap the current available Tx descriptor */
+	if (tx_desc_used == tx_busy_desc && !mp->tx_resource_err)
+		return ETH_END_OF_JOB;
+
 	command_status = p_tx_desc_used->cmd_sts;
 
 	/* Still transmitting... */
-#ifndef MV64340_CHECKSUM_OFFLOAD_TX
 	if (command_status & (ETH_BUFFER_OWNED_BY_DMA))
 		return ETH_RETRY;
-#endif
-	/* Stop release. About to overlap the current available Tx descriptor */
-#ifdef MV64340_CHECKSUM_OFFLOAD_TX
-	if (tx_desc_used == tx_first_desc && !mp->tx_resource_err)
-		return ETH_END_OF_JOB;
-#else
-	if (tx_desc_used == tx_desc_curr && !mp->tx_resource_err)
-		return ETH_END_OF_JOB;
-#endif
 
 	/* Pass the packet information to the caller */
 	p_pkt_info->cmd_sts = command_status;
@@ -2513,7 +2682,7 @@
 	mp->tx_skb[tx_desc_used] = NULL;
 
 	/* Update the next descriptor to release. */
-	mp->tx_used_desc_q = (tx_desc_used + 1) % MV64340_TX_QUEUE_SIZE;
+	mp->tx_used_desc_q = (tx_desc_used + 1) % mp->tx_ring_size;
 
 	/* Any Tx return cancels the Tx resource error status */
 	mp->tx_resource_err = 0;
@@ -2525,30 +2694,30 @@
  * eth_port_receive - Get received information from Rx ring.
  *
  * DESCRIPTION:
- * 	This routine returns the received data to the caller. There is no 
- *	data copying during routine operation. All information is returned 
- *	using pointer to packet information struct passed from the caller. 
- *      If the routine exhausts	Rx ring resources then the resource error flag 
- *      is set.  
+ * 	This routine returns the received data to the caller. There is no
+ *	data copying during routine operation. All information is returned
+ *	using pointer to packet information struct passed from the caller.
+ *	If the routine exhausts Rx ring resources then the resource error flag
+ *	is set.
  *
  * INPUT:
- *	struct mv64340_private   *mp   Ethernet Port Control srtuct. 
- *	struct pkt_info        *p_pkt_info       User packet buffer.
+ *	struct mv643xx_private	*mp		Ethernet Port Control srtuct.
+ *	struct pkt_info		*p_pkt_info	User packet buffer.
  *
  * OUTPUT:
- *	Rx ring current and used indexes are updated. 
+ *	Rx ring current and used indexes are updated.
  *
  * RETURN:
  *	ETH_ERROR in case the routine can not access Rx desc ring.
  *	ETH_QUEUE_FULL if Rx ring resources are exhausted.
  *	ETH_END_OF_JOB if there is no received data.
- *      ETH_OK otherwise.
+ *	ETH_OK otherwise.
  */
-static ETH_FUNC_RET_STATUS eth_port_receive(struct mv64340_private * mp,
-					    struct pkt_info * p_pkt_info)
+static ETH_FUNC_RET_STATUS eth_port_receive(struct mv643xx_private *mp,
+						struct pkt_info *p_pkt_info)
 {
 	int rx_next_curr_desc, rx_curr_desc, rx_used_desc;
-	volatile struct eth_rx_desc * p_rx_desc;
+	volatile struct eth_rx_desc *p_rx_desc;
 	unsigned int command_status;
 
 	/* Do not process Rx ring in case of Rx ring resource error */
@@ -2563,6 +2732,7 @@
 
 	/* The following parameters are used to save readings from memory */
 	command_status = p_rx_desc->cmd_sts;
+	rmb();
 
 	/* Nothing to receive... */
 	if (command_status & (ETH_BUFFER_OWNED_BY_DMA))
@@ -2575,18 +2745,17 @@
 	p_pkt_info->l4i_chk = p_rx_desc->buf_size;
 
 	/* Clean the return info field to indicate that the packet has been */
-	/* moved to the upper layers                                        */
+	/* moved to the upper layers					    */
 	mp->rx_skb[rx_curr_desc] = NULL;
 
 	/* Update current index in data structure */
-	rx_next_curr_desc = (rx_curr_desc + 1) % MV64340_RX_QUEUE_SIZE;
+	rx_next_curr_desc = (rx_curr_desc + 1) % mp->rx_ring_size;
 	mp->rx_curr_desc_q = rx_next_curr_desc;
 
 	/* Rx descriptors exhausted. Set the Rx ring resource error flag */
 	if (rx_next_curr_desc == rx_used_desc)
 		mp->rx_resource_err = 1;
 
-	mb();
 	return ETH_OK;
 }
 
@@ -2594,27 +2763,27 @@
  * eth_rx_return_buff - Returns a Rx buffer back to the Rx ring.
  *
  * DESCRIPTION:
- *	This routine returns a Rx buffer back to the Rx ring. It retrieves the 
- *      next 'used' descriptor and attached the returned buffer to it.
- *      In case the Rx ring was in "resource error" condition, where there are 
- *      no available Rx resources, the function resets the resource error flag.
+ *	This routine returns a Rx buffer back to the Rx ring. It retrieves the
+ *	next 'used' descriptor and attached the returned buffer to it.
+ *	In case the Rx ring was in "resource error" condition, where there are
+ *	no available Rx resources, the function resets the resource error flag.
  *
  * INPUT:
- *	struct mv64340_private *mp   Ethernet Port Control srtuct. 
- *      struct pkt_info        *p_pkt_info   Information on the returned buffer.
+ *	struct mv643xx_private	*mp		Ethernet Port Control srtuct.
+ *	struct pkt_info		*p_pkt_info	Information on returned buffer.
  *
  * OUTPUT:
  *	New available Rx resource in Rx descriptor ring.
  *
  * RETURN:
  *	ETH_ERROR in case the routine can not access Rx desc ring.
- *      ETH_OK otherwise.
+ *	ETH_OK otherwise.
  */
-static ETH_FUNC_RET_STATUS eth_rx_return_buff(struct mv64340_private * mp,
-	struct pkt_info * p_pkt_info)
+static ETH_FUNC_RET_STATUS eth_rx_return_buff(struct mv643xx_private *mp,
+						struct pkt_info *p_pkt_info)
 {
 	int used_rx_desc;	/* Where to return Rx resource */
-	volatile struct eth_rx_desc* p_used_rx_desc;
+	volatile struct eth_rx_desc *p_used_rx_desc;
 
 	/* Get 'used' Rx descriptor */
 	used_rx_desc = mp->rx_used_desc_q;
@@ -2625,20 +2794,240 @@
 	mp->rx_skb[used_rx_desc] = p_pkt_info->return_info;
 
 	/* Flush the write pipe */
-	mb();
 
 	/* Return the descriptor to DMA ownership */
+	wmb();
 	p_used_rx_desc->cmd_sts =
-		ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT;
-
-	/* Flush descriptor and CPU pipe */
-	mb();
+			ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT;
+	wmb();
 
 	/* Move the used descriptor pointer to the next descriptor */
-	mp->rx_used_desc_q = (used_rx_desc + 1) % MV64340_RX_QUEUE_SIZE;
+	mp->rx_used_desc_q = (used_rx_desc + 1) % mp->rx_ring_size;
 
 	/* Any Rx return cancels the Rx resource error status */
 	mp->rx_resource_err = 0;
 
 	return ETH_OK;
 }
+
+/************* Begin ethtool support *************************/
+
+struct mv643xx_stats {
+	char stat_string[ETH_GSTRING_LEN];
+	int sizeof_stat;
+	int stat_offset;
+};
+
+#define MV643XX_STAT(m) sizeof(((struct mv643xx_private *)0)->m), \
+		      offsetof(struct mv643xx_private, m)
+
+static const struct mv643xx_stats mv643xx_gstrings_stats[] = {
+	{ "rx_packets", MV643XX_STAT(stats.rx_packets) },
+	{ "tx_packets", MV643XX_STAT(stats.tx_packets) },
+	{ "rx_bytes", MV643XX_STAT(stats.rx_bytes) },
+	{ "tx_bytes", MV643XX_STAT(stats.tx_bytes) },
+	{ "rx_errors", MV643XX_STAT(stats.rx_errors) },
+	{ "tx_errors", MV643XX_STAT(stats.tx_errors) },
+	{ "rx_dropped", MV643XX_STAT(stats.rx_dropped) },
+	{ "tx_dropped", MV643XX_STAT(stats.tx_dropped) },
+	{ "good_octets_received", MV643XX_STAT(mib_counters.good_octets_received) },
+	{ "bad_octets_received", MV643XX_STAT(mib_counters.bad_octets_received) },
+	{ "internal_mac_transmit_err", MV643XX_STAT(mib_counters.internal_mac_transmit_err) },
+	{ "good_frames_received", MV643XX_STAT(mib_counters.good_frames_received) },
+	{ "bad_frames_received", MV643XX_STAT(mib_counters.bad_frames_received) },
+	{ "broadcast_frames_received", MV643XX_STAT(mib_counters.broadcast_frames_received) },
+	{ "multicast_frames_received", MV643XX_STAT(mib_counters.multicast_frames_received) },
+	{ "frames_64_octets", MV643XX_STAT(mib_counters.frames_64_octets) },
+	{ "frames_65_to_127_octets", MV643XX_STAT(mib_counters.frames_65_to_127_octets) },
+	{ "frames_128_to_255_octets", MV643XX_STAT(mib_counters.frames_128_to_255_octets) },
+	{ "frames_256_to_511_octets", MV643XX_STAT(mib_counters.frames_256_to_511_octets) },
+	{ "frames_512_to_1023_octets", MV643XX_STAT(mib_counters.frames_512_to_1023_octets) },
+	{ "frames_1024_to_max_octets", MV643XX_STAT(mib_counters.frames_1024_to_max_octets) },
+	{ "good_octets_sent", MV643XX_STAT(mib_counters.good_octets_sent) },
+	{ "good_frames_sent", MV643XX_STAT(mib_counters.good_frames_sent) },
+	{ "excessive_collision", MV643XX_STAT(mib_counters.excessive_collision) },
+	{ "multicast_frames_sent", MV643XX_STAT(mib_counters.multicast_frames_sent) },
+	{ "broadcast_frames_sent", MV643XX_STAT(mib_counters.broadcast_frames_sent) },
+	{ "unrec_mac_control_received", MV643XX_STAT(mib_counters.unrec_mac_control_received) },
+	{ "fc_sent", MV643XX_STAT(mib_counters.fc_sent) },
+	{ "good_fc_received", MV643XX_STAT(mib_counters.good_fc_received) },
+	{ "bad_fc_received", MV643XX_STAT(mib_counters.bad_fc_received) },
+	{ "undersize_received", MV643XX_STAT(mib_counters.undersize_received) },
+	{ "fragments_received", MV643XX_STAT(mib_counters.fragments_received) },
+	{ "oversize_received", MV643XX_STAT(mib_counters.oversize_received) },
+	{ "jabber_received", MV643XX_STAT(mib_counters.jabber_received) },
+	{ "mac_receive_error", MV643XX_STAT(mib_counters.mac_receive_error) },
+	{ "bad_crc_event", MV643XX_STAT(mib_counters.bad_crc_event) },
+	{ "collision", MV643XX_STAT(mib_counters.collision) },
+	{ "late_collision", MV643XX_STAT(mib_counters.late_collision) },
+};
+
+#define MV643XX_STATS_LEN	\
+	sizeof(mv643xx_gstrings_stats) / sizeof(struct mv643xx_stats)
+
+static int
+mv643xx_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+{
+	struct mv643xx_private *mp = netdev->priv;
+	int port_num = mp->port_num;
+	int autoneg = eth_port_autoneg_supported(port_num);
+	int mode_10_bit;
+	int auto_duplex;
+	int half_duplex = 0;
+	int full_duplex = 0;
+	int auto_speed;
+	int speed_10 = 0;
+	int speed_100 = 0;
+	int speed_1000 = 0;
+
+	u32 pcs = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num));
+	u32 psr = mv_read(MV643XX_ETH_PORT_STATUS_REG(port_num));
+
+	mode_10_bit = psr & MV643XX_ETH_PORT_STATUS_MODE_10_BIT;
+
+	if (mode_10_bit) {
+		ecmd->supported = SUPPORTED_10baseT_Half;
+	} else {
+		ecmd->supported = (SUPPORTED_10baseT_Half		|
+				   SUPPORTED_10baseT_Full		|
+				   SUPPORTED_100baseT_Half		|
+				   SUPPORTED_100baseT_Full		|
+				   SUPPORTED_1000baseT_Full		|
+				   (autoneg ? SUPPORTED_Autoneg : 0)	|
+				   SUPPORTED_TP);
+
+		auto_duplex = !(pcs & MV643XX_ETH_DISABLE_AUTO_NEG_FOR_DUPLX);
+		auto_speed = !(pcs & MV643XX_ETH_DISABLE_AUTO_NEG_SPEED_GMII);
+
+		ecmd->advertising = ADVERTISED_TP;
+
+		if (autoneg) {
+			ecmd->advertising |= ADVERTISED_Autoneg;
+
+			if (auto_duplex) {
+				half_duplex = 1;
+				full_duplex = 1;
+			} else {
+				if (pcs & MV643XX_ETH_SET_FULL_DUPLEX_MODE)
+					full_duplex = 1;
+				else
+					half_duplex = 1;
+			}
+
+			if (auto_speed) {
+				speed_10 = 1;
+				speed_100 = 1;
+				speed_1000 = 1;
+			} else {
+				if (pcs & MV643XX_ETH_SET_GMII_SPEED_TO_1000)
+					speed_1000 = 1;
+				else if (pcs & MV643XX_ETH_SET_MII_SPEED_TO_100)
+					speed_100 = 1;
+				else
+					speed_10 = 1;
+			}
+
+			if (speed_10 & half_duplex)
+				ecmd->advertising |= ADVERTISED_10baseT_Half;
+			if (speed_10 & full_duplex)
+				ecmd->advertising |= ADVERTISED_10baseT_Full;
+			if (speed_100 & half_duplex)
+				ecmd->advertising |= ADVERTISED_100baseT_Half;
+			if (speed_100 & full_duplex)
+				ecmd->advertising |= ADVERTISED_100baseT_Full;
+			if (speed_1000)
+				ecmd->advertising |= ADVERTISED_1000baseT_Full;
+		}
+	}
+
+	ecmd->port = PORT_TP;
+	ecmd->phy_address = ethernet_phy_get(port_num);
+
+	ecmd->transceiver = XCVR_EXTERNAL;
+
+	if (netif_carrier_ok(netdev)) {
+		if (mode_10_bit)
+			ecmd->speed = SPEED_10;
+		else {
+			if (psr & MV643XX_ETH_PORT_STATUS_GMII_1000)
+				ecmd->speed = SPEED_1000;
+			else if (psr & MV643XX_ETH_PORT_STATUS_MII_100)
+				ecmd->speed = SPEED_100;
+			else
+				ecmd->speed = SPEED_10;
+		}
+
+		if (psr & MV643XX_ETH_PORT_STATUS_FULL_DUPLEX)
+			ecmd->duplex = DUPLEX_FULL;
+		else
+			ecmd->duplex = DUPLEX_HALF;
+	} else {
+		ecmd->speed = -1;
+		ecmd->duplex = -1;
+	}
+
+	ecmd->autoneg = autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+	return 0;
+}
+
+static void
+mv643xx_get_drvinfo(struct net_device *netdev,
+                       struct ethtool_drvinfo *drvinfo)
+{
+	strncpy(drvinfo->driver,  mv643xx_driver_name, 32);
+	strncpy(drvinfo->version, mv643xx_driver_version, 32);
+	strncpy(drvinfo->fw_version, "N/A", 32);
+	strncpy(drvinfo->bus_info, "mv643xx", 32);
+	drvinfo->n_stats = MV643XX_STATS_LEN;
+}
+
+static int 
+mv643xx_get_stats_count(struct net_device *netdev)
+{
+	return MV643XX_STATS_LEN;
+}
+
+static void 
+mv643xx_get_ethtool_stats(struct net_device *netdev, 
+		struct ethtool_stats *stats, uint64_t *data)
+{
+	struct mv643xx_private *mp = netdev->priv;
+	int i;
+
+	eth_update_mib_counters(mp);
+
+	for(i = 0; i < MV643XX_STATS_LEN; i++) {
+		char *p = (char *)mp+mv643xx_gstrings_stats[i].stat_offset;	
+		data[i] = (mv643xx_gstrings_stats[i].sizeof_stat == 
+			sizeof(uint64_t)) ? *(uint64_t *)p : *(uint32_t *)p;
+	}
+}
+
+static void 
+mv643xx_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data)
+{
+	int i;
+
+	switch(stringset) {
+	case ETH_SS_STATS:
+		for (i=0; i < MV643XX_STATS_LEN; i++) {
+			memcpy(data + i * ETH_GSTRING_LEN, 
+			mv643xx_gstrings_stats[i].stat_string,
+			ETH_GSTRING_LEN);
+		}
+		break;
+	}
+}
+
+static struct ethtool_ops mv643xx_ethtool_ops = {
+	.get_settings           = mv643xx_get_settings,
+	.get_drvinfo            = mv643xx_get_drvinfo,
+	.get_link               = ethtool_op_get_link,
+	.get_sg			= ethtool_op_get_sg,
+	.set_sg			= ethtool_op_set_sg,
+	.get_strings            = mv643xx_get_strings,
+	.get_stats_count        = mv643xx_get_stats_count,
+	.get_ethtool_stats      = mv643xx_get_ethtool_stats,
+};
+
+/************* End ethtool support *************************/
diff -Nru a/drivers/net/mv643xx_eth.h b/drivers/net/mv643xx_eth.h
--- a/drivers/net/mv643xx_eth.h	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/mv643xx_eth.h	2005-03-08 14:29:45 -05:00
@@ -1,5 +1,5 @@
-#ifndef __MV64340_ETH_H__
-#define __MV64340_ETH_H__
+#ifndef __MV643XX_ETH_H__
+#define __MV643XX_ETH_H__
 
 #include <linux/version.h>
 #include <linux/module.h>
@@ -46,17 +46,16 @@
  *  The first part is the high level driver of the gigE ethernet ports.
  */
 
-#define ETH_PORT0_IRQ_NUM 48			/* main high register, bit0 */
-#define ETH_PORT1_IRQ_NUM ETH_PORT0_IRQ_NUM+1	/* main high register, bit1 */
-#define ETH_PORT2_IRQ_NUM ETH_PORT0_IRQ_NUM+2	/* main high register, bit1 */
-
-/* Checksum offload for Tx works */
-#define  MV64340_CHECKSUM_OFFLOAD_TX
-#define	 MV64340_NAPI
-#define	 MV64340_TX_FAST_REFILL
-#undef	 MV64340_COAL
+/* Checksum offload for Tx works for most packets, but
+ * fails if previous packet sent did not use hw csum
+ */
+#undef	MV643XX_CHECKSUM_OFFLOAD_TX
+#define	MV643XX_NAPI
+#define	MV643XX_TX_FAST_REFILL
+#undef	MV643XX_RX_QUEUE_FILL_ON_TASK	/* Does not work, yet */
+#undef	MV643XX_COAL
 
-/* 
+/*
  * Number of RX / TX descriptors on RX / TX rings.
  * Note that allocating RX descriptors is done by allocating the RX
  * ring AND a preallocated RX buffers (skb's) for each descriptor.
@@ -65,89 +64,35 @@
  */
 
 /* Default TX ring size is 1000 descriptors */
-#define MV64340_TX_QUEUE_SIZE 1000
+#define MV643XX_DEFAULT_TX_QUEUE_SIZE 1000
 
 /* Default RX ring size is 400 descriptors */
-#define MV64340_RX_QUEUE_SIZE 400
+#define MV643XX_DEFAULT_RX_QUEUE_SIZE 400
 
-#define MV64340_TX_COAL 100
-#ifdef MV64340_COAL
-#define MV64340_RX_COAL 100
+#define MV643XX_TX_COAL 100
+#ifdef MV643XX_COAL
+#define MV643XX_RX_COAL 100
 #endif
 
-
 /*
- * The second part is the low level driver of the gigE ethernet ports.   *
+ * The second part is the low level driver of the gigE ethernet ports.
  */
 
-
 /*
- * Header File for : MV-643xx network interface header 
+ * Header File for : MV-643xx network interface header
  *
  * DESCRIPTION:
- *       This header file contains macros typedefs and function declaration for
- *       the Marvell Gig Bit Ethernet Controller. 
+ *	This header file contains macros typedefs and function declaration for
+ *	the Marvell Gig Bit Ethernet Controller.
  *
  * DEPENDENCIES:
- *       None.
+ *	None.
  *
  */
 
-/* Default port configuration value */
-#define PORT_CONFIG_VALUE                       \
-             ETH_UNICAST_NORMAL_MODE		|   \
-             ETH_DEFAULT_RX_QUEUE_0		|   \
-             ETH_DEFAULT_RX_ARP_QUEUE_0		|   \
-             ETH_RECEIVE_BC_IF_NOT_IP_OR_ARP	|   \
-             ETH_RECEIVE_BC_IF_IP		|   \
-             ETH_RECEIVE_BC_IF_ARP 		|   \
-             ETH_CAPTURE_TCP_FRAMES_DIS		|   \
-             ETH_CAPTURE_UDP_FRAMES_DIS		|   \
-             ETH_DEFAULT_RX_TCP_QUEUE_0		|   \
-             ETH_DEFAULT_RX_UDP_QUEUE_0		|   \
-             ETH_DEFAULT_RX_BPDU_QUEUE_0
-
-/* Default port extend configuration value */
-#define PORT_CONFIG_EXTEND_VALUE		\
-             ETH_SPAN_BPDU_PACKETS_AS_NORMAL	|   \
-             ETH_PARTITION_DISABLE
-
-
-/* Default sdma control value */
-#define PORT_SDMA_CONFIG_VALUE			\
-			 ETH_RX_BURST_SIZE_16_64BIT 	|	\
-			 GT_ETH_IPG_INT_RX(0) 		|	\
-			 ETH_TX_BURST_SIZE_16_64BIT;
-
-#define GT_ETH_IPG_INT_RX(value)                \
-            ((value & 0x3fff) << 8)
-
-/* Default port serial control value */
-#define PORT_SERIAL_CONTROL_VALUE		\
-			ETH_FORCE_LINK_PASS 			|	\
-			ETH_ENABLE_AUTO_NEG_FOR_DUPLX		|	\
-			ETH_DISABLE_AUTO_NEG_FOR_FLOW_CTRL 	|	\
-			ETH_ADV_SYMMETRIC_FLOW_CTRL 		|	\
-			ETH_FORCE_FC_MODE_NO_PAUSE_DIS_TX 	|	\
-			ETH_FORCE_BP_MODE_NO_JAM 		|	\
-			BIT9 					|	\
-			ETH_DO_NOT_FORCE_LINK_FAIL 		|	\
-			ETH_RETRANSMIT_16_ATTEMPTS 		|	\
-			ETH_ENABLE_AUTO_NEG_SPEED_GMII	 	|	\
-			ETH_DTE_ADV_0 				|	\
-			ETH_DISABLE_AUTO_NEG_BYPASS		|	\
-			ETH_AUTO_NEG_NO_CHANGE 			|	\
-			ETH_MAX_RX_PACKET_9700BYTE 		|	\
-			ETH_CLR_EXT_LOOPBACK 			|	\
-			ETH_SET_FULL_DUPLEX_MODE 		|	\
-			ETH_ENABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX
-
-#define RX_BUFFER_MAX_SIZE  0x4000000
-#define TX_BUFFER_MAX_SIZE  0x4000000
-
 /* MAC accepet/reject macros */
-#define ACCEPT_MAC_ADDR	    0
-#define REJECT_MAC_ADDR	    1
+#define ACCEPT_MAC_ADDR				0
+#define REJECT_MAC_ADDR				1
 
 /* Buffer offset from buffer pointer */
 #define RX_BUF_OFFSET				0x2
@@ -155,277 +100,132 @@
 /* Gigabit Ethernet Unit Global Registers */
 
 /* MIB Counters register definitions */
-#define ETH_MIB_GOOD_OCTETS_RECEIVED_LOW   0x0
-#define ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH  0x4
-#define ETH_MIB_BAD_OCTETS_RECEIVED        0x8
-#define ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR  0xc
-#define ETH_MIB_GOOD_FRAMES_RECEIVED       0x10
-#define ETH_MIB_BAD_FRAMES_RECEIVED        0x14
-#define ETH_MIB_BROADCAST_FRAMES_RECEIVED  0x18
-#define ETH_MIB_MULTICAST_FRAMES_RECEIVED  0x1c
-#define ETH_MIB_FRAMES_64_OCTETS           0x20
-#define ETH_MIB_FRAMES_65_TO_127_OCTETS    0x24
-#define ETH_MIB_FRAMES_128_TO_255_OCTETS   0x28
-#define ETH_MIB_FRAMES_256_TO_511_OCTETS   0x2c
-#define ETH_MIB_FRAMES_512_TO_1023_OCTETS  0x30
-#define ETH_MIB_FRAMES_1024_TO_MAX_OCTETS  0x34
-#define ETH_MIB_GOOD_OCTETS_SENT_LOW       0x38
-#define ETH_MIB_GOOD_OCTETS_SENT_HIGH      0x3c
-#define ETH_MIB_GOOD_FRAMES_SENT           0x40
-#define ETH_MIB_EXCESSIVE_COLLISION        0x44
-#define ETH_MIB_MULTICAST_FRAMES_SENT      0x48
-#define ETH_MIB_BROADCAST_FRAMES_SENT      0x4c
-#define ETH_MIB_UNREC_MAC_CONTROL_RECEIVED 0x50
-#define ETH_MIB_FC_SENT                    0x54
-#define ETH_MIB_GOOD_FC_RECEIVED           0x58
-#define ETH_MIB_BAD_FC_RECEIVED            0x5c
-#define ETH_MIB_UNDERSIZE_RECEIVED         0x60
-#define ETH_MIB_FRAGMENTS_RECEIVED         0x64
-#define ETH_MIB_OVERSIZE_RECEIVED          0x68
-#define ETH_MIB_JABBER_RECEIVED            0x6c
-#define ETH_MIB_MAC_RECEIVE_ERROR          0x70
-#define ETH_MIB_BAD_CRC_EVENT              0x74
-#define ETH_MIB_COLLISION                  0x78
-#define ETH_MIB_LATE_COLLISION             0x7c
+#define ETH_MIB_GOOD_OCTETS_RECEIVED_LOW	0x0
+#define ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH	0x4
+#define ETH_MIB_BAD_OCTETS_RECEIVED		0x8
+#define ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR	0xc
+#define ETH_MIB_GOOD_FRAMES_RECEIVED		0x10
+#define ETH_MIB_BAD_FRAMES_RECEIVED		0x14
+#define ETH_MIB_BROADCAST_FRAMES_RECEIVED	0x18
+#define ETH_MIB_MULTICAST_FRAMES_RECEIVED	0x1c
+#define ETH_MIB_FRAMES_64_OCTETS		0x20
+#define ETH_MIB_FRAMES_65_TO_127_OCTETS		0x24
+#define ETH_MIB_FRAMES_128_TO_255_OCTETS	0x28
+#define ETH_MIB_FRAMES_256_TO_511_OCTETS	0x2c
+#define ETH_MIB_FRAMES_512_TO_1023_OCTETS	0x30
+#define ETH_MIB_FRAMES_1024_TO_MAX_OCTETS	0x34
+#define ETH_MIB_GOOD_OCTETS_SENT_LOW		0x38
+#define ETH_MIB_GOOD_OCTETS_SENT_HIGH		0x3c
+#define ETH_MIB_GOOD_FRAMES_SENT		0x40
+#define ETH_MIB_EXCESSIVE_COLLISION		0x44
+#define ETH_MIB_MULTICAST_FRAMES_SENT		0x48
+#define ETH_MIB_BROADCAST_FRAMES_SENT		0x4c
+#define ETH_MIB_UNREC_MAC_CONTROL_RECEIVED	0x50
+#define ETH_MIB_FC_SENT				0x54
+#define ETH_MIB_GOOD_FC_RECEIVED		0x58
+#define ETH_MIB_BAD_FC_RECEIVED			0x5c
+#define ETH_MIB_UNDERSIZE_RECEIVED		0x60
+#define ETH_MIB_FRAGMENTS_RECEIVED		0x64
+#define ETH_MIB_OVERSIZE_RECEIVED		0x68
+#define ETH_MIB_JABBER_RECEIVED			0x6c
+#define ETH_MIB_MAC_RECEIVE_ERROR		0x70
+#define ETH_MIB_BAD_CRC_EVENT			0x74
+#define ETH_MIB_COLLISION			0x78
+#define ETH_MIB_LATE_COLLISION			0x7c
 
 /* Port serial status reg (PSR) */
-#define ETH_INTERFACE_GMII_MII                          0
-#define ETH_INTERFACE_PCM                               BIT0
-#define ETH_LINK_IS_DOWN                                0
-#define ETH_LINK_IS_UP                                  BIT1
-#define ETH_PORT_AT_HALF_DUPLEX                         0
-#define ETH_PORT_AT_FULL_DUPLEX                         BIT2
-#define ETH_RX_FLOW_CTRL_DISABLED                       0
-#define ETH_RX_FLOW_CTRL_ENBALED                        BIT3
-#define ETH_GMII_SPEED_100_10                           0
-#define ETH_GMII_SPEED_1000                             BIT4
-#define ETH_MII_SPEED_10                                0
-#define ETH_MII_SPEED_100                               BIT5
-#define ETH_NO_TX                                       0
-#define ETH_TX_IN_PROGRESS                              BIT7
-#define ETH_BYPASS_NO_ACTIVE                            0
-#define ETH_BYPASS_ACTIVE                               BIT8
-#define ETH_PORT_NOT_AT_PARTITION_STATE                 0
-#define ETH_PORT_AT_PARTITION_STATE                     BIT9
-#define ETH_PORT_TX_FIFO_NOT_EMPTY                      0
-#define ETH_PORT_TX_FIFO_EMPTY                          BIT10
-
-
-/* These macros describes the Port configuration reg (Px_cR) bits */
-#define ETH_UNICAST_NORMAL_MODE                         0
-#define ETH_UNICAST_PROMISCUOUS_MODE                    BIT0
-#define ETH_DEFAULT_RX_QUEUE_0                          0
-#define ETH_DEFAULT_RX_QUEUE_1                          BIT1
-#define ETH_DEFAULT_RX_QUEUE_2                          BIT2
-#define ETH_DEFAULT_RX_QUEUE_3                          (BIT2 | BIT1)
-#define ETH_DEFAULT_RX_QUEUE_4                          BIT3
-#define ETH_DEFAULT_RX_QUEUE_5                          (BIT3 | BIT1)
-#define ETH_DEFAULT_RX_QUEUE_6                          (BIT3 | BIT2)
-#define ETH_DEFAULT_RX_QUEUE_7                          (BIT3 | BIT2 | BIT1)
-#define ETH_DEFAULT_RX_ARP_QUEUE_0                      0
-#define ETH_DEFAULT_RX_ARP_QUEUE_1                      BIT4
-#define ETH_DEFAULT_RX_ARP_QUEUE_2                      BIT5
-#define ETH_DEFAULT_RX_ARP_QUEUE_3                      (BIT5 | BIT4)
-#define ETH_DEFAULT_RX_ARP_QUEUE_4                      BIT6
-#define ETH_DEFAULT_RX_ARP_QUEUE_5                      (BIT6 | BIT4)
-#define ETH_DEFAULT_RX_ARP_QUEUE_6                      (BIT6 | BIT5)
-#define ETH_DEFAULT_RX_ARP_QUEUE_7                      (BIT6 | BIT5 | BIT4)
-#define ETH_RECEIVE_BC_IF_NOT_IP_OR_ARP                 0
-#define ETH_REJECT_BC_IF_NOT_IP_OR_ARP                  BIT7
-#define ETH_RECEIVE_BC_IF_IP                            0
-#define ETH_REJECT_BC_IF_IP                             BIT8
-#define ETH_RECEIVE_BC_IF_ARP                           0
-#define ETH_REJECT_BC_IF_ARP                            BIT9
-#define ETH_TX_AM_NO_UPDATE_ERROR_SUMMARY               BIT12
-#define ETH_CAPTURE_TCP_FRAMES_DIS                      0
-#define ETH_CAPTURE_TCP_FRAMES_EN                       BIT14
-#define ETH_CAPTURE_UDP_FRAMES_DIS                      0
-#define ETH_CAPTURE_UDP_FRAMES_EN                       BIT15
-#define ETH_DEFAULT_RX_TCP_QUEUE_0                      0
-#define ETH_DEFAULT_RX_TCP_QUEUE_1                      BIT16
-#define ETH_DEFAULT_RX_TCP_QUEUE_2                      BIT17
-#define ETH_DEFAULT_RX_TCP_QUEUE_3                      (BIT17 | BIT16)
-#define ETH_DEFAULT_RX_TCP_QUEUE_4                      BIT18
-#define ETH_DEFAULT_RX_TCP_QUEUE_5                      (BIT18 | BIT16)
-#define ETH_DEFAULT_RX_TCP_QUEUE_6                      (BIT18 | BIT17)
-#define ETH_DEFAULT_RX_TCP_QUEUE_7                      (BIT18 | BIT17 | BIT16)
-#define ETH_DEFAULT_RX_UDP_QUEUE_0                      0
-#define ETH_DEFAULT_RX_UDP_QUEUE_1                      BIT19
-#define ETH_DEFAULT_RX_UDP_QUEUE_2                      BIT20
-#define ETH_DEFAULT_RX_UDP_QUEUE_3                      (BIT20 | BIT19)
-#define ETH_DEFAULT_RX_UDP_QUEUE_4                      (BIT21
-#define ETH_DEFAULT_RX_UDP_QUEUE_5                      (BIT21 | BIT19)
-#define ETH_DEFAULT_RX_UDP_QUEUE_6                      (BIT21 | BIT20)
-#define ETH_DEFAULT_RX_UDP_QUEUE_7                      (BIT21 | BIT20 | BIT19)
-#define ETH_DEFAULT_RX_BPDU_QUEUE_0                      0
-#define ETH_DEFAULT_RX_BPDU_QUEUE_1                     BIT22
-#define ETH_DEFAULT_RX_BPDU_QUEUE_2                     BIT23
-#define ETH_DEFAULT_RX_BPDU_QUEUE_3                     (BIT23 | BIT22)
-#define ETH_DEFAULT_RX_BPDU_QUEUE_4                     BIT24
-#define ETH_DEFAULT_RX_BPDU_QUEUE_5                     (BIT24 | BIT22)
-#define ETH_DEFAULT_RX_BPDU_QUEUE_6                     (BIT24 | BIT23)
-#define ETH_DEFAULT_RX_BPDU_QUEUE_7                     (BIT24 | BIT23 | BIT22)
-
-
-/* These macros describes the Port configuration extend reg (Px_cXR) bits*/
-#define ETH_CLASSIFY_EN                                 BIT0
-#define ETH_SPAN_BPDU_PACKETS_AS_NORMAL                 0
-#define ETH_SPAN_BPDU_PACKETS_TO_RX_QUEUE_7             BIT1
-#define ETH_PARTITION_DISABLE                           0
-#define ETH_PARTITION_ENABLE                            BIT2
-
-
-/* Tx/Rx queue command reg (RQCR/TQCR)*/
-#define ETH_QUEUE_0_ENABLE                              BIT0
-#define ETH_QUEUE_1_ENABLE                              BIT1
-#define ETH_QUEUE_2_ENABLE                              BIT2
-#define ETH_QUEUE_3_ENABLE                              BIT3
-#define ETH_QUEUE_4_ENABLE                              BIT4
-#define ETH_QUEUE_5_ENABLE                              BIT5
-#define ETH_QUEUE_6_ENABLE                              BIT6
-#define ETH_QUEUE_7_ENABLE                              BIT7
-#define ETH_QUEUE_0_DISABLE                             BIT8
-#define ETH_QUEUE_1_DISABLE                             BIT9
-#define ETH_QUEUE_2_DISABLE                             BIT10
-#define ETH_QUEUE_3_DISABLE                             BIT11
-#define ETH_QUEUE_4_DISABLE                             BIT12
-#define ETH_QUEUE_5_DISABLE                             BIT13
-#define ETH_QUEUE_6_DISABLE                             BIT14
-#define ETH_QUEUE_7_DISABLE                             BIT15
-
-
-/* These macros describes the Port Sdma configuration reg (SDCR) bits */
-#define ETH_RIFB                                        BIT0
-#define ETH_RX_BURST_SIZE_1_64BIT                       0
-#define ETH_RX_BURST_SIZE_2_64BIT                       BIT1
-#define ETH_RX_BURST_SIZE_4_64BIT                       BIT2
-#define ETH_RX_BURST_SIZE_8_64BIT                       (BIT2 | BIT1)
-#define ETH_RX_BURST_SIZE_16_64BIT                      BIT3
-#define ETH_BLM_RX_NO_SWAP                              BIT4
-#define ETH_BLM_RX_BYTE_SWAP                            0
-#define ETH_BLM_TX_NO_SWAP                              BIT5
-#define ETH_BLM_TX_BYTE_SWAP                            0
-#define ETH_DESCRIPTORS_BYTE_SWAP                       BIT6
-#define ETH_DESCRIPTORS_NO_SWAP                         0
-#define ETH_TX_BURST_SIZE_1_64BIT                       0
-#define ETH_TX_BURST_SIZE_2_64BIT                       BIT22
-#define ETH_TX_BURST_SIZE_4_64BIT                       BIT23
-#define ETH_TX_BURST_SIZE_8_64BIT                       (BIT23 | BIT22)
-#define ETH_TX_BURST_SIZE_16_64BIT                      BIT24
-
-
-
-/* These macros describes the Port serial control reg (PSCR) bits */
-#define ETH_SERIAL_PORT_DISABLE                         0
-#define ETH_SERIAL_PORT_ENABLE                          BIT0
-#define ETH_FORCE_LINK_PASS                             BIT1
-#define ETH_DO_NOT_FORCE_LINK_PASS                      0
-#define ETH_ENABLE_AUTO_NEG_FOR_DUPLX                   0
-#define ETH_DISABLE_AUTO_NEG_FOR_DUPLX                  BIT2
-#define ETH_ENABLE_AUTO_NEG_FOR_FLOW_CTRL               0
-#define ETH_DISABLE_AUTO_NEG_FOR_FLOW_CTRL              BIT3
-#define ETH_ADV_NO_FLOW_CTRL                            0
-#define ETH_ADV_SYMMETRIC_FLOW_CTRL                     BIT4
-#define ETH_FORCE_FC_MODE_NO_PAUSE_DIS_TX               0
-#define ETH_FORCE_FC_MODE_TX_PAUSE_DIS                  BIT5
-#define ETH_FORCE_BP_MODE_NO_JAM                        0
-#define ETH_FORCE_BP_MODE_JAM_TX                        BIT7
-#define ETH_FORCE_BP_MODE_JAM_TX_ON_RX_ERR              BIT8
-#define ETH_FORCE_LINK_FAIL                             0
-#define ETH_DO_NOT_FORCE_LINK_FAIL                      BIT10
-#define ETH_RETRANSMIT_16_ATTEMPTS                      0
-#define ETH_RETRANSMIT_FOREVER                          BIT11
-#define ETH_DISABLE_AUTO_NEG_SPEED_GMII                 BIT13
-#define ETH_ENABLE_AUTO_NEG_SPEED_GMII                  0
-#define ETH_DTE_ADV_0                                   0
-#define ETH_DTE_ADV_1                                   BIT14
-#define ETH_DISABLE_AUTO_NEG_BYPASS                     0
-#define ETH_ENABLE_AUTO_NEG_BYPASS                      BIT15
-#define ETH_AUTO_NEG_NO_CHANGE                          0
-#define ETH_RESTART_AUTO_NEG                            BIT16
-#define ETH_MAX_RX_PACKET_1518BYTE                      0
-#define ETH_MAX_RX_PACKET_1522BYTE                      BIT17
-#define ETH_MAX_RX_PACKET_1552BYTE                      BIT18
-#define ETH_MAX_RX_PACKET_9022BYTE                      (BIT18 | BIT17)
-#define ETH_MAX_RX_PACKET_9192BYTE                      BIT19
-#define ETH_MAX_RX_PACKET_9700BYTE                      (BIT19 | BIT17)
-#define ETH_SET_EXT_LOOPBACK                            BIT20
-#define ETH_CLR_EXT_LOOPBACK                            0
-#define ETH_SET_FULL_DUPLEX_MODE                        BIT21
-#define ETH_SET_HALF_DUPLEX_MODE                        0
-#define ETH_ENABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX       BIT22
-#define ETH_DISABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX      0
-#define ETH_SET_GMII_SPEED_TO_10_100                    0
-#define ETH_SET_GMII_SPEED_TO_1000                      BIT23
-#define ETH_SET_MII_SPEED_TO_10                         0
-#define ETH_SET_MII_SPEED_TO_100                        BIT24
-
+#define ETH_INTERFACE_GMII_MII			0
+#define ETH_INTERFACE_PCM			BIT0
+#define ETH_LINK_IS_DOWN			0
+#define ETH_LINK_IS_UP				BIT1
+#define ETH_PORT_AT_HALF_DUPLEX			0
+#define ETH_PORT_AT_FULL_DUPLEX			BIT2
+#define ETH_RX_FLOW_CTRL_DISABLED		0
+#define ETH_RX_FLOW_CTRL_ENBALED		BIT3
+#define ETH_GMII_SPEED_100_10			0
+#define ETH_GMII_SPEED_1000			BIT4
+#define ETH_MII_SPEED_10			0
+#define ETH_MII_SPEED_100			BIT5
+#define ETH_NO_TX				0
+#define ETH_TX_IN_PROGRESS			BIT7
+#define ETH_BYPASS_NO_ACTIVE			0
+#define ETH_BYPASS_ACTIVE			BIT8
+#define ETH_PORT_NOT_AT_PARTITION_STATE		0
+#define ETH_PORT_AT_PARTITION_STATE		BIT9
+#define ETH_PORT_TX_FIFO_NOT_EMPTY		0
+#define ETH_PORT_TX_FIFO_EMPTY			BIT10
+
+#define ETH_DEFAULT_RX_BPDU_QUEUE_3		(BIT23 | BIT22)
+#define ETH_DEFAULT_RX_BPDU_QUEUE_4		BIT24
+#define ETH_DEFAULT_RX_BPDU_QUEUE_5		(BIT24 | BIT22)
+#define ETH_DEFAULT_RX_BPDU_QUEUE_6		(BIT24 | BIT23)
+#define ETH_DEFAULT_RX_BPDU_QUEUE_7		(BIT24 | BIT23 | BIT22)
 
 /* SMI reg */
-#define ETH_SMI_BUSY        	BIT28	/* 0 - Write, 1 - Read          */
-#define ETH_SMI_READ_VALID  	BIT27	/* 0 - Write, 1 - Read          */
+#define ETH_SMI_BUSY		BIT28	/* 0 - Write, 1 - Read		*/
+#define ETH_SMI_READ_VALID	BIT27	/* 0 - Write, 1 - Read		*/
 #define ETH_SMI_OPCODE_WRITE	0	/* Completion of Read operation */
-#define ETH_SMI_OPCODE_READ 	BIT26	/* Operation is in progress             */
+#define ETH_SMI_OPCODE_READ 	BIT26	/* Operation is in progress	*/
 
 /* SDMA command status fields macros */
 
 /* Tx & Rx descriptors status */
-#define ETH_ERROR_SUMMARY                   (BIT0)
+#define ETH_ERROR_SUMMARY			(BIT0)
 
 /* Tx & Rx descriptors command */
-#define ETH_BUFFER_OWNED_BY_DMA             (BIT31)
+#define ETH_BUFFER_OWNED_BY_DMA			(BIT31)
 
 /* Tx descriptors status */
-#define ETH_LC_ERROR                        (0	  )
-#define ETH_UR_ERROR                        (BIT1 )
-#define ETH_RL_ERROR                        (BIT2 )
-#define ETH_LLC_SNAP_FORMAT                 (BIT9 )
+#define ETH_LC_ERROR				(0    )
+#define ETH_UR_ERROR				(BIT1 )
+#define ETH_RL_ERROR				(BIT2 )
+#define ETH_LLC_SNAP_FORMAT			(BIT9 )
 
 /* Rx descriptors status */
-#define ETH_CRC_ERROR                       (0	  )
-#define ETH_OVERRUN_ERROR                   (BIT1 )
-#define ETH_MAX_FRAME_LENGTH_ERROR          (BIT2 )
-#define ETH_RESOURCE_ERROR                  ((BIT2 | BIT1))
-#define ETH_VLAN_TAGGED                     (BIT19)
-#define ETH_BPDU_FRAME                      (BIT20)
-#define ETH_TCP_FRAME_OVER_IP_V_4           (0    )
-#define ETH_UDP_FRAME_OVER_IP_V_4           (BIT21)
-#define ETH_OTHER_FRAME_TYPE                (BIT22)
-#define ETH_LAYER_2_IS_ETH_V_2              (BIT23)
-#define ETH_FRAME_TYPE_IP_V_4               (BIT24)
-#define ETH_FRAME_HEADER_OK                 (BIT25)
-#define ETH_RX_LAST_DESC                    (BIT26)
-#define ETH_RX_FIRST_DESC                   (BIT27)
-#define ETH_UNKNOWN_DESTINATION_ADDR        (BIT28)
-#define ETH_RX_ENABLE_INTERRUPT             (BIT29)
-#define ETH_LAYER_4_CHECKSUM_OK             (BIT30)
+#define ETH_CRC_ERROR				(0    )
+#define ETH_OVERRUN_ERROR			(BIT1 )
+#define ETH_MAX_FRAME_LENGTH_ERROR		(BIT2 )
+#define ETH_RESOURCE_ERROR			((BIT2 | BIT1))
+#define ETH_VLAN_TAGGED				(BIT19)
+#define ETH_BPDU_FRAME				(BIT20)
+#define ETH_TCP_FRAME_OVER_IP_V_4		(0    )
+#define ETH_UDP_FRAME_OVER_IP_V_4		(BIT21)
+#define ETH_OTHER_FRAME_TYPE			(BIT22)
+#define ETH_LAYER_2_IS_ETH_V_2			(BIT23)
+#define ETH_FRAME_TYPE_IP_V_4			(BIT24)
+#define ETH_FRAME_HEADER_OK			(BIT25)
+#define ETH_RX_LAST_DESC			(BIT26)
+#define ETH_RX_FIRST_DESC			(BIT27)
+#define ETH_UNKNOWN_DESTINATION_ADDR		(BIT28)
+#define ETH_RX_ENABLE_INTERRUPT			(BIT29)
+#define ETH_LAYER_4_CHECKSUM_OK			(BIT30)
 
 /* Rx descriptors byte count */
-#define ETH_FRAME_FRAGMENTED                (BIT2)
+#define ETH_FRAME_FRAGMENTED			(BIT2)
 
 /* Tx descriptors command */
 #define ETH_LAYER_4_CHECKSUM_FIRST_DESC		(BIT10)
-#define ETH_FRAME_SET_TO_VLAN               (BIT15)
-#define ETH_TCP_FRAME                       (0	  )
-#define ETH_UDP_FRAME                       (BIT16)
-#define ETH_GEN_TCP_UDP_CHECKSUM            (BIT17)
-#define ETH_GEN_IP_V_4_CHECKSUM             (BIT18)
-#define ETH_ZERO_PADDING                    (BIT19)
-#define ETH_TX_LAST_DESC                    (BIT20)
-#define ETH_TX_FIRST_DESC                   (BIT21)
-#define ETH_GEN_CRC                         (BIT22)
-#define ETH_TX_ENABLE_INTERRUPT             (BIT23)
-#define ETH_AUTO_MODE                       (BIT30)
+#define ETH_FRAME_SET_TO_VLAN			(BIT15)
+#define ETH_TCP_FRAME				(0    )
+#define ETH_UDP_FRAME				(BIT16)
+#define ETH_GEN_TCP_UDP_CHECKSUM		(BIT17)
+#define ETH_GEN_IP_V_4_CHECKSUM			(BIT18)
+#define ETH_ZERO_PADDING			(BIT19)
+#define ETH_TX_LAST_DESC			(BIT20)
+#define ETH_TX_FIRST_DESC			(BIT21)
+#define ETH_GEN_CRC				(BIT22)
+#define ETH_TX_ENABLE_INTERRUPT			(BIT23)
+#define ETH_AUTO_MODE				(BIT30)
 
 /* typedefs */
 
 typedef enum _eth_func_ret_status {
-	ETH_OK,			/* Returned as expected.                    */
-	ETH_ERROR,		/* Fundamental error.                       */
-	ETH_RETRY,		/* Could not process request. Try later.    */
-	ETH_END_OF_JOB,		/* Ring has nothing to process.             */
-	ETH_QUEUE_FULL,		/* Ring resource error.                     */
-	ETH_QUEUE_LAST_RESOURCE	/* Ring resources about to exhaust.         */
+	ETH_OK,			/* Returned as expected.		*/
+	ETH_ERROR,		/* Fundamental error.			*/
+	ETH_RETRY,		/* Could not process request. Try later.*/
+	ETH_END_OF_JOB,		/* Ring has nothing to process.		*/
+	ETH_QUEUE_FULL,		/* Ring resource error.			*/
+	ETH_QUEUE_LAST_RESOURCE	/* Ring resources about to exhaust.	*/
 } ETH_FUNC_RET_STATUS;
 
 typedef enum _eth_target {
@@ -441,66 +241,103 @@
  */
 #if defined(__BIG_ENDIAN)
 struct eth_rx_desc {
-	u16	byte_cnt;	/* Descriptor buffer byte count     */
-	u16	buf_size;	/* Buffer size                      */
-	u32	cmd_sts;	/* Descriptor command status        */
-	u32	next_desc_ptr;	/* Next descriptor pointer          */
-	u32	buf_ptr;	/* Descriptor buffer pointer        */
+	u16 byte_cnt;		/* Descriptor buffer byte count		*/
+	u16 buf_size;		/* Buffer size				*/
+	u32 cmd_sts;		/* Descriptor command status		*/
+	u32 next_desc_ptr;	/* Next descriptor pointer		*/
+	u32 buf_ptr;		/* Descriptor buffer pointer		*/
 };
 
 struct eth_tx_desc {
-	u16	byte_cnt;	/* buffer byte count */
-	u16	l4i_chk;	/* CPU provided TCP checksum */
-	u32	cmd_sts;	/* Command/status field */
-	u32	next_desc_ptr;	/* Pointer to next descriptor */
-	u32	buf_ptr;	/* pointer to buffer for this descriptor */
+	u16 byte_cnt;		/* buffer byte count			*/
+	u16 l4i_chk;		/* CPU provided TCP checksum		*/
+	u32 cmd_sts;		/* Command/status field			*/
+	u32 next_desc_ptr;	/* Pointer to next descriptor		*/
+	u32 buf_ptr;		/* pointer to buffer for this descriptor*/
 };
 
 #elif defined(__LITTLE_ENDIAN)
 struct eth_rx_desc {
-	u32	cmd_sts;	/* Descriptor command status        */
-	u16	buf_size;	/* Buffer size                      */
-	u16	byte_cnt;	/* Descriptor buffer byte count     */
-	u32	buf_ptr;	/* Descriptor buffer pointer        */
-	u32	next_desc_ptr;	/* Next descriptor pointer          */
+	u32 cmd_sts;		/* Descriptor command status		*/
+	u16 buf_size;		/* Buffer size				*/
+	u16 byte_cnt;		/* Descriptor buffer byte count		*/
+	u32 buf_ptr;		/* Descriptor buffer pointer		*/
+	u32 next_desc_ptr;	/* Next descriptor pointer		*/
 };
 
 struct eth_tx_desc {
-	u32	cmd_sts;	/* Command/status field */
-	u16	l4i_chk;	/* CPU provided TCP checksum */
-	u16	byte_cnt;	/* buffer byte count */
-	u32	buf_ptr;	/* pointer to buffer for this descriptor */
-	u32	next_desc_ptr;	/* Pointer to next descriptor */
+	u32 cmd_sts;		/* Command/status field			*/
+	u16 l4i_chk;		/* CPU provided TCP checksum		*/
+	u16 byte_cnt;		/* buffer byte count			*/
+	u32 buf_ptr;		/* pointer to buffer for this descriptor*/
+	u32 next_desc_ptr;	/* Pointer to next descriptor		*/
 };
 #else
 #error One of __BIG_ENDIAN or __LITTLE_ENDIAN must be defined
 #endif
 
-/* Unified struct for Rx and Tx operations. The user is not required to */
-/* be familier with neither Tx nor Rx descriptors.                       */
+/* Unified struct for Rx and Tx operations. The user is not required to	*/
+/* be familier with neither Tx nor Rx descriptors.			*/
 struct pkt_info {
-	unsigned short	byte_cnt;	/* Descriptor buffer byte count     */
-	unsigned short	l4i_chk;	/* Tx CPU provided TCP Checksum     */
-	unsigned int	cmd_sts;	/* Descriptor command status        */
-	dma_addr_t	buf_ptr;	/* Descriptor buffer pointer        */
-	struct sk_buff	* return_info;	/* User resource return information */
+	unsigned short byte_cnt;	/* Descriptor buffer byte count	*/
+	unsigned short l4i_chk;		/* Tx CPU provided TCP Checksum	*/
+	unsigned int cmd_sts;		/* Descriptor command status	*/
+	dma_addr_t buf_ptr;		/* Descriptor buffer pointer	*/
+	struct sk_buff *return_info;	/* User resource return information */
 };
 
-
 /* Ethernet port specific infomation */
 
-struct mv64340_private {
-	int	port_num;		/* User Ethernet port number */
-	u8	port_mac_addr[6];	/* User defined port MAC address. */
-	u32	port_config;		/* User port configuration value */
-	u32	port_config_extend;	/* User port config extend value */
-	u32	port_sdma_config;	/* User port SDMA config value */
-	u32	port_serial_control;	/* User port serial control value */
-	u32	port_tx_queue_command;	/* Port active Tx queues summary */
-	u32	port_rx_queue_command;	/* Port active Rx queues summary */
+struct mv643xx_mib_counters {
+	u64 good_octets_received;
+	u32 bad_octets_received;
+	u32 internal_mac_transmit_err;
+	u32 good_frames_received;
+	u32 bad_frames_received;
+	u32 broadcast_frames_received;
+	u32 multicast_frames_received;
+	u32 frames_64_octets;
+	u32 frames_65_to_127_octets;
+	u32 frames_128_to_255_octets;
+	u32 frames_256_to_511_octets;
+	u32 frames_512_to_1023_octets;
+	u32 frames_1024_to_max_octets;
+	u64 good_octets_sent;
+	u32 good_frames_sent;
+	u32 excessive_collision;
+	u32 multicast_frames_sent;
+	u32 broadcast_frames_sent;
+	u32 unrec_mac_control_received;
+	u32 fc_sent;
+	u32 good_fc_received;
+	u32 bad_fc_received;
+	u32 undersize_received;
+	u32 fragments_received;
+	u32 oversize_received;
+	u32 jabber_received;
+	u32 mac_receive_error;
+	u32 bad_crc_event;
+	u32 collision;
+	u32 late_collision;
+};
+
+struct mv643xx_private {
+	int port_num;			/* User Ethernet port number	*/
+	u8 port_mac_addr[6];		/* User defined port MAC address.*/
+	u32 port_config;		/* User port configuration value*/
+	u32 port_config_extend;		/* User port config extend value*/
+	u32 port_sdma_config;		/* User port SDMA config value	*/
+	u32 port_serial_control;	/* User port serial control value */
+	u32 port_tx_queue_command;	/* Port active Tx queues summary*/
+	u32 port_rx_queue_command;	/* Port active Rx queues summary*/
+
+	u32 rx_sram_addr;		/* Base address of rx sram area */
+	u32 rx_sram_size;		/* Size of rx sram area		*/
+	u32 tx_sram_addr;		/* Base address of tx sram area */
+	u32 tx_sram_size;		/* Size of tx sram area		*/
 
-	int	rx_resource_err;	/* Rx ring resource error flag */
-	int	tx_resource_err;	/* Tx ring resource error flag */
+	int rx_resource_err;		/* Rx ring resource error flag */
+	int tx_resource_err;		/* Tx ring resource error flag */
 
 	/* Tx/Rx rings managment indexes fields. For driver use */
 
@@ -509,30 +346,32 @@
 
 	/* Next available and first returning Tx resource */
 	int tx_curr_desc_q, tx_used_desc_q;
-#ifdef MV64340_CHECKSUM_OFFLOAD_TX
-        int tx_first_desc_q;
+#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
+	int tx_first_desc_q;
+	u32 tx_first_command;
 #endif
 
-#ifdef MV64340_TX_FAST_REFILL
-	u32	tx_clean_threshold;
+#ifdef MV643XX_TX_FAST_REFILL
+	u32 tx_clean_threshold;
 #endif
 
-	volatile struct eth_rx_desc	* p_rx_desc_area;
-	dma_addr_t			rx_desc_dma;
-	unsigned int			rx_desc_area_size;
-	struct sk_buff			* rx_skb[MV64340_RX_QUEUE_SIZE];
-
-	volatile struct eth_tx_desc	* p_tx_desc_area;
-	dma_addr_t			tx_desc_dma;
-	unsigned int			tx_desc_area_size;
-	struct sk_buff			* tx_skb[MV64340_TX_QUEUE_SIZE];
+	struct eth_rx_desc *p_rx_desc_area;
+	dma_addr_t rx_desc_dma;
+	unsigned int rx_desc_area_size;
+	struct sk_buff **rx_skb;
+
+	struct eth_tx_desc *p_tx_desc_area;
+	dma_addr_t tx_desc_dma;
+	unsigned int tx_desc_area_size;
+	struct sk_buff **tx_skb;
 
-	struct work_struct		tx_timeout_task;
+	struct work_struct tx_timeout_task;
 
 	/*
-	 * Former struct mv64340_eth_priv members start here
+	 * Former struct mv643xx_eth_priv members start here
 	 */
 	struct net_device_stats stats;
+	struct mv643xx_mib_counters mib_counters;
 	spinlock_t lock;
 	/* Size of Tx Ring per queue */
 	unsigned int tx_ring_size;
@@ -544,13 +383,13 @@
 	unsigned int rx_ring_skbs;
 
 	/*
-	 * rx_task used to fill RX ring out of bottom half context 
+	 * rx_task used to fill RX ring out of bottom half context
 	 */
 	struct work_struct rx_task;
 
-	/* 
-	 * Used in case RX Ring is empty, which can be caused when 
-	 * system does not have resources (skb's) 
+	/*
+	 * Used in case RX Ring is empty, which can be caused when
+	 * system does not have resources (skb's)
 	 */
 	struct timer_list timeout;
 	long rx_task_busy __attribute__ ((aligned(SMP_CACHE_BYTES)));
@@ -563,9 +402,9 @@
 /* ethernet.h API list */
 
 /* Port operation control routines */
-static void eth_port_init(struct mv64340_private *mp);
+static void eth_port_init(struct mv643xx_private *mp);
 static void eth_port_reset(unsigned int eth_port_num);
-static int eth_port_start(struct mv64340_private *mp);
+static void eth_port_start(struct mv643xx_private *mp);
 
 static void ethernet_set_config_reg(unsigned int eth_port_num,
 				    unsigned int value);
@@ -576,26 +415,24 @@
 				 unsigned char *p_addr);
 
 /* PHY and MIB routines */
-static int ethernet_phy_reset(unsigned int eth_port_num);
+static void ethernet_phy_reset(unsigned int eth_port_num);
+
+static void eth_port_write_smi_reg(unsigned int eth_port_num,
+				   unsigned int phy_reg, unsigned int value);
 
-static int eth_port_write_smi_reg(unsigned int eth_port_num,
-				   unsigned int phy_reg,
-				   unsigned int value);
-
-static int eth_port_read_smi_reg(unsigned int eth_port_num,
-				  unsigned int phy_reg,
-				  unsigned int *value);
+static void eth_port_read_smi_reg(unsigned int eth_port_num,
+				  unsigned int phy_reg, unsigned int *value);
 
 static void eth_clear_mib_counters(unsigned int eth_port_num);
 
 /* Port data flow control routines */
-static ETH_FUNC_RET_STATUS eth_port_send(struct mv64340_private *mp,
-					 struct pkt_info * p_pkt_info);
-static ETH_FUNC_RET_STATUS eth_tx_return_desc(struct mv64340_private *mp,
-					      struct pkt_info * p_pkt_info);
-static ETH_FUNC_RET_STATUS eth_port_receive(struct mv64340_private *mp,
-					    struct pkt_info * p_pkt_info);
-static ETH_FUNC_RET_STATUS eth_rx_return_buff(struct mv64340_private *mp,
-					      struct pkt_info * p_pkt_info);
+static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
+					 struct pkt_info *p_pkt_info);
+static ETH_FUNC_RET_STATUS eth_tx_return_desc(struct mv643xx_private *mp,
+					      struct pkt_info *p_pkt_info);
+static ETH_FUNC_RET_STATUS eth_port_receive(struct mv643xx_private *mp,
+					    struct pkt_info *p_pkt_info);
+static ETH_FUNC_RET_STATUS eth_rx_return_buff(struct mv643xx_private *mp,
+					      struct pkt_info *p_pkt_info);
 
-#endif  /* __MV64340_ETH_H__ */
+#endif				/* __MV643XX_ETH_H__ */
diff -Nru a/drivers/net/sis900.c b/drivers/net/sis900.c
--- a/drivers/net/sis900.c	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/sis900.c	2005-03-08 14:29:45 -05:00
@@ -1,6 +1,6 @@
 /* sis900.c: A SiS 900/7016 PCI Fast Ethernet driver for Linux.
    Copyright 1999 Silicon Integrated System Corporation 
-   Revision:	1.08.06 Sep. 24 2002
+   Revision:	1.08.08 Jan. 22 2005
    
    Modified from the driver which is originally written by Donald Becker.
    
@@ -16,8 +16,8 @@
    preliminary Rev. 1.0 Nov. 10, 1998
    SiS 7014 Single Chip 100BASE-TX/10BASE-T Physical Layer Solution,
    preliminary Rev. 1.0 Jan. 18, 1998
-   http://www.sis.com.tw/support/databook.htm
 
+   Rev 1.08.08 Jan. 22 2005 Daniele Venzano use netif_msg for debugging messages
    Rev 1.08.07 Nov.  2 2003 Daniele Venzano <webvenza@libero.it> add suspend/resume support
    Rev 1.08.06 Sep. 24 2002 Mufasa Yang bug fix for Tx timeout & add SiS963 support
    Rev 1.08.05 Jun.  6 2002 Mufasa Yang bug fix for read_eeprom & Tx descriptor over-boundary
@@ -74,7 +74,7 @@
 #include "sis900.h"
 
 #define SIS900_MODULE_NAME "sis900"
-#define SIS900_DRV_VERSION "v1.08.07 11/02/2003"
+#define SIS900_DRV_VERSION "v1.08.08 Jan. 22 2005"
 
 static char version[] __devinitdata =
 KERN_INFO "sis900.c: " SIS900_DRV_VERSION "\n";
@@ -82,8 +82,13 @@
 static int max_interrupt_work = 40;
 static int multicast_filter_limit = 128;
 
-#define sis900_debug debug
-static int sis900_debug;
+static int sis900_debug = -1; /* Use SIS900_DEF_MSG as value */
+
+#define SIS900_DEF_MSG \
+	(NETIF_MSG_DRV		| \
+	 NETIF_MSG_LINK		| \
+	 NETIF_MSG_RX_ERR	| \
+	 NETIF_MSG_TX_ERR)
 
 /* Time in jiffies before concluding the transmitter is hung. */
 #define TX_TIMEOUT  (4*HZ)
@@ -160,6 +165,8 @@
 	struct timer_list timer; /* Link status detection timer. */
 	u8 autong_complete; /* 1: auto-negotiate complete  */
 
+	u32 msg_enable;
+
 	unsigned int cur_rx, dirty_rx; /* producer/comsumer pointers for Tx/Rx ring */
 	unsigned int cur_tx, dirty_tx;
 
@@ -174,6 +181,7 @@
 
 	unsigned int tx_full; /* The Tx queue is full. */
 	u8 host_bridge_rev;
+	u8 chipset_rev;
 };
 
 MODULE_AUTHOR("Jim Huang <cmhuang@sis.com.tw>, Ollie Lho <ollie@sis.com.tw>");
@@ -182,11 +190,12 @@
 
 module_param(multicast_filter_limit, int, 0444);
 module_param(max_interrupt_work, int, 0444);
-module_param(debug, int, 0444);
+module_param(sis900_debug, int, 0444);
 MODULE_PARM_DESC(multicast_filter_limit, "SiS 900/7016 maximum number of filtered multicast addresses");
 MODULE_PARM_DESC(max_interrupt_work, "SiS 900/7016 maximum events handled per interrupt");
-MODULE_PARM_DESC(debug, "SiS 900/7016 debug level (2-4)");
+MODULE_PARM_DESC(sis900_debug, "SiS 900/7016 bitmapped debugging message level");
 
+static void sis900_poll(struct net_device *dev);
 static int sis900_open(struct net_device *net_dev);
 static int sis900_mii_probe (struct net_device * net_dev);
 static void sis900_init_rxfilter (struct net_device * net_dev);
@@ -235,7 +244,7 @@
 	/* check to see if we have sane EEPROM */
 	signature = (u16) read_eeprom(ioaddr, EEPROMSignature);    
 	if (signature == 0xffff || signature == 0x0000) {
-		printk (KERN_INFO "%s: Error EERPOM read %x\n", 
+		printk (KERN_WARNING "%s: Error EERPOM read %x\n", 
 			net_dev->name, signature);
 		return 0;
 	}
@@ -268,7 +277,7 @@
 	if (!isa_bridge)
 		isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, 0x0018, isa_bridge);
 	if (!isa_bridge) {
-		printk("%s: Can not find ISA bridge\n", net_dev->name);
+		printk(KERN_WARNING "%s: Can not find ISA bridge\n", net_dev->name);
 		return 0;
 	}
 	pci_read_config_byte(isa_bridge, 0x48, &reg);
@@ -386,7 +395,6 @@
 	void *ring_space;
 	long ioaddr;
 	int i, ret;
-	u8 revision;
 	char *card_name = card_names[pci_id->driver_data];
 
 /* when built into the kernel, we only print version if device is found */
@@ -456,35 +464,50 @@
 	net_dev->tx_timeout = sis900_tx_timeout;
 	net_dev->watchdog_timeo = TX_TIMEOUT;
 	net_dev->ethtool_ops = &sis900_ethtool_ops;
-	
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+        net_dev->poll_controller = &sis900_poll;
+#endif
+
+	if (sis900_debug > 0)
+		sis_priv->msg_enable = sis900_debug;
+	else
+		sis_priv->msg_enable = SIS900_DEF_MSG;
+
 	ret = register_netdev(net_dev);
 	if (ret)
 		goto err_unmap_rx;
 		
 	/* Get Mac address according to the chip revision */
-	pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &revision);
+	pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &(sis_priv->chipset_rev));
+	if(netif_msg_probe(sis_priv))
+		printk(KERN_DEBUG "%s: detected revision %2.2x, "
+				"trying to get MAC address...\n",
+				net_dev->name, sis_priv->chipset_rev);
+	
 	ret = 0;
-
-	if (revision == SIS630E_900_REV)
+	if (sis_priv->chipset_rev == SIS630E_900_REV)
 		ret = sis630e_get_mac_addr(pci_dev, net_dev);
-	else if ((revision > 0x81) && (revision <= 0x90) )
+	else if ((sis_priv->chipset_rev > 0x81) && (sis_priv->chipset_rev <= 0x90) )
 		ret = sis635_get_mac_addr(pci_dev, net_dev);
-	else if (revision == SIS96x_900_REV)
+	else if (sis_priv->chipset_rev == SIS96x_900_REV)
 		ret = sis96x_get_mac_addr(pci_dev, net_dev);
 	else
 		ret = sis900_get_mac_addr(pci_dev, net_dev);
 
 	if (ret == 0) {
+		printk(KERN_WARNING "%s: Cannot read MAC address.\n", net_dev->name);
 		ret = -ENODEV;
 		goto err_out_unregister;
 	}
 	
 	/* 630ET : set the mii access mode as software-mode */
-	if (revision == SIS630ET_900_REV)
+	if (sis_priv->chipset_rev == SIS630ET_900_REV)
 		outl(ACCESSMODE | inl(ioaddr + cr), ioaddr + cr);
 
 	/* probe for mii transceiver */
 	if (sis900_mii_probe(net_dev) == 0) {
+		printk(KERN_WARNING "%s: Error probing MII device.\n", net_dev->name);
 		ret = -ENODEV;
 		goto err_out_unregister;
 	}
@@ -536,7 +559,6 @@
 	u16 poll_bit = MII_STAT_LINK, status = 0;
 	unsigned long timeout = jiffies + 5 * HZ;
 	int phy_addr;
-	u8 revision;
 
 	sis_priv->mii = NULL;
 
@@ -550,12 +572,16 @@
 		for(i = 0; i < 2; i++)
 			mii_status = mdio_read(net_dev, phy_addr, MII_STATUS);
 
-		if (mii_status == 0xffff || mii_status == 0x0000)
-			/* the mii is not accessible, try next one */
+		if (mii_status == 0xffff || mii_status == 0x0000) {
+			if (netif_msg_probe(sis_priv))
+				printk(KERN_DEBUG "%s: MII at address %d"
+						" not accessible\n",
+						net_dev->name, phy_addr);
 			continue;
+		}
 		
 		if ((mii_phy = kmalloc(sizeof(struct mii_phy), GFP_KERNEL)) == NULL) {
-			printk(KERN_INFO "Cannot allocate mem for struct mii_phy\n");
+			printk(KERN_WARNING "Cannot allocate mem for struct mii_phy\n");
 			mii_phy = sis_priv->first_mii;
 			while (mii_phy) {
 				struct mii_phy *phy;
@@ -581,9 +607,11 @@
 				if (mii_chip_table[i].phy_types == MIX)
 					mii_phy->phy_types =
 					    (mii_status & (MII_STAT_CAN_TX_FDX | MII_STAT_CAN_TX)) ? LAN : HOME;
-				printk(KERN_INFO "%s: %s transceiver found at address %d.\n",
-				       net_dev->name, mii_chip_table[i].name,
-				       phy_addr);
+				printk(KERN_INFO "%s: %s transceiver found "
+							"at address %d.\n",
+							net_dev->name,
+							mii_chip_table[i].name,
+							phy_addr);
 				break;
 			}
 			
@@ -627,8 +655,7 @@
 		}
 	}
 
-	pci_read_config_byte(sis_priv->pci_dev, PCI_CLASS_REVISION, &revision);
-	if (revision == SIS630E_900_REV) {
+	if (sis_priv->chipset_rev == SIS630E_900_REV) {
 		/* SiS 630E has some bugs on default value of PHY registers */
 		mdio_write(net_dev, sis_priv->cur_phy, MII_ANADV, 0x05e1);
 		mdio_write(net_dev, sis_priv->cur_phy, MII_CONFIG1, 0x22);
@@ -930,6 +957,20 @@
 	return status;
 }
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+*/
+static void sis900_poll(struct net_device *dev)
+{
+	disable_irq(dev->irq);
+	sis900_interrupt(dev->irq, dev, NULL);
+	enable_irq(dev->irq);
+}
+#endif
+
 /**
  *	sis900_open - open sis900 device
  *	@net_dev: the net device to open
@@ -943,15 +984,13 @@
 {
 	struct sis900_private *sis_priv = net_dev->priv;
 	long ioaddr = net_dev->base_addr;
-	u8 revision;
 	int ret;
 
 	/* Soft reset the chip. */
 	sis900_reset(net_dev);
 
 	/* Equalizer workaround Rule */
-	pci_read_config_byte(sis_priv->pci_dev, PCI_CLASS_REVISION, &revision);
-	sis630_set_eq(net_dev, revision);
+	sis630_set_eq(net_dev, sis_priv->chipset_rev);
 
 	ret = request_irq(net_dev->irq, &sis900_interrupt, SA_SHIRQ,
 						net_dev->name, net_dev);
@@ -999,6 +1038,7 @@
 static void
 sis900_init_rxfilter (struct net_device * net_dev)
 {
+	struct sis900_private *sis_priv = net_dev->priv;
 	long ioaddr = net_dev->base_addr;
 	u32 rfcrSave;
 	u32 i;
@@ -1016,8 +1056,8 @@
 		outl((i << RFADDR_shift), ioaddr + rfcr);
 		outl(w, ioaddr + rfdr);
 
-		if (sis900_debug > 2) {
-			printk(KERN_INFO "%s: Receive Filter Addrss[%d]=%x\n",
+		if (netif_msg_hw(sis_priv)) {
+			printk(KERN_DEBUG "%s: Receive Filter Addrss[%d]=%x\n",
 			       net_dev->name, i, inl(ioaddr + rfdr));
 		}
 	}
@@ -1054,8 +1094,8 @@
 
 	/* load Transmit Descriptor Register */
 	outl(sis_priv->tx_ring_dma, ioaddr + txdp);
-	if (sis900_debug > 2)
-		printk(KERN_INFO "%s: TX descriptor register loaded with: %8.8x\n",
+	if (netif_msg_hw(sis_priv))
+		printk(KERN_DEBUG "%s: TX descriptor register loaded with: %8.8x\n",
 		       net_dev->name, inl(ioaddr + txdp));
 }
 
@@ -1108,8 +1148,8 @@
 
 	/* load Receive Descriptor Register */
 	outl(sis_priv->rx_ring_dma, ioaddr + rxdp);
-	if (sis900_debug > 2)
-		printk(KERN_INFO "%s: RX descriptor register loaded with: %8.8x\n",
+	if (netif_msg_hw(sis_priv))
+		printk(KERN_DEBUG "%s: RX descriptor register loaded with: %8.8x\n",
 		       net_dev->name, inl(ioaddr + rxdp));
 }
 
@@ -1219,7 +1259,6 @@
 	struct mii_phy *mii_phy = sis_priv->mii;
 	static int next_tick = 5*HZ;
 	u16 status;
-	u8 revision;
 
 	if (!sis_priv->autong_complete){
 		int speed, duplex = 0;
@@ -1227,9 +1266,7 @@
 		sis900_read_mode(net_dev, &speed, &duplex);
 		if (duplex){
 			sis900_set_mode(net_dev->base_addr, speed, duplex);
-			pci_read_config_byte(sis_priv->pci_dev,
-						PCI_CLASS_REVISION, &revision);
-			sis630_set_eq(net_dev, revision);
+			sis630_set_eq(net_dev, sis_priv->chipset_rev);
 			netif_start_queue(net_dev);
 		}
 
@@ -1256,16 +1293,15 @@
 	/* Link ON -> OFF */
                 if (!(status & MII_STAT_LINK)){
                 	netif_carrier_off(net_dev);
-                	printk(KERN_INFO "%s: Media Link Off\n", net_dev->name);
+			if(netif_msg_link(sis_priv))
+                		printk(KERN_INFO "%s: Media Link Off\n", net_dev->name);
 
                 	/* Change mode issue */
                 	if ((mii_phy->phy_id0 == 0x001D) && 
 			    ((mii_phy->phy_id1 & 0xFFF0) == 0x8000))
                			sis900_reset_phy(net_dev,  sis_priv->cur_phy);
   
-                	pci_read_config_byte(sis_priv->pci_dev,
-					PCI_CLASS_REVISION, &revision);
-			sis630_set_eq(net_dev, revision);
+			sis630_set_eq(net_dev, sis_priv->chipset_rev);
   
                 	goto LookForLink;
                 }
@@ -1371,7 +1407,8 @@
 		status = mdio_read(net_dev, phy_addr, MII_STATUS);
 
 	if (!(status & MII_STAT_LINK)){
-		printk(KERN_INFO "%s: Media Link Off\n", net_dev->name);
+		if(netif_msg_link(sis_priv))
+			printk(KERN_INFO "%s: Media Link Off\n", net_dev->name);
 		sis_priv->autong_complete = 1;
 		netif_carrier_off(net_dev);
 		return;
@@ -1433,7 +1470,8 @@
 			*speed = HW_SPEED_100_MBPS;
 	}
 
-	printk(KERN_INFO "%s: Media Link On %s %s-duplex \n",
+	if(netif_msg_link(sis_priv))
+		printk(KERN_INFO "%s: Media Link On %s %s-duplex \n",
 	       				net_dev->name,
 	       				*speed == HW_SPEED_100_MBPS ?
 	       					"100mbps" : "10mbps",
@@ -1456,8 +1494,9 @@
 	unsigned long flags;
 	int i;
 
-	printk(KERN_INFO "%s: Transmit timeout, status %8.8x %8.8x \n",
-	       net_dev->name, inl(ioaddr + cr), inl(ioaddr + isr));
+	if(netif_msg_tx_err(sis_priv))
+		printk(KERN_INFO "%s: Transmit timeout, status %8.8x %8.8x \n",
+	       		net_dev->name, inl(ioaddr + cr), inl(ioaddr + isr));
 
 	/* Disable interrupts by clearing the interrupt mask. */
 	outl(0x0000, ioaddr + imr);
@@ -1558,8 +1597,8 @@
 
 	net_dev->trans_start = jiffies;
 
-	if (sis900_debug > 3)
-		printk(KERN_INFO "%s: Queued Tx packet at %p size %d "
+	if (netif_msg_tx_queued(sis_priv))
+		printk(KERN_DEBUG "%s: Queued Tx packet at %p size %d "
 		       "to slot %d.\n",
 		       net_dev->name, skb->data, (int)skb->len, entry);
 
@@ -1606,20 +1645,22 @@
 
 		/* something strange happened !!! */
 		if (status & HIBERR) {
-			printk(KERN_INFO "%s: Abnormal interrupt,"
-			       "status %#8.8x.\n", net_dev->name, status);
+			if(netif_msg_intr(sis_priv))
+				printk(KERN_INFO "%s: Abnormal interrupt,"
+					"status %#8.8x.\n", net_dev->name, status);
 			break;
 		}
 		if (--boguscnt < 0) {
-			printk(KERN_INFO "%s: Too much work at interrupt, "
-			       "interrupt status = %#8.8x.\n",
-			       net_dev->name, status);
+			if(netif_msg_intr(sis_priv))
+				printk(KERN_INFO "%s: Too much work at interrupt, "
+					"interrupt status = %#8.8x.\n",
+					net_dev->name, status);
 			break;
 		}
 	} while (1);
 
-	if (sis900_debug > 3)
-		printk(KERN_INFO "%s: exiting interrupt, "
+	if(netif_msg_intr(sis_priv))
+		printk(KERN_DEBUG "%s: exiting interrupt, "
 		       "interrupt status = 0x%#8.8x.\n",
 		       net_dev->name, inl(ioaddr + isr));
 	
@@ -1644,8 +1685,8 @@
 	unsigned int entry = sis_priv->cur_rx % NUM_RX_DESC;
 	u32 rx_status = sis_priv->rx_ring[entry].cmdsts;
 
-	if (sis900_debug > 3)
-		printk(KERN_INFO "sis900_rx, cur_rx:%4.4d, dirty_rx:%4.4d "
+	if (netif_msg_rx_status(sis_priv))
+		printk(KERN_DEBUG "sis900_rx, cur_rx:%4.4d, dirty_rx:%4.4d "
 		       "status:0x%8.8x\n",
 		       sis_priv->cur_rx, sis_priv->dirty_rx, rx_status);
 
@@ -1656,8 +1697,8 @@
 
 		if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) {
 			/* corrupted packet received */
-			if (sis900_debug > 3)
-				printk(KERN_INFO "%s: Corrupted packet "
+			if (netif_msg_rx_err(sis_priv))
+				printk(KERN_DEBUG "%s: Corrupted packet "
 				       "received, buffer status = 0x%8.8x.\n",
 				       net_dev->name, rx_status);
 			sis_priv->stats.rx_errors++;
@@ -1678,9 +1719,10 @@
 			   some unknow bugs, it is possible that
 			   we are working on NULL sk_buff :-( */
 			if (sis_priv->rx_skbuff[entry] == NULL) {
-				printk(KERN_INFO "%s: NULL pointer " 
-				       "encountered in Rx ring, skipping\n",
-				       net_dev->name);
+				if (netif_msg_rx_err(sis_priv))
+					printk(KERN_INFO "%s: NULL pointer " 
+						"encountered in Rx ring, skipping\n",
+						net_dev->name);
 				break;
 			}
 
@@ -1707,9 +1749,10 @@
 				 * "hole" on the buffer ring, it is not clear
 				 * how the hardware will react to this kind
 				 * of degenerated buffer */
-				printk(KERN_INFO "%s: Memory squeeze,"
-				       "deferring packet.\n",
-				       net_dev->name);
+				if (netif_msg_rx_status(sis_priv))
+					printk(KERN_INFO "%s: Memory squeeze,"
+						"deferring packet.\n",
+						net_dev->name);
 				sis_priv->rx_skbuff[entry] = NULL;
 				/* reset buffer descriptor state */
 				sis_priv->rx_ring[entry].cmdsts = 0;
@@ -1743,9 +1786,10 @@
 				 * "hole" on the buffer ring, it is not clear
 				 * how the hardware will react to this kind
 				 * of degenerated buffer */
-				printk(KERN_INFO "%s: Memory squeeze,"
-				       "deferring packet.\n",
-				       net_dev->name);
+				if (netif_msg_rx_err(sis_priv))
+					printk(KERN_INFO "%s: Memory squeeze,"
+						"deferring packet.\n",
+						net_dev->name);
 				sis_priv->stats.rx_dropped++;
 				break;
 			}
@@ -1794,8 +1838,8 @@
 
 		if (tx_status & (ABORT | UNDERRUN | OWCOLL)) {
 			/* packet unsuccessfully transmitted */
-			if (sis900_debug > 3)
-				printk(KERN_INFO "%s: Transmit "
+			if (netif_msg_tx_err(sis_priv))
+				printk(KERN_DEBUG "%s: Transmit "
 				       "error, Tx status %8.8x.\n",
 				       net_dev->name, tx_status);
 			sis_priv->stats.tx_errors++;
@@ -1906,8 +1950,22 @@
 	strcpy (info->bus_info, pci_name(sis_priv->pci_dev));
 }
 
+static u32 sis900_get_msglevel(struct net_device *net_dev)
+{
+	struct sis900_private *sis_priv = net_dev->priv;
+	return sis_priv->msg_enable;
+}
+  
+static void sis900_set_msglevel(struct net_device *net_dev, u32 value)
+{
+	struct sis900_private *sis_priv = net_dev->priv;
+	sis_priv->msg_enable = value;
+}
+
 static struct ethtool_ops sis900_ethtool_ops = {
-	.get_drvinfo =		sis900_get_drvinfo,
+	.get_drvinfo 	= sis900_get_drvinfo,
+	.get_msglevel	= sis900_get_msglevel,
+	.set_msglevel	= sis900_set_msglevel,
 };
 
 /**
@@ -2048,12 +2106,10 @@
 		case IF_PORT_AUI: /* AUI */
 		case IF_PORT_100BASEFX: /* 100BaseFx */
                 	/* These Modes are not supported (are they?)*/
-			printk(KERN_INFO "Not supported");
 			return -EOPNOTSUPP;
 			break;
             
 		default:
-			printk(KERN_INFO "Invalid");
 			return -EINVAL;
 		}
 	}
@@ -2099,11 +2155,10 @@
 	u16 mc_filter[16] = {0};	/* 256/128 bits multicast hash table */
 	int i, table_entries;
 	u32 rx_mode;
-	u8 revision;
 
 	/* 635 Hash Table entires = 256(2^16) */
-	pci_read_config_byte(sis_priv->pci_dev, PCI_CLASS_REVISION, &revision);
-	if((revision >= SIS635A_900_REV) || (revision == SIS900B_900_REV))
+	if((sis_priv->chipset_rev >= SIS635A_900_REV) ||
+			(sis_priv->chipset_rev == SIS900B_900_REV))
 		table_entries = 16;
 	else
 		table_entries = 8;
@@ -2129,7 +2184,7 @@
 			mclist && i < net_dev->mc_count;
 			i++, mclist = mclist->next) {
 			unsigned int bit_nr =
-				sis900_mcast_bitnr(mclist->dmi_addr, revision);
+				sis900_mcast_bitnr(mclist->dmi_addr, sis_priv->chipset_rev);
 			mc_filter[bit_nr >> 4] |= (1 << (bit_nr & 0xf));
 		}
 	}
@@ -2175,7 +2230,6 @@
 	long ioaddr = net_dev->base_addr;
 	int i = 0;
 	u32 status = TxRCMP | RxRCMP;
-	u8  revision;
 
 	outl(0, ioaddr + ier);
 	outl(0, ioaddr + imr);
@@ -2188,8 +2242,8 @@
 		status ^= (inl(isr + ioaddr) & status);
 	}
 
-	pci_read_config_byte(sis_priv->pci_dev, PCI_CLASS_REVISION, &revision);
-	if( (revision >= SIS635A_900_REV) || (revision == SIS900B_900_REV) )
+	if( (sis_priv->chipset_rev >= SIS635A_900_REV) ||
+			(sis_priv->chipset_rev == SIS900B_900_REV) )
 		outl(PESEL | RND_CNT, ioaddr + cfg);
 	else
 		outl(PESEL, ioaddr + cfg);
diff -Nru a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
--- a/drivers/net/via-rhine.c	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/via-rhine.c	2005-03-08 14:29:45 -05:00
@@ -1197,8 +1197,10 @@
 		       dev->name, rp->pdev->irq);
 
 	rc = alloc_ring(dev);
-	if (rc)
+	if (rc) {
+		free_irq(rp->pdev->irq, dev);
 		return rc;
+	}
 	alloc_rbufs(dev);
 	alloc_tbufs(dev);
 	rhine_chip_reset(dev);
diff -Nru a/drivers/net/wireless/airport.c b/drivers/net/wireless/airport.c
--- a/drivers/net/wireless/airport.c	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/wireless/airport.c	2005-03-08 14:29:45 -05:00
@@ -28,7 +28,6 @@
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
 #include <linux/wireless.h>
-#include <linux/delay.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
@@ -45,7 +44,7 @@
 
 struct airport {
 	struct macio_dev *mdev;
-	void *vaddr;
+	void __iomem *vaddr;
 	int irq_requested;
 	int ndev_registered;
 };
@@ -150,7 +149,7 @@
 	ssleep(1);
 
 	macio_set_drvdata(mdev, NULL);
-	free_netdev(dev);
+	free_orinocodev(dev);
 
 	return 0;
 }
@@ -194,14 +193,14 @@
 	hermes_t *hw;
 
 	if (macio_resource_count(mdev) < 1 || macio_irq_count(mdev) < 1) {
-		printk(KERN_ERR PFX "wrong interrupt/addresses in OF tree\n");
+		printk(KERN_ERR PFX "Wrong interrupt/addresses in OF tree\n");
 		return -ENODEV;
 	}
 
 	/* Allocate space for private device-specific data */
 	dev = alloc_orinocodev(sizeof(*card), airport_hard_reset);
 	if (! dev) {
-		printk(KERN_ERR PFX "can't allocate device datas\n");
+		printk(KERN_ERR PFX "Cannot allocate network device\n");
 		return -ENODEV;
 	}
 	priv = netdev_priv(dev);
@@ -212,7 +211,7 @@
 
 	if (macio_request_resource(mdev, 0, "airport")) {
 		printk(KERN_ERR PFX "can't request IO resource !\n");
-		free_netdev(dev);
+		free_orinocodev(dev);
 		return -EBUSY;
 	}
 
@@ -224,16 +223,15 @@
 	/* Setup interrupts & base address */
 	dev->irq = macio_irq(mdev, 0);
 	phys_addr = macio_resource_start(mdev, 0);  /* Physical address */
-	printk(KERN_DEBUG PFX "Airport at physical address %lx\n", phys_addr);
+	printk(KERN_DEBUG PFX "Physical address %lx\n", phys_addr);
 	dev->base_addr = phys_addr;
 	card->vaddr = ioremap(phys_addr, AIRPORT_IO_LEN);
 	if (!card->vaddr) {
-		printk(PFX "ioremap() failed\n");
+		printk(KERN_ERR PFX "ioremap() failed\n");
 		goto failed;
 	}
 
-	hermes_struct_init(hw, (ulong)card->vaddr,
-			HERMES_MEM, HERMES_16BIT_REGSPACING);
+	hermes_struct_init(hw, card->vaddr, HERMES_16BIT_REGSPACING);
 		
 	/* Power up card */
 	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 1);
@@ -242,7 +240,7 @@
 	/* Reset it before we get the interrupt */
 	hermes_init(hw);
 
-	if (request_irq(dev->irq, orinoco_interrupt, 0, "Airport", dev)) {
+	if (request_irq(dev->irq, orinoco_interrupt, 0, dev->name, dev)) {
 		printk(KERN_ERR PFX "Couldn't get IRQ %d\n", dev->irq);
 		goto failed;
 	}
@@ -253,7 +251,7 @@
 		printk(KERN_ERR PFX "register_netdev() failed\n");
 		goto failed;
 	}
-	printk(KERN_DEBUG PFX "card registered for interface %s\n", dev->name);
+	printk(KERN_DEBUG PFX "Card registered for interface %s\n", dev->name);
 	card->ndev_registered = 1;
 	return 0;
  failed:
diff -Nru a/drivers/net/wireless/hermes.c b/drivers/net/wireless/hermes.c
--- a/drivers/net/wireless/hermes.c	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/wireless/hermes.c	2005-03-08 14:29:45 -05:00
@@ -48,6 +48,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/net.h>
 #include <asm/errno.h>
 
 #include "hermes.h"
@@ -67,8 +68,7 @@
  * Debugging helpers
  */
 
-#define IO_TYPE(hw)	((hw)->io_space ? "IO " : "MEM ")
-#define DMSG(stuff...) do {printk(KERN_DEBUG "hermes @ %s0x%x: " , IO_TYPE(hw), hw->iobase); \
+#define DMSG(stuff...) do {printk(KERN_DEBUG "hermes @ %p: " , hw->iobase); \
 			printk(stuff);} while (0)
 
 #undef HERMES_DEBUG
@@ -123,11 +123,9 @@
  * Function definitions
  */
 
-void hermes_struct_init(hermes_t *hw, ulong address,
-			int io_space, int reg_spacing)
+void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing)
 {
 	hw->iobase = address;
-	hw->io_space = io_space;
 	hw->reg_spacing = reg_spacing;
 	hw->inten = 0x0;
 
@@ -200,9 +198,9 @@
 	}
 		
 	if (! (reg & HERMES_EV_CMD)) {
-		printk(KERN_ERR "hermes @ %s0x%lx: " 
+		printk(KERN_ERR "hermes @ %p: " 
 		       "Timeout waiting for card to reset (reg=0x%04x)!\n",
-		       IO_TYPE(hw), hw->iobase, reg);
+		       hw->iobase, reg);
 		err = -ETIMEDOUT;
 		goto out;
 	}
@@ -235,13 +233,16 @@
 	err = hermes_issue_cmd(hw, cmd, parm0);
 	if (err) {
 		if (! hermes_present(hw)) {
-			printk(KERN_WARNING "hermes @ %s0x%lx: "
-			       "Card removed while issuing command.\n",
-			       IO_TYPE(hw), hw->iobase);
+			if (net_ratelimit())
+				printk(KERN_WARNING "hermes @ %p: "
+				       "Card removed while issuing command "
+				       "0x%04x.\n", hw->iobase, cmd);
 			err = -ENODEV;
 		} else 
-			printk(KERN_ERR "hermes @ %s0x%lx: Error %d issuing command.\n",
-			       IO_TYPE(hw), hw->iobase, err);
+			if (net_ratelimit())
+				printk(KERN_ERR "hermes @ %p: "
+				       "Error %d issuing command 0x%04x.\n",
+				       hw->iobase, err, cmd);
 		goto out;
 	}
 
@@ -254,17 +255,16 @@
 	}
 
 	if (! hermes_present(hw)) {
-		printk(KERN_WARNING "hermes @ %s0x%lx: "
-		       "Card removed while waiting for command completion.\n",
-		       IO_TYPE(hw), hw->iobase);
+		printk(KERN_WARNING "hermes @ %p: Card removed "
+		       "while waiting for command 0x%04x completion.\n",
+		       hw->iobase, cmd);
 		err = -ENODEV;
 		goto out;
 	}
 		
 	if (! (reg & HERMES_EV_CMD)) {
-		printk(KERN_ERR "hermes @ %s0x%lx: "
-		       "Timeout waiting for command completion.\n",
-		       IO_TYPE(hw), hw->iobase);
+		printk(KERN_ERR "hermes @ %p: Timeout waiting for "
+		       "command 0x%04x completion.\n", hw->iobase, cmd);
 		err = -ETIMEDOUT;
 		goto out;
 	}
@@ -309,16 +309,16 @@
 	}
 	
 	if (! hermes_present(hw)) {
-		printk(KERN_WARNING "hermes @ %s0x%lx: "
+		printk(KERN_WARNING "hermes @ %p: "
 		       "Card removed waiting for frame allocation.\n",
-		       IO_TYPE(hw), hw->iobase);
+		       hw->iobase);
 		return -ENODEV;
 	}
 		
 	if (! (reg & HERMES_EV_ALLOC)) {
-		printk(KERN_ERR "hermes @ %s0x%lx: "
+		printk(KERN_ERR "hermes @ %p: "
 		       "Timeout waiting for frame allocation\n",
-		       IO_TYPE(hw), hw->iobase);
+		       hw->iobase);
 		return -ETIMEDOUT;
 	}
 
@@ -383,12 +383,17 @@
 		reg = hermes_read_reg(hw, oreg);
 	}
 
-	if (reg & HERMES_OFFSET_BUSY) {
-		return -ETIMEDOUT;
-	}
+	if (reg != offset) {
+		printk(KERN_ERR "hermes @ %p: BAP%d offset %s: "
+		       "reg=0x%x id=0x%x offset=0x%x\n", hw->iobase, bap,
+		       (reg & HERMES_OFFSET_BUSY) ? "timeout" : "error",
+		       reg, id, offset);
+
+		if (reg & HERMES_OFFSET_BUSY) {
+			return -ETIMEDOUT;
+		}
 
-	if (reg & HERMES_OFFSET_ERR) {
-		return -EIO;
+		return -EIO;		/* error or wrong offset */
 	}
 
 	return 0;
@@ -476,7 +481,7 @@
 	rlength = hermes_read_reg(hw, dreg);
 
 	if (! rlength)
-		return -ENOENT;
+		return -ENODATA;
 
 	rtype = hermes_read_reg(hw, dreg);
 
@@ -484,14 +489,13 @@
 		*length = rlength;
 
 	if (rtype != rid)
-		printk(KERN_WARNING "hermes @ %s0x%lx: "
-		       "hermes_read_ltv(): rid  (0x%04x) does not match type (0x%04x)\n",
-		       IO_TYPE(hw), hw->iobase, rid, rtype);
+		printk(KERN_WARNING "hermes @ %p: %s(): "
+		       "rid (0x%04x) does not match type (0x%04x)\n",
+		       hw->iobase, __FUNCTION__, rid, rtype);
 	if (HERMES_RECLEN_TO_BYTES(rlength) > bufsize)
-		printk(KERN_WARNING "hermes @ %s0x%lx: "
+		printk(KERN_WARNING "hermes @ %p: "
 		       "Truncating LTV record from %d to %d bytes. "
-		       "(rid=0x%04x, len=0x%04x)\n",
-		       IO_TYPE(hw), hw->iobase,
+		       "(rid=0x%04x, len=0x%04x)\n", hw->iobase,
 		       HERMES_RECLEN_TO_BYTES(rlength), bufsize, rid, rlength);
 
 	nwords = min((unsigned)rlength - 1, bufsize / 2);
diff -Nru a/drivers/net/wireless/hermes.h b/drivers/net/wireless/hermes.h
--- a/drivers/net/wireless/hermes.h	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/wireless/hermes.h	2005-03-08 14:29:45 -05:00
@@ -340,14 +340,11 @@
 #ifdef __KERNEL__
 
 /* Timeouts */
-#define HERMES_BAP_BUSY_TIMEOUT (500) /* In iterations of ~1us */
+#define HERMES_BAP_BUSY_TIMEOUT (10000) /* In iterations of ~1us */
 
 /* Basic control structure */
 typedef struct hermes {
-	unsigned long iobase;
-	int io_space; /* 1 if we IO-mapped IO, 0 for memory-mapped IO? */
-#define HERMES_IO	1
-#define HERMES_MEM	0
+	void __iomem *iobase;
 	int reg_spacing;
 #define HERMES_16BIT_REGSPACING	0
 #define HERMES_32BIT_REGSPACING	1
@@ -362,21 +359,15 @@
 } hermes_t;
 
 /* Register access convenience macros */
-#define hermes_read_reg(hw, off) ((hw)->io_space ? \
-	inw((hw)->iobase + ( (off) << (hw)->reg_spacing )) : \
-	readw((hw)->iobase + ( (off) << (hw)->reg_spacing )))
-#define hermes_write_reg(hw, off, val) do { \
-	if ((hw)->io_space) \
-		outw_p((val), (hw)->iobase + ((off) << (hw)->reg_spacing)); \
-	else \
-		writew((val), (hw)->iobase + ((off) << (hw)->reg_spacing)); \
-	} while (0)
+#define hermes_read_reg(hw, off) \
+	(ioread16((hw)->iobase + ( (off) << (hw)->reg_spacing )))
+#define hermes_write_reg(hw, off, val) \
+	(iowrite16((val), (hw)->iobase + ((off) << (hw)->reg_spacing)))
 #define hermes_read_regn(hw, name) hermes_read_reg((hw), HERMES_##name)
 #define hermes_write_regn(hw, name, val) hermes_write_reg((hw), HERMES_##name, (val))
 
 /* Function prototypes */
-void hermes_struct_init(hermes_t *hw, ulong address, int io_space,
-			int reg_spacing);
+void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing);
 int hermes_init(hermes_t *hw);
 int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
 		      struct hermes_response *resp);
@@ -430,41 +421,13 @@
 static inline void hermes_read_words(struct hermes *hw, int off, void *buf, unsigned count)
 {
 	off = off << hw->reg_spacing;
-
-	if (hw->io_space) {
-		insw(hw->iobase + off, buf, count);
-	} else {
-		unsigned i;
-		u16 *p;
-
-		/* This needs to *not* byteswap (like insw()) but
-		 * readw() does byteswap hence the conversion.  I hope
-		 * gcc is smart enough to fold away the two swaps on
-		 * big-endian platforms. */
-		for (i = 0, p = buf; i < count; i++) {
-			*p++ = cpu_to_le16(readw(hw->iobase + off));
-		}
-	}
+	ioread16_rep(hw->iobase + off, buf, count);
 }
 
 static inline void hermes_write_words(struct hermes *hw, int off, const void *buf, unsigned count)
 {
 	off = off << hw->reg_spacing;
-
-	if (hw->io_space) {
-		outsw(hw->iobase + off, buf, count);
-	} else {
-		unsigned i;
-		const u16 *p;
-
-		/* This needs to *not* byteswap (like outsw()) but
-		 * writew() does byteswap hence the conversion.  I
-		 * hope gcc is smart enough to fold away the two swaps
-		 * on big-endian platforms. */
-		for (i = 0, p = buf; i < count; i++) {
-			writew(le16_to_cpu(*p++), hw->iobase + off);
-		}
-	}
+	iowrite16_rep(hw->iobase + off, buf, count);
 }
 
 static inline void hermes_clear_words(struct hermes *hw, int off, unsigned count)
@@ -473,13 +436,8 @@
 
 	off = off << hw->reg_spacing;
 
-	if (hw->io_space) {
-		for (i = 0; i < count; i++)
-			outw(0, hw->iobase + off);
-	} else {
-		for (i = 0; i < count; i++)
-			writew(0, hw->iobase + off);
-	}
+	for (i = 0; i < count; i++)
+		iowrite16(0, hw->iobase + off);
 }
 
 #define HERMES_READ_RECORD(hw, bap, rid, buf) \
diff -Nru a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
--- a/drivers/net/wireless/orinoco.c	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/wireless/orinoco.c	2005-03-08 14:29:45 -05:00
@@ -393,6 +393,29 @@
  *	  in the rx_dropped statistics.
  *	o Provided a module parameter to suppress linkstatus messages.
  *
+ * v0.13e -> v0.14alpha1 - 30 Sep 2003 - David Gibson
+ *	o Replaced priv->connected logic with netif_carrier_on/off()
+ *	  calls.
+ *	o Remove has_ibss_any and never set the CREATEIBSS RID when
+ *	  the ESSID is empty.  Too many firmwares break if we do.
+ *	o 2.6 merges: Replace pdev->slot_name with pci_name(), remove
+ *	  __devinitdata from PCI ID tables, use free_netdev().
+ *	o Enabled shared-key authentication for Agere firmware (from
+ *	  Robert J. Moore <Robert.J.Moore AT allanbank.com>
+ *	o Move netif_wake_queue() (back) to the Tx completion from the
+ *	  ALLOC event.  This seems to prevent/mitigate the rolling
+ *	  error -110 problems at least on some Intersil firmwares.
+ *	  Theoretically reduces performance, but I can't measure it.
+ *	  Patch from Andrew Tridgell <tridge AT samba.org>
+ *
+ * v0.14alpha1 -> v0.14alpha2 - 20 Oct 2003 - David Gibson
+ *	o Correctly turn off shared-key authentication when requested
+ *	  (bugfix from Robert J. Moore).
+ *	o Correct airport sleep interfaces for current 2.6 kernels.
+ *	o Add code for key change without disabling/enabling the MAC
+ *	  port.  This is supposed to allow 802.1x to work sanely, but
+ *	  doesn't seem to yet.
+ *
  * TODO
  *	o New wireless extensions API (patch from Moustafa
  *	  Youssef, updated by Jim Carter and Pavel Roskin).
@@ -461,12 +484,14 @@
 /* Level of debugging. Used in the macros in orinoco.h */
 #ifdef ORINOCO_DEBUG
 int orinoco_debug = ORINOCO_DEBUG;
-module_param(orinoco_debug, int, 0);
+module_param(orinoco_debug, int, 0644);
+MODULE_PARM_DESC(orinoco_debug, "Debug level");
 EXPORT_SYMBOL(orinoco_debug);
 #endif
 
 static int suppress_linkstatus; /* = 0 */
-module_param(suppress_linkstatus, bool, 0);
+module_param(suppress_linkstatus, bool, 0644);
+MODULE_PARM_DESC(suppress_linkstatus, "Don't log link status changes");
 
 /********************************************************************/
 /* Compile time configuration and compatibility stuff               */
@@ -784,7 +809,7 @@
 		return 1;
 	}
 
-	if (! priv->connected) {
+	if (! netif_carrier_ok(dev)) {
 		/* Oops, the firmware hasn't established a connection,
                    silently drop the packet (this seems to be the
                    safest approach). */
@@ -805,8 +830,9 @@
  	desc.tx_control = cpu_to_le16(HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX);
 	err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), txfid, 0);
 	if (err) {
-		printk(KERN_ERR "%s: Error %d writing Tx descriptor to BAP\n",
-		       dev->name, err);
+		if (net_ratelimit())
+			printk(KERN_ERR "%s: Error %d writing Tx descriptor "
+			       "to BAP\n", dev->name, err);
 		stats->tx_errors++;
 		goto fail;
 	}
@@ -836,8 +862,9 @@
 		err  = hermes_bap_pwrite(hw, USER_BAP, &hdr, sizeof(hdr),
 					 txfid, HERMES_802_3_OFFSET);
 		if (err) {
-			printk(KERN_ERR "%s: Error %d writing packet header to BAP\n",
-			       dev->name, err);
+			if (net_ratelimit())
+				printk(KERN_ERR "%s: Error %d writing packet "
+				       "header to BAP\n", dev->name, err);
 			stats->tx_errors++;
 			goto fail;
 		}
@@ -897,8 +924,6 @@
 			printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n",
 			       dev->name, fid);
 		return;
-	} else {
-		netif_wake_queue(dev);
 	}
 
 	hermes_write_regn(hw, ALLOCFID, DUMMY_FID);
@@ -911,6 +936,8 @@
 
 	stats->tx_packets++;
 
+	netif_wake_queue(dev);
+
 	hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
 }
 
@@ -937,6 +964,7 @@
 	
 	stats->tx_errors++;
 
+	netif_wake_queue(dev);
 	hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
 }
 
@@ -962,15 +990,17 @@
 
 /* Does the frame have a SNAP header indicating it should be
  * de-encapsulated to Ethernet-II? */
-static inline int is_ethersnap(struct header_struct *hdr)
+static inline int is_ethersnap(void *_hdr)
 {
+	u8 *hdr = _hdr;
+
 	/* We de-encapsulate all packets which, a) have SNAP headers
 	 * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header
 	 * and where b) the OUI of the SNAP header is 00:00:00 or
 	 * 00:00:f8 - we need both because different APs appear to use
 	 * different OUIs for some reason */
-	return (memcmp(&hdr->dsap, &encaps_hdr, 5) == 0)
-		&& ( (hdr->oui[2] == 0x00) || (hdr->oui[2] == 0xf8) );
+	return (memcmp(hdr, &encaps_hdr, 5) == 0)
+		&& ( (hdr[5] == 0x00) || (hdr[5] == 0xf8) );
 }
 
 static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
@@ -1269,6 +1299,7 @@
 	case HERMES_INQ_LINKSTATUS: {
 		struct hermes_linkstatus linkstatus;
 		u16 newstatus;
+		int connected;
 
 		if (len != sizeof(linkstatus)) {
 			printk(KERN_WARNING "%s: Unexpected size for linkstatus frame (%d bytes)\n",
@@ -1280,15 +1311,14 @@
 				  len / 2);
 		newstatus = le16_to_cpu(linkstatus.linkstatus);
 
-		if ( (newstatus == HERMES_LINKSTATUS_CONNECTED)
-		     || (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
-		     || (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE) )
-			priv->connected = 1;
-		else if ( (newstatus == HERMES_LINKSTATUS_NOT_CONNECTED)
-			  || (newstatus == HERMES_LINKSTATUS_DISCONNECTED)
-			  || (newstatus == HERMES_LINKSTATUS_AP_OUT_OF_RANGE)
-			  || (newstatus == HERMES_LINKSTATUS_ASSOC_FAILED) )
-			priv->connected = 0;
+		connected = (newstatus == HERMES_LINKSTATUS_CONNECTED)
+			|| (newstatus == HERMES_LINKSTATUS_AP_CHANGE)
+			|| (newstatus == HERMES_LINKSTATUS_AP_IN_RANGE);
+
+		if (connected)
+			netif_carrier_on(dev);
+		else
+			netif_carrier_off(dev);
 
 		if (newstatus != priv->last_linkstatus)
 			print_linkstatus(dev, newstatus);
@@ -1297,8 +1327,8 @@
 	}
 	break;
 	default:
-		printk(KERN_DEBUG "%s: Unknown information frame received "
-		       "(type %04x).\n", dev->name, type);
+		printk(KERN_DEBUG "%s: Unknown information frame received: "
+		       "type 0x%04x, length %d\n", dev->name, type, len);
 		/* We don't actually do anything about it */
 		break;
 	}
@@ -1307,7 +1337,7 @@
 static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
 {
 	if (net_ratelimit())
-		printk(KERN_WARNING "%s: Information frame lost.\n", dev->name);
+		printk(KERN_DEBUG "%s: Information frame lost.\n", dev->name);
 }
 
 /********************************************************************/
@@ -1366,8 +1396,8 @@
 	}
 	
 	/* firmware will have to reassociate */
+	netif_carrier_off(dev);
 	priv->last_linkstatus = 0xffff;
-	priv->connected = 0;
 
 	return 0;
 }
@@ -1430,55 +1460,46 @@
 	return err;
 }
 
-static int __orinoco_hw_setup_wep(struct orinoco_private *priv)
+/* Change the WEP keys and/or the current keys.  Can be called
+ * either from __orinoco_hw_setup_wep() or directly from
+ * orinoco_ioctl_setiwencode().  In the later case the association
+ * with the AP is not broken (if the firmware can handle it),
+ * which is needed for 802.1x implementations. */
+static int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
 {
 	hermes_t *hw = &priv->hw;
 	int err = 0;
-	int	master_wep_flag;
-	int	auth_flag;
 
 	switch (priv->firmware_type) {
-	case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
-		if (priv->wep_on) {
-			err = hermes_write_wordrec(hw, USER_BAP,
-						   HERMES_RID_CNFTXKEY_AGERE,
-						   priv->tx_key);
-			if (err)
-				return err;
-			
-			err = HERMES_WRITE_RECORD(hw, USER_BAP,
-						  HERMES_RID_CNFWEPKEYS_AGERE,
-						  &priv->keys);
-			if (err)
-				return err;
-		}
+	case FIRMWARE_TYPE_AGERE:
+		err = HERMES_WRITE_RECORD(hw, USER_BAP,
+					  HERMES_RID_CNFWEPKEYS_AGERE,
+					  &priv->keys);
+		if (err)
+			return err;
 		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFWEPENABLED_AGERE,
-					   priv->wep_on);
+					   HERMES_RID_CNFTXKEY_AGERE,
+					   priv->tx_key);
 		if (err)
 			return err;
 		break;
-
-	case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
-	case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
-		master_wep_flag = 0;		/* Off */
-		if (priv->wep_on) {
+	case FIRMWARE_TYPE_INTERSIL:
+	case FIRMWARE_TYPE_SYMBOL:
+		{
 			int keylen;
 			int i;
 
-			/* Fudge around firmware weirdness */
+			/* Force uniform key length to work around firmware bugs */
 			keylen = le16_to_cpu(priv->keys[priv->tx_key].len);
 			
+			if (keylen > LARGE_KEY_SIZE) {
+				printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
+				       priv->ndev->name, priv->tx_key, keylen);
+				return -E2BIG;
+			}
+
 			/* Write all 4 keys */
 			for(i = 0; i < ORINOCO_MAX_KEYS; i++) {
-/*  				int keylen = le16_to_cpu(priv->keys[i].len); */
-				
-				if (keylen > LARGE_KEY_SIZE) {
-					printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
-					       priv->ndev->name, i, keylen);
-					return -E2BIG;
-				}
-
 				err = hermes_write_ltv(hw, USER_BAP,
 						       HERMES_RID_CNFDEFAULTKEY0 + i,
 						       HERMES_BYTES_TO_RECLEN(keylen),
@@ -1493,27 +1514,63 @@
 						   priv->tx_key);
 			if (err)
 				return err;
-			
-			if (priv->wep_restrict) {
-				auth_flag = 2;
-				master_wep_flag = 3;
-			} else {
-				/* Authentication is where Intersil and Symbol
-				 * firmware differ... */
-				auth_flag = 1;
-				if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
-					master_wep_flag = 3; /* Symbol */ 
-				else 
-					master_wep_flag = 1; /* Intersil */
-			}
+		}
+		break;
+	}
 
+	return 0;
+}
+
+static int __orinoco_hw_setup_wep(struct orinoco_private *priv)
+{
+	hermes_t *hw = &priv->hw;
+	int err = 0;
+	int master_wep_flag;
+	int auth_flag;
+
+	if (priv->wep_on)
+		__orinoco_hw_setup_wepkeys(priv);
+
+	if (priv->wep_restrict)
+		auth_flag = HERMES_AUTH_SHARED_KEY;
+	else
+		auth_flag = HERMES_AUTH_OPEN;
+
+	switch (priv->firmware_type) {
+	case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
+		if (priv->wep_on) {
+			/* Enable the shared-key authentication. */
+			err = hermes_write_wordrec(hw, USER_BAP,
+						   HERMES_RID_CNFAUTHENTICATION_AGERE,
+						   auth_flag);
+		}
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFWEPENABLED_AGERE,
+					   priv->wep_on);
+		if (err)
+			return err;
+		break;
+
+	case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
+	case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
+		if (priv->wep_on) {
+			if (priv->wep_restrict ||
+			    (priv->firmware_type == FIRMWARE_TYPE_SYMBOL))
+				master_wep_flag = HERMES_WEP_PRIVACY_INVOKED |
+						  HERMES_WEP_EXCL_UNENCRYPTED;
+			else
+				master_wep_flag = HERMES_WEP_PRIVACY_INVOKED;
 
 			err = hermes_write_wordrec(hw, USER_BAP,
 						   HERMES_RID_CNFAUTHENTICATION,
 						   auth_flag);
 			if (err)
 				return err;
-		}
+		} else
+			master_wep_flag = 0;
+
+		if (priv->iw_mode == IW_MODE_MONITOR)
+			master_wep_flag |= HERMES_WEP_HOST_DECRYPT;
 
 		/* Master WEP setting : on/off */
 		err = hermes_write_wordrec(hw, USER_BAP,
@@ -1523,13 +1580,6 @@
 			return err;	
 
 		break;
-
-	default:
-		if (priv->wep_on) {
-			printk(KERN_ERR "%s: WEP enabled, although not supported!\n",
-			       priv->ndev->name);
-			return -EINVAL;
-		}
 	}
 
 	return 0;
@@ -1574,21 +1624,26 @@
 	}
 
 	if (priv->has_ibss) {
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFCREATEIBSS,
-					   priv->createibss);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n", dev->name, err);
-			return err;
-		}
+		u16 createibss;
 
-		if ((strlen(priv->desired_essid) == 0) && (priv->createibss)
-		   && (!priv->has_ibss_any)) {
+		if ((strlen(priv->desired_essid) == 0) && (priv->createibss)) {
 			printk(KERN_WARNING "%s: This firmware requires an "
 			       "ESSID in IBSS-Ad-Hoc mode.\n", dev->name);
 			/* With wvlan_cs, in this case, we would crash.
 			 * hopefully, this driver will behave better...
 			 * Jean II */
+			createibss = 0;
+		} else {
+			createibss = priv->createibss;
+		}
+		
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFCREATEIBSS,
+					   createibss);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting CREATEIBSS\n",
+			       dev->name, err);
+			return err;
 		}
 	}
 
@@ -1785,7 +1840,8 @@
 		}
 		
 		if (p)
-			printk(KERN_WARNING "Multicast list is longer than mc_count\n");
+			printk(KERN_WARNING "%s: Multicast list is "
+			       "longer than mc_count\n", dev->name);
 
 		err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFGROUPADDRESSES,
 				       HERMES_BYTES_TO_RECLEN(priv->mc_count * ETH_ALEN),
@@ -1878,7 +1934,7 @@
 
 	priv->hw_unavailable++;
 	priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */
-	priv->connected = 0;
+	netif_carrier_off(dev);
 
 	orinoco_unlock(priv, &flags);
 
@@ -2014,51 +2070,81 @@
 /* Initialization                                                   */
 /********************************************************************/
 
-struct sta_id {
+struct comp_id {
 	u16 id, variant, major, minor;
 } __attribute__ ((packed));
 
-static int determine_firmware_type(struct net_device *dev, struct sta_id *sta_id)
+static inline fwtype_t determine_firmware_type(struct comp_id *nic_id)
 {
-	/* FIXME: this is fundamentally broken */
-	unsigned int firmver = ((u32)sta_id->major << 16) | sta_id->minor;
-	
-	if (sta_id->variant == 1)
+	if (nic_id->id < 0x8000)
 		return FIRMWARE_TYPE_AGERE;
-	else if ((sta_id->variant == 2) &&
-		   ((firmver == 0x10001) || (firmver == 0x20001)))
+	else if (nic_id->id == 0x8000 && nic_id->major == 0)
 		return FIRMWARE_TYPE_SYMBOL;
 	else
 		return FIRMWARE_TYPE_INTERSIL;
 }
 
-static void determine_firmware(struct net_device *dev)
+/* Set priv->firmware type, determine firmware properties */
+static int determine_firmware(struct net_device *dev)
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	hermes_t *hw = &priv->hw;
 	int err;
-	struct sta_id sta_id;
+	struct comp_id nic_id, sta_id;
 	unsigned int firmver;
 	char tmp[SYMBOL_MAX_VER_LEN+1];
 
+	/* Get the hardware version */
+	err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id);
+	if (err) {
+		printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n",
+		       dev->name, err);
+		return err;
+	}
+
+	le16_to_cpus(&nic_id.id);
+	le16_to_cpus(&nic_id.variant);
+	le16_to_cpus(&nic_id.major);
+	le16_to_cpus(&nic_id.minor);
+	printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n",
+	       dev->name, nic_id.id, nic_id.variant,
+	       nic_id.major, nic_id.minor);
+
+	priv->firmware_type = determine_firmware_type(&nic_id);
+
 	/* Get the firmware version */
 	err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
 	if (err) {
-		printk(KERN_WARNING "%s: Error %d reading firmware info. Wildly guessing capabilities...\n",
+		printk(KERN_ERR "%s: Cannot read station identity: error %d\n",
 		       dev->name, err);
-		memset(&sta_id, 0, sizeof(sta_id));
+		return err;
 	}
 
 	le16_to_cpus(&sta_id.id);
 	le16_to_cpus(&sta_id.variant);
 	le16_to_cpus(&sta_id.major);
 	le16_to_cpus(&sta_id.minor);
-	printk(KERN_DEBUG "%s: Station identity %04x:%04x:%04x:%04x\n",
+	printk(KERN_DEBUG "%s: Station identity  %04x:%04x:%04x:%04x\n",
 	       dev->name, sta_id.id, sta_id.variant,
 	       sta_id.major, sta_id.minor);
 
-	if (! priv->firmware_type)
-		priv->firmware_type = determine_firmware_type(dev, &sta_id);
+	switch (sta_id.id) {
+	case 0x15:
+		printk(KERN_ERR "%s: Primary firmware is active\n",
+		       dev->name);
+		return -ENODEV;
+	case 0x14b:
+		printk(KERN_ERR "%s: Tertiary firmware is active\n",
+		       dev->name);
+		return -ENODEV;
+	case 0x1f:	/* Intersil, Agere, Symbol Spectrum24 */
+	case 0x21:	/* Symbol Spectrum24 Trilogy */
+		break;
+	default:
+		printk(KERN_NOTICE "%s: Unknown station ID, please report\n",
+		       dev->name);
+		break;
+	}
 
 	/* Default capabilities */
 	priv->has_sensitivity = 1;
@@ -2066,7 +2152,6 @@
 	priv->has_preamble = 0;
 	priv->has_port3 = 1;
 	priv->has_ibss = 1;
-	priv->has_ibss_any = 0;
 	priv->has_wep = 0;
 	priv->has_big_wep = 0;
 
@@ -2075,14 +2160,12 @@
 	case FIRMWARE_TYPE_AGERE:
 		/* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
 		   ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
-		printk(KERN_DEBUG "%s: Looks like a Lucent/Agere firmware "
-		       "version %d.%02d\n", dev->name,
-		       sta_id.major, sta_id.minor);
+		snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
+			 "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor);
 
 		firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor;
 
 		priv->has_ibss = (firmver >= 0x60006);
-		priv->has_ibss_any = (firmver >= 0x60010);
 		priv->has_wep = (firmver >= 0x40020);
 		priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell
 					  Gold cards from the others? */
@@ -2121,14 +2204,15 @@
 			tmp[SYMBOL_MAX_VER_LEN] = '\0';
 		}
 
-		printk(KERN_DEBUG "%s: Looks like a Symbol firmware "
-		       "version [%s] (parsing to %X)\n", dev->name,
-		       tmp, firmver);
+		snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
+			 "Symbol %s", tmp);
 
 		priv->has_ibss = (firmver >= 0x20000);
 		priv->has_wep = (firmver >= 0x15012);
 		priv->has_big_wep = (firmver >= 0x20000);
-		priv->has_pm = (firmver >= 0x20000) && (firmver < 0x22000);
+		priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) || 
+			       (firmver >= 0x29000 && firmver < 0x30000) ||
+			       firmver >= 0x31000;
 		priv->has_preamble = (firmver >= 0x20000);
 		priv->ibss_port = 4;
 		/* Tested with Intel firmware : 0x20015 => Jean II */
@@ -2140,9 +2224,9 @@
 		 * different and less well tested */
 		/* D-Link MAC : 00:40:05:* */
 		/* Addtron MAC : 00:90:D1:* */
-		printk(KERN_DEBUG "%s: Looks like an Intersil firmware "
-		       "version %d.%d.%d\n", dev->name,
-		       sta_id.major, sta_id.minor, sta_id.variant);
+		snprintf(priv->fw_name, sizeof(priv->fw_name) - 1,
+			 "Intersil %d.%d.%d", sta_id.major, sta_id.minor,
+			 sta_id.variant);
 
 		firmver = ((unsigned long)sta_id.major << 16) |
 			((unsigned long)sta_id.minor << 8) | sta_id.variant;
@@ -2160,9 +2244,11 @@
 			priv->ibss_port = 1;
 		}
 		break;
-	default:
-		break;
 	}
+	printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name,
+	       priv->fw_name);
+
+	return 0;
 }
 
 static int orinoco_init(struct net_device *dev)
@@ -2188,7 +2274,12 @@
 		goto out;
 	}
 
-	determine_firmware(dev);
+	err = determine_firmware(dev);
+	if (err != 0) {
+		printk(KERN_ERR "%s: Incompatible firmware, aborting\n",
+		       dev->name);
+		goto out;
+	}
 
 	if (priv->has_port3)
 		printk(KERN_DEBUG "%s: Ad-hoc demo mode supported\n", dev->name);
@@ -2388,13 +2479,18 @@
 				   * hardware */
 	INIT_WORK(&priv->reset_work, (void (*)(void *))orinoco_reset, dev);
 
+	netif_carrier_off(dev);
 	priv->last_linkstatus = 0xffff;
-	priv->connected = 0;
 
 	return dev;
 
 }
 
+void free_orinocodev(struct net_device *dev)
+{
+	free_netdev(dev);
+}
+
 /********************************************************************/
 /* Wireless extensions                                              */
 /********************************************************************/
@@ -2686,11 +2782,17 @@
 	int err = 0;
 	char keybuf[ORINOCO_MAX_KEY_SIZE];
 	unsigned long flags;
-	
+
+	if (! priv->has_wep)
+		return -EOPNOTSUPP;
+
 	if (erq->pointer) {
-		/* We actually have a key to set */
-		if ( (erq->length < SMALL_KEY_SIZE) || (erq->length > ORINOCO_MAX_KEY_SIZE) )
-			return -EINVAL;
+		/* We actually have a key to set - check its length */
+		if (erq->length > LARGE_KEY_SIZE)
+			return -E2BIG;
+
+		if ( (erq->length > SMALL_KEY_SIZE) && !priv->has_big_wep )
+			return -E2BIG;
 		
 		if (copy_from_user(keybuf, erq->pointer, erq->length))
 			return -EFAULT;
@@ -2698,19 +2800,8 @@
 
 	if (orinoco_lock(priv, &flags) != 0)
 		return -EBUSY;
-	
+
 	if (erq->pointer) {
-		if (erq->length > ORINOCO_MAX_KEY_SIZE) {
-			err = -E2BIG;
-			goto out;
-		}
-		
-		if ( (erq->length > LARGE_KEY_SIZE)
-		     || ( ! priv->has_big_wep && (erq->length > SMALL_KEY_SIZE))  ) {
-			err = -EINVAL;
-			goto out;
-		}
-		
 		if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
 			index = priv->tx_key;
 
@@ -2721,7 +2812,7 @@
 			xlen = SMALL_KEY_SIZE;
 		} else
 			xlen = 0;
-		
+
 		/* Switch on WEP if off */
 		if ((!enable) && (xlen > 0)) {
 			setindex = index;
@@ -2745,10 +2836,9 @@
 			setindex = index;
 		}
 	}
-	
+
 	if (erq->flags & IW_ENCODE_DISABLED)
 		enable = 0;
-	/* Only for Prism2 & Symbol cards (so far) - Jean II */
 	if (erq->flags & IW_ENCODE_OPEN)
 		restricted = 0;
 	if (erq->flags & IW_ENCODE_RESTRICTED)
@@ -2761,6 +2851,15 @@
 		memcpy(priv->keys[index].data, keybuf, erq->length);
 	}
 	priv->tx_key = setindex;
+
+	/* Try fast key change if connected and only keys are changed */
+	if (priv->wep_on && enable && (priv->wep_restrict == restricted) &&
+	    netif_carrier_ok(dev)) {
+		err = __orinoco_hw_setup_wepkeys(priv);
+		/* No need to commit if successful */
+		goto out;
+	}
+
 	priv->wep_on = enable;
 	priv->wep_restrict = restricted;
 
@@ -2778,6 +2877,9 @@
 	char keybuf[ORINOCO_MAX_KEY_SIZE];
 	unsigned long flags;
 
+	if (! priv->has_wep)
+		return -EOPNOTSUPP;
+
 	if (orinoco_lock(priv, &flags) != 0)
 		return -EBUSY;
 
@@ -2788,23 +2890,18 @@
 	if (! priv->wep_on)
 		erq->flags |= IW_ENCODE_DISABLED;
 	erq->flags |= index + 1;
-	
-	/* Only for symbol cards - Jean II */
-	if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
-		if(priv->wep_restrict)
-			erq->flags |= IW_ENCODE_RESTRICTED;
-		else
-			erq->flags |= IW_ENCODE_OPEN;
-	}
+
+	if (priv->wep_restrict)
+		erq->flags |= IW_ENCODE_RESTRICTED;
+	else
+		erq->flags |= IW_ENCODE_OPEN;
 
 	xlen = le16_to_cpu(priv->keys[index].len);
 
 	erq->length = xlen;
 
-	if (erq->pointer) {
-		memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
-	}
-	
+	memcpy(keybuf, priv->keys[index].data, ORINOCO_MAX_KEY_SIZE);
+
 	orinoco_unlock(priv, &flags);
 
 	if (erq->pointer) {
@@ -3045,8 +3142,9 @@
 			priv->mwo_robust = 0;
 		else {
 			if (frq->fixed)
-				printk(KERN_WARNING "%s: Fixed fragmentation not \
-supported on this firmware. Using MWO robust instead.\n", dev->name);
+				printk(KERN_WARNING "%s: Fixed fragmentation is "
+				       "not supported on this firmware. "
+				       "Using MWO robust instead.\n", dev->name);
 			priv->mwo_robust = 1;
 		}
 	} else {
@@ -3518,7 +3616,7 @@
 		}
 		/* Copy stats */
 		/* In theory, we should disable irqs while copying the stats
-		 * because the rx path migh update it in the middle...
+		 * because the rx path might update it in the middle...
 		 * Bah, who care ? - Jean II */
 		memcpy(&spy_stat, priv->spy_stat,
 		       sizeof(struct iw_quality) * IW_MAX_SPY);
@@ -3609,22 +3707,12 @@
 		break;
 
 	case SIOCSIWENCODE:
-		if (! priv->has_wep) {
-			err = -EOPNOTSUPP;
-			break;
-		}
-
 		err = orinoco_ioctl_setiwencode(dev, &wrq->u.encoding);
 		if (! err)
 			changed = 1;
 		break;
 
 	case SIOCGIWENCODE:
-		if (! priv->has_wep) {
-			err = -EOPNOTSUPP;
-			break;
-		}
-
 		if (! capable(CAP_NET_ADMIN)) {
 			err = -EPERM;
 			break;
@@ -4127,6 +4215,7 @@
 /********************************************************************/
 
 EXPORT_SYMBOL(alloc_orinocodev);
+EXPORT_SYMBOL(free_orinocodev);
 
 EXPORT_SYMBOL(__orinoco_up);
 EXPORT_SYMBOL(__orinoco_down);
diff -Nru a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
--- a/drivers/net/wireless/orinoco.h	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/wireless/orinoco.h	2005-03-08 14:29:45 -05:00
@@ -7,7 +7,7 @@
 #ifndef _ORINOCO_H
 #define _ORINOCO_H
 
-#define DRIVER_VERSION "0.13e"
+#define DRIVER_VERSION "0.14alpha2"
 
 #include <linux/types.h>
 #include <linux/spinlock.h>
@@ -30,6 +30,12 @@
 	char data[ORINOCO_MAX_KEY_SIZE];
 } __attribute__ ((packed));
 
+typedef enum {
+	FIRMWARE_TYPE_AGERE,
+	FIRMWARE_TYPE_INTERSIL,
+	FIRMWARE_TYPE_SYMBOL
+} fwtype_t;
+
 struct orinoco_private {
 	void *card;	/* Pointer to card dependent structure */
 	int (*hard_reset)(struct orinoco_private *);
@@ -42,7 +48,6 @@
 	/* driver state */
 	int open;
 	u16 last_linkstatus;
-	int connected;
 
 	/* Net device stuff */
 	struct net_device *ndev;
@@ -54,19 +59,22 @@
 	u16 txfid;
 
 	/* Capabilities of the hardware/firmware */
-	int firmware_type;
-#define FIRMWARE_TYPE_AGERE 1
-#define FIRMWARE_TYPE_INTERSIL 2
-#define FIRMWARE_TYPE_SYMBOL 3
-	int has_ibss, has_port3, has_ibss_any, ibss_port;
-	int has_wep, has_big_wep;
-	int has_mwo;
-	int has_pm;
-	int has_preamble;
-	int has_sensitivity;
+	fwtype_t firmware_type;
+	char fw_name[32];
+	int ibss_port;
 	int nicbuf_size;
 	u16 channel_mask;
-	int broken_disableport;
+
+	/* Boolean capabilities */
+	unsigned int has_ibss:1;
+	unsigned int has_port3:1;
+	unsigned int has_wep:1;
+	unsigned int has_big_wep:1;
+	unsigned int has_mwo:1;
+	unsigned int has_pm:1;
+	unsigned int has_preamble:1;
+	unsigned int has_sensitivity:1;
+	unsigned int broken_disableport:1;
 
 	/* Configuration paramaters */
 	u32 iw_mode;
@@ -108,6 +116,7 @@
 
 extern struct net_device *alloc_orinocodev(int sizeof_card,
 					   int (*hard_reset)(struct orinoco_private *));
+extern void free_orinocodev(struct net_device *dev);
 extern int __orinoco_up(struct net_device *dev);
 extern int __orinoco_down(struct net_device *dev);
 extern int orinoco_stop(struct net_device *dev);
@@ -127,7 +136,7 @@
 {
 	spin_lock_irqsave(&priv->lock, *flags);
 	if (priv->hw_unavailable) {
-		printk(KERN_DEBUG "orinoco_lock() called with hw_unavailable (dev=%p)\n",
+		DEBUG(1, "orinoco_lock() called with hw_unavailable (dev=%p)\n",
 		       priv->ndev);
 		spin_unlock_irqrestore(&priv->lock, *flags);
 		return -EBUSY;
diff -Nru a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
--- a/drivers/net/wireless/orinoco_cs.c	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/wireless/orinoco_cs.c	2005-03-08 14:29:45 -05:00
@@ -57,8 +57,8 @@
 /* Some D-Link cards have buggy CIS. They do work at 5v properly, but
  * don't have any CIS entry for it. This workaround it... */
 static int ignore_cis_vcc; /* = 0 */
-
 module_param(ignore_cis_vcc, int, 0);
+MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket");
 
 /********************************************************************/
 /* Magic constants						    */
@@ -128,6 +128,7 @@
 	if (err)
 		return err;
 
+	msleep(100);
 	clear_bit(0, &card->hard_reset_in_progress);
 
 	return 0;
@@ -166,9 +167,10 @@
 	link->priv = dev;
 
 	/* Interrupt setup */
-	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
 	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
-	link->irq.Handler = NULL;
+	link->irq.Handler = orinoco_interrupt;
+	link->irq.Instance = dev; 
 
 	/* General socket configuration defaults can go here.  In this
 	 * client, we assume very little, and rely on the CIS for
@@ -235,7 +237,7 @@
 		      dev);
 		unregister_netdev(dev);
 	}
-	free_netdev(dev);
+	free_orinocodev(dev);
 }				/* orinoco_cs_detach */
 
 /*
@@ -262,6 +264,7 @@
 	cisinfo_t info;
 	tuple_t tuple;
 	cisparse_t parse;
+	void __iomem *mem;
 
 	CS_CHECK(ValidateCIS, pcmcia_validate_cis(handle, &info));
 
@@ -308,8 +311,8 @@
 		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
 		cistpl_cftable_entry_t dflt = { .index = 0 };
 
-		if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
-				pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
+		if ( (pcmcia_get_tuple_data(handle, &tuple) != 0)
+		    || (pcmcia_parse_tuple(handle, &tuple, &parse) != 0))
 			goto next_entry;
 
 		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
@@ -348,8 +351,7 @@
 			    dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
 		
 		/* Do we need to allocate an interrupt? */
-		if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
-			link->conf.Attributes |= CONF_ENABLE_IRQ;
+		link->conf.Attributes |= CONF_ENABLE_IRQ;
 
 		/* IO window settings */
 		link->io.NumPorts1 = link->io.NumPorts2 = 0;
@@ -390,7 +392,7 @@
 		last_ret = pcmcia_get_next_tuple(handle, &tuple);
 		if (last_ret  == CS_NO_MORE_ITEMS) {
 			printk(KERN_ERR PFX "GetNextTuple(): No matching "
-			       "CIS configuration, maybe you need the "
+			       "CIS configuration.  Maybe you need the "
 			       "ignore_cis_vcc=1 parameter.\n");
 			goto cs_failed;
 		}
@@ -401,20 +403,16 @@
 	 * a handler to the interrupt, unless the 'Handler' member of
 	 * the irq structure is initialized.
 	 */
-	if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-		link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-		link->irq.IRQInfo1 = IRQ_LEVEL_ID;
-  		link->irq.Handler = orinoco_interrupt; 
-  		link->irq.Instance = dev; 
-		
-		CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
-	}
+	CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
 
 	/* We initialize the hermes structure before completing PCMCIA
 	 * configuration just in case the interrupt handler gets
 	 * called. */
-	hermes_struct_init(hw, link->io.BasePort1,
-				HERMES_IO, HERMES_16BIT_REGSPACING);
+	mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
+	if (!mem)
+		goto cs_failed;
+
+	hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
 
 	/*
 	 * This actually configures the PCMCIA socket -- setting up
@@ -430,8 +428,6 @@
 	SET_MODULE_OWNER(dev);
 	card->node.major = card->node.minor = 0;
 
-	/* register_netdev will give us an ethX name */
-	dev->name[0] = '\0';
 	SET_NETDEV_DEV(dev, &handle_to_dev(handle));
 	/* Tell the stack we exist */
 	if (register_netdev(dev) != 0) {
@@ -454,8 +450,7 @@
 	if (link->conf.Vpp1)
 		printk(", Vpp %d.%d", link->conf.Vpp1 / 10,
 		       link->conf.Vpp1 % 10);
-	if (link->conf.Attributes & CONF_ENABLE_IRQ)
-		printk(", irq %d", link->irq.AssignedIRQ);
+	printk(", irq %d", link->irq.AssignedIRQ);
 	if (link->io.NumPorts1)
 		printk(", io 0x%04x-0x%04x", link->io.BasePort1,
 		       link->io.BasePort1 + link->io.NumPorts1 - 1);
@@ -498,6 +493,8 @@
 	if (link->irq.AssignedIRQ)
 		pcmcia_release_irq(link->handle, &link->irq);
 	link->state &= ~DEV_CONFIG;
+	if (priv->hw.iobase)
+		ioport_unmap(priv->hw.iobase);
 }				/* orinoco_cs_release */
 
 /*
@@ -519,12 +516,12 @@
 	case CS_EVENT_CARD_REMOVAL:
 		link->state &= ~DEV_PRESENT;
 		if (link->state & DEV_CONFIG) {
-			orinoco_lock(priv, &flags);
+			unsigned long flags;
 
+			spin_lock_irqsave(&priv->lock, flags);
 			netif_device_detach(dev);
 			priv->hw_unavailable++;
-
-			orinoco_unlock(priv, &flags);
+			spin_unlock_irqrestore(&priv->lock, flags);
 		}
 		break;
 
diff -Nru a/drivers/net/wireless/orinoco_pci.c b/drivers/net/wireless/orinoco_pci.c
--- a/drivers/net/wireless/orinoco_pci.c	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/wireless/orinoco_pci.c	2005-03-08 14:29:45 -05:00
@@ -129,6 +129,11 @@
 #define HERMES_PCI_COR_OFFT	(500)		/* ms */
 #define HERMES_PCI_COR_BUSYT	(500)		/* ms */
 
+/* Orinoco PCI specific data */
+struct orinoco_pci_card {
+	void __iomem *pci_ioaddr;
+};
+
 /*
  * Do a soft reset of the PCI card using the Configuration Option Register
  * We need this to get going...
@@ -151,25 +156,11 @@
 
 	/* Assert the reset until the card notice */
 	hermes_write_regn(hw, PCI_COR, HERMES_PCI_COR_MASK);
-	printk(KERN_NOTICE "Reset done");
-	timeout = jiffies + (HERMES_PCI_COR_ONT * HZ / 1000);
-	while(time_before(jiffies, timeout)) {
-		printk(".");
-		mdelay(1);
-	}
-	printk(";\n");
-	//mdelay(HERMES_PCI_COR_ONT);
+	mdelay(HERMES_PCI_COR_ONT);
 
 	/* Give time for the card to recover from this hard effort */
 	hermes_write_regn(hw, PCI_COR, 0x0000);
-	printk(KERN_NOTICE "Clear Reset");
-	timeout = jiffies + (HERMES_PCI_COR_OFFT * HZ / 1000);
-	while(time_before(jiffies, timeout)) {
-		printk(".");
-		mdelay(1);
-	}
-	printk(";\n");
-	//mdelay(HERMES_PCI_COR_OFFT);
+	mdelay(HERMES_PCI_COR_OFFT);
 
 	/* The card is ready when it's no longer busy */
 	timeout = jiffies + (HERMES_PCI_COR_BUSYT * HZ / 1000);
@@ -178,12 +169,12 @@
 		mdelay(1);
 		reg = hermes_read_regn(hw, CMD);
 	}
-	/* Did we timeout ? */
-	if(time_after_eq(jiffies, timeout)) {
+
+	/* Still busy? */
+	if (reg & HERMES_CMD_BUSY) {
 		printk(KERN_ERR PFX "Busy timeout\n");
 		return -ETIMEDOUT;
 	}
-	printk(KERN_NOTICE "pci_cor : reg = 0x%X - %lX - %lX\n", reg, timeout, jiffies);
 
 	return 0;
 }
@@ -196,84 +187,93 @@
 {
 	int err = 0;
 	unsigned long pci_iorange;
-	u16 *pci_ioaddr = NULL;
+	u16 __iomem *pci_ioaddr = NULL;
 	unsigned long pci_iolen;
 	struct orinoco_private *priv = NULL;
+	struct orinoco_pci_card *card;
 	struct net_device *dev = NULL;
 
 	err = pci_enable_device(pdev);
-	if (err)
-		return -EIO;
+	if (err) {
+		printk(KERN_ERR PFX "Cannot enable PCI device\n");
+		return err;
+	}
+
+	err = pci_request_regions(pdev, DRIVER_NAME);
+	if (err != 0) {
+		printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
+		goto fail_resources;
+	}
 
 	/* Resource 0 is mapped to the hermes registers */
 	pci_iorange = pci_resource_start(pdev, 0);
 	pci_iolen = pci_resource_len(pdev, 0);
 	pci_ioaddr = ioremap(pci_iorange, pci_iolen);
-	if (! pci_iorange)
-		goto fail;
+	if (!pci_iorange) {
+		printk(KERN_ERR PFX "Cannot remap hardware registers\n");
+		goto fail_map;
+	}
 
 	/* Allocate network device */
-	dev = alloc_orinocodev(0, NULL);
+	dev = alloc_orinocodev(sizeof(*card), orinoco_pci_cor_reset);
 	if (! dev) {
 		err = -ENOMEM;
-		goto fail;
+		goto fail_alloc;
 	}
 
 	priv = netdev_priv(dev);
-	dev->base_addr = (unsigned long) pci_ioaddr;
+	card = priv->card;
+	card->pci_ioaddr = pci_ioaddr;
 	dev->mem_start = pci_iorange;
 	dev->mem_end = pci_iorange + pci_iolen - 1;
 	SET_MODULE_OWNER(dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
-	printk(KERN_DEBUG PFX
-	       "Detected Orinoco/Prism2 PCI device at %s, mem:0x%lX to 0x%lX -> 0x%p, irq:%d\n",
-	       pci_name(pdev), dev->mem_start, dev->mem_end, pci_ioaddr, pdev->irq);
+	hermes_struct_init(&priv->hw, pci_ioaddr, HERMES_32BIT_REGSPACING);
 
-	hermes_struct_init(&priv->hw, dev->base_addr,
-			   HERMES_MEM, HERMES_32BIT_REGSPACING);
-	pci_set_drvdata(pdev, dev);
+	printk(KERN_DEBUG PFX "Detected device %s, mem:0x%lx-0x%lx, irq %d\n",
+	       pci_name(pdev), dev->mem_start, dev->mem_end, pdev->irq);
 
 	err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
 			  dev->name, dev);
 	if (err) {
-		printk(KERN_ERR PFX "Error allocating IRQ %d.\n",
-		       pdev->irq);
+		printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
 		err = -EBUSY;
-		goto fail;
+		goto fail_irq;
 	}
 	dev->irq = pdev->irq;
 
 	/* Perform a COR reset to start the card */
-	if(orinoco_pci_cor_reset(priv) != 0) {
-		printk(KERN_ERR "%s: Failed to start the card\n", dev->name);
-		err = -ETIMEDOUT;
+	err = orinoco_pci_cor_reset(priv);
+	if (err) {
+		printk(KERN_ERR PFX "Initial reset failed\n");
 		goto fail;
 	}
 
-	/* Override the normal firmware detection - the Prism 2.5 PCI
-	 * cards look like Lucent firmware but are actually Intersil */
-	priv->firmware_type = FIRMWARE_TYPE_INTERSIL;
-
 	err = register_netdev(dev);
 	if (err) {
-		printk(KERN_ERR "%s: Failed to register net device\n", dev->name);
+		printk(KERN_ERR PFX "Failed to register net device\n");
 		goto fail;
 	}
 
+	pci_set_drvdata(pdev, dev);
+
 	return 0;
 
  fail:
-	if (dev) {
-		if (dev->irq)
-			free_irq(dev->irq, dev);
+	free_irq(pdev->irq, dev);
 
-		free_netdev(dev);
-	}
+ fail_irq:
+	pci_set_drvdata(pdev, NULL);
+	free_orinocodev(dev);
 
-	if (pci_ioaddr)
-		iounmap(pci_ioaddr);
+ fail_alloc:
+	iounmap(pci_ioaddr);
 
+ fail_map:
+	pci_release_regions(pdev);
+
+ fail_resources:
 	pci_disable_device(pdev);
 
 	return err;
@@ -283,18 +283,14 @@
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_pci_card *card = priv->card;
 
 	unregister_netdev(dev);
-
-	if (dev->irq)
-		free_irq(dev->irq, dev);
-
-	if (priv->hw.iobase)
-		iounmap((unsigned char *) priv->hw.iobase);
-
+	free_irq(dev->irq, dev);
 	pci_set_drvdata(pdev, NULL);
-	free_netdev(dev);
-
+	free_orinocodev(dev);
+	iounmap(card->pci_ioaddr);
+	pci_release_regions(pdev);
 	pci_disable_device(pdev);
 }
 
@@ -326,6 +322,9 @@
 	
 	orinoco_unlock(priv, &flags);
 
+	pci_save_state(pdev);
+	pci_set_power_state(pdev, 3);
+
 	return 0;
 }
 
@@ -338,6 +337,9 @@
 
 	printk(KERN_DEBUG "%s: Orinoco-PCI waking up\n", dev->name);
 
+	pci_set_power_state(pdev, 0);
+	pci_restore_state(pdev);
+
 	err = orinoco_reinit_firmware(dev);
 	if (err) {
 		printk(KERN_ERR "%s: Error %d re-initializing firmware on orinoco_pci_resume()\n",
@@ -368,6 +370,8 @@
 	{0x1260, 0x3872, PCI_ANY_ID, PCI_ANY_ID,},
 	/* Intersil Prism 2.5 */
 	{0x1260, 0x3873, PCI_ANY_ID, PCI_ANY_ID,},
+	/* Samsung MagicLAN SWL-2210P */
+	{0x167d, 0xa000, PCI_ANY_ID, PCI_ANY_ID,},
 	{0,},
 };
 
diff -Nru a/drivers/net/wireless/orinoco_plx.c b/drivers/net/wireless/orinoco_plx.c
--- a/drivers/net/wireless/orinoco_plx.c	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/wireless/orinoco_plx.c	2005-03-08 14:29:45 -05:00
@@ -142,146 +142,199 @@
 #include "hermes.h"
 #include "orinoco.h"
 
-#define COR_OFFSET	(0x3e0/2) /* COR attribute offset of Prism2 PC card */
+#define COR_OFFSET	(0x3e0)	/* COR attribute offset of Prism2 PC card */
 #define COR_VALUE	(COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
+#define COR_RESET     (0x80)	/* reset bit in the COR register */
+#define PLX_RESET_TIME	(500)	/* milliseconds */
 
 #define PLX_INTCSR		0x4c /* Interrupt Control & Status Register */
 #define PLX_INTCSR_INTEN	(1<<6) /* Interrupt Enable bit */
 
-static const u16 cis_magic[] = {
-	0x0001, 0x0003, 0x0000, 0x0000, 0x00ff, 0x0017, 0x0004, 0x0067
+static const u8 cis_magic[] = {
+	0x01, 0x03, 0x00, 0x00, 0xff, 0x17, 0x04, 0x67
 };
 
+/* Orinoco PLX specific data */
+struct orinoco_plx_card {
+	void __iomem *attr_mem;
+};
+
+/*
+ * Do a soft reset of the card using the Configuration Option Register
+ */
+static int orinoco_plx_cor_reset(struct orinoco_private *priv)
+{
+	hermes_t *hw = &priv->hw;
+	struct orinoco_plx_card *card = priv->card;
+	u8 __iomem *attr_mem = card->attr_mem;
+	unsigned long timeout;
+	u16 reg;
+
+	writeb(COR_VALUE | COR_RESET, attr_mem + COR_OFFSET);
+	mdelay(1);
+
+	writeb(COR_VALUE, attr_mem + COR_OFFSET);
+	mdelay(1);
+
+	/* Just in case, wait more until the card is no longer busy */
+	timeout = jiffies + (PLX_RESET_TIME * HZ / 1000);
+	reg = hermes_read_regn(hw, CMD);
+	while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) {
+		mdelay(1);
+		reg = hermes_read_regn(hw, CMD);
+	}
+
+	/* Did we timeout ? */
+	if (reg & HERMES_CMD_BUSY) {
+		printk(KERN_ERR PFX "Busy timeout\n");
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+
 static int orinoco_plx_init_one(struct pci_dev *pdev,
 				const struct pci_device_id *ent)
 {
 	int err = 0;
-	u16 *attr_mem = NULL;
-	u32 reg, addr;
+	u8 __iomem *attr_mem = NULL;
+	u32 csr_reg, plx_addr;
 	struct orinoco_private *priv = NULL;
+	struct orinoco_plx_card *card;
 	unsigned long pccard_ioaddr = 0;
 	unsigned long pccard_iolen = 0;
 	struct net_device *dev = NULL;
+	void __iomem *mem;
 	int i;
 
 	err = pci_enable_device(pdev);
-	if (err)
-		return -EIO;
-
-	/* Resource 2 is mapped to the PCMCIA space */
-	attr_mem = ioremap(pci_resource_start(pdev, 2), PAGE_SIZE);
-	if (! attr_mem)
-		goto fail;
-
-	printk(KERN_DEBUG "orinoco_plx: CIS: ");
-	for (i = 0; i < 16; i++) {
-		printk("%02X:", (int)attr_mem[i]);
+	if (err) {
+		printk(KERN_ERR PFX "Cannot enable PCI device\n");
+		return err;
 	}
-	printk("\n");
 
-	/* Verify whether PC card is present */
-	/* FIXME: we probably need to be smarted about this */
-	if (memcmp(attr_mem, cis_magic, sizeof(cis_magic)) != 0) {
-		printk(KERN_ERR "orinoco_plx: The CIS value of Prism2 PC card is invalid.\n");
-		err = -EIO;
-		goto fail;
+	err = pci_request_regions(pdev, DRIVER_NAME);
+	if (err != 0) {
+		printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
+		goto fail_resources;
 	}
 
-	/* PCMCIA COR is the first byte following CIS: this write should
-	 * enable I/O mode and select level-triggered interrupts */
-	attr_mem[COR_OFFSET] = COR_VALUE;
-	mdelay(1);
-	reg = attr_mem[COR_OFFSET];
-	if (reg != COR_VALUE) {
-		printk(KERN_ERR "orinoco_plx: Error setting COR value (reg=%x)\n", reg);
-		goto fail;
-	}			
-
-	iounmap(attr_mem);
-	attr_mem = NULL; /* done with this now, it seems */
+	/* Resource 1 is mapped to PLX-specific registers */
+	plx_addr = pci_resource_start(pdev, 1);
 
-	/* bjoern: We need to tell the card to enable interrupts, in
-	   case the serial eprom didn't do this already. See the
-	   PLX9052 data book, p8-1 and 8-24 for reference. */
-	addr = pci_resource_start(pdev, 1);
-	reg = 0;
-	reg = inl(addr+PLX_INTCSR);
-	if (reg & PLX_INTCSR_INTEN)
-		printk(KERN_DEBUG "orinoco_plx: "
-		       "Local Interrupt already enabled\n");
-	else {
-		reg |= PLX_INTCSR_INTEN;
-		outl(reg, addr+PLX_INTCSR);
-		reg = inl(addr+PLX_INTCSR);
-		if(!(reg & PLX_INTCSR_INTEN)) {
-			printk(KERN_ERR "orinoco_plx: "
-			       "Couldn't enable Local Interrupts\n");
-			goto fail;
-		}
+	/* Resource 2 is mapped to the PCMCIA attribute memory */
+	attr_mem = ioremap(pci_resource_start(pdev, 2),
+			   pci_resource_len(pdev, 2));
+	if (!attr_mem) {
+		printk(KERN_ERR PFX "Cannot remap PCMCIA space\n");
+		goto fail_map_attr;
 	}
 
-	/* and 3 to the PCMCIA slot I/O address space */
+	/* Resource 3 is mapped to the PCMCIA I/O address space */
 	pccard_ioaddr = pci_resource_start(pdev, 3);
 	pccard_iolen = pci_resource_len(pdev, 3);
-	if (! request_region(pccard_ioaddr, pccard_iolen, DRIVER_NAME)) {
-		printk(KERN_ERR "orinoco_plx: I/O resource 0x%lx @ 0x%lx busy\n",
-		       pccard_iolen, pccard_ioaddr);
-		pccard_ioaddr = 0;
-		err = -EBUSY;
-		goto fail;
+
+	mem = pci_iomap(pdev, 3, 0);
+	if (!mem) {
+		err = -ENOMEM;
+		goto fail_map_io;
 	}
 
 	/* Allocate network device */
-	dev = alloc_orinocodev(0, NULL);
-	if (! dev) {
+	dev = alloc_orinocodev(sizeof(*card), orinoco_plx_cor_reset);
+	if (!dev) {
+		printk(KERN_ERR PFX "Cannot allocate network device\n");
 		err = -ENOMEM;
-		goto fail;
+		goto fail_alloc;
 	}
 
 	priv = netdev_priv(dev);
+	card = priv->card;
+	card->attr_mem = attr_mem;
 	dev->base_addr = pccard_ioaddr;
 	SET_MODULE_OWNER(dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
+	hermes_struct_init(&priv->hw, mem, HERMES_16BIT_REGSPACING);
+
 	printk(KERN_DEBUG PFX "Detected Orinoco/Prism2 PLX device "
 	       "at %s irq:%d, io addr:0x%lx\n", pci_name(pdev), pdev->irq,
 	       pccard_ioaddr);
 
-	hermes_struct_init(&(priv->hw), dev->base_addr, HERMES_IO,
-			   HERMES_16BIT_REGSPACING);
-	pci_set_drvdata(pdev, dev);
-
 	err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
 			  dev->name, dev);
 	if (err) {
-		printk(KERN_ERR PFX "Error allocating IRQ %d.\n", pdev->irq);
+		printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
 		err = -EBUSY;
-		goto fail;
+		goto fail_irq;
 	}
 	dev->irq = pdev->irq;
 
+	/* bjoern: We need to tell the card to enable interrupts, in
+	   case the serial eprom didn't do this already.  See the
+	   PLX9052 data book, p8-1 and 8-24 for reference. */
+	csr_reg = inl(plx_addr + PLX_INTCSR);
+	if (!(csr_reg & PLX_INTCSR_INTEN)) {
+		csr_reg |= PLX_INTCSR_INTEN;
+		outl(csr_reg, plx_addr + PLX_INTCSR);
+		csr_reg = inl(plx_addr + PLX_INTCSR);
+		if (!(csr_reg & PLX_INTCSR_INTEN)) {
+			printk(KERN_ERR PFX "Cannot enable interrupts\n");
+			goto fail;
+		}
+	}
+
+	err = orinoco_plx_cor_reset(priv);
+	if (err) {
+		printk(KERN_ERR PFX "Initial reset failed\n");
+		goto fail;
+	}
+
+	printk(KERN_DEBUG PFX "CIS: ");
+	for (i = 0; i < 16; i++) {
+		printk("%02X:", readb(attr_mem + 2*i));
+	}
+	printk("\n");
+
+	/* Verify whether a supported PC card is present */
+	/* FIXME: we probably need to be smarted about this */
+	for (i = 0; i < sizeof(cis_magic); i++) {
+		if (cis_magic[i] != readb(attr_mem +2*i)) {
+			printk(KERN_ERR PFX "The CIS value of Prism2 PC "
+			       "card is unexpected\n");
+			err = -EIO;
+			goto fail;
+		}
+	}
+
 	err = register_netdev(dev);
-	if (err)
+	if (err) {
+		printk(KERN_ERR PFX "Cannot register network device\n");
 		goto fail;
+	}
+
+	pci_set_drvdata(pdev, dev);
 
 	return 0;
 
  fail:
-	printk(KERN_DEBUG PFX "init_one(), FAIL!\n");
+	free_irq(pdev->irq, dev);
 
-	if (dev) {
-		if (dev->irq)
-			free_irq(dev->irq, dev);
-		
-		free_netdev(dev);
-	}
+ fail_irq:
+	pci_set_drvdata(pdev, NULL);
+	free_orinocodev(dev);
 
-	if (pccard_ioaddr)
-		release_region(pccard_ioaddr, pccard_iolen);
+ fail_alloc:
+	pci_iounmap(pdev, mem);
+
+ fail_map_io:
+	iounmap(attr_mem);
 
-	if (attr_mem)
-		iounmap(attr_mem);
+ fail_map_attr:
+	pci_release_regions(pdev);
 
+ fail_resources:
 	pci_disable_device(pdev);
 
 	return err;
@@ -290,20 +343,19 @@
 static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_plx_card *card = priv->card;
+	u8 __iomem *attr_mem = card->attr_mem;
 
 	BUG_ON(! dev);
 
 	unregister_netdev(dev);
-		
-	if (dev->irq)
-		free_irq(dev->irq, dev);
-		
+	free_irq(dev->irq, dev);
 	pci_set_drvdata(pdev, NULL);
-
-	free_netdev(dev);
-
-	release_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3));
-
+	free_orinocodev(dev);
+	pci_iounmap(pdev, priv->hw.iobase);
+	iounmap(attr_mem);
+	pci_release_regions(pdev);
 	pci_disable_device(pdev);
 }
 
@@ -352,8 +404,7 @@
 static void __exit orinoco_plx_exit(void)
 {
 	pci_unregister_driver(&orinoco_plx_driver);
-	current->state = TASK_UNINTERRUPTIBLE;
-	schedule_timeout(HZ);
+	ssleep(1);
 }
 
 module_init(orinoco_plx_init);
diff -Nru a/drivers/net/wireless/orinoco_tmd.c b/drivers/net/wireless/orinoco_tmd.c
--- a/drivers/net/wireless/orinoco_tmd.c	2005-03-08 14:29:45 -05:00
+++ b/drivers/net/wireless/orinoco_tmd.c	2005-03-08 14:29:45 -05:00
@@ -79,90 +79,137 @@
 #include "orinoco.h"
 
 #define COR_VALUE	(COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
+#define COR_RESET     (0x80)	/* reset bit in the COR register */
+#define TMD_RESET_TIME	(500)	/* milliseconds */
+
+/* Orinoco TMD specific data */
+struct orinoco_tmd_card {
+	u32 tmd_io;
+};
+
+
+/*
+ * Do a soft reset of the card using the Configuration Option Register
+ */
+static int orinoco_tmd_cor_reset(struct orinoco_private *priv)
+{
+	hermes_t *hw = &priv->hw;
+	struct orinoco_tmd_card *card = priv->card;
+	u32 addr = card->tmd_io;
+	unsigned long timeout;
+	u16 reg;
+
+	outb(COR_VALUE | COR_RESET, addr);
+	mdelay(1);
+
+	outb(COR_VALUE, addr);
+	mdelay(1);
+
+	/* Just in case, wait more until the card is no longer busy */
+	timeout = jiffies + (TMD_RESET_TIME * HZ / 1000);
+	reg = hermes_read_regn(hw, CMD);
+	while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) {
+		mdelay(1);
+		reg = hermes_read_regn(hw, CMD);
+	}
+
+	/* Did we timeout ? */
+	if (reg & HERMES_CMD_BUSY) {
+		printk(KERN_ERR PFX "Busy timeout\n");
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
 
 static int orinoco_tmd_init_one(struct pci_dev *pdev,
 				const struct pci_device_id *ent)
 {
 	int err = 0;
-	u32 reg, addr;
 	struct orinoco_private *priv = NULL;
-	unsigned long pccard_ioaddr = 0;
-	unsigned long pccard_iolen = 0;
+	struct orinoco_tmd_card *card;
 	struct net_device *dev = NULL;
+	void __iomem *mem;
 
 	err = pci_enable_device(pdev);
-	if (err)
-		return -EIO;
+	if (err) {
+		printk(KERN_ERR PFX "Cannot enable PCI device\n");
+		return err;
+	}
 
-	printk(KERN_DEBUG PFX "TMD setup\n");
-	pccard_ioaddr = pci_resource_start(pdev, 2);
-	pccard_iolen = pci_resource_len(pdev, 2);
-	if (! request_region(pccard_ioaddr, pccard_iolen, DRIVER_NAME)) {
-		printk(KERN_ERR PFX "I/O resource at 0x%lx len 0x%lx busy\n",
-			pccard_ioaddr, pccard_iolen);
-		pccard_ioaddr = 0;
-		err = -EBUSY;
-		goto fail;
+	err = pci_request_regions(pdev, DRIVER_NAME);
+	if (err != 0) {
+		printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
+		goto fail_resources;
 	}
-	addr = pci_resource_start(pdev, 1);
-	outb(COR_VALUE, addr);
-	mdelay(1);
-	reg = inb(addr);
-	if (reg != COR_VALUE) {
-		printk(KERN_ERR PFX "Error setting TMD COR values %x should be %x\n", reg, COR_VALUE);
-		err = -EIO;
-		goto fail;
+
+	mem = pci_iomap(pdev, 2, 0);
+	if (! mem) {
+		err = -ENOMEM;
+		goto fail_iomap;
 	}
 
 	/* Allocate network device */
-	dev = alloc_orinocodev(0, NULL);
+	dev = alloc_orinocodev(sizeof(*card), orinoco_tmd_cor_reset);
 	if (! dev) {
+		printk(KERN_ERR PFX "Cannot allocate network device\n");
 		err = -ENOMEM;
-		goto fail;
+		goto fail_alloc;
 	}
 
 	priv = netdev_priv(dev);
-	dev->base_addr = pccard_ioaddr;
+	card = priv->card;
+	card->tmd_io = pci_resource_start(pdev, 1);
+	dev->base_addr = pci_resource_start(pdev, 2);
 	SET_MODULE_OWNER(dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
+	hermes_struct_init(&priv->hw, mem, HERMES_16BIT_REGSPACING);
+
 	printk(KERN_DEBUG PFX "Detected Orinoco/Prism2 TMD device "
 	       "at %s irq:%d, io addr:0x%lx\n", pci_name(pdev), pdev->irq,
-	       pccard_ioaddr);
-
-	hermes_struct_init(&(priv->hw), dev->base_addr,
-			HERMES_IO, HERMES_16BIT_REGSPACING);
-	pci_set_drvdata(pdev, dev);
+	       dev->base_addr);
 
 	err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
 			  dev->name, dev);
 	if (err) {
-		printk(KERN_ERR PFX "Error allocating IRQ %d.\n",
-		       pdev->irq);
+		printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
 		err = -EBUSY;
-		goto fail;
+		goto fail_irq;
 	}
 	dev->irq = pdev->irq;
 
+	err = orinoco_tmd_cor_reset(priv);
+	if (err) {
+		printk(KERN_ERR PFX "Initial reset failed\n");
+		goto fail;
+	}
+
 	err = register_netdev(dev);
-	if (err)
+	if (err) {
+		printk(KERN_ERR PFX "Cannot register network device\n");
 		goto fail;
+	}
+
+	pci_set_drvdata(pdev, dev);
 
 	return 0;
 
  fail:
-	printk(KERN_DEBUG PFX "init_one(), FAIL!\n");
+	free_irq(pdev->irq, dev);
 
-	if (dev) {
-		if (dev->irq)
-			free_irq(dev->irq, dev);
-		
-		free_netdev(dev);
-	}
+ fail_irq:
+	pci_set_drvdata(pdev, NULL);
+	free_orinocodev(dev);
+
+ fail_alloc:
+	pci_iounmap(pdev, mem);
 
-	if (pccard_ioaddr)
-		release_region(pccard_ioaddr, pccard_iolen);
+ fail_iomap:
+	pci_release_regions(pdev);
 
+ fail_resources:
 	pci_disable_device(pdev);
 
 	return err;
@@ -171,20 +218,16 @@
 static void __devexit orinoco_tmd_remove_one(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
+	struct orinoco_private *priv = dev->priv;
 
 	BUG_ON(! dev);
 
 	unregister_netdev(dev);
-		
-	if (dev->irq)
-		free_irq(dev->irq, dev);
-		
+	free_irq(dev->irq, dev);
 	pci_set_drvdata(pdev, NULL);
-
-	free_netdev(dev);
-
-	release_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2));
-
+	free_orinocodev(dev);
+	pci_iounmap(pdev, priv->hw.iobase);
+	pci_release_regions(pdev);
 	pci_disable_device(pdev);
 }
 
@@ -218,8 +261,7 @@
 static void __exit orinoco_tmd_exit(void)
 {
 	pci_unregister_driver(&orinoco_tmd_driver);
-	current->state = TASK_UNINTERRUPTIBLE;
-	schedule_timeout(HZ);
+	ssleep(1);
 }
 
 module_init(orinoco_tmd_init);
diff -Nru a/include/linux/mv643xx.h b/include/linux/mv643xx.h
--- a/include/linux/mv643xx.h	2005-03-08 14:29:45 -05:00
+++ b/include/linux/mv643xx.h	2005-03-08 14:29:45 -05:00
@@ -1,5 +1,5 @@
 /*
- * mv64340.h - MV-64340 Internal registers definition file.
+ * mv643xx.h - MV-643XX Internal registers definition file.
  *
  * Copyright 2002 Momentum Computer, Inc.
  * 	Author: Matthew Dharm <mdharm@momenco.com>
@@ -10,8 +10,8 @@
  * Free Software Foundation;  either version 2 of the  License, or (at your
  * option) any later version.
  */
-#ifndef __ASM_MV64340_H
-#define __ASM_MV64340_H
+#ifndef __ASM_MV643XX_H
+#define __ASM_MV643XX_H
 
 #ifdef __MIPS__
 #include <asm/addrspace.h>
@@ -662,116 +662,119 @@
 /*        Ethernet Unit Registers  		*/
 /****************************************/
 
-#define MV64340_ETH_PHY_ADDR_REG                                    0x2000
-#define MV64340_ETH_SMI_REG                                         0x2004
-#define MV64340_ETH_UNIT_DEFAULT_ADDR_REG                           0x2008
-#define MV64340_ETH_UNIT_DEFAULTID_REG                              0x200c
-#define MV64340_ETH_UNIT_INTERRUPT_CAUSE_REG                        0x2080
-#define MV64340_ETH_UNIT_INTERRUPT_MASK_REG                         0x2084
-#define MV64340_ETH_UNIT_INTERNAL_USE_REG                           0x24fc
-#define MV64340_ETH_UNIT_ERROR_ADDR_REG                             0x2094
-#define MV64340_ETH_BAR_0                                           0x2200
-#define MV64340_ETH_BAR_1                                           0x2208
-#define MV64340_ETH_BAR_2                                           0x2210
-#define MV64340_ETH_BAR_3                                           0x2218
-#define MV64340_ETH_BAR_4                                           0x2220
-#define MV64340_ETH_BAR_5                                           0x2228
-#define MV64340_ETH_SIZE_REG_0                                      0x2204
-#define MV64340_ETH_SIZE_REG_1                                      0x220c
-#define MV64340_ETH_SIZE_REG_2                                      0x2214
-#define MV64340_ETH_SIZE_REG_3                                      0x221c
-#define MV64340_ETH_SIZE_REG_4                                      0x2224
-#define MV64340_ETH_SIZE_REG_5                                      0x222c
-#define MV64340_ETH_HEADERS_RETARGET_BASE_REG                       0x2230
-#define MV64340_ETH_HEADERS_RETARGET_CONTROL_REG                    0x2234
-#define MV64340_ETH_HIGH_ADDR_REMAP_REG_0                           0x2280
-#define MV64340_ETH_HIGH_ADDR_REMAP_REG_1                           0x2284
-#define MV64340_ETH_HIGH_ADDR_REMAP_REG_2                           0x2288
-#define MV64340_ETH_HIGH_ADDR_REMAP_REG_3                           0x228c
-#define MV64340_ETH_BASE_ADDR_ENABLE_REG                            0x2290
-#define MV64340_ETH_ACCESS_PROTECTION_REG(port)                    (0x2294 + (port<<2))
-#define MV64340_ETH_MIB_COUNTERS_BASE(port)                        (0x3000 + (port<<7))
-#define MV64340_ETH_PORT_CONFIG_REG(port)                          (0x2400 + (port<<10))
-#define MV64340_ETH_PORT_CONFIG_EXTEND_REG(port)                   (0x2404 + (port<<10))
-#define MV64340_ETH_MII_SERIAL_PARAMETRS_REG(port)                 (0x2408 + (port<<10))
-#define MV64340_ETH_GMII_SERIAL_PARAMETRS_REG(port)                (0x240c + (port<<10))
-#define MV64340_ETH_VLAN_ETHERTYPE_REG(port)                       (0x2410 + (port<<10))
-#define MV64340_ETH_MAC_ADDR_LOW(port)                             (0x2414 + (port<<10))
-#define MV64340_ETH_MAC_ADDR_HIGH(port)                            (0x2418 + (port<<10))
-#define MV64340_ETH_SDMA_CONFIG_REG(port)                          (0x241c + (port<<10))
-#define MV64340_ETH_DSCP_0(port)                                   (0x2420 + (port<<10))
-#define MV64340_ETH_DSCP_1(port)                                   (0x2424 + (port<<10))
-#define MV64340_ETH_DSCP_2(port)                                   (0x2428 + (port<<10))
-#define MV64340_ETH_DSCP_3(port)                                   (0x242c + (port<<10))
-#define MV64340_ETH_DSCP_4(port)                                   (0x2430 + (port<<10))
-#define MV64340_ETH_DSCP_5(port)                                   (0x2434 + (port<<10))
-#define MV64340_ETH_DSCP_6(port)                                   (0x2438 + (port<<10))
-#define MV64340_ETH_PORT_SERIAL_CONTROL_REG(port)                  (0x243c + (port<<10))
-#define MV64340_ETH_VLAN_PRIORITY_TAG_TO_PRIORITY(port)            (0x2440 + (port<<10))
-#define MV64340_ETH_PORT_STATUS_REG(port)                          (0x2444 + (port<<10))
-#define MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(port)               (0x2448 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_FIXED_PRIORITY(port)                  (0x244c + (port<<10))
-#define MV64340_ETH_PORT_TX_TOKEN_BUCKET_RATE_CONFIG(port)         (0x2450 + (port<<10))
-#define MV64340_ETH_MAXIMUM_TRANSMIT_UNIT(port)                    (0x2458 + (port<<10))
-#define MV64340_ETH_PORT_MAXIMUM_TOKEN_BUCKET_SIZE(port)           (0x245c + (port<<10))
-#define MV64340_ETH_INTERRUPT_CAUSE_REG(port)                      (0x2460 + (port<<10))
-#define MV64340_ETH_INTERRUPT_CAUSE_EXTEND_REG(port)               (0x2464 + (port<<10))
-#define MV64340_ETH_INTERRUPT_MASK_REG(port)                       (0x2468 + (port<<10))
-#define MV64340_ETH_INTERRUPT_EXTEND_MASK_REG(port)                (0x246c + (port<<10))
-#define MV64340_ETH_RX_FIFO_URGENT_THRESHOLD_REG(port)             (0x2470 + (port<<10))
-#define MV64340_ETH_TX_FIFO_URGENT_THRESHOLD_REG(port)             (0x2474 + (port<<10))
-#define MV64340_ETH_RX_MINIMAL_FRAME_SIZE_REG(port)                (0x247c + (port<<10))
-#define MV64340_ETH_RX_DISCARDED_FRAMES_COUNTER(port)              (0x2484 + (port<<10)
-#define MV64340_ETH_PORT_DEBUG_0_REG(port)                         (0x248c + (port<<10))
-#define MV64340_ETH_PORT_DEBUG_1_REG(port)                         (0x2490 + (port<<10))
-#define MV64340_ETH_PORT_INTERNAL_ADDR_ERROR_REG(port)             (0x2494 + (port<<10))
-#define MV64340_ETH_INTERNAL_USE_REG(port)                         (0x24fc + (port<<10))
-#define MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(port)                (0x2680 + (port<<10))
-#define MV64340_ETH_CURRENT_SERVED_TX_DESC_PTR(port)               (0x2684 + (port<<10))      
-#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_0(port)              (0x260c + (port<<10))     
-#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_1(port)              (0x261c + (port<<10))     
-#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_2(port)              (0x262c + (port<<10))     
-#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_3(port)              (0x263c + (port<<10))     
-#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_4(port)              (0x264c + (port<<10))     
-#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_5(port)              (0x265c + (port<<10))     
-#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_6(port)              (0x266c + (port<<10))     
-#define MV64340_ETH_RX_CURRENT_QUEUE_DESC_PTR_7(port)              (0x267c + (port<<10))     
-#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_0(port)              (0x26c0 + (port<<10))     
-#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_1(port)              (0x26c4 + (port<<10))     
-#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_2(port)              (0x26c8 + (port<<10))     
-#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_3(port)              (0x26cc + (port<<10))     
-#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_4(port)              (0x26d0 + (port<<10))     
-#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_5(port)              (0x26d4 + (port<<10))     
-#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_6(port)              (0x26d8 + (port<<10))     
-#define MV64340_ETH_TX_CURRENT_QUEUE_DESC_PTR_7(port)              (0x26dc + (port<<10))     
-#define MV64340_ETH_TX_QUEUE_0_TOKEN_BUCKET_COUNT(port)            (0x2700 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_1_TOKEN_BUCKET_COUNT(port)            (0x2710 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_2_TOKEN_BUCKET_COUNT(port)            (0x2720 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_3_TOKEN_BUCKET_COUNT(port)            (0x2730 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_4_TOKEN_BUCKET_COUNT(port)            (0x2740 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_5_TOKEN_BUCKET_COUNT(port)            (0x2750 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_6_TOKEN_BUCKET_COUNT(port)            (0x2760 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_7_TOKEN_BUCKET_COUNT(port)            (0x2770 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_0_TOKEN_BUCKET_CONFIG(port)           (0x2704 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_1_TOKEN_BUCKET_CONFIG(port)           (0x2714 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_2_TOKEN_BUCKET_CONFIG(port)           (0x2724 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_3_TOKEN_BUCKET_CONFIG(port)           (0x2734 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_4_TOKEN_BUCKET_CONFIG(port)           (0x2744 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_5_TOKEN_BUCKET_CONFIG(port)           (0x2754 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_6_TOKEN_BUCKET_CONFIG(port)           (0x2764 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_7_TOKEN_BUCKET_CONFIG(port)           (0x2774 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_0_ARBITER_CONFIG(port)                (0x2708 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_1_ARBITER_CONFIG(port)                (0x2718 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_2_ARBITER_CONFIG(port)                (0x2728 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_3_ARBITER_CONFIG(port)                (0x2738 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_4_ARBITER_CONFIG(port)                (0x2748 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_5_ARBITER_CONFIG(port)                (0x2758 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_6_ARBITER_CONFIG(port)                (0x2768 + (port<<10))
-#define MV64340_ETH_TX_QUEUE_7_ARBITER_CONFIG(port)                (0x2778 + (port<<10))
-#define MV64340_ETH_PORT_TX_TOKEN_BUCKET_COUNT(port)               (0x2780 + (port<<10))
-#define MV64340_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(port)   (0x3400 + (port<<10))
-#define MV64340_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(port)     (0x3500 + (port<<10))
-#define MV64340_ETH_DA_FILTER_UNICAST_TABLE_BASE(port)             (0x3600 + (port<<10))
+#define MV643XX_ETH_SHARED_REGS                                     0x2000
+#define MV643XX_ETH_SHARED_REGS_SIZE                                0x2000
+
+#define MV643XX_ETH_PHY_ADDR_REG                                    0x2000
+#define MV643XX_ETH_SMI_REG                                         0x2004
+#define MV643XX_ETH_UNIT_DEFAULT_ADDR_REG                           0x2008
+#define MV643XX_ETH_UNIT_DEFAULTID_REG                              0x200c
+#define MV643XX_ETH_UNIT_INTERRUPT_CAUSE_REG                        0x2080
+#define MV643XX_ETH_UNIT_INTERRUPT_MASK_REG                         0x2084
+#define MV643XX_ETH_UNIT_INTERNAL_USE_REG                           0x24fc
+#define MV643XX_ETH_UNIT_ERROR_ADDR_REG                             0x2094
+#define MV643XX_ETH_BAR_0                                           0x2200
+#define MV643XX_ETH_BAR_1                                           0x2208
+#define MV643XX_ETH_BAR_2                                           0x2210
+#define MV643XX_ETH_BAR_3                                           0x2218
+#define MV643XX_ETH_BAR_4                                           0x2220
+#define MV643XX_ETH_BAR_5                                           0x2228
+#define MV643XX_ETH_SIZE_REG_0                                      0x2204
+#define MV643XX_ETH_SIZE_REG_1                                      0x220c
+#define MV643XX_ETH_SIZE_REG_2                                      0x2214
+#define MV643XX_ETH_SIZE_REG_3                                      0x221c
+#define MV643XX_ETH_SIZE_REG_4                                      0x2224
+#define MV643XX_ETH_SIZE_REG_5                                      0x222c
+#define MV643XX_ETH_HEADERS_RETARGET_BASE_REG                       0x2230
+#define MV643XX_ETH_HEADERS_RETARGET_CONTROL_REG                    0x2234
+#define MV643XX_ETH_HIGH_ADDR_REMAP_REG_0                           0x2280
+#define MV643XX_ETH_HIGH_ADDR_REMAP_REG_1                           0x2284
+#define MV643XX_ETH_HIGH_ADDR_REMAP_REG_2                           0x2288
+#define MV643XX_ETH_HIGH_ADDR_REMAP_REG_3                           0x228c
+#define MV643XX_ETH_BASE_ADDR_ENABLE_REG                            0x2290
+#define MV643XX_ETH_ACCESS_PROTECTION_REG(port)                    (0x2294 + (port<<2))
+#define MV643XX_ETH_MIB_COUNTERS_BASE(port)                        (0x3000 + (port<<7))
+#define MV643XX_ETH_PORT_CONFIG_REG(port)                          (0x2400 + (port<<10))
+#define MV643XX_ETH_PORT_CONFIG_EXTEND_REG(port)                   (0x2404 + (port<<10))
+#define MV643XX_ETH_MII_SERIAL_PARAMETRS_REG(port)                 (0x2408 + (port<<10))
+#define MV643XX_ETH_GMII_SERIAL_PARAMETRS_REG(port)                (0x240c + (port<<10))
+#define MV643XX_ETH_VLAN_ETHERTYPE_REG(port)                       (0x2410 + (port<<10))
+#define MV643XX_ETH_MAC_ADDR_LOW(port)                             (0x2414 + (port<<10))
+#define MV643XX_ETH_MAC_ADDR_HIGH(port)                            (0x2418 + (port<<10))
+#define MV643XX_ETH_SDMA_CONFIG_REG(port)                          (0x241c + (port<<10))
+#define MV643XX_ETH_DSCP_0(port)                                   (0x2420 + (port<<10))
+#define MV643XX_ETH_DSCP_1(port)                                   (0x2424 + (port<<10))
+#define MV643XX_ETH_DSCP_2(port)                                   (0x2428 + (port<<10))
+#define MV643XX_ETH_DSCP_3(port)                                   (0x242c + (port<<10))
+#define MV643XX_ETH_DSCP_4(port)                                   (0x2430 + (port<<10))
+#define MV643XX_ETH_DSCP_5(port)                                   (0x2434 + (port<<10))
+#define MV643XX_ETH_DSCP_6(port)                                   (0x2438 + (port<<10))
+#define MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port)                  (0x243c + (port<<10))
+#define MV643XX_ETH_VLAN_PRIORITY_TAG_TO_PRIORITY(port)            (0x2440 + (port<<10))
+#define MV643XX_ETH_PORT_STATUS_REG(port)                          (0x2444 + (port<<10))
+#define MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port)               (0x2448 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_FIXED_PRIORITY(port)                  (0x244c + (port<<10))
+#define MV643XX_ETH_PORT_TX_TOKEN_BUCKET_RATE_CONFIG(port)         (0x2450 + (port<<10))
+#define MV643XX_ETH_MAXIMUM_TRANSMIT_UNIT(port)                    (0x2458 + (port<<10))
+#define MV643XX_ETH_PORT_MAXIMUM_TOKEN_BUCKET_SIZE(port)           (0x245c + (port<<10))
+#define MV643XX_ETH_INTERRUPT_CAUSE_REG(port)                      (0x2460 + (port<<10))
+#define MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port)               (0x2464 + (port<<10))
+#define MV643XX_ETH_INTERRUPT_MASK_REG(port)                       (0x2468 + (port<<10))
+#define MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port)                (0x246c + (port<<10))
+#define MV643XX_ETH_RX_FIFO_URGENT_THRESHOLD_REG(port)             (0x2470 + (port<<10))
+#define MV643XX_ETH_TX_FIFO_URGENT_THRESHOLD_REG(port)             (0x2474 + (port<<10))
+#define MV643XX_ETH_RX_MINIMAL_FRAME_SIZE_REG(port)                (0x247c + (port<<10))
+#define MV643XX_ETH_RX_DISCARDED_FRAMES_COUNTER(port)              (0x2484 + (port<<10)
+#define MV643XX_ETH_PORT_DEBUG_0_REG(port)                         (0x248c + (port<<10))
+#define MV643XX_ETH_PORT_DEBUG_1_REG(port)                         (0x2490 + (port<<10))
+#define MV643XX_ETH_PORT_INTERNAL_ADDR_ERROR_REG(port)             (0x2494 + (port<<10))
+#define MV643XX_ETH_INTERNAL_USE_REG(port)                         (0x24fc + (port<<10))
+#define MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port)                (0x2680 + (port<<10))
+#define MV643XX_ETH_CURRENT_SERVED_TX_DESC_PTR(port)               (0x2684 + (port<<10))      
+#define MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_0(port)              (0x260c + (port<<10))     
+#define MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_1(port)              (0x261c + (port<<10))     
+#define MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_2(port)              (0x262c + (port<<10))     
+#define MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_3(port)              (0x263c + (port<<10))     
+#define MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_4(port)              (0x264c + (port<<10))     
+#define MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_5(port)              (0x265c + (port<<10))     
+#define MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_6(port)              (0x266c + (port<<10))     
+#define MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_7(port)              (0x267c + (port<<10))     
+#define MV643XX_ETH_TX_CURRENT_QUEUE_DESC_PTR_0(port)              (0x26c0 + (port<<10))     
+#define MV643XX_ETH_TX_CURRENT_QUEUE_DESC_PTR_1(port)              (0x26c4 + (port<<10))     
+#define MV643XX_ETH_TX_CURRENT_QUEUE_DESC_PTR_2(port)              (0x26c8 + (port<<10))     
+#define MV643XX_ETH_TX_CURRENT_QUEUE_DESC_PTR_3(port)              (0x26cc + (port<<10))     
+#define MV643XX_ETH_TX_CURRENT_QUEUE_DESC_PTR_4(port)              (0x26d0 + (port<<10))     
+#define MV643XX_ETH_TX_CURRENT_QUEUE_DESC_PTR_5(port)              (0x26d4 + (port<<10))     
+#define MV643XX_ETH_TX_CURRENT_QUEUE_DESC_PTR_6(port)              (0x26d8 + (port<<10))     
+#define MV643XX_ETH_TX_CURRENT_QUEUE_DESC_PTR_7(port)              (0x26dc + (port<<10))     
+#define MV643XX_ETH_TX_QUEUE_0_TOKEN_BUCKET_COUNT(port)            (0x2700 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_1_TOKEN_BUCKET_COUNT(port)            (0x2710 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_2_TOKEN_BUCKET_COUNT(port)            (0x2720 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_3_TOKEN_BUCKET_COUNT(port)            (0x2730 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_4_TOKEN_BUCKET_COUNT(port)            (0x2740 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_5_TOKEN_BUCKET_COUNT(port)            (0x2750 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_6_TOKEN_BUCKET_COUNT(port)            (0x2760 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_7_TOKEN_BUCKET_COUNT(port)            (0x2770 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_0_TOKEN_BUCKET_CONFIG(port)           (0x2704 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_1_TOKEN_BUCKET_CONFIG(port)           (0x2714 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_2_TOKEN_BUCKET_CONFIG(port)           (0x2724 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_3_TOKEN_BUCKET_CONFIG(port)           (0x2734 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_4_TOKEN_BUCKET_CONFIG(port)           (0x2744 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_5_TOKEN_BUCKET_CONFIG(port)           (0x2754 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_6_TOKEN_BUCKET_CONFIG(port)           (0x2764 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_7_TOKEN_BUCKET_CONFIG(port)           (0x2774 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_0_ARBITER_CONFIG(port)                (0x2708 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_1_ARBITER_CONFIG(port)                (0x2718 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_2_ARBITER_CONFIG(port)                (0x2728 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_3_ARBITER_CONFIG(port)                (0x2738 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_4_ARBITER_CONFIG(port)                (0x2748 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_5_ARBITER_CONFIG(port)                (0x2758 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_6_ARBITER_CONFIG(port)                (0x2768 + (port<<10))
+#define MV643XX_ETH_TX_QUEUE_7_ARBITER_CONFIG(port)                (0x2778 + (port<<10))
+#define MV643XX_ETH_PORT_TX_TOKEN_BUCKET_COUNT(port)               (0x2780 + (port<<10))
+#define MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(port)   (0x3400 + (port<<10))
+#define MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(port)     (0x3500 + (port<<10))
+#define MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE(port)             (0x3600 + (port<<10))
 
 /*******************************************/
 /*          CUNIT  Registers               */
@@ -1090,4 +1093,221 @@
 	u32	retries;
 };
 
-#endif /* __ASM_MV64340_H */
+/* These macros describe Ethernet Port configuration reg (Px_cR) bits */
+#define MV643XX_ETH_UNICAST_NORMAL_MODE		0
+#define MV643XX_ETH_UNICAST_PROMISCUOUS_MODE	(1<<0)
+#define MV643XX_ETH_DEFAULT_RX_QUEUE_0		0
+#define MV643XX_ETH_DEFAULT_RX_QUEUE_1		(1<<1)
+#define MV643XX_ETH_DEFAULT_RX_QUEUE_2		(1<<2)
+#define MV643XX_ETH_DEFAULT_RX_QUEUE_3		((1<<2) | (1<<1))
+#define MV643XX_ETH_DEFAULT_RX_QUEUE_4		(1<<3)
+#define MV643XX_ETH_DEFAULT_RX_QUEUE_5		((1<<3) | (1<<1))
+#define MV643XX_ETH_DEFAULT_RX_QUEUE_6		((1<<3) | (1<<2))
+#define MV643XX_ETH_DEFAULT_RX_QUEUE_7		((1<<3) | (1<<2) | (1<<1))
+#define MV643XX_ETH_DEFAULT_RX_ARP_QUEUE_0	0
+#define MV643XX_ETH_DEFAULT_RX_ARP_QUEUE_1	(1<<4)
+#define MV643XX_ETH_DEFAULT_RX_ARP_QUEUE_2	(1<<5)
+#define MV643XX_ETH_DEFAULT_RX_ARP_QUEUE_3	((1<<5) | (1<<4))
+#define MV643XX_ETH_DEFAULT_RX_ARP_QUEUE_4	(1<<6)
+#define MV643XX_ETH_DEFAULT_RX_ARP_QUEUE_5	((1<<6) | (1<<4))
+#define MV643XX_ETH_DEFAULT_RX_ARP_QUEUE_6	((1<<6) | (1<<5))
+#define MV643XX_ETH_DEFAULT_RX_ARP_QUEUE_7	((1<<6) | (1<<5) | (1<<4))
+#define MV643XX_ETH_RECEIVE_BC_IF_NOT_IP_OR_ARP	0
+#define MV643XX_ETH_REJECT_BC_IF_NOT_IP_OR_ARP	(1<<7)
+#define MV643XX_ETH_RECEIVE_BC_IF_IP		0
+#define MV643XX_ETH_REJECT_BC_IF_IP		(1<<8)
+#define MV643XX_ETH_RECEIVE_BC_IF_ARP		0
+#define MV643XX_ETH_REJECT_BC_IF_ARP		(1<<9)
+#define MV643XX_ETH_TX_AM_NO_UPDATE_ERROR_SUMMARY (1<<12)
+#define MV643XX_ETH_CAPTURE_TCP_FRAMES_DIS	0
+#define MV643XX_ETH_CAPTURE_TCP_FRAMES_EN	(1<<14)
+#define MV643XX_ETH_CAPTURE_UDP_FRAMES_DIS	0
+#define MV643XX_ETH_CAPTURE_UDP_FRAMES_EN	(1<<15)
+#define MV643XX_ETH_DEFAULT_RX_TCP_QUEUE_0	0
+#define MV643XX_ETH_DEFAULT_RX_TCP_QUEUE_1	(1<<16)
+#define MV643XX_ETH_DEFAULT_RX_TCP_QUEUE_2	(1<<17)
+#define MV643XX_ETH_DEFAULT_RX_TCP_QUEUE_3	((1<<17) | (1<<16))
+#define MV643XX_ETH_DEFAULT_RX_TCP_QUEUE_4	(1<<18)
+#define MV643XX_ETH_DEFAULT_RX_TCP_QUEUE_5	((1<<18) | (1<<16))
+#define MV643XX_ETH_DEFAULT_RX_TCP_QUEUE_6	((1<<18) | (1<<17))
+#define MV643XX_ETH_DEFAULT_RX_TCP_QUEUE_7	((1<<18) | (1<<17) | (1<<16))
+#define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_0	0
+#define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_1	(1<<19)
+#define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_2	(1<<20)
+#define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_3	((1<<20) | (1<<19))
+#define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_4	((1<<21)
+#define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_5	((1<<21) | (1<<19))
+#define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_6	((1<<21) | (1<<20))
+#define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_7	((1<<21) | (1<<20) | (1<<19))
+#define MV643XX_ETH_DEFAULT_RX_BPDU_QUEUE_0	0
+#define MV643XX_ETH_DEFAULT_RX_BPDU_QUEUE_1	(1<<22)
+#define MV643XX_ETH_DEFAULT_RX_BPDU_QUEUE_2	(1<<23)
+#define MV643XX_ETH_DEFAULT_RX_BPDU_QUEUE_3	((1<<23) | (1<<22))
+#define MV643XX_ETH_DEFAULT_RX_BPDU_QUEUE_4	(1<<24)
+#define MV643XX_ETH_DEFAULT_RX_BPDU_QUEUE_5	((1<<24) | (1<<22))
+#define MV643XX_ETH_DEFAULT_RX_BPDU_QUEUE_6	((1<<24) | (1<<23))
+#define MV643XX_ETH_DEFAULT_RX_BPDU_QUEUE_7	((1<<24) | (1<<23) | (1<<22))
+
+#define	MV643XX_ETH_PORT_CONFIG_DEFAULT_VALUE			\
+		MV643XX_ETH_UNICAST_NORMAL_MODE		|	\
+		MV643XX_ETH_DEFAULT_RX_QUEUE_0		|	\
+		MV643XX_ETH_DEFAULT_RX_ARP_QUEUE_0	|	\
+		MV643XX_ETH_RECEIVE_BC_IF_NOT_IP_OR_ARP	|	\
+		MV643XX_ETH_RECEIVE_BC_IF_IP		|	\
+		MV643XX_ETH_RECEIVE_BC_IF_ARP		|	\
+		MV643XX_ETH_CAPTURE_TCP_FRAMES_DIS	|	\
+		MV643XX_ETH_CAPTURE_UDP_FRAMES_DIS	|	\
+		MV643XX_ETH_DEFAULT_RX_TCP_QUEUE_0	|	\
+		MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_0	|	\
+		MV643XX_ETH_DEFAULT_RX_BPDU_QUEUE_0
+
+/* These macros describe Ethernet Port configuration extend reg (Px_cXR) bits*/
+#define MV643XX_ETH_CLASSIFY_EN				(1<<0)
+#define MV643XX_ETH_SPAN_BPDU_PACKETS_AS_NORMAL		0
+#define MV643XX_ETH_SPAN_BPDU_PACKETS_TO_RX_QUEUE_7	(1<<1)
+#define MV643XX_ETH_PARTITION_DISABLE			0
+#define MV643XX_ETH_PARTITION_ENABLE			(1<<2)
+
+#define	MV643XX_ETH_PORT_CONFIG_EXTEND_DEFAULT_VALUE		\
+		MV643XX_ETH_SPAN_BPDU_PACKETS_AS_NORMAL	|	\
+		MV643XX_ETH_PARTITION_DISABLE
+
+/* These macros describe Ethernet Port Sdma configuration reg (SDCR) bits */
+#define MV643XX_ETH_RIFB			(1<<0)
+#define MV643XX_ETH_RX_BURST_SIZE_1_64BIT		0
+#define MV643XX_ETH_RX_BURST_SIZE_2_64BIT		(1<<1)
+#define MV643XX_ETH_RX_BURST_SIZE_4_64BIT		(1<<2)
+#define MV643XX_ETH_RX_BURST_SIZE_8_64BIT		((1<<2) | (1<<1))
+#define MV643XX_ETH_RX_BURST_SIZE_16_64BIT		(1<<3)
+#define MV643XX_ETH_BLM_RX_NO_SWAP			(1<<4)
+#define MV643XX_ETH_BLM_RX_BYTE_SWAP			0
+#define MV643XX_ETH_BLM_TX_NO_SWAP			(1<<5)
+#define MV643XX_ETH_BLM_TX_BYTE_SWAP			0
+#define MV643XX_ETH_DESCRIPTORS_BYTE_SWAP		(1<<6)
+#define MV643XX_ETH_DESCRIPTORS_NO_SWAP			0
+#define MV643XX_ETH_TX_BURST_SIZE_1_64BIT		0
+#define MV643XX_ETH_TX_BURST_SIZE_2_64BIT		(1<<22)
+#define MV643XX_ETH_TX_BURST_SIZE_4_64BIT		(1<<23)
+#define MV643XX_ETH_TX_BURST_SIZE_8_64BIT		((1<<23) | (1<<22))
+#define MV643XX_ETH_TX_BURST_SIZE_16_64BIT		(1<<24)
+
+#define	MV643XX_ETH_IPG_INT_RX(value) ((value & 0x3fff) << 8)
+
+#define	MV643XX_ETH_PORT_SDMA_CONFIG_DEFAULT_VALUE		\
+		MV643XX_ETH_RX_BURST_SIZE_4_64BIT	|	\
+		MV643XX_ETH_IPG_INT_RX(0)		|	\
+		MV643XX_ETH_TX_BURST_SIZE_4_64BIT
+
+/* These macros describe Ethernet Port serial control reg (PSCR) bits */
+#define MV643XX_ETH_SERIAL_PORT_DISABLE			0
+#define MV643XX_ETH_SERIAL_PORT_ENABLE			(1<<0)
+#define MV643XX_ETH_FORCE_LINK_PASS			(1<<1)
+#define MV643XX_ETH_DO_NOT_FORCE_LINK_PASS		0
+#define MV643XX_ETH_ENABLE_AUTO_NEG_FOR_DUPLX		0
+#define MV643XX_ETH_DISABLE_AUTO_NEG_FOR_DUPLX		(1<<2)
+#define MV643XX_ETH_ENABLE_AUTO_NEG_FOR_FLOW_CTRL	0
+#define MV643XX_ETH_DISABLE_AUTO_NEG_FOR_FLOW_CTRL	(1<<3)
+#define MV643XX_ETH_ADV_NO_FLOW_CTRL			0
+#define MV643XX_ETH_ADV_SYMMETRIC_FLOW_CTRL		(1<<4)
+#define MV643XX_ETH_FORCE_FC_MODE_NO_PAUSE_DIS_TX	0
+#define MV643XX_ETH_FORCE_FC_MODE_TX_PAUSE_DIS		(1<<5)
+#define MV643XX_ETH_FORCE_BP_MODE_NO_JAM		0
+#define MV643XX_ETH_FORCE_BP_MODE_JAM_TX		(1<<7)
+#define MV643XX_ETH_FORCE_BP_MODE_JAM_TX_ON_RX_ERR	(1<<8)
+#define MV643XX_ETH_FORCE_LINK_FAIL			0
+#define MV643XX_ETH_DO_NOT_FORCE_LINK_FAIL		(1<<10)
+#define MV643XX_ETH_RETRANSMIT_16_ATTEMPTS		0
+#define MV643XX_ETH_RETRANSMIT_FOREVER			(1<<11)
+#define MV643XX_ETH_DISABLE_AUTO_NEG_SPEED_GMII		(1<<13)
+#define MV643XX_ETH_ENABLE_AUTO_NEG_SPEED_GMII		0
+#define MV643XX_ETH_DTE_ADV_0				0
+#define MV643XX_ETH_DTE_ADV_1				(1<<14)
+#define MV643XX_ETH_DISABLE_AUTO_NEG_BYPASS		0
+#define MV643XX_ETH_ENABLE_AUTO_NEG_BYPASS		(1<<15)
+#define MV643XX_ETH_AUTO_NEG_NO_CHANGE			0
+#define MV643XX_ETH_RESTART_AUTO_NEG			(1<<16)
+#define MV643XX_ETH_MAX_RX_PACKET_1518BYTE		0
+#define MV643XX_ETH_MAX_RX_PACKET_1522BYTE		(1<<17)
+#define MV643XX_ETH_MAX_RX_PACKET_1552BYTE		(1<<18)
+#define MV643XX_ETH_MAX_RX_PACKET_9022BYTE		((1<<18) | (1<<17))
+#define MV643XX_ETH_MAX_RX_PACKET_9192BYTE		(1<<19)
+#define MV643XX_ETH_MAX_RX_PACKET_9700BYTE		((1<<19) | (1<<17))
+#define MV643XX_ETH_SET_EXT_LOOPBACK			(1<<20)
+#define MV643XX_ETH_CLR_EXT_LOOPBACK			0
+#define MV643XX_ETH_SET_FULL_DUPLEX_MODE		(1<<21)
+#define MV643XX_ETH_SET_HALF_DUPLEX_MODE		0
+#define MV643XX_ETH_ENABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX (1<<22)
+#define MV643XX_ETH_DISABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX 0
+#define MV643XX_ETH_SET_GMII_SPEED_TO_10_100		0
+#define MV643XX_ETH_SET_GMII_SPEED_TO_1000		(1<<23)
+#define MV643XX_ETH_SET_MII_SPEED_TO_10			0
+#define MV643XX_ETH_SET_MII_SPEED_TO_100		(1<<24)
+
+#define	MV643XX_ETH_PORT_SERIAL_CONTROL_DEFAULT_VALUE		\
+		MV643XX_ETH_DO_NOT_FORCE_LINK_PASS	|	\
+		MV643XX_ETH_ENABLE_AUTO_NEG_FOR_DUPLX	|	\
+		MV643XX_ETH_DISABLE_AUTO_NEG_FOR_FLOW_CTRL |	\
+		MV643XX_ETH_ADV_SYMMETRIC_FLOW_CTRL	|	\
+		MV643XX_ETH_FORCE_FC_MODE_NO_PAUSE_DIS_TX |	\
+		MV643XX_ETH_FORCE_BP_MODE_NO_JAM	|	\
+		(1<<9)	/* reserved */			|	\
+		MV643XX_ETH_DO_NOT_FORCE_LINK_FAIL	|	\
+		MV643XX_ETH_RETRANSMIT_16_ATTEMPTS	|	\
+		MV643XX_ETH_ENABLE_AUTO_NEG_SPEED_GMII	|	\
+		MV643XX_ETH_DTE_ADV_0			|	\
+		MV643XX_ETH_DISABLE_AUTO_NEG_BYPASS	|	\
+		MV643XX_ETH_AUTO_NEG_NO_CHANGE		|	\
+		MV643XX_ETH_MAX_RX_PACKET_9700BYTE	|	\
+		MV643XX_ETH_CLR_EXT_LOOPBACK		|	\
+		MV643XX_ETH_SET_FULL_DUPLEX_MODE	|	\
+		MV643XX_ETH_ENABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX
+
+/* These macros describe Ethernet Serial Status reg (PSR) bits */
+#define MV643XX_ETH_PORT_STATUS_MODE_10_BIT		(1<<0)
+#define MV643XX_ETH_PORT_STATUS_LINK_UP			(1<<1)
+#define MV643XX_ETH_PORT_STATUS_FULL_DUPLEX		(1<<2)
+#define MV643XX_ETH_PORT_STATUS_FLOW_CONTROL		(1<<3)
+#define MV643XX_ETH_PORT_STATUS_GMII_1000		(1<<4)
+#define MV643XX_ETH_PORT_STATUS_MII_100			(1<<5)
+/* PSR bit 6 is undocumented */
+#define MV643XX_ETH_PORT_STATUS_TX_IN_PROGRESS		(1<<7)
+#define MV643XX_ETH_PORT_STATUS_AUTONEG_BYPASSED	(1<<8)
+#define MV643XX_ETH_PORT_STATUS_PARTITION		(1<<9)
+#define MV643XX_ETH_PORT_STATUS_TX_FIFO_EMPTY		(1<<10)
+/* PSR bits 11-31 are reserved */
+
+#define	MV643XX_ETH_PORT_DEFAULT_TRANSMIT_QUEUE_SIZE	800
+#define	MV643XX_ETH_PORT_DEFAULT_RECEIVE_QUEUE_SIZE	400
+
+#define MV643XX_ETH_DESC_SIZE				64
+
+#define MV643XX_ETH_SHARED_NAME	"mv643xx_eth_shared"
+#define MV643XX_ETH_NAME	"mv643xx_eth"
+
+struct mv643xx_eth_platform_data {
+	/* 
+	 * Non-values for mac_addr, phy_addr, port_config, etc.
+	 * override the default value.  Setting the corresponding
+	 * force_* field, causes the default value to be overridden
+	 * even when zero.
+	 */
+	unsigned int	force_phy_addr:1;
+	unsigned int	force_port_config:1;
+	unsigned int	force_port_config_extend:1;
+	unsigned int	force_port_sdma_config:1;
+	unsigned int	force_port_serial_control:1;
+	int		phy_addr;
+	char		*mac_addr;	/* pointer to mac address */
+	u32		port_config;
+	u32		port_config_extend;
+	u32		port_sdma_config;
+	u32		port_serial_control;
+	u32		tx_queue_size;
+	u32		rx_queue_size;
+	u32		tx_sram_addr;
+	u32		tx_sram_size;
+	u32		rx_sram_addr;
+	u32		rx_sram_size;
+};
+
+#endif /* __ASM_MV643XX_H */

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [BK PATCHES] 2.6.x net driver updates
@ 2005-03-07 17:10 Jeff Garzik
  0 siblings, 0 replies; 28+ messages in thread
From: Jeff Garzik @ 2005-03-07 17:10 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: Netdev, Linux Kernel

[-- Attachment #1: Type: text/plain, Size: 0 bytes --]



[-- Attachment #2: changelog.txt --]
[-- Type: text/plain, Size: 3558 bytes --]

Please do a

	bk pull bk://gkernel.bkbits.net/net-drivers-2.6

This will update the following files:

 Documentation/networking/bonding.txt    | 2101 ++++++++++++++++++++------------
 drivers/net/3c59x.c                     |    2 
 drivers/net/8139too.c                   |   99 -
 drivers/net/Kconfig                     |   15 
 drivers/net/amd8111e.c                  |    2 
 drivers/net/b44.c                       |    2 
 drivers/net/b44.h                       |   14 
 drivers/net/bonding/bond_alb.c          |    8 
 drivers/net/bonding/bond_main.c         |   35 
 drivers/net/e100.c                      |    4 
 drivers/net/eepro100.c                  |    6 
 drivers/net/epic100.c                   |    2 
 drivers/net/ibmlana.c                   |   99 -
 drivers/net/ibmlana.h                   |    1 
 drivers/net/irda/donauboe.c             |    2 
 drivers/net/mii.c                       |   63 
 drivers/net/natsemi.c                   |    2 
 drivers/net/ne2k-pci.c                  |    4 
 drivers/net/s2io.c                      |   53 
 drivers/net/sis900.c                    |    2 
 drivers/net/sk_mca.c                    |  126 -
 drivers/net/sk_mca.h                    |   19 
 drivers/net/smc91x.h                    |   19 
 drivers/net/sundance.c                  |    7 
 drivers/net/sungem.c                    |    2 
 drivers/net/tg3.c                       |    4 
 drivers/net/tg3.h                       |   14 
 drivers/net/tulip/tulip_core.c          |    2 
 drivers/net/typhoon.c                   |   10 
 drivers/net/via-rhine.c                 |    2 
 drivers/net/via-velocity.c              |    4 
 drivers/net/wireless/arlan.h            |    4 
 drivers/net/wireless/atmel.c            |  103 +
 drivers/net/wireless/atmel.h            |   43 
 drivers/net/wireless/atmel_cs.c         |   49 
 drivers/net/wireless/atmel_pci.c        |    6 
 drivers/net/wireless/prism54/isl_38xx.c |   12 
 include/linux/mii.h                     |   20 
 include/linux/netdevice.h               |    2 
 net/core/dev.c                          |   28 
 40 files changed, 1869 insertions(+), 1123 deletions(-)

through these ChangeSets:

<andi:cosy.sbg.ac.at>:
  o sundance: attempt to address high irqs due to TX overflow

<dcbw:redhat.com>:
  o wireless: Make Atmel driver use SET_NETDEV_DEV
  o wireless: WEXT quality cleanups + max rssi
  o wireless: Clean up firmware loading in

<jchapman:katalix.com>:
  o mii: add GigE support

Alexander Viro:
  o ibmlana part 2 (iomem annotations and isa-ectomy)
  o ibmlana part 1 (netdev_priv())
  o sk_mca - iomem and isa-ectomy
  o sk_mca - netdev_priv()

David T. Hollis:
  o Move MII-related constants from b44/tg3 drivers to linux/mii.h

Jay Vosburgh:
  o bonding: Update/rewrite bonding.txt
  o bonding: Update kconfig description
  o bonding: change misleading warning
  o bonding: use wrappers to change mtu and MAC
  o net/core: move set MAC into separate function

Jeff Garzik:
  o [wireless atmel] Add support LG LW2100N WLAN PCMCIA card

Nishanth Aravamudan:
  o net/s2io: replace schedule_timeout() with msleep()

Paul Mundt:
  o net: port smc91x to SH4-202 Microdev

Pavel Machek:
  o Fix u32 vs. pm_message_t in network device drivers

Randy Dunlap:
  o prism54: fix printk format warnings
  o (v2) arlan: remove gcc warning with CONFIG_PROC_FS=n

Rene Herman:
  o 8139too Interframe Gap Time

Stephen Hemminger:
  o 8139too: use netdev_priv

Thomas Gleixner:
  o rtl8139too.c: Fix missing pci_disable_dev
  o rtl8139too.c: Fix missing pci_disable_dev


[-- Attachment #3: patch --]
[-- Type: text/plain, Size: 190316 bytes --]

diff -Nru a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
--- a/Documentation/networking/bonding.txt	2005-03-07 12:09:08 -05:00
+++ b/Documentation/networking/bonding.txt	2005-03-07 12:09:08 -05:00
@@ -1,5 +1,5 @@
 
-                   Linux Ethernet Bonding Driver mini-howto
+                   Linux Ethernet Bonding Driver HOWTO
 
 Initial release : Thomas Davis <tadavis at lbl.gov>
 Corrections, HA extensions : 2000/10/03-15 :
@@ -9,8 +9,11 @@
   - Janice Girouard <girouard at us dot ibm dot com>
   - Jay Vosburgh <fubar at us dot ibm dot com>
 
+Reorganized and updated Feb 2005 by Jay Vosburgh
+
 Note :
 ------
+	
 The bonding driver originally came from Donald Becker's beowulf patches for
 kernel 2.0. It has changed quite a bit since, and the original tools from
 extreme-linux and beowulf sites will not work with this version of the driver.
@@ -18,218 +21,190 @@
 For new versions of the driver, patches for older kernels and the updated
 userspace tools, please follow the links at the end of this file.
 
-
 Table of Contents
 =================
 
-Installation
-Bond Configuration
-Module Parameters
-Configuring Multiple Bonds
-Switch Configuration
-Verifying Bond Configuration
-Frequently Asked Questions
-High Availability
-Promiscuous Sniffing notes
-8021q VLAN support
-Limitations
-Resources and Links
-
-
-Installation
-============
-
-1) Build kernel with the bonding driver
----------------------------------------
-For the latest version of the bonding driver, use kernel 2.4.12 or above
-(otherwise you will need to apply a patch).
-
-Configure kernel with `make menuconfig/xconfig/config', and select "Bonding
-driver support" in the "Network device support" section. It is recommended
-to configure the driver as module since it is currently the only way to
-pass parameters to the driver and configure more than one bonding device.
-
-Build and install the new kernel and modules.
-
-2) Get and install the userspace tools
---------------------------------------
-This version of the bonding driver requires updated ifenslave program. The
-original one from extreme-linux and beowulf will not work. Kernels 2.4.12
-and above include the updated version of ifenslave.c in
-Documentation/networking directory. For older kernels, please follow the
-links at the end of this file.
-
-IMPORTANT!!!  If you are running on Redhat 7.1 or greater, you need
-to be careful because /usr/include/linux is no longer a symbolic link
-to /usr/src/linux/include/linux.  If you build ifenslave while this is
-true, ifenslave will appear to succeed but your bond won't work.  The purpose
-of the -I option on the ifenslave compile line is to make sure it uses
-/usr/src/linux/include/linux/if_bonding.h instead of the version from
-/usr/include/linux.
-
-To install ifenslave.c, do:
-    # gcc -Wall -Wstrict-prototypes -O -I/usr/src/linux/include ifenslave.c -o ifenslave
-    # cp ifenslave /sbin/ifenslave
+1. Bonding Driver Installation
 
+2. Bonding Driver Options
 
-Bond Configuration
-==================
+3. Configuring Bonding Devices
+3.1	Configuration with sysconfig support
+3.2	Configuration with initscripts support
+3.3	Configuring Bonding Manually
+3.4	Configuring Multiple Bonds
 
-You will need to add at least the following line to /etc/modprobe.conf
-so the bonding driver will automatically load when the bond0 interface is
-configured. Refer to the modprobe.conf manual page for specific modprobe.conf
-syntax details. The Module Parameters section of this document describes each
-bonding driver parameter.
-
-	alias bond0 bonding
-
-Use standard distribution techniques to define the bond0 network interface. For
-example, on modern Red Hat distributions, create an ifcfg-bond0 file in
-the /etc/sysconfig/network-scripts directory that resembles the following:
+5. Querying Bonding Configuration
+5.1	Bonding Configuration
+5.2	Network Configuration
 
-DEVICE=bond0
-IPADDR=192.168.1.1
-NETMASK=255.255.255.0
-NETWORK=192.168.1.0
-BROADCAST=192.168.1.255
-ONBOOT=yes
-BOOTPROTO=none
-USERCTL=no
+6. Switch Configuration
 
-(use appropriate values for your network above)
+7. 802.1q VLAN Support
 
-All interfaces that are part of a bond should have SLAVE and MASTER
-definitions. For example, in the case of Red Hat, if you wish to make eth0 and
-eth1 a part of the bonding interface bond0, their config files (ifcfg-eth0 and
-ifcfg-eth1) should resemble the following:
+8. Link Monitoring
+8.1	ARP Monitor Operation
+8.2	Configuring Multiple ARP Targets
+8.3	MII Monitor Operation
 
-DEVICE=eth0
-USERCTL=no
-ONBOOT=yes
-MASTER=bond0
-SLAVE=yes
-BOOTPROTO=none
+9. Potential Trouble Sources
+9.1	Adventures in Routing
+9.2	Ethernet Device Renaming
+9.3	Painfully Slow Or No Failed Link Detection By Miimon
 
-Use DEVICE=eth1 in the ifcfg-eth1 config file. If you configure a second
-bonding interface (bond1), use MASTER=bond1 in the config file to make the
-network interface be a slave of bond1.
-
-Restart the networking subsystem or just bring up the bonding device if your
-administration tools allow it. Otherwise, reboot. On Red Hat distros you can
-issue `ifup bond0' or `/etc/rc.d/init.d/network restart'.
-
-If the administration tools of your distribution do not support
-master/slave notation in configuring network interfaces, you will need to
-manually configure the bonding device with the following commands:
-
-    # /sbin/ifconfig bond0 192.168.1.1 netmask 255.255.255.0 \
-      broadcast 192.168.1.255 up
-
-    # /sbin/ifenslave bond0 eth0
-    # /sbin/ifenslave bond0 eth1
-
-(use appropriate values for your network above)
-
-You can then create a script containing these commands and place it in the
-appropriate rc directory.
-
-If you specifically need all network drivers loaded before the bonding driver,
-adding the following line to modprobe.conf will cause the network driver for
-eth0 and eth1 to be loaded before the bonding driver.
-
-install bond0 /sbin/modprobe -a eth0 eth1 && /sbin/modprobe bonding
-
-Be careful not to reference bond0 itself at the end of the line, or modprobe
-will die in an endless recursive loop.
-
-If running SNMP agents, the bonding driver should be loaded before any network
-drivers participating in a bond. This requirement is due to the the interface
-index (ipAdEntIfIndex) being associated to the first interface found with a
-given IP address. That is, there is only one ipAdEntIfIndex for each IP
-address. For example, if eth0 and eth1 are slaves of bond0 and the driver for
-eth0 is loaded before the bonding driver, the interface for the IP address
-will be associated with the eth0 interface. This configuration is shown below,
-the IP address 192.168.1.1 has an interface index of 2 which indexes to eth0
-in the ifDescr table (ifDescr.2).
+10. SNMP agents
 
-     interfaces.ifTable.ifEntry.ifDescr.1 = lo
-     interfaces.ifTable.ifEntry.ifDescr.2 = eth0
-     interfaces.ifTable.ifEntry.ifDescr.3 = eth1
-     interfaces.ifTable.ifEntry.ifDescr.4 = eth2
-     interfaces.ifTable.ifEntry.ifDescr.5 = eth3
-     interfaces.ifTable.ifEntry.ifDescr.6 = bond0
-     ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.10.10.10.10 = 5
-     ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.192.168.1.1 = 2
-     ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.10.74.20.94 = 4
-     ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.127.0.0.1 = 1
+11. Promiscuous mode
 
-This problem is avoided by loading the bonding driver before any network
-drivers participating in a bond. Below is an example of loading the bonding
-driver first, the IP address 192.168.1.1 is correctly associated with
-ifDescr.2.
+12. High Availability Information
+12.1	High Availability in a Single Switch Topology
+12.1.1		Bonding Mode Selection for Single Switch Topology
+12.1.2		Link Monitoring for Single Switch Topology
+12.2	High Availability in a Multiple Switch Topology
+12.2.1		Bonding Mode Selection for Multiple Switch Topology
+12.2.2		Link Monitoring for Multiple Switch Topology
+12.3	Switch Behavior Issues for High Availability
 
-     interfaces.ifTable.ifEntry.ifDescr.1 = lo
-     interfaces.ifTable.ifEntry.ifDescr.2 = bond0
-     interfaces.ifTable.ifEntry.ifDescr.3 = eth0
-     interfaces.ifTable.ifEntry.ifDescr.4 = eth1
-     interfaces.ifTable.ifEntry.ifDescr.5 = eth2
-     interfaces.ifTable.ifEntry.ifDescr.6 = eth3
-     ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.10.10.10.10 = 6
-     ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.192.168.1.1 = 2
-     ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.10.74.20.94 = 5
-     ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.127.0.0.1 = 1
+13. Hardware Specific Considerations
+13.1	IBM BladeCenter
 
-While some distributions may not report the interface name in ifDescr,
-the association between the IP address and IfIndex remains and SNMP
-functions such as Interface_Scan_Next will report that association.
+14. Frequently Asked Questions
 
+15. Resources and Links
 
-Module Parameters
-=================
 
-Optional parameters for the bonding driver can be supplied as command line
-arguments to the insmod command. Typically, these parameters are specified in
-the file /etc/modprobe.conf (see the manual page for modprobe.conf). The
-available bonding driver parameters are listed below. If a parameter is not
-specified the default value is used. When initially configuring a bond, it
-is recommended "tail -f /var/log/messages" be run in a separate window to
-watch for bonding driver error messages.
-
-It is critical that either the miimon or arp_interval and arp_ip_target
-parameters be specified, otherwise serious network degradation will occur
-during link failures.
+1. Bonding Driver Installation
+==============================
+
+	Most popular distro kernels ship with the bonding driver
+already available as a module and the ifenslave user level control
+program installed and ready for use. If your distro does not, or you
+have need to compile bonding from source (e.g., configuring and
+installing a mainline kernel from kernel.org), you'll need to perform
+the following steps:
+
+1.1 Configure and build the kernel with bonding
+-----------------------------------------------
+
+	The latest version of the bonding driver is available in the
+drivers/net/bonding subdirectory of the most recent kernel source
+(which is available on http://kernel.org).
+
+	Prior to the 2.4.11 kernel, the bonding driver was maintained
+largely outside the kernel tree; patches for some earlier kernels are
+available on the bonding sourceforge site, although those patches are
+still several years out of date.  Most users will want to use either
+the most recent kernel from kernel.org or whatever kernel came with
+their distro.
+
+	Configure kernel with "make menuconfig" (or "make xconfig" or
+"make config"), then select "Bonding driver support" in the "Network
+device support" section.  It is recommended that you configure the
+driver as module since it is currently the only way to pass parameters
+to the driver or configure more than one bonding device.
+
+	Build and install the new kernel and modules, then proceed to
+step 2.
+
+1.2 Install ifenslave Control Utility
+-------------------------------------
+
+	The ifenslave user level control program is included in the
+kernel source tree, in the file Documentation/networking/ifenslave.c.
+It is generally recommended that you use the ifenslave that
+corresponds to the kernel that you are using (either from the same
+source tree or supplied with the distro), however, ifenslave
+executables from older kernels should function (but features newer
+than the ifenslave release are not supported).  Running an ifenslave
+that is newer than the kernel is not supported, and may or may not
+work.
+
+	To install ifenslave, do the following:
+
+# gcc -Wall -O -I/usr/src/linux/include ifenslave.c -o ifenslave
+# cp ifenslave /sbin/ifenslave
+
+	If your kernel source is not in "/usr/src/linux," then replace
+"/usr/src/linux/include" in the above with the location of your kernel
+source include directory.
+
+	You may wish to back up any existing /sbin/ifenslave, or, for
+testing or informal use, tag the ifenslave to the kernel version
+(e.g., name the ifenslave executable /sbin/ifenslave-2.6.10).
+
+IMPORTANT NOTE:
+
+	If you omit the "-I" or specify an incorrect directory, you
+may end up with an ifenslave that is incompatible with the kernel
+you're trying to build it for.  Some distros (e.g., Red Hat from 7.1
+onwards) do not have /usr/include/linux symbolically linked to the
+default kernel source include directory.
+
+
+2. Bonding Driver Options
+=========================
+
+	Options for the bonding driver are supplied as parameters to
+the bonding module at load time.  They may be given as command line
+arguments to the insmod or modprobe command, but are usually specified
+in either the /etc/modprobe.conf configuration file, or in a
+distro-specific configuration file (some of which are detailed in the
+next section).
+
+	The available bonding driver parameters are listed below. If a
+parameter is not specified the default value is used.  When initially
+configuring a bond, it is recommended "tail -f /var/log/messages" be
+run in a separate window to watch for bonding driver error messages.
+
+	It is critical that either the miimon or arp_interval and
+arp_ip_target parameters be specified, otherwise serious network
+degradation will occur during link failures.  Very few devices do not
+support at least miimon, so there is really no reason not to use it.
+
+	Options with textual values will accept either the text name
+	or, for backwards compatibility, the option value.  E.g.,
+	"mode=802.3ad" and "mode=4" set the same mode.
+
+	The parameters are as follows:
 
 arp_interval
 
-        Specifies the ARP monitoring frequency in milli-seconds.
-        If ARP monitoring is used in a load-balancing mode (mode 0 or 2), the
-        switch should be configured in a mode that evenly distributes packets
-        across all links - such as round-robin. If the switch is configured to
-        distribute the packets in an XOR fashion, all replies from the ARP
-        targets will be received on the same link which could cause the other
-        team members to fail. ARP monitoring should not be used in conjunction
-        with miimon. A value of 0 disables ARP monitoring. The default value
-        is 0.
+	Specifies the ARP monitoring frequency in milli-seconds. If
+	ARP monitoring is used in a load-balancing mode (mode 0 or 2),
+	the switch should be configured in a mode that evenly
+	distributes packets across all links - such as round-robin. If
+	the switch is configured to distribute the packets in an XOR
+	fashion, all replies from the ARP targets will be received on
+	the same link which could cause the other team members to
+	fail. ARP monitoring should not be used in conjunction with
+	miimon. A value of 0 disables ARP monitoring. The default
+	value is 0.
 
 arp_ip_target
 
-	Specifies the ip addresses to use when arp_interval is > 0. These
-	are the targets of the ARP request sent to determine the health of
-	the link to the targets. Specify these values in ddd.ddd.ddd.ddd
-	format. Multiple ip adresses must be seperated by a comma. At least
-	one ip address needs to be given for ARP monitoring to work. The
-	maximum number of targets that can be specified is set at 16.
+	Specifies the ip addresses to use when arp_interval is > 0.
+	These are the targets of the ARP request sent to determine the
+	health of the link to the targets.  Specify these values in
+	ddd.ddd.ddd.ddd format.  Multiple ip adresses must be
+	seperated by a comma.  At least one IP address must be given
+	for ARP monitoring to function.  The maximum number of targets
+	that can be specified is 16.  The default value is no IP
+	addresses.
 
 downdelay
 
-        Specifies the delay time in milli-seconds to disable a link after a
-        link failure has been detected. This should be a multiple of miimon
-        value, otherwise the value will be rounded. The default value is 0.
+	Specifies the time, in milliseconds, to wait before disabling
+	a slave after a link failure has been detected.  This option
+	is only valid for the miimon link monitor.  The downdelay
+	value should be a multiple of the miimon value; if not, it
+	will be rounded down to the nearest multiple.  The default
+	value is 0.
 
 lacp_rate
 
-        Option specifying the rate in which we'll ask our link partner to
-	transmit LACPDU packets in 802.3ad mode.  Possible values are:
+	Option specifying the rate in which we'll ask our link partner
+	to transmit LACPDU packets in 802.3ad mode.  Possible values
+	are:
 
 	slow or 0
 		Request partner to transmit LACPDUs every 30 seconds (default)
@@ -246,69 +221,76 @@
 
 miimon
 
-        Specifies the frequency in milli-seconds that MII link monitoring
-        will occur. A value of zero disables MII link monitoring. A value
-        of 100 is a good starting point. See High Availability section for
-        additional information. The default value is 0.
+	Specifies the frequency in milli-seconds that MII link
+	monitoring will occur.  A value of zero disables MII link
+	monitoring.  A value of 100 is a good starting point.  The
+	use_carrier option, below, affects how the link state is
+	determined.  See the High Availability section for additional
+	information.  The default value is 0.
 
 mode
 
 	Specifies one of the bonding policies. The default is
-	round-robin (balance-rr).  Possible values are (you can use
-	either the text or numeric option):
+	balance-rr (round robin).  Possible values are:
 
 	balance-rr or 0
 
-		Round-robin policy: Transmit in a sequential order
-		from the first available slave through the last. This
-		mode provides load balancing and fault tolerance.
+		Round-robin policy: Transmit packets in sequential
+		order from the first available slave through the
+		last.  This mode provides load balancing and fault
+		tolerance.
 
 	active-backup or 1
 
 		Active-backup policy: Only one slave in the bond is
-		active. A different slave becomes active if, and only
-		if, the active slave fails. The bond's MAC address is
+		active.  A different slave becomes active if, and only
+		if, the active slave fails.  The bond's MAC address is
 		externally visible on only one port (network adapter)
 		to avoid confusing the switch.  This mode provides
-		fault tolerance.
+		fault tolerance.  The primary option affects the
+		behavior of this mode.
 
 	balance-xor or 2
 
 		XOR policy: Transmit based on [(source MAC address
-		XOR'd with destination MAC address) modula slave
-		count]. This selects the same slave for each
-		destination MAC address. This mode provides load
+		XOR'd with destination MAC address) modulo slave
+		count].  This selects the same slave for each
+		destination MAC address.  This mode provides load
 		balancing and fault tolerance.
 
 	broadcast or 3
 
 		Broadcast policy: transmits everything on all slave
-		interfaces. This mode provides fault tolerance.
+		interfaces.  This mode provides fault tolerance.
 
 	802.3ad or 4
 
-		IEEE 802.3ad Dynamic link aggregation. Creates aggregation
-		groups that share the same speed and duplex settings.
-		Transmits and receives on all slaves in the active
-		aggregator.
+		IEEE 802.3ad Dynamic link aggregation.  Creates
+		aggregation groups that share the same speed and
+		duplex settings.  Utilizes all slaves in the active
+		aggregator according to the 802.3ad specification.
 
 		Pre-requisites:
 
-		1. Ethtool support in the base drivers for retrieving the
-		speed and duplex of each slave.
+		1. Ethtool support in the base drivers for retrieving
+		the speed and duplex of each slave.
 
 		2. A switch that supports IEEE 802.3ad Dynamic link
 		aggregation.
 
+		Most switches will require some type of configuration
+		to enable 802.3ad mode.
+
 	balance-tlb or 5
 
-		Adaptive transmit load balancing: channel bonding that does
-		not require any special switch support. The outgoing
-		traffic is distributed according to the current load
-		(computed relative to the speed) on each slave. Incoming
-		traffic is received by the current slave. If the receiving
-		slave fails, another slave takes over the MAC address of
-		the failed receiving slave.
+		Adaptive transmit load balancing: channel bonding that
+		does not require any special switch support.  The
+		outgoing traffic is distributed according to the
+		current load (computed relative to the speed) on each
+		slave.  Incoming traffic is received by the current
+		slave.  If the receiving slave fails, another slave
+		takes over the MAC address of the failed receiving
+		slave.
 
 		Prerequisite:
 
@@ -317,205 +299,452 @@
 
 	balance-alb or 6
 
-		Adaptive load balancing: includes balance-tlb + receive
-		load balancing (rlb) for IPV4 traffic and does not require
-		any special switch support. The receive load balancing is
-		achieved by ARP negotiation. The bonding driver intercepts
-		the ARP Replies sent by the server on their way out and
-		overwrites the src hw address with the unique hw address of
-		one of the slaves in the bond such that different clients
-		use different hw addresses for the server.
-
-		Receive traffic from connections created by the server is
-		also balanced. When the server sends an ARP Request the
-		bonding driver copies and saves the client's IP information
-		from the ARP. When the ARP Reply arrives from the client,
-		its hw address is retrieved and the bonding driver
-		initiates an ARP reply to this client assigning it to one
-		of the slaves in the bond. A problematic outcome of using
-		ARP negotiation for balancing is that each time that an ARP
-		request is broadcasted it uses the hw address of the
-		bond. Hence, clients learn the hw address of the bond and
-		the balancing of receive traffic collapses to the current
-		salve. This is handled by sending updates (ARP Replies) to
-		all the clients with their assigned hw address such that
-		the traffic is redistributed. Receive traffic is also
-		redistributed when a new slave is added to the bond and
-		when an inactive slave is re-activated. The receive load is
-		distributed sequentially (round robin) among the group of
-		highest speed slaves in the bond.
-
-		When a link is reconnected or a new slave joins the bond
-		the receive traffic is redistributed among all active
-		slaves in the bond by intiating ARP Replies with the
-		selected mac address to each of the clients. The updelay
-		modeprobe parameter must be set to a value equal or greater
-		than the switch's forwarding delay so that the ARP Replies
-		sent to the clients will not be blocked by the switch.
+		Adaptive load balancing: includes balance-tlb plus
+		receive load balancing (rlb) for IPV4 traffic, and
+		does not require any special switch support.  The
+		receive load balancing is achieved by ARP negotiation.
+		The bonding driver intercepts the ARP Replies sent by
+		the local system on their way out and overwrites the
+		source hardware address with the unique hardware
+		address of one of the slaves in the bond such that
+		different peers use different hardware addresses for
+		the server.
+
+		Receive traffic from connections created by the server
+		is also balanced.  When the local system sends an ARP
+		Request the bonding driver copies and saves the peer's
+		IP information from the ARP packet.  When the ARP
+		Reply arrives from the peer, its hardware address is
+		retrieved and the bonding driver initiates an ARP
+		reply to this peer assigning it to one of the slaves
+		in the bond.  A problematic outcome of using ARP
+		negotiation for balancing is that each time that an
+		ARP request is broadcast it uses the hardware address
+		of the bond.  Hence, peers learn the hardware address
+		of the bond and the balancing of receive traffic
+		collapses to the current slave.  This is handled by
+		sending updates (ARP Replies) to all the peers with
+		their individually assigned hardware address such that
+		the traffic is redistributed.  Receive traffic is also
+		redistributed when a new slave is added to the bond
+		and when an inactive slave is re-activated.  The
+		receive load is distributed sequentially (round robin)
+		among the group of highest speed slaves in the bond.
+
+		When a link is reconnected or a new slave joins the
+		bond the receive traffic is redistributed among all
+		active slaves in the bond by intiating ARP Replies
+		with the selected mac address to each of the
+		clients. The updelay parameter (detailed below) must
+		be set to a value equal or greater than the switch's
+		forwarding delay so that the ARP Replies sent to the
+		peers will not be blocked by the switch.
 
 		Prerequisites:
 
-		1. Ethtool support in the base drivers for retrieving the
-		speed of each slave.
+		1. Ethtool support in the base drivers for retrieving
+		the speed of each slave.
 
-		2. Base driver support for setting the hw address of a
-		device also when it is open. This is required so that there
-		will always be one slave in the team using the bond hw
-		address (the curr_active_slave) while having a unique hw
-		address for each slave in the bond. If the curr_active_slave
-		fails it's hw address is swapped with the new curr_active_slave
-		that was chosen.
+		2. Base driver support for setting the hardware
+		address of a device while it is open.  This is
+		required so that there will always be one slave in the
+		team using the bond hardware address (the
+		curr_active_slave) while having a unique hardware
+		address for each slave in the bond.  If the
+		curr_active_slave fails its hardware address is
+		swapped with the new curr_active_slave that was
+		chosen.
 
 primary
 
-        A string (eth0, eth2, etc) to equate to a primary device. If this
-        value is entered, and the device is on-line, it will be used first
-        as the output media. Only when this device is off-line, will
-        alternate devices be used. Otherwise, once a failover is detected
-        and a new default output is chosen, it will remain the output media
-        until it too fails. This is useful when one slave was preferred
-        over another, i.e. when one slave is 1000Mbps and another is
-        100Mbps. If the 1000Mbps slave fails and is later restored, it may
-        be preferred the faster slave gracefully become the active slave -
-        without deliberately failing the 100Mbps slave. Specifying a
-        primary is only valid in active-backup mode.
+	A string (eth0, eth2, etc) specifying which slave is the
+	primary device.  The specified device will always be the
+	active slave while it is available.  Only when the primary is
+	off-line will alternate devices be used.  This is useful when
+	one slave is preferred over another, e.g., when one slave has
+	higher throughput than another.
+
+	The primary option is only valid for active-backup mode.
 
 updelay
 
-        Specifies the delay time in milli-seconds to enable a link after a
-        link up status has been detected. This should be a multiple of miimon
-        value, otherwise the value will be rounded. The default value is 0.
+	Specifies the time, in milliseconds, to wait before enabling a
+	slave after a link recovery has been detected.  This option is
+	only valid for the miimon link monitor.  The updelay value
+	should be a multiple of the miimon value; if not, it will be
+	rounded down to the nearest multiple.  The default value is 0.
 
 use_carrier
 
-        Specifies whether or not miimon should use MII or ETHTOOL
-        ioctls vs. netif_carrier_ok() to determine the link status.
-        The MII or ETHTOOL ioctls are less efficient and utilize a
-        deprecated calling sequence within the kernel.  The
-        netif_carrier_ok() relies on the device driver to maintain its
-        state with netif_carrier_on/off; at this writing, most, but
-        not all, device drivers support this facility.
-
-        If bonding insists that the link is up when it should not be,
-        it may be that your network device driver does not support
-        netif_carrier_on/off.  This is because the default state for
-        netif_carrier is "carrier on." In this case, disabling
-        use_carrier will cause bonding to revert to the MII / ETHTOOL
-        ioctl method to determine the link state.
-
-        A value of 1 enables the use of netif_carrier_ok(), a value of
-        0 will use the deprecated MII / ETHTOOL ioctls.  The default
-        value is 1.
-
-
-Configuring Multiple Bonds
-==========================
-
-If several bonding interfaces are required, either specify the max_bonds
-parameter (described above), or load the driver multiple times.  Using
-the max_bonds parameter is less complicated, but has the limitation that
-all bonding instances created will have the same options.  Loading the
-driver multiple times allows each instance of the driver to have differing
-options.
-
-For example, to configure two bonding interfaces, one with mii link
-monitoring performed every 100 milliseconds, and one with ARP link
-monitoring performed every 200 milliseconds, the /etc/conf.modules should
-resemble the following:
+	Specifies whether or not miimon should use MII or ETHTOOL
+	ioctls vs. netif_carrier_ok() to determine the link
+	status. The MII or ETHTOOL ioctls are less efficient and
+	utilize a deprecated calling sequence within the kernel.  The
+	netif_carrier_ok() relies on the device driver to maintain its
+	state with netif_carrier_on/off; at this writing, most, but
+	not all, device drivers support this facility.
+
+	If bonding insists that the link is up when it should not be,
+	it may be that your network device driver does not support
+	netif_carrier_on/off.  The default state for netif_carrier is
+	"carrier on," so if a driver does not support netif_carrier,
+	it will appear as if the link is always up.  In this case,
+	setting use_carrier to 0 will cause bonding to revert to the
+	MII / ETHTOOL ioctl method to determine the link state.
+
+	A value of 1 enables the use of netif_carrier_ok(), a value of
+	0 will use the deprecated MII / ETHTOOL ioctls.  The default
+	value is 1.
+
+
+
+3. Configuring Bonding Devices
+==============================
+
+	There are, essentially, two methods for configuring bonding:
+with support from the distro's network initialization scripts, and
+without.  Distros generally use one of two packages for the network
+initialization scripts: initscripts or sysconfig.  Recent versions of
+these packages have support for bonding, while older versions do not.
+
+	We will first describe the options for configuring bonding for
+distros using versions of initscripts and sysconfig with full or
+partial support for bonding, then provide information on enabling
+bonding without support from the network initialization scripts (i.e.,
+older versions of initscripts or sysconfig).
+
+	If you're unsure whether your distro uses sysconfig or
+initscripts, or don't know if it's new enough, have no fear.
+Determining this is fairly straightforward.
+
+	First, issue the command:
+
+$ rpm -qf /sbin/ifup
+
+	It will respond with a line of text starting with either
+"initscripts" or "sysconfig," followed by some numbers.  This is the
+package that provides your network initialization scripts.
+
+	Next, to determine if your installation supports bonding,
+issue the command:
+
+$ grep ifenslave /sbin/ifup
+
+	If this returns any matches, then your initscripts or
+sysconfig has support for bonding.
+
+3.1 Configuration with sysconfig support
+----------------------------------------
+
+	This section applies to distros using a version of sysconfig
+with bonding support, for example, SuSE Linux Enterprise Server 9.
+
+	SuSE SLES 9's networking configuration system does support
+bonding, however, at this writing, the YaST system configuration
+frontend does not provide any means to work with bonding devices.
+Bonding devices can be managed by hand, however, as follows.
+
+	First, if they have not already been configured, configure the
+slave devices.  On SLES 9, this is most easily done by running the
+yast2 sysconfig configuration utility.  The goal is for to create an
+ifcfg-id file for each slave device.  The simplest way to accomplish
+this is to configure the devices for DHCP.  The name of the
+configuration file for each device will be of the form:
+
+ifcfg-id-xx:xx:xx:xx:xx:xx
+
+	Where the "xx" portion will be replaced with the digits from
+the device's permanent MAC address.
+
+	Once the set of ifcfg-id-xx:xx:xx:xx:xx:xx files has been
+created, it is necessary to edit the configuration files for the slave
+devices (the MAC addresses correspond to those of the slave devices).
+Before editing, the file will contain muliple lines, and will look
+something like this:
+
+BOOTPROTO='dhcp'
+STARTMODE='on'
+USERCTL='no'
+UNIQUE='XNzu.WeZGOGF+4wE'
+_nm_name='bus-pci-0001:61:01.0'
+
+	Change the BOOTPROTO and STARTMODE lines to the following:
+
+BOOTPROTO='none'
+STARTMODE='off'
+
+	Do not alter the UNIQUE or _nm_name lines.  Remove any other
+lines (USERCTL, etc).
+
+	Once the ifcfg-id-xx:xx:xx:xx:xx:xx files have been modified,
+it's time to create the configuration file for the bonding device
+itself.  This file is named ifcfg-bondX, where X is the number of the
+bonding device to create, starting at 0.  The first such file is
+ifcfg-bond0, the second is ifcfg-bond1, and so on.  The sysconfig
+network configuration system will correctly start multiple instances
+of bonding.
+
+	The contents of the ifcfg-bondX file is as follows:
+
+BOOTPROTO="static"
+BROADCAST="10.0.2.255"
+IPADDR="10.0.2.10"
+NETMASK="255.255.0.0"
+NETWORK="10.0.2.0"
+REMOTE_IPADDR=""
+STARTMODE="onboot"
+BONDING_MASTER="yes"
+BONDING_MODULE_OPTS="mode=active-backup miimon=100"
+BONDING_SLAVE0="eth0"
+BONDING_SLAVE1="eth1"
+
+	Replace the sample BROADCAST, IPADDR, NETMASK and NETWORK
+values with the appropriate values for your network.
+
+	Note that configuring the bonding device with BOOTPROTO='dhcp'
+does not work; the scripts attempt to obtain the device address from
+DHCP prior to adding any of the slave devices.  Without active slaves,
+the DHCP requests are not sent to the network.
+
+	The STARTMODE specifies when the device is brought online.
+The possible values are:
+
+	onboot:	 The device is started at boot time.  If you're not
+		 sure, this is probably what you want.
+
+	manual:	 The device is started only when ifup is called
+		 manually.  Bonding devices may be configured this
+		 way if you do not wish them to start automatically
+		 at boot for some reason.
+
+	hotplug: The device is started by a hotplug event.  This is not
+		 a valid choice for a bonding device.
+
+	off or ignore: The device configuration is ignored.
+
+	The line BONDING_MASTER='yes' indicates that the device is a
+bonding master device.  The only useful value is "yes."
+
+	The contents of BONDING_MODULE_OPTS are supplied to the
+instance of the bonding module for this device.  Specify the options
+for the bonding mode, link monitoring, and so on here.  Do not include
+the max_bonds bonding parameter; this will confuse the configuration
+system if you have multiple bonding devices.
+
+	Finally, supply one BONDING_SLAVEn="ethX" for each slave,
+where "n" is an increasing value, one for each slave, and "ethX" is
+the name of the slave device (eth0, eth1, etc).
+
+	When all configuration files have been modified or created,
+networking must be restarted for the configuration changes to take
+effect.  This can be accomplished via the following:
+
+# /etc/init.d/network restart
+
+	Note that the network control script (/sbin/ifdown) will
+remove the bonding module as part of the network shutdown processing,
+so it is not necessary to remove the module by hand if, e.g., the
+module paramters have changed.
+
+	Also, at this writing, YaST/YaST2 will not manage bonding
+devices (they do not show bonding interfaces on its list of network
+devices).  It is necessary to edit the configuration file by hand to
+change the bonding configuration.
+
+	Additional general options and details of the ifcfg file
+format can be found in an example ifcfg template file:
+
+/etc/sysconfig/network/ifcfg.template
+
+	Note that the template does not document the various BONDING_
+settings described above, but does describe many of the other options.
+
+3.2 Configuration with initscripts support
+------------------------------------------
+
+	This section applies to distros using a version of initscripts
+with bonding support, for example, Red Hat Linux 9 or Red Hat
+Enterprise Linux version 3.  On these systems, the network
+initialization scripts have some knowledge of bonding, and can be
+configured to control bonding devices.
+
+	These distros will not automatically load the network adapter
+driver unless the ethX device is configured with an IP address.
+Because of this constraint, users must manually configure a
+network-script file for all physical adapters that will be members of
+a bondX link.  Network script files are located in the directory:
+
+/etc/sysconfig/network-scripts
+
+	The file name must be prefixed with "ifcfg-eth" and suffixed
+with the adapter's physical adapter number.  For example, the script
+for eth0 would be named /etc/sysconfig/network-scripts/ifcfg-eth0.
+Place the following text in the file:
 
-alias bond0 bonding
-alias bond1 bonding
+DEVICE=eth0
+USERCTL=no
+ONBOOT=yes
+MASTER=bond0
+SLAVE=yes
+BOOTPROTO=none
 
-options bond0 miimon=100
-options bond1 -o bonding1 arp_interval=200 arp_ip_target=10.0.0.1
+	The DEVICE= line will be different for every ethX device and
+must correspond with the name of the file, i.e., ifcfg-eth1 must have
+a device line of DEVICE=eth1.  The setting of the MASTER= line will
+also depend on the final bonding interface name chosen for your bond.
+As with other network devices, these typically start at 0, and go up
+one for each device, i.e., the first bonding instance is bond0, the
+second is bond1, and so on.
+
+	Next, create a bond network script.  The file name for this
+script will be /etc/sysconfig/network-scripts/ifcfg-bondX where X is
+the number of the bond.  For bond0 the file is named "ifcfg-bond0",
+for bond1 it is named "ifcfg-bond1", and so on.  Within that file,
+place the following text:
 
-Configuring Multiple ARP Targets
-================================
+DEVICE=bond0
+IPADDR=192.168.1.1
+NETMASK=255.255.255.0
+NETWORK=192.168.1.0
+BROADCAST=192.168.1.255
+ONBOOT=yes
+BOOTPROTO=none
+USERCTL=no
 
-While ARP monitoring can be done with just one target, it can be useful
-in a High Availability setup to have several targets to monitor. In the
-case of just one target,  the target itself may go down or have a problem
-making it unresponsive to ARP requests. Having an additional target (or
-several) increases the reliability of the ARP monitoring.
+	Be sure to change the networking specific lines (IPADDR,
+NETMASK, NETWORK and BROADCAST) to match your network configuration.
 
-Multiple ARP targets must be seperated by commas as follows:
+	Finally, it is necessary to edit /etc/modules.conf to load the
+bonding module when the bond0 interface is brought up.  The following
+sample lines in /etc/modules.conf will load the bonding module, and
+select its options:
 
-# example options for ARP monitoring with three targets
 alias bond0 bonding
-options bond0 arp_interval=60 arp_ip_target=192.168.0.1,192.168.0.3,192.168.0.9
+options bond0 mode=balance-alb miimon=100
 
-For just a single target the options would resemble:
+	Replace the sample parameters with the appropriate set of
+options for your configuration.
 
-# example options for ARP monitoring with one target
+	Finally run "/etc/rc.d/init.d/network restart" as root.  This
+will restart the networking subsystem and your bond link should be now
+up and running.
+
+
+3.3 Configuring Bonding Manually
+--------------------------------
+
+	This section applies to distros whose network initialization
+scripts (the sysconfig or initscripts package) do not have specific
+knowledge of bonding.  One such distro is SuSE Linux Enterprise Server
+version 8.
+
+	The general methodology for these systems is to place the
+bonding module parameters into /etc/modprobe.conf, then add modprobe
+and/or ifenslave commands to the system's global init script.  The
+name of the global init script differs; for sysconfig, it is
+/etc/init.d/boot.local and for initscripts it is /etc/rc.d/rc.local.
+
+	For example, if you wanted to make a simple bond of two e100
+devices (presumed to be eth0 and eth1), and have it persist across
+reboots, edit the appropriate file (/etc/init.d/boot.local or
+/etc/rc.d/rc.local), and add the following:
+
+modprobe bonding -obond0 mode=balance-alb miimon=100
+modprobe e100
+ifconfig bond0 192.168.1.1 netmask 255.255.255.0 up
+ifenslave bond0 eth0
+ifenslave bond0 eth1
+
+	Replace the example bonding module parameters and bond0
+network configuration (IP address, netmask, etc) with the appropriate
+values for your configuration.  The above example loads the bonding
+module with the name "bond0," this simplifies the naming if multiple
+bonding modules are loaded (each successive instance of the module is
+given a different name, and the module instance names match the
+bonding interface names).
+
+	Unfortunately, this method will not provide support for the
+ifup and ifdown scripts on the bond devices.  To reload the bonding
+configuration, it is necessary to run the initialization script, e.g.,
+
+# /etc/init.d/boot.local
+
+	or
+
+# /etc/rc.d/rc.local
+
+	It may be desirable in such a case to create a separate script
+which only initializes the bonding configuration, then call that
+separate script from within boot.local.  This allows for bonding to be
+enabled without re-running the entire global init script.
+
+	To shut down the bonding devices, it is necessary to first
+mark the bonding device itself as being down, then remove the
+appropriate device driver modules.  For our example above, you can do
+the following:
+
+# ifconfig bond0 down
+# rmmod bond0
+# rmmod e100
+
+	Again, for convenience, it may be desirable to create a script
+with these commands.
+
+
+3.4 Configuring Multiple Bonds
+------------------------------
+
+	This section contains information on configuring multiple
+bonding devices with differing options.  If you require multiple
+bonding devices, but all with the same options, see the "max_bonds"
+module paramter, documented above.
+
+	To create multiple bonding devices with differing options, it
+is necessary to load the bonding driver multiple times.  Note that
+current versions of the sysconfig network initialization scripts
+handle this automatically; if your distro uses these scripts, no
+special action is needed.  See the section Configuring Bonding
+Devices, above, if you're not sure about your network initialization
+scripts.
+
+	To load multiple instances of the module, it is necessary to
+specify a different name for each instance (the module loading system
+requires that every loaded module, even multiple instances of the same
+module, have a unique name).  This is accomplished by supplying
+multiple sets of bonding options in /etc/modprobe.conf, for example:
+	
 alias bond0 bonding
-options bond0 arp_interval=60 arp_ip_target=192.168.0.100
-
-Potential Problems When Using ARP Monitor
-=========================================
+options bond0 -o bond0 mode=balance-rr miimon=100
 
-1. Driver support
-
-The ARP monitor relies on the network device driver to maintain two
-statistics: the last receive time (dev->last_rx), and the last
-transmit time (dev->trans_start).  If the network device driver does
-not update one or both of these, then the typical result will be that,
-upon startup, all links in the bond will immediately be declared down,
-and remain that way.  A network monitoring tool (tcpdump, e.g.) will
-show ARP requests and replies being sent and received on the bonding
-device.
-
-The possible resolutions for this are to (a) fix the device driver, or
-(b) discontinue the ARP monitor (using miimon as an alternative, for
-example).
-
-2. Adventures in Routing
-
-When bonding is set up with the ARP monitor, it is important that the
-slave devices not have routes that supercede routes of the master (or,
-generally, not have routes at all).  For example, suppose the bonding
-device bond0 has two slaves, eth0 and eth1, and the routing table is
-as follows:
-
-Kernel IP routing table
-Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
-10.0.0.0        0.0.0.0         255.255.0.0     U        40 0          0 eth0
-10.0.0.0        0.0.0.0         255.255.0.0     U        40 0          0 eth1
-10.0.0.0        0.0.0.0         255.255.0.0     U        40 0          0 bond0
-127.0.0.0       0.0.0.0         255.0.0.0       U        40 0          0 lo
+alias bond1 bonding
+options bond1 -o bond1 mode=balance-alb miimon=50
 
-In this case, the ARP monitor (and ARP itself) may become confused,
-because ARP requests will be sent on one interface (bond0), but the
-corresponding reply will arrive on a different interface (eth0).  This
-reply looks to ARP as an unsolicited ARP reply (because ARP matches
-replies on an interface basis), and is discarded.  This will likely
-still update the receive/transmit times in the driver, but will lose
-packets.
-
-The resolution here is simply to insure that slaves do not have routes
-of their own, and if for some reason they must, those routes do not
-supercede routes of their master.  This should generally be the case,
-but unusual configurations or errant manual or automatic static route
-additions may cause trouble.
+	will load the bonding module two times.  The first instance is
+named "bond0" and creates the bond0 device in balance-rr mode with an
+miimon of 100.  The second instance is named "bond1" and creates the
+bond1 device in balance-alb mode with an miimon of 50.
 
-Switch Configuration
-====================
+	This may be repeated any number of times, specifying a new and
+unique name in place of bond0 or bond1 for each instance.
 
-While the switch does not need to be configured when the active-backup,
-balance-tlb or balance-alb policies (mode=1,5,6) are used, it does need to
-be configured for the round-robin, XOR, broadcast, or 802.3ad policies
-(mode=0,2,3,4).
+	When the appropriate module paramters are in place, then
+configure bonding according to the instructions for your distro.
 
+5. Querying Bonding Configuration 
+=================================
 
-Verifying Bond Configuration
-============================
+5.1 Bonding Configuration
+-------------------------
 
-1) Bonding information files
-----------------------------
-The bonding driver information files reside in the /proc/net/bonding directory.
+	Each bonding device has a read-only file residing in the
+/proc/net/bonding directory.  The file contents include information
+about the bonding configuration, options and state of each slave.
 
-Sample contents of /proc/net/bonding/bond0 after the driver is loaded with
-parameters of mode=0 and miimon=1000 is shown below.
+	For example, the contents of /proc/net/bonding/bond0 after the
+driver is loaded with parameters of mode=0 and miimon=1000 is
+generally as follows:
 
+	Ethernet Channel Bonding Driver: 2.6.1 (October 29, 2004)
         Bonding Mode: load balancing (round-robin)
         Currently Active Slave: eth0
         MII Status: up
@@ -531,15 +760,23 @@
         MII Status: up
         Link Failure Count: 1
 
-2) Network verification
------------------------
-The network configuration can be verified using the ifconfig command. In
-the example below, the bond0 interface is the master (MASTER) while eth0 and
-eth1 are slaves (SLAVE). Notice all slaves of bond0 have the same MAC address
-(HWaddr) as bond0 for all modes except TLB and ALB that require a unique MAC
-address for each slave.
+	The precise format and contents will change depending upon the
+bonding configuration, state, and version of the bonding driver.
+
+5.2 Network configuration
+-------------------------
+
+	The network configuration can be inspected using the ifconfig
+command.  Bonding devices will have the MASTER flag set; Bonding slave
+devices will have the SLAVE flag set.  The ifconfig output does not
+contain information on which slaves are associated with which masters.
+
+	In the example below, the bond0 interface is the master
+(MASTER) while eth0 and eth1 are slaves (SLAVE). Notice all slaves of
+bond0 have the same MAC address (HWaddr) as bond0 for all modes except
+TLB and ALB that require a unique MAC address for each slave.
 
-[root]# /sbin/ifconfig
+# /sbin/ifconfig
 bond0     Link encap:Ethernet  HWaddr 00:C0:F0:1F:37:B4
           inet addr:XXX.XXX.XXX.YYY  Bcast:XXX.XXX.XXX.255  Mask:255.255.252.0
           UP BROADCAST RUNNING MASTER MULTICAST  MTU:1500  Metric:1
@@ -563,430 +800,819 @@
           collisions:0 txqueuelen:100
           Interrupt:9 Base address:0x1400
 
+6. Switch Configuration
+=======================
 
-Frequently Asked Questions
-==========================
+	For this section, "switch" refers to whatever system the
+bonded devices are directly connected to (i.e., where the other end of
+the cable plugs into).  This may be an actual dedicated switch device,
+or it may be another regular system (e.g., another computer running
+Linux),
+
+	The active-backup, balance-tlb and balance-alb modes do not
+require any specific configuration of the switch.
+
+	The 802.3ad mode requires that the switch have the appropriate
+ports configured as an 802.3ad aggregation.  The precise method used
+to configure this varies from switch to switch, but, for example, a
+Cisco 3550 series switch requires that the appropriate ports first be
+grouped together in a single etherchannel instance, then that
+etherchannel is set to mode "lacp" to enable 802.3ad (instead of
+standard EtherChannel).
+
+	The balance-rr, balance-xor and broadcast modes generally
+require that the switch have the appropriate ports grouped together.
+The nomenclature for such a group differs between switches, it may be
+called an "etherchannel" (as in the Cisco example, above), a "trunk
+group" or some other similar variation.  For these modes, each switch
+will also have its own configuration options for the switch's transmit
+policy to the bond.  Typical choices include XOR of either the MAC or
+IP addresses.  The transmit policy of the two peers does not need to
+match.  For these three modes, the bonding mode really selects a
+transmit policy for an EtherChannel group; all three will interoperate
+with another EtherChannel group.
+
+
+7. 802.1q VLAN Support
+======================
+
+	It is possible to configure VLAN devices over a bond interface
+using the 8021q driver.  However, only packets coming from the 8021q
+driver and passing through bonding will be tagged by default.  Self
+generated packets, for example, bonding's learning packets or ARP
+packets generated by either ALB mode or the ARP monitor mechanism, are
+tagged internally by bonding itself.  As a result, bonding must
+"learn" the VLAN IDs configured above it, and use those IDs to tag
+self generated packets.
+
+	For reasons of simplicity, and to support the use of adapters
+that can do VLAN hardware acceleration offloding, the bonding
+interface declares itself as fully hardware offloaing capable, it gets
+the add_vid/kill_vid notifications to gather the necessary
+information, and it propagates those actions to the slaves.  In case
+of mixed adapter types, hardware accelerated tagged packets that
+should go through an adapter that is not offloading capable are
+"un-accelerated" by the bonding driver so the VLAN tag sits in the
+regular location.
+
+	VLAN interfaces *must* be added on top of a bonding interface
+only after enslaving at least one slave.  The bonding interface has a
+hardware address of 00:00:00:00:00:00 until the first slave is added.
+If the VLAN interface is created prior to the first enslavement, it
+would pick up the all-zeroes hardware address.  Once the first slave
+is attached to the bond, the bond device itself will pick up the
+slave's hardware address, which is then available for the VLAN device.
+
+	Also, be aware that a similar problem can occur if all slaves
+are released from a bond that still has one or more VLAN interfaces on
+top of it.  When a new slave is added, the bonding interface will
+obtain its hardware address from the first slave, which might not
+match the hardware address of the VLAN interfaces (which was
+ultimately copied from an earlier slave).
+
+	There are two methods to insure that the VLAN device operates
+with the correct hardware address if all slaves are removed from a
+bond interface:
+
+	1. Remove all VLAN interfaces then recreate them
+
+	2. Set the bonding interface's hardware address so that it
+matches the hardware address of the VLAN interfaces.
+
+	Note that changing a VLAN interface's HW address would set the
+underlying device -- i.e. the bonding interface -- to promiscouos
+mode, which might not be what you want.
 
-1.  Is it SMP safe?
-
-	Yes. The old 2.0.xx channel bonding patch was not SMP safe.
-	The new driver was designed to be SMP safe from the start.
 
-2.  What type of cards will work with it?
-
-	Any Ethernet type cards (you can even mix cards - a Intel
-	EtherExpress PRO/100 and a 3com 3c905b, for example).
-	You can even bond together Gigabit Ethernet cards!
+8. Link Monitoring
+==================
 
-3.  How many bonding devices can I have?
+	The bonding driver at present supports two schemes for
+monitoring a slave device's link state: the ARP monitor and the MII
+monitor.
+
+	At the present time, due to implementation restrictions in the
+bonding driver itself, it is not possible to enable both ARP and MII
+monitoring simultaneously.
+
+8.1 ARP Monitor Operation
+-------------------------
+
+	The ARP monitor operates as its name suggests: it sends ARP
+queries to one or more designated peer systems on the network, and
+uses the response as an indication that the link is operating.  This
+gives some assurance that traffic is actually flowing to and from one
+or more peers on the local network.
+
+	The ARP monitor relies on the device driver itself to verify
+that traffic is flowing.  In particular, the driver must keep up to
+date the last receive time, dev->last_rx, and transmit start time,
+dev->trans_start.  If these are not updated by the driver, then the
+ARP monitor will immediately fail any slaves using that driver, and
+those slaves will stay down.  If networking monitoring (tcpdump, etc)
+shows the ARP requests and replies on the network, then it may be that
+your device driver is not updating last_rx and trans_start.
 
-	There is no limit.
+8.2 Configuring Multiple ARP Targets
+------------------------------------
 
-4.  How many slaves can a bonding device have?
+	While ARP monitoring can be done with just one target, it can
+be useful in a High Availability setup to have several targets to
+monitor.  In the case of just one target, the target itself may go
+down or have a problem making it unresponsive to ARP requests.  Having
+an additional target (or several) increases the reliability of the ARP
+monitoring.
 
-	Limited by the number of network interfaces Linux supports and/or the
-	number of network cards you can place in your system.
+	Multiple ARP targets must be seperated by commas as follows:
 
-5.  What happens when a slave link dies?
+# example options for ARP monitoring with three targets
+alias bond0 bonding
+options bond0 arp_interval=60 arp_ip_target=192.168.0.1,192.168.0.3,192.168.0.9
 
-	If your ethernet cards support MII or ETHTOOL link status monitoring
-        and the MII monitoring has been enabled in the driver (see description
-        of module parameters), there will be no adverse consequences. This
-        release of the bonding driver knows how to get the MII information and
-	enables or disables its slaves according to their link status.
-	See section on High Availability for additional information.
-
-	For ethernet cards not supporting MII status, the arp_interval and
-        arp_ip_target parameters must be specified for bonding to work
-        correctly. If packets have not been sent or received during the
-        specified arp_interval duration, an ARP request is sent to the
-        targets to generate send and receive traffic. If after this
-        interval, either the successful send and/or receive count has not
-        incremented, the next slave in the sequence will become the active
-        slave.
-
-	If neither mii_monitor and arp_interval is configured, the bonding
-	driver will not handle this situation very well. The driver will
-	continue to send packets but some packets will be lost. Retransmits
-	will cause serious degradation of performance (in the case when one
-	of two slave links fails, 50% packets will be lost, which is a serious
-	problem for both TCP and UDP).
+	For just a single target the options would resemble:
 
-6.  Can bonding be used for High Availability?
+# example options for ARP monitoring with one target
+alias bond0 bonding
+options bond0 arp_interval=60 arp_ip_target=192.168.0.100
 
-        Yes, if you use MII monitoring and ALL your cards support MII link
-        status reporting. See section on High Availability for more
-        information.
 
-7.  Which switches/systems does it work with?
+8.3 MII Monitor Operation
+-------------------------
 
-	In round-robin and XOR mode, it works with systems that support
-	trunking:
+	The MII monitor monitors only the carrier state of the local
+network interface.  It accomplishes this in one of three ways: by
+depending upon the device driver to maintain its carrier state, by
+querying the device's MII registers, or by making an ethtool query to
+the device.
+
+	If the use_carrier module parameter is 1 (the default value),
+then the MII monitor will rely on the driver for carrier state
+information (via the netif_carrier subsystem).  As explained in the
+use_carrier parameter information, above, if the MII monitor fails to
+detect carrier loss on the device (e.g., when the cable is physically
+disconnected), it may be that the driver does not support
+netif_carrier.
+
+	If use_carrier is 0, then the MII monitor will first query the
+device's (via ioctl) MII registers and check the link state.  If that
+request fails (not just that it returns carrier down), then the MII
+monitor will make an ethtool ETHOOL_GLINK request to attempt to obtain
+the same information.  If both methods fail (i.e., the driver either
+does not support or had some error in processing both the MII register
+and ethtool requests), then the MII monitor will assume the link is
+up.
 
-	* Many Cisco switches and routers (look for EtherChannel support).
-	* SunTrunking software.
-	* Alteon AceDirector switches / WebOS (use Trunks).
-	* BayStack Switches (trunks must be explicitly configured). Stackable
-	  models (450) can define trunks between ports on different physical
-	  units.
-	* Linux bonding, of course !
-
-	In 802.3ad mode, it works with with systems that support IEEE 802.3ad
-	Dynamic Link Aggregation:
-
-	* Extreme networks Summit 7i (look for link-aggregation).
-	* Many Cisco switches and routers (look for LACP support; this may
-	  require an upgrade to your IOS software; LACP support was added
-	  by Cisco in late 2002).
-	* Foundry Big Iron 4000
+9. Potential Sources of Trouble
+===============================
 
-        In active-backup, balance-tlb and balance-alb modes, it should work
-        with any Layer-II switch.
+9.1 Adventures in Routing
+-------------------------
 
+	When bonding is configured, it is important that the slave
+devices not have routes that supercede routes of the master (or,
+generally, not have routes at all).  For example, suppose the bonding
+device bond0 has two slaves, eth0 and eth1, and the routing table is
+as follows:
 
-8.  Where does a bonding device get its MAC address from?
+Kernel IP routing table
+Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
+10.0.0.0        0.0.0.0         255.255.0.0     U        40 0          0 eth0
+10.0.0.0        0.0.0.0         255.255.0.0     U        40 0          0 eth1
+10.0.0.0        0.0.0.0         255.255.0.0     U        40 0          0 bond0
+127.0.0.0       0.0.0.0         255.0.0.0       U        40 0          0 lo
 
-	If not explicitly configured with ifconfig, the MAC address of the
-	bonding device is taken from its first slave device. This MAC address
-	is then passed to all following slaves and remains persistent (even if
-	the the first slave is removed) until the bonding device is brought
-	down or reconfigured.
+	This routing configuration will likely still update the
+receive/transmit times in the driver (needed by the ARP monitor), but
+may bypass the bonding driver (because outgoing traffic to, in this
+case, another host on network 10 would use eth0 or eth1 before bond0).
+
+	The ARP monitor (and ARP itself) may become confused by this
+configuration, because ARP requests (generated by the ARP monitor)
+will be sent on one interface (bond0), but the corresponding reply
+will arrive on a different interface (eth0).  This reply looks to ARP
+as an unsolicited ARP reply (because ARP matches replies on an
+interface basis), and is discarded.  The MII monitor is not affected
+by the state of the routing table.
+
+	The solution here is simply to insure that slaves do not have
+routes of their own, and if for some reason they must, those routes do
+not supercede routes of their master.  This should generally be the
+case, but unusual configurations or errant manual or automatic static
+route additions may cause trouble.
 
-	If you wish to change the MAC address, you can set it with ifconfig:
+9.2 Ethernet Device Renaming
+----------------------------
 
-	  # ifconfig bond0 hw ether 00:11:22:33:44:55
+	On systems with network configuration scripts that do not
+associate physical devices directly with network interface names (so
+that the same physical device always has the same "ethX" name), it may
+be necessary to add some special logic to either /etc/modules.conf or
+/etc/modprobe.conf (depending upon which is installed on the system).
 
-	The MAC address can be also changed by bringing down/up the device
-	and then changing its slaves (or their order):
+	For example, given a modules.conf containing the following:
 
-	  # ifconfig bond0 down ; modprobe -r bonding
-	  # ifconfig bond0 .... up
-	  # ifenslave bond0 eth...
+alias bond0 bonding
+options bond0 mode=some-mode miimon=50
+alias eth0 tg3
+alias eth1 tg3
+alias eth2 e1000
+alias eth3 e1000
+
+	If neither eth0 and eth1 are slaves to bond0, then when the
+bond0 interface comes up, the devices may end up reordered.  This
+happens because bonding is loaded first, then its slave device's
+drivers are loaded next.  Since no other drivers have been loaded,
+when the e1000 driver loads, it will receive eth0 and eth1 for its
+devices, but the bonding configuration tries to enslave eth2 and eth3
+(which may later be assigned to the tg3 devices).
+
+	Adding the following:
+
+add above bonding e1000 tg3
+
+	causes modprobe to load e1000 then tg3, in that order, when
+bonding is loaded.  This command is fully documented in the
+modules.conf manual page.
+
+	On systems utilizing modprobe.conf (or modprobe.conf.local),
+an equivalent problem can occur.  In this case, the following can be
+added to modprobe.conf (or modprobe.conf.local, as appropriate), as
+follows (all on one line; it has been split here for clarity):
+
+install bonding /sbin/modprobe tg3; /sbin/modprobe e1000;
+	/sbin/modprobe --ignore-install bonding
+
+	This will, when loading the bonding module, rather than
+performing the normal action, instead execute the provided command.
+This command loads the device drivers in the order needed, then calls
+modprobe with --ingore-install to cause the normal action to then take
+place.  Full documentation on this can be found in the modprobe.conf
+and modprobe manual pages.
+
+9.3. Painfully Slow Or No Failed Link Detection By Miimon
+---------------------------------------------------------
+
+	By default, bonding enables the use_carrier option, which
+instructs bonding to trust the driver to maintain carrier state.
+
+	As discussed in the options section, above, some drivers do
+not support the netif_carrier_on/_off link state tracking system.
+With use_carrier enabled, bonding will always see these links as up,
+regardless of their actual state.
+
+	Additionally, other drivers do support netif_carrier, but do
+not maintain it in real time, e.g., only polling the link state at
+some fixed interval.  In this case, miimon will detect failures, but
+only after some long period of time has expired.  If it appears that
+miimon is very slow in detecting link failures, try specifying
+use_carrier=0 to see if that improves the failure detection time.  If
+it does, then it may be that the driver checks the carrier state at a
+fixed interval, but does not cache the MII register values (so the
+use_carrier=0 method of querying the registers directly works).  If
+use_carrier=0 does not improve the failover, then the driver may cache
+the registers, or the problem may be elsewhere.
+
+	Also, remember that miimon only checks for the device's
+carrier state.  It has no way to determine the state of devices on or
+beyond other ports of a switch, or if a switch is refusing to pass
+traffic while still maintaining carrier on.
+
+10. SNMP agents
+===============
+
+	If running SNMP agents, the bonding driver should be loaded
+before any network drivers participating in a bond.  This requirement
+is due to the the interface index (ipAdEntIfIndex) being associated to
+the first interface found with a given IP address.  That is, there is
+only one ipAdEntIfIndex for each IP address.  For example, if eth0 and
+eth1 are slaves of bond0 and the driver for eth0 is loaded before the
+bonding driver, the interface for the IP address will be associated
+with the eth0 interface.  This configuration is shown below, the IP
+address 192.168.1.1 has an interface index of 2 which indexes to eth0
+in the ifDescr table (ifDescr.2).
 
-	This method will automatically take the address from the next slave
-	that will be added.
+     interfaces.ifTable.ifEntry.ifDescr.1 = lo
+     interfaces.ifTable.ifEntry.ifDescr.2 = eth0
+     interfaces.ifTable.ifEntry.ifDescr.3 = eth1
+     interfaces.ifTable.ifEntry.ifDescr.4 = eth2
+     interfaces.ifTable.ifEntry.ifDescr.5 = eth3
+     interfaces.ifTable.ifEntry.ifDescr.6 = bond0
+     ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.10.10.10.10 = 5
+     ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.192.168.1.1 = 2
+     ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.10.74.20.94 = 4
+     ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.127.0.0.1 = 1
 
-	To restore your slaves' MAC addresses, you need to detach them
-	from the bond (`ifenslave -d bond0 eth0'). The bonding driver will then
-	restore the MAC addresses that the slaves had before they were enslaved.
+	This problem is avoided by loading the bonding driver before
+any network drivers participating in a bond.  Below is an example of
+loading the bonding driver first, the IP address 192.168.1.1 is
+correctly associated with ifDescr.2.
 
-9.  Which transmit polices can be used?
+     interfaces.ifTable.ifEntry.ifDescr.1 = lo
+     interfaces.ifTable.ifEntry.ifDescr.2 = bond0
+     interfaces.ifTable.ifEntry.ifDescr.3 = eth0
+     interfaces.ifTable.ifEntry.ifDescr.4 = eth1
+     interfaces.ifTable.ifEntry.ifDescr.5 = eth2
+     interfaces.ifTable.ifEntry.ifDescr.6 = eth3
+     ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.10.10.10.10 = 6
+     ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.192.168.1.1 = 2
+     ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.10.74.20.94 = 5
+     ip.ipAddrTable.ipAddrEntry.ipAdEntIfIndex.127.0.0.1 = 1
 
-	Round-robin, based on the order of enslaving, the output device
-	is selected base on the next available slave. Regardless of
-	the source and/or destination of the packet.
+	While some distributions may not report the interface name in
+ifDescr, the association between the IP address and IfIndex remains
+and SNMP functions such as Interface_Scan_Next will report that
+association.
 
-	Active-backup policy that ensures that one and only one device will
-	transmit at any given moment. Active-backup policy is useful for
-	implementing high availability solutions using two hubs (see
-	section on High Availability).
+11. Promiscuous mode
+====================
 
-	XOR, based on (src hw addr XOR dst hw addr) % slave count. This
-	policy selects the same slave for each destination hw address.
+	When running network monitoring tools, e.g., tcpdump, it is
+common to enable promiscuous mode on the device, so that all traffic
+is seen (instead of seeing only traffic destined for the local host).
+The bonding driver handles promiscuous mode changes to the bonding
+master device (e.g., bond0), and propogates the setting to the slave
+devices.
+
+	For the balance-rr, balance-xor, broadcast, and 802.3ad modes,
+the promiscuous mode setting is propogated to all slaves.
+
+	For the active-backup, balance-tlb and balance-alb modes, the
+promiscuous mode setting is propogated only to the active slave.
+
+	For balance-tlb mode, the active slave is the slave currently
+receiving inbound traffic.
+
+	For balance-alb mode, the active slave is the slave used as a
+"primary."  This slave is used for mode-specific control traffic, for
+sending to peers that are unassigned or if the load is unbalanced.
+
+	For the active-backup, balance-tlb and balance-alb modes, when
+the active slave changes (e.g., due to a link failure), the
+promiscuous setting will be propogated to the new active slave.
+
+12. High Availability Information
+=================================
+
+	High Availability refers to configurations that provide
+maximum network availability by having redundant or backup devices,
+links and switches between the host and the rest of the world.
+
+	There are currently two basic methods for configuring to
+maximize availability. They are dependent on the network topology and
+the primary goal of the configuration, but in general, a configuration
+can be optimized for maximum available bandwidth, or for maximum
+network availability.
+
+12.1 High Availability in a Single Switch Topology
+--------------------------------------------------
+
+	If two hosts (or a host and a switch) are directly connected
+via multiple physical links, then there is no network availability
+penalty for optimizing for maximum bandwidth: there is only one switch
+(or peer), so if it fails, you have no alternative access to fail over
+to.
 
-	Broadcast policy transmits everything on all slave interfaces.
+Example 1 : host to switch (or other host)
 
-	802.3ad, based on XOR but distributes traffic among all interfaces
-	in the active aggregator.
+          +----------+                          +----------+
+          |          |eth0                  eth0|  switch  |
+          | Host A   +--------------------------+    or    |
+          |          +--------------------------+  other   |
+          |          |eth1                  eth1|  host    |
+          +----------+                          +----------+
 
-	Transmit load balancing (balance-tlb) balances the traffic
-	according to the current load on each slave. The balancing is
-	clients based and the least loaded slave is selected for each new
-	client. The load of each slave is calculated relative to its speed
-	and enables load balancing in mixed speed teams.
 
-	Adaptive load balancing (balance-alb) uses the Transmit load
-	balancing for the transmit load. The receive load is balanced only
-	among the group of highest speed active slaves in the bond. The
-	load is distributed with round-robin i.e. next available slave in
-	the high speed group of active slaves.
+12.1.1 Bonding Mode Selection for single switch topology
+--------------------------------------------------------
 
-High Availability
-=================
+	This configuration is the easiest to set up and to understand,
+although you will have to decide which bonding mode best suits your
+needs.  The tradeoffs for each mode are detailed below:
+
+balance-rr: This mode is the only mode that will permit a single
+	TCP/IP connection to stripe traffic across multiple
+	interfaces. It is therefore the only mode that will allow a
+	single TCP/IP stream to utilize more than one interface's
+	worth of throughput.  This comes at a cost, however: the
+	striping often results in peer systems receiving packets out
+	of order, causing TCP/IP's congestion control system to kick
+	in, often by retransmitting segments.
+
+	It is possible to adjust TCP/IP's congestion limits by
+	altering the net.ipv4.tcp_reordering sysctl parameter.  The
+	usual default value is 3, and the maximum useful value is 127.
+	For a four interface balance-rr bond, expect that a single
+	TCP/IP stream will utilize no more than approximately 2.3
+	interface's worth of throughput, even after adjusting
+	tcp_reordering.
+
+	If you are utilizing protocols other than TCP/IP, UDP for
+	example, and your application can tolerate out of order
+	delivery, then this mode can allow for single stream datagram
+	performance that scales near linearly as interfaces are added
+	to the bond.
+
+	This mode requires the switch to have the appropriate ports
+	configured for "etherchannel" or "trunking."
+
+active-backup: There is not much advantage in this network topology to
+	the active-backup mode, as the inactive backup devices are all
+	connected to the same peer as the primary.  In this case, a
+	load balancing mode (with link monitoring) will provide the
+	same level of network availability, but with increased
+	available bandwidth.  On the plus side, it does not require
+	any configuration of the switch.
+
+balance-xor: This mode will limit traffic such that packets destined
+	for specific peers will always be sent over the same
+	interface.  Since the destination is determined by the MAC
+	addresses involved, this may be desirable if you have a large
+	network with many hosts.  It is likely to be suboptimal if all
+	your traffic is passed through a single router, however.  As
+	with balance-rr, the switch ports need to be configured for
+	"etherchannel" or "trunking."
+
+broadcast: Like active-backup, there is not much advantage to this
+	mode in this type of network topology.
+
+802.3ad: This mode can be a good choice for this type of network
+	topology.  The 802.3ad mode is an IEEE standard, so all peers
+	that implement 802.3ad should interoperate well.  The 802.3ad
+	protocol includes automatic configuration of the aggregates,
+	so minimal manual configuration of the switch is needed
+	(typically only to designate that some set of devices is
+	usable for 802.3ad).  The 802.3ad standard also mandates that
+	frames be delivered in order (within certain limits), so in
+	general single connections will not see misordering of
+	packets.  The 802.3ad mode does have some drawbacks: the
+	standard mandates that all devices in the aggregate operate at
+	the same speed and duplex.  Also, as with all bonding load
+	balance modes other than balance-rr, no single connection will
+	be able to utilize more than a single interface's worth of
+	bandwidth.  Additionally, the linux bonding 802.3ad
+	implementation distributes traffic by peer (using an XOR of
+	MAC addresses), so in general all traffic to a particular
+	destination will use the same interface.  Finally, the 802.3ad
+	mode mandates the use of the MII monitor, therefore, the ARP
+	monitor is not available in this mode.
+
+balance-tlb: This mode is also a good choice for this type of
+	topology.  It has no special switch configuration
+	requirements, and balances outgoing traffic by peer, in a
+	vaguely intelligent manner (not a simple XOR as in balance-xor
+	or 802.3ad mode), so that unlucky MAC addresses will not all
+	"bunch up" on a single interface.  Interfaces may be of
+	differing speeds.  On the down side, in this mode all incoming
+	traffic arrives over a single interface, this mode requires
+	certain ethtool support in the network device driver of the
+	slave interfaces, and the ARP monitor is not available.
+
+balance-alb: This mode is everything that balance-tlb is, and more. It
+	has all of the features (and restrictions) of balance-tlb, and
+	will also balance incoming traffic from peers (as described in
+	the Bonding Module Options section, above).  The only extra
+	down side to this mode is that the network device driver must
+	support changing the hardware address while the device is
+	open.
+
+12.1.2 Link Monitoring for Single Switch Topology
+-------------------------------------------------
+
+	The choice of link monitoring may largely depend upon which
+mode you choose to use.  The more advanced load balancing modes do not
+support the use of the ARP monitor, and are thus restricted to using
+the MII monitor (which does not provide as high a level of assurance
+as the ARP monitor).
+
+
+12.2 High Availability in a Multiple Switch Topology
+----------------------------------------------------
+
+	With multiple switches, the configuration of bonding and the
+network changes dramatically.  In multiple switch topologies, there is
+a tradeoff between network availability and usable bandwidth.
 
-To implement high availability using the bonding driver, the driver needs to be
-compiled as a module, because currently it is the only way to pass parameters
-to the driver. This may change in the future.
-
-High availability is achieved by using MII or ETHTOOL status reporting. You
-need to verify that all your interfaces support MII or ETHTOOL link status
-reporting.  On Linux kernel 2.2.17, all the 100 Mbps capable drivers and
-yellowfin gigabit driver support MII. To determine if ETHTOOL link reporting
-is available for interface eth0, type "ethtool eth0" and the "Link detected:"
-line should contain the correct link status. If your system has an interface
-that does not support MII or ETHTOOL status reporting, a failure of its link
-will not be detected! A message indicating MII and ETHTOOL is not supported by
-a network driver is logged when the bonding driver is loaded with a non-zero
-miimon value.
-
-The bonding driver can regularly check all its slaves links using the ETHTOOL
-IOCTL (ETHTOOL_GLINK command) or by checking the MII status registers. The
-check interval is specified by the module argument "miimon" (MII monitoring).
-It takes an integer that represents the checking time in milliseconds. It
-should not come to close to (1000/HZ) (10 milli-seconds on i386) because it
-may then reduce the system interactivity. A value of 100 seems to be a good
-starting point. It means that a dead link will be detected at most 100
-milli-seconds after it goes down.
-
-Example:
-
-   # modprobe bonding miimon=100
-
-Or, put the following line in /etc/modprobe.conf:
-
-   options bond0 miimon=100
-
-There are currently two policies for high availability. They are dependent on
-whether:
-
-   a) hosts are connected to a single host or switch that support trunking
-
-   b) hosts are connected to several different switches or a single switch that
-      does not support trunking
-
-
-1) High Availability on a single switch or host - load balancing
-----------------------------------------------------------------
-It is the easiest to set up and to understand. Simply configure the
-remote equipment (host or switch) to aggregate traffic over several
-ports (Trunk, EtherChannel, etc.) and configure the bonding interfaces.
-If the module has been loaded with the proper MII option, it will work
-automatically. You can then try to remove and restore different links
-and see in your logs what the driver detects. When testing, you may
-encounter problems on some buggy switches that disable the trunk for a
-long time if all ports in a trunk go down. This is not Linux, but really
-the switch (reboot it to ensure).
+	Below is a sample network, configured to maximize the
+availability of the network:
 
-Example 1 : host to host at twice the speed
+                |                                     |
+                |port3                           port3|
+          +-----+----+                          +-----+----+
+          |          |port2       ISL      port2|          |
+          | switch A +--------------------------+ switch B |
+          |          |                          |          |
+          +-----+----+                          +-----++---+
+                |port1                           port1|
+                |             +-------+               |
+                +-------------+ host1 +---------------+
+                         eth0 +-------+ eth1
 
-          +----------+                          +----------+
-          |          |eth0                  eth0|          |
-          | Host A   +--------------------------+  Host B  |
-          |          +--------------------------+          |
-          |          |eth1                  eth1|          |
-          +----------+                          +----------+
+	In this configuration, there is a link between the two
+switches (ISL, or inter switch link), and multiple ports connecting to
+the outside world ("port3" on each switch).  There is no technical
+reason that this could not be extended to a third switch.
+
+12.2.1 Bonding Mode Selection for Multiple Switch Topology
+----------------------------------------------------------
+
+	In a topology such as this, the active-backup and broadcast
+modes are the only useful bonding modes; the other modes require all
+links to terminate on the same peer for them to behave rationally.
+
+active-backup: This is generally the preferred mode, particularly if
+	the switches have an ISL and play together well.  If the
+	network configuration is such that one switch is specifically
+	a backup switch (e.g., has lower capacity, higher cost, etc),
+	then the primary option can be used to insure that the
+	preferred link is always used when it is available.
+
+broadcast: This mode is really a special purpose mode, and is suitable
+	only for very specific needs.  For example, if the two
+	switches are not connected (no ISL), and the networks beyond
+	them are totally independant.  In this case, if it is
+	necessary for some specific one-way traffic to reach both
+	independent networks, then the broadcast mode may be suitable.
+
+12.2.2 Link Monitoring Selection for Multiple Switch Topology
+-------------------------------------------------------------
+
+	The choice of link monitoring ultimately depends upon your
+switch.  If the switch can reliably fail ports in response to other
+failures, then either the MII or ARP monitors should work.  For
+example, in the above example, if the "port3" link fails at the remote
+end, the MII monitor has no direct means to detect this.  The ARP
+monitor could be configured with a target at the remote end of port3,
+thus detecting that failure without switch support.
+
+	In general, however, in a multiple switch topology, the ARP
+monitor can provide a higher level of reliability in detecting link
+failures.  Additionally, it should be configured with multiple targets
+(at least one for each switch in the network).  This will insure that,
+regardless of which switch is active, the ARP monitor has a suitable
+target to query.
+
+
+12.3 Switch Behavior Issues for High Availability
+-------------------------------------------------
+
+	You may encounter issues with the timing of link up and down
+reporting by the switch.
+
+	First, when a link comes up, some switches may indicate that
+the link is up (carrier available), but not pass traffic over the
+interface for some period of time.  This delay is typically due to
+some type of autonegotiation or routing protocol, but may also occur
+during switch initialization (e.g., during recovery after a switch
+failure).  If you find this to be a problem, specify an appropriate
+value to the updelay bonding module option to delay the use of the
+relevant interface(s).
+
+	Second, some switches may "bounce" the link state one or more
+times while a link is changing state.  This occurs most commonly while
+the switch is initializing.  Again, an appropriate updelay value may
+help, but note that if all links are down, then updelay is ignored
+when any link becomes active (the slave closest to completing its
+updelay is chosen).
+
+	Note that when a bonding interface has no active links, the
+driver will immediately reuse the first link that goes up, even if
+updelay parameter was specified.  If there are slave interfaces
+waiting for the updelay timeout to expire, the interface that first
+went into that state will be immediately reused.  This reduces down
+time of the network if the value of updelay has been overestimated.
+
+	In addition to the concerns about switch timings, if your
+switches take a long time to go into backup mode, it may be desirable
+to not activate a backup interface immediately after a link goes down.
+Failover may be delayed via the downdelay bonding module option.
+
+13. Hardware Specific Considerations
+====================================
+
+	This section contains additional information for configuring
+bonding on specific hardware platforms, or for interfacing bonding
+with particular switches or other devices.
+
+13.1 IBM BladeCenter
+--------------------
+
+	This applies to the JS20 and similar systems.
+
+	On the JS20 blades, the bonding driver supports only
+balance-rr, active-backup, balance-tlb and balance-alb modes.  This is
+largely due to the network topology inside the BladeCenter, detailed
+below.
+
+JS20 network adapter information
+--------------------------------
+
+	All JS20s come with two Broadcom Gigabit Ethernet ports
+integrated on the planar.  In the BladeCenter chassis, the eth0 port
+of all JS20 blades is hard wired to I/O Module #1; similarly, all eth1
+ports are wired to I/O Module #2.  An add-on Broadcom daughter card
+can be installed on a JS20 to provide two more Gigabit Ethernet ports.
+These ports, eth2 and eth3, are wired to I/O Modules 3 and 4,
+respectively.
+
+	Each I/O Module may contain either a switch or a passthrough
+module (which allows ports to be directly connected to an external
+switch).  Some bonding modes require a specific BladeCenter internal
+network topology in order to function; these are detailed below.
 
-  On each host :
-     # modprobe bonding miimon=100
-     # ifconfig bond0 addr
-     # ifenslave bond0 eth0 eth1
+	Additional BladeCenter-specific networking information can be
+found in two IBM Redbooks (www.ibm.com/redbooks):
 
-Example 2 : host to switch at twice the speed
+"IBM eServer BladeCenter Networking Options"
+"IBM eServer BladeCenter Layer 2-7 Network Switching"
 
-          +----------+                          +----------+
-          |          |eth0                 port1|          |
-          | Host A   +--------------------------+  switch  |
-          |          +--------------------------+          |
-          |          |eth1                 port2|          |
-          +----------+                          +----------+
+BladeCenter networking configuration
+------------------------------------
 
-  On host A :                             On the switch :
-     # modprobe bonding miimon=100           # set up a trunk on port1
-     # ifconfig bond0 addr                     and port2
-     # ifenslave bond0 eth0 eth1
+	Because a BladeCenter can be configured in a very large number
+of ways, this discussion will be confined to describing basic
+configurations.
+
+	Normally, Ethernet Switch Modules (ESM) are used in I/O
+modules 1 and 2.  In this configuration, the eth0 and eth1 ports of a
+JS20 will be connected to different internal switches (in the
+respective I/O modules).
+
+	An optical passthru module (OPM) connects the I/O module
+directly to an external switch.  By using OPMs in I/O module #1 and
+#2, the eth0 and eth1 interfaces of a JS20 can be redirected to the
+outside world and connected to a common external switch.
+
+	Depending upon the mix of ESM and OPM modules, the network
+will appear to bonding as either a single switch topology (all OPM
+modules) or as a multiple switch topology (one or more ESM modules,
+zero or more OPM modules).  It is also possible to connect ESM modules
+together, resulting in a configuration much like the example in "High
+Availability in a multiple switch topology."
+
+Requirements for specifc modes
+------------------------------
+
+	The balance-rr mode requires the use of OPM modules for
+devices in the bond, all connected to an common external switch.  That
+switch must be configured for "etherchannel" or "trunking" on the
+appropriate ports, as is usual for balance-rr.
+
+	The balance-alb and balance-tlb modes will function with
+either switch modules or passthrough modules (or a mix).  The only
+specific requirement for these modes is that all network interfaces
+must be able to reach all destinations for traffic sent over the
+bonding device (i.e., the network must converge at some point outside
+the BladeCenter).
+
+	The active-backup mode has no additional requirements.
+
+Link monitoring issues
+----------------------
+
+	When an Ethernet Switch Module is in place, only the ARP
+monitor will reliably detect link loss to an external switch.  This is
+nothing unusual, but examination of the BladeCenter cabinet would
+suggest that the "external" network ports are the ethernet ports for
+the system, when it fact there is a switch between these "external"
+ports and the devices on the JS20 system itself.  The MII monitor is
+only able to detect link failures between the ESM and the JS20 system.
+
+	When a passthrough module is in place, the MII monitor does
+detect failures to the "external" port, which is then directly
+connected to the JS20 system.
+
+Other concerns
+--------------
+
+	The Serial Over LAN link is established over the primary
+ethernet (eth0) only, therefore, any loss of link to eth0 will result
+in losing your SoL connection.  It will not fail over with other
+network traffic.
+
+	It may be desirable to disable spanning tree on the switch
+(either the internal Ethernet Switch Module, or an external switch) to
+avoid fail-over delays issues when using bonding.
+
+	
+14. Frequently Asked Questions
+==============================
 
+1.  Is it SMP safe?
 
-2) High Availability on two or more switches (or a single switch without
-   trunking support)
----------------------------------------------------------------------------
-This mode is more problematic because it relies on the fact that there
-are multiple ports and the host's MAC address should be visible on one
-port only to avoid confusing the switches.
+	Yes. The old 2.0.xx channel bonding patch was not SMP safe.
+The new driver was designed to be SMP safe from the start.
 
-If you need to know which interface is the active one, and which ones are
-backup, use ifconfig. All backup interfaces have the NOARP flag set.
+2.  What type of cards will work with it?
 
-To use this mode, pass "mode=1" to the module at load time :
+	Any Ethernet type cards (you can even mix cards - a Intel
+EtherExpress PRO/100 and a 3com 3c905b, for example).  They need not
+be of the same speed.
 
-    # modprobe bonding miimon=100 mode=active-backup
+3.  How many bonding devices can I have?
 
-	or:
+	There is no limit.
 
-    # modprobe bonding miimon=100 mode=1
+4.  How many slaves can a bonding device have?
 
-Or, put in your /etc/modprobe.conf :
+	This is limited only by the number of network interfaces Linux
+supports and/or the number of network cards you can place in your
+system.
 
-    options bond0 miimon=100 mode=active-backup
+5.  What happens when a slave link dies?
 
-Example 1: Using multiple host and multiple switches to build a "no single
-point of failure" solution.
+	If link monitoring is enabled, then the failing device will be
+disabled.  The active-backup mode will fail over to a backup link, and
+other modes will ignore the failed link.  The link will continue to be
+monitored, and should it recover, it will rejoin the bond (in whatever
+manner is appropriate for the mode). See the section on High
+Availability for additional information.
+	
+	Link monitoring can be enabled via either the miimon or
+arp_interval paramters (described in the module paramters section,
+above).  In general, miimon monitors the carrier state as sensed by
+the underlying network device, and the arp monitor (arp_interval)
+monitors connectivity to another host on the local network.
+
+	If no link monitoring is configured, the bonding driver will
+be unable to detect link failures, and will assume that all links are
+always available.  This will likely result in lost packets, and a
+resulting degredation of performance.  The precise performance loss
+depends upon the bonding mode and network configuration.
 
+6.  Can bonding be used for High Availability?
 
-                |                                     |
-                |port3                           port3|
-          +-----+----+                          +-----+----+
-          |          |port7       ISL      port7|          |
-          | switch A +--------------------------+ switch B |
-          |          +--------------------------+          |
-          |          |port8                port8|          |
-          +----++----+                          +-----++---+
-          port2||port1                           port1||port2
-               ||             +-------+               ||
-               |+-------------+ host1 +---------------+|
-               |         eth0 +-------+ eth1           |
-               |                                       |
-               |              +-------+                |
-               +--------------+ host2 +----------------+
-                         eth0 +-------+ eth1
+	Yes.  See the section on High Availability for details.
 
-In this configuration, there is an ISL - Inter Switch Link (could be a trunk),
-several servers (host1, host2 ...) attached to both switches each, and one or
-more ports to the outside world (port3...). One and only one slave on each host
-is active at a time, while all links are still monitored (the system can
-detect a failure of active and backup links).
-
-Each time a host changes its active interface, it sticks to the new one until
-it goes down. In this example, the hosts are negligibly affected by the
-expiration time of the switches' forwarding tables.
-
-If host1 and host2 have the same functionality and are used in load balancing
-by another external mechanism, it is good to have host1's active interface
-connected to one switch and host2's to the other. Such system will survive
-a failure of a single host, cable, or switch. The worst thing that may happen
-in the case of a switch failure is that half of the hosts will be temporarily
-unreachable until the other switch expires its tables.
+7.  Which switches/systems does it work with?
 
-Example 2: Using multiple ethernet cards connected to a switch to configure
-           NIC failover (switch is not required to support trunking).
+	The full answer to this depends upon the desired mode.
 
+	In the basic balance modes (balance-rr and balance-xor), it
+works with any system that supports etherchannel (also called
+trunking).  Most managed switches currently available have such
+support, and many unmananged switches as well.
+
+	The advanced balance modes (balance-tlb and balance-alb) do
+not have special switch requirements, but do need device drivers that
+support specific features (described in the appropriate section under
+module paramters, above).
+
+	In 802.3ad mode, it works with with systems that support IEEE
+802.3ad Dynamic Link Aggregation.  Most managed and many unmanaged
+switches currently available support 802.3ad.
 
-          +----------+                          +----------+
-          |          |eth0                 port1|          |
-          | Host A   +--------------------------+  switch  |
-          |          +--------------------------+          |
-          |          |eth1                 port2|          |
-          +----------+                          +----------+
+        The active-backup mode should work with any Layer-II switch.
 
-  On host A :                                 On the switch :
-     # modprobe bonding miimon=100 mode=1     # (optional) minimize the time
-     # ifconfig bond0 addr                    # for table expiration
-     # ifenslave bond0 eth0 eth1
+8.  Where does a bonding device get its MAC address from?
 
-Each time the host changes its active interface, it sticks to the new one until
-it goes down. In this example, the host is strongly affected by the expiration
-time of the switch forwarding table.
+	If not explicitly configured with ifconfig, the MAC address of
+the bonding device is taken from its first slave device. This MAC
+address is then passed to all following slaves and remains persistent
+(even if the the first slave is removed) until the bonding device is
+brought down or reconfigured.
+
+	If you wish to change the MAC address, you can set it with
+ifconfig:
+
+# ifconfig bond0 hw ether 00:11:22:33:44:55
+
+	The MAC address can be also changed by bringing down/up the
+device and then changing its slaves (or their order):
+
+# ifconfig bond0 down ; modprobe -r bonding
+# ifconfig bond0 .... up
+# ifenslave bond0 eth...
 
+	This method will automatically take the address from the next
+slave that is added.
 
-3) Adapting to your switches' timing
-------------------------------------
-If your switches take a long time to go into backup mode, it may be
-desirable not to activate a backup interface immediately after a link goes
-down. It is possible to delay the moment at which a link will be
-completely disabled by passing the module parameter "downdelay" (in
-milliseconds, must be a multiple of miimon).
-
-When a switch reboots, it is possible that its ports report "link up" status
-before they become usable. This could fool a bond device by causing it to
-use some ports that are not ready yet. It is possible to delay the moment at
-which an active link will be reused by passing the module parameter "updelay"
-(in milliseconds, must be a multiple of miimon).
-
-A similar situation can occur when a host re-negotiates a lost link with the
-switch (a case of cable replacement).
-
-A special case is when a bonding interface has lost all slave links. Then the
-driver will immediately reuse the first link that goes up, even if updelay
-parameter was specified. (If there are slave interfaces in the "updelay" state,
-the interface that first went into that state will be immediately reused.) This
-allows to reduce down-time if the value of updelay has been overestimated.
-
-Examples :
-
-    # modprobe bonding miimon=100 mode=1 downdelay=2000 updelay=5000
-    # modprobe bonding miimon=100 mode=balance-rr downdelay=0 updelay=5000
-
-
-Promiscuous Sniffing notes
-==========================
-
-If you wish to bond channels together for a network sniffing
-application --- you wish to run tcpdump, or ethereal, or an IDS like
-snort, with its input aggregated from multiple interfaces using the
-bonding driver --- then you need to handle the Promiscuous interface
-setting by hand. Specifically, when you "ifconfing bond0 up" you
-must add the promisc flag there; it will be propagated down to the
-slave interfaces at ifenslave time; a full example might look like:
-
-   ifconfig bond0 promisc up
-   for if in eth1 eth2 ...;do
-       ifconfig $if up
-       ifenslave bond0 $if
-   done
-   snort ... -i bond0 ...
-
-Ifenslave also wants to propagate addresses from interface to
-interface, appropriately for its design functions in HA and channel
-capacity aggregating; but it works fine for unnumbered interfaces;
-just ignore all the warnings it emits.
+	To restore your slaves' MAC addresses, you need to detach them
+from the bond (`ifenslave -d bond0 eth0'). The bonding driver will
+then restore the MAC addresses that the slaves had before they were
+enslaved.
 
+15. Resources and Links
+=======================
 
-8021q VLAN support
-==================
+The latest version of the bonding driver can be found in the latest
+version of the linux kernel, found on http://kernel.org
 
-It is possible to configure VLAN devices over a bond interface using the 8021q
-driver. However, only packets coming from the 8021q driver and passing through
-bonding will be tagged by default. Self generated packets, like bonding's
-learning packets or ARP packets generated by either ALB mode or the ARP
-monitor mechanism, are tagged internally by bonding itself. As a result,
-bonding has to "learn" what VLAN IDs are configured on top of it, and it uses
-those IDs to tag self generated packets.
-
-For simplicity reasons, and to support the use of adapters that can do VLAN
-hardware acceleration offloding, the bonding interface declares itself as
-fully hardware offloaing capable, it gets the add_vid/kill_vid notifications
-to gather the necessary information, and it propagates those actions to the
-slaves.
-In case of mixed adapter types, hardware accelerated tagged packets that should
-go through an adapter that is not offloading capable are "un-accelerated" by the
-bonding driver so the VLAN tag sits in the regular location.
-
-VLAN interfaces *must* be added on top of a bonding interface only after
-enslaving at least one slave. This is because until the first slave is added the
-bonding interface has a HW address of 00:00:00:00:00:00, which will be copied by
-the VLAN interface when it is created.
-
-Notice that a problem would occur if all slaves are released from a bond that
-still has VLAN interfaces on top of it. When later coming to add new slaves, the
-bonding interface would get a HW address from the first slave, which might not
-match that of the VLAN interfaces. It is recommended that either all VLANs are
-removed and then re-added, or to manually set the bonding interface's HW
-address so it matches the VLAN's. (Note: changing a VLAN interface's HW address
-would set the underlying device -- i.e. the bonding interface -- to promiscouos
-mode, which might not be what you want).
-
-
-Limitations
-===========
-The main limitations are :
-  - only the link status is monitored. If the switch on the other side is
-    partially down (e.g. doesn't forward anymore, but the link is OK), the link
-    won't be disabled. Another way to check for a dead link could be to count
-    incoming frames on a heavily loaded host. This is not applicable to small
-    servers, but may be useful when the front switches send multicast
-    information on their links (e.g. VRRP), or even health-check the servers.
-    Use the arp_interval/arp_ip_target parameters to count incoming/outgoing
-    frames.
+Discussions regarding the bonding driver take place primarily on the
+bonding-devel mailing list, hosted at sourceforge.net.  If you have
+questions or problems, post them to the list.
 
+bonding-devel@lists.sourceforge.net
 
+https://lists.sourceforge.net/lists/listinfo/bonding-devel
 
-Resources and Links
-===================
+There is also a project site on sourceforge.
 
-Current development on this driver is posted to:
- - http://www.sourceforge.net/projects/bonding/
+http://www.sourceforge.net/projects/bonding
 
 Donald Becker's Ethernet Drivers and diag programs may be found at :
  - http://www.scyld.com/network/
 
-You will also find a lot of information regarding Ethernet, NWay, MII, etc. at
-www.scyld.com.
-
-Patches for 2.2 kernels are at Willy Tarreau's site :
- - http://wtarreau.free.fr/pub/bonding/
- - http://www-miaif.lip6.fr/~tarreau/pub/bonding/
-
-To get latest informations about Linux Kernel development, please consult
-the Linux Kernel Mailing List Archives at :
-   http://www.ussg.iu.edu/hypermail/linux/kernel/
+You will also find a lot of information regarding Ethernet, NWay, MII,
+etc. at www.scyld.com.
 
 -- END --
diff -Nru a/drivers/net/3c59x.c b/drivers/net/3c59x.c
--- a/drivers/net/3c59x.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/3c59x.c	2005-03-07 12:09:08 -05:00
@@ -964,7 +964,7 @@
 
 #ifdef CONFIG_PM
 
-static int vortex_suspend (struct pci_dev *pdev, u32 state)
+static int vortex_suspend (struct pci_dev *pdev, pm_message_t state)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 
diff -Nru a/drivers/net/8139too.c b/drivers/net/8139too.c
--- a/drivers/net/8139too.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/8139too.c	2005-03-07 12:09:08 -05:00
@@ -389,8 +389,14 @@
 
 /* Bits in TxConfig. */
 enum tx_config_bits {
-	TxIFG1 = (1 << 25),	/* Interframe Gap Time */
-	TxIFG0 = (1 << 24),	/* Enabling these bits violates IEEE 802.3 */
+
+        /* Interframe Gap Time. Only TxIFG96 doesn't violate IEEE 802.3 */
+        TxIFGShift = 24,
+        TxIFG84 = (0 << TxIFGShift),    /* 8.4us / 840ns (10 / 100Mbps) */
+        TxIFG88 = (1 << TxIFGShift),    /* 8.8us / 880ns (10 / 100Mbps) */
+        TxIFG92 = (2 << TxIFGShift),    /* 9.2us / 920ns (10 / 100Mbps) */
+        TxIFG96 = (3 << TxIFGShift),    /* 9.6us / 960ns (10 / 100Mbps) */
+
 	TxLoopBack = (1 << 18) | (1 << 17), /* enable loopback test mode */
 	TxCRC = (1 << 16),	/* DISABLE appending CRC to end of Tx packets */
 	TxClearAbt = (1 << 0),	/* Clear abort (WO) */
@@ -723,17 +729,14 @@
 #endif
 
 static const unsigned int rtl8139_tx_config =
-	(TX_DMA_BURST << TxDMAShift) | (TX_RETRY << TxRetryShift);
+	TxIFG96 | (TX_DMA_BURST << TxDMAShift) | (TX_RETRY << TxRetryShift);
 
 static void __rtl8139_cleanup_dev (struct net_device *dev)
 {
-	struct rtl8139_private *tp;
+	struct rtl8139_private *tp = netdev_priv(dev);
 	struct pci_dev *pdev;
 
 	assert (dev != NULL);
-	assert (dev->priv != NULL);
-
-	tp = dev->priv;
 	assert (tp->pci_dev != NULL);
 	pdev = tp->pci_dev;
 
@@ -746,7 +749,7 @@
 	pci_release_regions (pdev);
 
 	free_netdev(dev);
-
+	pci_disable_device(pdev);
 	pci_set_drvdata (pdev, NULL);
 }
 
@@ -785,7 +788,7 @@
 
 	*dev_out = NULL;
 
-	/* dev and dev->priv zeroed in alloc_etherdev */
+	/* dev and priv zeroed in alloc_etherdev */
 	dev = alloc_etherdev (sizeof (*tp));
 	if (dev == NULL) {
 		printk (KERN_ERR PFX "%s: Unable to alloc new net device\n", pci_name(pdev));
@@ -794,7 +797,7 @@
 	SET_MODULE_OWNER(dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
-	tp = dev->priv;
+	tp = netdev_priv(dev);
 	tp->pci_dev = pdev;
 
 	/* enable device (incl. PCI PM wakeup and hotplug setup) */
@@ -976,8 +979,8 @@
 		return i;
 
 	assert (dev != NULL);
-	tp = dev->priv;
-	assert (tp != NULL);
+	tp = netdev_priv(dev);
+
 	ioaddr = tp->mmio_addr;
 	assert (ioaddr != NULL);
 
@@ -1010,8 +1013,8 @@
 
 	dev->irq = pdev->irq;
 
-	/* dev->priv/tp zeroed and aligned in alloc_etherdev */
-	tp = dev->priv;
+	/* tp zeroed and aligned in alloc_etherdev */
+	tp = netdev_priv(dev);
 
 	/* note: tp->chipset set in rtl8139_init_board */
 	tp->drv_flags = board_info[ent->driver_data].hw_flags;
@@ -1116,11 +1119,8 @@
 static void __devexit rtl8139_remove_one (struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
-	struct rtl8139_private *np;
 
 	assert (dev != NULL);
-	np = dev->priv;
-	assert (np != NULL);
 
 	unregister_netdev (dev);
 
@@ -1234,7 +1234,7 @@
 
 static int mdio_read (struct net_device *dev, int phy_id, int location)
 {
-	struct rtl8139_private *tp = dev->priv;
+	struct rtl8139_private *tp = netdev_priv(dev);
 	int retval = 0;
 #ifdef CONFIG_8139TOO_8129
 	void *mdio_addr = tp->mmio_addr + Config4;
@@ -1276,7 +1276,7 @@
 static void mdio_write (struct net_device *dev, int phy_id, int location,
 			int value)
 {
-	struct rtl8139_private *tp = dev->priv;
+	struct rtl8139_private *tp = netdev_priv(dev);
 #ifdef CONFIG_8139TOO_8129
 	void *mdio_addr = tp->mmio_addr + Config4;
 	int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location << 18) | value;
@@ -1319,7 +1319,7 @@
 
 static int rtl8139_open (struct net_device *dev)
 {
-	struct rtl8139_private *tp = dev->priv;
+	struct rtl8139_private *tp = netdev_priv(dev);
 	int retval;
 	void *ioaddr = tp->mmio_addr;
 
@@ -1367,7 +1367,7 @@
 
 static void rtl_check_media (struct net_device *dev, unsigned int init_media)
 {
-	struct rtl8139_private *tp = dev->priv;
+	struct rtl8139_private *tp = netdev_priv(dev);
 
 	if (tp->phys[0] >= 0) {
 		mii_check_media(&tp->mii, netif_msg_link(tp), init_media);
@@ -1377,7 +1377,7 @@
 /* Start the hardware at open or resume. */
 static void rtl8139_hw_start (struct net_device *dev)
 {
-	struct rtl8139_private *tp = dev->priv;
+	struct rtl8139_private *tp = netdev_priv(dev);
 	void *ioaddr = tp->mmio_addr;
 	u32 i;
 	u8 tmp;
@@ -1399,8 +1399,6 @@
 
 	tp->rx_config = rtl8139_rx_config | AcceptBroadcast | AcceptMyPhys;
 	RTL_W32 (RxConfig, tp->rx_config);
-
-	/* Check this value: the documentation for IFG contradicts ifself. */
 	RTL_W32 (TxConfig, rtl8139_tx_config);
 
 	tp->cur_rx = 0;
@@ -1446,7 +1444,7 @@
 /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
 static void rtl8139_init_ring (struct net_device *dev)
 {
-	struct rtl8139_private *tp = dev->priv;
+	struct rtl8139_private *tp = netdev_priv(dev);
 	int i;
 
 	tp->cur_rx = 0;
@@ -1613,7 +1611,7 @@
 static int rtl8139_thread (void *data)
 {
 	struct net_device *dev = data;
-	struct rtl8139_private *tp = dev->priv;
+	struct rtl8139_private *tp = netdev_priv(dev);
 	unsigned long timeout;
 
 	daemonize("%s", dev->name);
@@ -1645,7 +1643,7 @@
 
 static void rtl8139_start_thread(struct net_device *dev)
 {
-	struct rtl8139_private *tp = dev->priv;
+	struct rtl8139_private *tp = netdev_priv(dev);
 
 	tp->thr_pid = -1;
 	tp->twistie = 0;
@@ -1673,7 +1671,7 @@
 
 static void rtl8139_tx_timeout (struct net_device *dev)
 {
-	struct rtl8139_private *tp = dev->priv;
+	struct rtl8139_private *tp = netdev_priv(dev);
 	void *ioaddr = tp->mmio_addr;
 	int i;
 	u8 tmp8;
@@ -1718,7 +1716,7 @@
 
 static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
 {
-	struct rtl8139_private *tp = dev->priv;
+	struct rtl8139_private *tp = netdev_priv(dev);
 	void *ioaddr = tp->mmio_addr;
 	unsigned int entry;
 	unsigned int len = skb->len;
@@ -1766,7 +1764,6 @@
 	unsigned long dirty_tx, tx_left;
 
 	assert (dev != NULL);
-	assert (tp != NULL);
 	assert (ioaddr != NULL);
 
 	dirty_tx = tp->dirty_tx;
@@ -2125,7 +2122,7 @@
 
 static int rtl8139_poll(struct net_device *dev, int *budget)
 {
-	struct rtl8139_private *tp = dev->priv;
+	struct rtl8139_private *tp = netdev_priv(dev);
 	void *ioaddr = tp->mmio_addr;
 	int orig_budget = min(*budget, dev->quota);
 	int done = 1;
@@ -2163,7 +2160,7 @@
 			       struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *) dev_instance;
-	struct rtl8139_private *tp = dev->priv;
+	struct rtl8139_private *tp = netdev_priv(dev);
 	void *ioaddr = tp->mmio_addr;
 	u16 status, ackstat;
 	int link_changed = 0; /* avoid bogus "uninit" warning */
@@ -2239,7 +2236,7 @@
 
 static int rtl8139_close (struct net_device *dev)
 {
-	struct rtl8139_private *tp = dev->priv;
+	struct rtl8139_private *tp = netdev_priv(dev);
 	void *ioaddr = tp->mmio_addr;
 	int ret = 0;
 	unsigned long flags;
@@ -2302,7 +2299,7 @@
    other threads or interrupts aren't messing with the 8139.  */
 static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
-	struct rtl8139_private *np = dev->priv;
+	struct rtl8139_private *np = netdev_priv(dev);
 	void *ioaddr = np->mmio_addr;
 
 	spin_lock_irq(&np->lock);
@@ -2336,7 +2333,7 @@
    aren't messing with the 8139.  */
 static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
-	struct rtl8139_private *np = dev->priv;
+	struct rtl8139_private *np = netdev_priv(dev);
 	void *ioaddr = np->mmio_addr;
 	u32 support;
 	u8 cfg3, cfg5;
@@ -2376,7 +2373,7 @@
 
 static void rtl8139_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
-	struct rtl8139_private *np = dev->priv;
+	struct rtl8139_private *np = netdev_priv(dev);
 	strcpy(info->driver, DRV_NAME);
 	strcpy(info->version, DRV_VERSION);
 	strcpy(info->bus_info, pci_name(np->pci_dev));
@@ -2385,7 +2382,7 @@
 
 static int rtl8139_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-	struct rtl8139_private *np = dev->priv;
+	struct rtl8139_private *np = netdev_priv(dev);
 	spin_lock_irq(&np->lock);
 	mii_ethtool_gset(&np->mii, cmd);
 	spin_unlock_irq(&np->lock);
@@ -2394,7 +2391,7 @@
 
 static int rtl8139_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-	struct rtl8139_private *np = dev->priv;
+	struct rtl8139_private *np = netdev_priv(dev);
 	int rc;
 	spin_lock_irq(&np->lock);
 	rc = mii_ethtool_sset(&np->mii, cmd);
@@ -2404,25 +2401,25 @@
 
 static int rtl8139_nway_reset(struct net_device *dev)
 {
-	struct rtl8139_private *np = dev->priv;
+	struct rtl8139_private *np = netdev_priv(dev);
 	return mii_nway_restart(&np->mii);
 }
 
 static u32 rtl8139_get_link(struct net_device *dev)
 {
-	struct rtl8139_private *np = dev->priv;
+	struct rtl8139_private *np = netdev_priv(dev);
 	return mii_link_ok(&np->mii);
 }
 
 static u32 rtl8139_get_msglevel(struct net_device *dev)
 {
-	struct rtl8139_private *np = dev->priv;
+	struct rtl8139_private *np = netdev_priv(dev);
 	return np->msg_enable;
 }
 
 static void rtl8139_set_msglevel(struct net_device *dev, u32 datum)
 {
-	struct rtl8139_private *np = dev->priv;
+	struct rtl8139_private *np = netdev_priv(dev);
 	np->msg_enable = datum;
 }
 
@@ -2433,13 +2430,13 @@
 #else
 static int rtl8139_get_regs_len(struct net_device *dev)
 {
-	struct rtl8139_private *np = dev->priv;
+	struct rtl8139_private *np = netdev_priv(dev);
 	return np->regs_len;
 }
 
 static void rtl8139_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
 {
-	struct rtl8139_private *np = dev->priv;
+	struct rtl8139_private *np = netdev_priv(dev);
 
 	regs->version = RTL_REGS_VER;
 
@@ -2456,7 +2453,7 @@
 
 static void rtl8139_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data)
 {
-	struct rtl8139_private *np = dev->priv;
+	struct rtl8139_private *np = netdev_priv(dev);
 
 	data[0] = np->xstats.early_rx;
 	data[1] = np->xstats.tx_buf_mapped;
@@ -2488,7 +2485,7 @@
 
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-	struct rtl8139_private *np = dev->priv;
+	struct rtl8139_private *np = netdev_priv(dev);
 	int rc;
 
 	if (!netif_running(dev))
@@ -2504,7 +2501,7 @@
 
 static struct net_device_stats *rtl8139_get_stats (struct net_device *dev)
 {
-	struct rtl8139_private *tp = dev->priv;
+	struct rtl8139_private *tp = netdev_priv(dev);
 	void *ioaddr = tp->mmio_addr;
 	unsigned long flags;
 
@@ -2523,7 +2520,7 @@
 
 static void __set_rx_mode (struct net_device *dev)
 {
-	struct rtl8139_private *tp = dev->priv;
+	struct rtl8139_private *tp = netdev_priv(dev);
 	void *ioaddr = tp->mmio_addr;
 	u32 mc_filter[2];	/* Multicast hash filter */
 	int i, rx_mode;
@@ -2572,7 +2569,7 @@
 static void rtl8139_set_rx_mode (struct net_device *dev)
 {
 	unsigned long flags;
-	struct rtl8139_private *tp = dev->priv;
+	struct rtl8139_private *tp = netdev_priv(dev);
 
 	spin_lock_irqsave (&tp->lock, flags);
 	__set_rx_mode(dev);
@@ -2581,10 +2578,10 @@
 
 #ifdef CONFIG_PM
 
-static int rtl8139_suspend (struct pci_dev *pdev, u32 state)
+static int rtl8139_suspend (struct pci_dev *pdev, pm_message_t state)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
-	struct rtl8139_private *tp = dev->priv;
+	struct rtl8139_private *tp = netdev_priv(dev);
 	void *ioaddr = tp->mmio_addr;
 	unsigned long flags;
 
diff -Nru a/drivers/net/Kconfig b/drivers/net/Kconfig
--- a/drivers/net/Kconfig	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/Kconfig	2005-03-07 12:09:08 -05:00
@@ -47,16 +47,13 @@
 	---help---
 	  Say 'Y' or 'M' if you wish to be able to 'bond' multiple Ethernet
 	  Channels together. This is called 'Etherchannel' by Cisco,
-	  'Trunking' by Sun, and 'Bonding' in Linux.
+	  'Trunking' by Sun, 802.3ad by the IEEE, and 'Bonding' in Linux.
 
-	  If you have two Ethernet connections to some other computer, you can
-	  make them behave like one double speed connection using this driver.
-	  Naturally, this has to be supported at the other end as well, either
-	  with a similar Bonding Linux driver, a Cisco 5500 switch or a
-	  SunTrunking SunSoft driver.
+	  The driver supports multiple bonding modes to allow for both high
+	  perfomance and high availability operation.
 
-	  This is similar to the EQL driver, but it merges Ethernet segments
-	  instead of serial lines.
+	  Refer to <file:Documentation/networking/bonding.txt> for more
+	  information.
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called bonding.
@@ -819,7 +816,7 @@
 	tristate "SMC 91C9x/91C1xxx support"
 	select CRC32
 	select MII
-	depends on NET_ETHERNET && (ARM || REDWOOD_5 || REDWOOD_6 || M32R)
+	depends on NET_ETHERNET && (ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH)
 	help
 	  This is a driver for SMC's 91x series of Ethernet chipsets,
 	  including the SMC91C94 and the SMC91C111. Say Y if you want it
diff -Nru a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
--- a/drivers/net/amd8111e.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/amd8111e.c	2005-03-07 12:09:08 -05:00
@@ -1799,7 +1799,7 @@
 	if(!err)
 		netif_wake_queue(dev);
 }
-static int amd8111e_suspend(struct pci_dev *pci_dev, u32 state)
+static int amd8111e_suspend(struct pci_dev *pci_dev, pm_message_t state)
 {	
 	struct net_device *dev = pci_get_drvdata(pci_dev);
 	struct amd8111e_priv *lp = netdev_priv(dev);
diff -Nru a/drivers/net/b44.c b/drivers/net/b44.c
--- a/drivers/net/b44.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/b44.c	2005-03-07 12:09:08 -05:00
@@ -1903,7 +1903,7 @@
 	}
 }
 
-static int b44_suspend(struct pci_dev *pdev, u32 state)
+static int b44_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct b44 *bp = netdev_priv(dev);
diff -Nru a/drivers/net/b44.h b/drivers/net/b44.h
--- a/drivers/net/b44.h	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/b44.h	2005-03-07 12:09:08 -05:00
@@ -302,20 +302,6 @@
 #define B44_MII_TLEDCTRL	27	/* Traffic Meter LED */
 #define  MII_TLEDCTRL_ENABLE	0x0040
 
-/* XXX Add this to mii.h */
-#ifndef ADVERTISE_PAUSE
-#define ADVERTISE_PAUSE_CAP		0x0400
-#endif
-#ifndef ADVERTISE_PAUSE_ASYM
-#define ADVERTISE_PAUSE_ASYM		0x0800
-#endif
-#ifndef LPA_PAUSE
-#define LPA_PAUSE_CAP			0x0400
-#endif
-#ifndef LPA_PAUSE_ASYM
-#define LPA_PAUSE_ASYM			0x0800
-#endif
-
 struct dma_desc {
 	u32	ctrl;
 	u32	addr;
diff -Nru a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
--- a/drivers/net/bonding/bond_alb.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/bonding/bond_alb.c	2005-03-07 12:09:08 -05:00
@@ -954,9 +954,9 @@
 	/* each slave will receive packets destined to a different mac */
 	memcpy(s_addr.sa_data, addr, dev->addr_len);
 	s_addr.sa_family = dev->type;
-	if (dev->set_mac_address(dev, &s_addr)) {
+	if (dev_set_mac_address(dev, &s_addr)) {
 		printk(KERN_ERR DRV_NAME
-		       ": Error: dev->set_mac_address of dev %s failed! ALB "
+		       ": Error: dev_set_mac_address of dev %s failed! ALB "
 		       "mode requires that the base driver support setting "
 		       "the hw address also when the network device's "
 		       "interface is open\n",
@@ -1209,7 +1209,7 @@
 		/* save net_device's current hw address */
 		memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
 
-		res = slave->dev->set_mac_address(slave->dev, addr);
+		res = dev_set_mac_address(slave->dev, addr);
 
 		/* restore net_device's hw address */
 		memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN);
@@ -1229,7 +1229,7 @@
 	stop_at = slave;
 	bond_for_each_slave_from_to(bond, slave, i, bond->first_slave, stop_at) {
 		memcpy(tmp_addr, slave->dev->dev_addr, ETH_ALEN);
-		slave->dev->set_mac_address(slave->dev, &sa);
+		dev_set_mac_address(slave->dev, &sa);
 		memcpy(slave->dev->dev_addr, tmp_addr, ETH_ALEN);
 	}
 
diff -Nru a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
--- a/drivers/net/bonding/bond_main.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/bonding/bond_main.c	2005-03-07 12:09:08 -05:00
@@ -1719,7 +1719,7 @@
 		 */
 		memcpy(addr.sa_data, bond_dev->dev_addr, bond_dev->addr_len);
 		addr.sa_family = slave_dev->type;
-		res = slave_dev->set_mac_address(slave_dev, &addr);
+		res = dev_set_mac_address(slave_dev, &addr);
 		if (res) {
 			dprintk("Error %d calling set_mac_address\n", res);
 			goto err_free;
@@ -1849,8 +1849,8 @@
 	if (bond_update_speed_duplex(new_slave) &&
 	    (new_slave->link != BOND_LINK_DOWN)) {
 		printk(KERN_WARNING DRV_NAME
-		       ": Warning: failed to get speed/duplex from %s, speed "
-		       "forced to 100Mbps, duplex forced to Full.\n",
+		       ": Warning: failed to get speed and duplex from %s, "
+		       "assumed to be 100Mb/sec and Full.\n",
 		       new_slave->dev->name);
 
 		if (bond->params.mode == BOND_MODE_8023AD) {
@@ -1991,7 +1991,7 @@
 err_restore_mac:
 	memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN);
 	addr.sa_family = slave_dev->type;
-	slave_dev->set_mac_address(slave_dev, &addr);
+	dev_set_mac_address(slave_dev, &addr);
 
 err_free:
 	kfree(new_slave);
@@ -2171,7 +2171,7 @@
 		/* restore original ("permanent") mac address */
 		memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
 		addr.sa_family = slave_dev->type;
-		slave_dev->set_mac_address(slave_dev, &addr);
+		dev_set_mac_address(slave_dev, &addr);
 	}
 
 	/* restore the original state of the
@@ -2262,7 +2262,7 @@
 			/* restore original ("permanent") mac address*/
 			memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
 			addr.sa_family = slave_dev->type;
-			slave_dev->set_mac_address(slave_dev, &addr);
+			dev_set_mac_address(slave_dev, &addr);
 		}
 
 		/* restore the original state of the IFF_NOARP flag that might have
@@ -3898,12 +3898,7 @@
 	bond_for_each_slave(bond, slave, i) {
 		dprintk("s %p s->p %p c_m %p\n", slave,
 			slave->prev, slave->dev->change_mtu);
-		if (slave->dev->change_mtu) {
-			res = slave->dev->change_mtu(slave->dev, new_mtu);
-		} else {
-			slave->dev->mtu = new_mtu;
-			res = 0;
-		}
+		res = dev_set_mtu(slave->dev, new_mtu);
 
 		if (res) {
 			/* If we failed to set the slave's mtu to the new value
@@ -3929,14 +3924,10 @@
 	bond_for_each_slave_from_to(bond, slave, i, bond->first_slave, stop_at) {
 		int tmp_res;
 
-		if (slave->dev->change_mtu) {
-			tmp_res = slave->dev->change_mtu(slave->dev, bond_dev->mtu);
-			if (tmp_res) {
-				dprintk("unwind err %d dev %s\n", tmp_res,
-					slave->dev->name);
-			}
-		} else {
-			slave->dev->mtu = bond_dev->mtu;
+		tmp_res = dev_set_mtu(slave->dev, bond_dev->mtu);
+		if (tmp_res) {
+			dprintk("unwind err %d dev %s\n", tmp_res,
+				slave->dev->name);
 		}
 	}
 
@@ -3988,7 +3979,7 @@
 			goto unwind;
 		}
 
-		res = slave->dev->set_mac_address(slave->dev, addr);
+		res = dev_set_mac_address(slave->dev, addr);
 		if (res) {
 			/* TODO: consider downing the slave
 			 * and retry ?
@@ -4014,7 +4005,7 @@
 	bond_for_each_slave_from_to(bond, slave, i, bond->first_slave, stop_at) {
 		int tmp_res;
 
-		tmp_res = slave->dev->set_mac_address(slave->dev, &tmp_sa);
+		tmp_res = dev_set_mac_address(slave->dev, &tmp_sa);
 		if (tmp_res) {
 			dprintk("unwind err %d dev %s\n", tmp_res,
 				slave->dev->name);
diff -Nru a/drivers/net/e100.c b/drivers/net/e100.c
--- a/drivers/net/e100.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/e100.c	2005-03-07 12:09:08 -05:00
@@ -2310,7 +2310,7 @@
 }
 
 #ifdef CONFIG_PM
-static int e100_suspend(struct pci_dev *pdev, u32 state)
+static int e100_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct nic *nic = netdev_priv(netdev);
@@ -2321,7 +2321,7 @@
 	netif_device_detach(netdev);
 
 	pci_save_state(pdev);
-	pci_enable_wake(pdev, state, nic->flags & (wol_magic | e100_asf(nic)));
+	pci_enable_wake(pdev, pci_choose_state(pdev, state), nic->flags & (wol_magic | e100_asf(nic)));
 	pci_disable_device(pdev);
 	pci_set_power_state(pdev, pci_choose_state(pdev, state));
 
diff -Nru a/drivers/net/eepro100.c b/drivers/net/eepro100.c
--- a/drivers/net/eepro100.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/eepro100.c	2005-03-07 12:09:08 -05:00
@@ -2281,7 +2281,7 @@
 }
 \f
 #ifdef CONFIG_PM
-static int eepro100_suspend(struct pci_dev *pdev, u32 state)
+static int eepro100_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
 	struct speedo_private *sp = netdev_priv(dev);
@@ -2299,7 +2299,7 @@
 	
 	/* XXX call pci_set_power_state ()? */
 	pci_disable_device(pdev);
-	pci_set_power_state (pdev, 3);
+	pci_set_power_state (pdev, PCI_D3hot);
 	return 0;
 }
 
@@ -2309,7 +2309,7 @@
 	struct speedo_private *sp = netdev_priv(dev);
 	void __iomem *ioaddr = sp->regs;
 
-	pci_set_power_state(pdev, 0);
+	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 	pci_enable_device(pdev);
 	pci_set_master(pdev);
diff -Nru a/drivers/net/epic100.c b/drivers/net/epic100.c
--- a/drivers/net/epic100.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/epic100.c	2005-03-07 12:09:08 -05:00
@@ -1624,7 +1624,7 @@
 
 #ifdef CONFIG_PM
 
-static int epic_suspend (struct pci_dev *pdev, u32 state)
+static int epic_suspend (struct pci_dev *pdev, pm_message_t state)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 	long ioaddr = dev->base_addr;
diff -Nru a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c
--- a/drivers/net/ibmlana.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/ibmlana.c	2005-03-07 12:09:08 -05:00
@@ -133,13 +133,14 @@
 
 static void dumpmem(struct net_device *dev, u32 start, u32 len)
 {
+	ibmlana_priv *priv = netdev_priv(dev);
 	int z;
 
 	printk("Address %04x:\n", start);
 	for (z = 0; z < len; z++) {
 		if ((z & 15) == 0)
 			printk("%04x:", z);
-		printk(" %02x", isa_readb(dev->mem_start + start + z));
+		printk(" %02x", readb(priv->base + start + z));
 		if ((z & 15) == 15)
 			printk("\n");
 	}
@@ -231,7 +232,7 @@
 
 static void InitDscrs(struct net_device *dev)
 {
-	ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
+	ibmlana_priv *priv = netdev_priv(dev);
 	u32 addr, baddr, raddr;
 	int z;
 	tda_t tda;
@@ -240,8 +241,8 @@
 
 	/* initialize RAM */
 
-	isa_memset_io(dev->mem_start, 0xaa,
-		      dev->mem_start - dev->mem_start);
+	memset_io(priv->base, 0xaa,
+		      dev->mem_start - dev->mem_start);	/* XXX: typo? */
 
 	/* setup n TX descriptors - independent of RAM size */
 
@@ -260,7 +261,7 @@
 		else
 			tda.link = addr + sizeof(tda_t);
 		tda.link |= 1;
-		isa_memcpy_toio(dev->mem_start + addr, &tda, sizeof(tda_t));
+		memcpy_toio(priv->base + addr, &tda, sizeof(tda_t));
 		addr += sizeof(tda_t);
 		baddr += PKTSIZE;
 	}
@@ -280,7 +281,7 @@
 		rra.starthi = 0;
 		rra.cntlo = PKTSIZE >> 1;
 		rra.cnthi = 0;
-		isa_memcpy_toio(dev->mem_start + raddr, &rra, sizeof(rra_t));
+		memcpy_toio(priv->base + raddr, &rra, sizeof(rra_t));
 
 		rda.status = 0;
 		rda.length = 0;
@@ -292,7 +293,7 @@
 		else
 			rda.link = 1;
 		rda.inuse = 1;
-		isa_memcpy_toio(dev->mem_start + addr, &rda, sizeof(rda_t));
+		memcpy_toio(priv->base + addr, &rda, sizeof(rda_t));
 
 		baddr += PKTSIZE;
 		raddr += sizeof(rra_t);
@@ -313,7 +314,7 @@
 
 static int InitSONIC(struct net_device *dev)
 {
-	ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
+	ibmlana_priv *priv = netdev_priv(dev);
 
 	/* set up start & end of resource area */
 
@@ -379,6 +380,7 @@
 
 static void InitBoard(struct net_device *dev)
 {
+	ibmlana_priv *priv = netdev_priv(dev);
 	int camcnt;
 	camentry_t cams[16];
 	u32 cammask;
@@ -429,8 +431,8 @@
 
 	/* feed CDA into SONIC, initialize RCR value (always get broadcasts) */
 
-	isa_memcpy_toio(dev->mem_start, cams, sizeof(camentry_t) * camcnt);
-	isa_memcpy_toio(dev->mem_start + (sizeof(camentry_t) * camcnt), &cammask, sizeof(cammask));
+	memcpy_toio(priv->base, cams, sizeof(camentry_t) * camcnt);
+	memcpy_toio(priv->base + (sizeof(camentry_t) * camcnt), &cammask, sizeof(cammask));
 
 #ifdef DEBUG
 	printk("CAM setup:\n");
@@ -520,7 +522,7 @@
 
 static void StartTx(struct net_device *dev, int descr)
 {
-	ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
+	ibmlana_priv *priv = netdev_priv(dev);
 	int addr;
 
 	addr = priv->tdastart + (descr * sizeof(tda_t));
@@ -543,7 +545,7 @@
 
 static void irqrbe_handler(struct net_device *dev)
 {
-	ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
+	ibmlana_priv *priv = netdev_priv(dev);
 
 	/* point the SONIC back to the RRA start */
 
@@ -555,7 +557,7 @@
 
 static void irqrx_handler(struct net_device *dev)
 {
-	ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
+	ibmlana_priv *priv = netdev_priv(dev);
 	rda_t rda;
 	u32 rdaaddr, lrdaaddr;
 
@@ -566,7 +568,7 @@
 
 		rdaaddr = priv->rdastart + (priv->nextrxdescr * sizeof(rda_t));
 		lrdaaddr = priv->rdastart + (priv->lastrxdescr * sizeof(rda_t));
-		isa_memcpy_fromio(&rda, dev->mem_start + rdaaddr, sizeof(rda_t));
+		memcpy_fromio(&rda, priv->base + rdaaddr, sizeof(rda_t));
 
 		/* iron out upper word halves of fields we use - SONIC will duplicate 
 		   bits 0..15 to 16..31 */
@@ -593,8 +595,8 @@
 			else {
 				/* copy out data */
 
-				isa_memcpy_fromio(skb_put(skb, rda.length),
-					       dev->mem_start +
+				memcpy_fromio(skb_put(skb, rda.length),
+					       priv->base +
 					       rda.startlo, rda.length);
 
 				/* set up skb fields */
@@ -627,14 +629,14 @@
 
 		rda.link = 1;
 		rda.inuse = 1;
-		isa_memcpy_toio(dev->mem_start + rdaaddr, &rda,
+		memcpy_toio(priv->base + rdaaddr, &rda,
 			     sizeof(rda_t));
 
 		/* set up link and EOL = 0 in currently last descriptor. Only write
 		   the link field since the SONIC may currently already access the
 		   other fields. */
 
-		isa_memcpy_toio(dev->mem_start + lrdaaddr + 20, &rdaaddr, 4);
+		memcpy_toio(priv->base + lrdaaddr + 20, &rdaaddr, 4);
 
 		/* advance indices */
 
@@ -648,11 +650,11 @@
 
 static void irqtx_handler(struct net_device *dev)
 {
-	ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
+	ibmlana_priv *priv = netdev_priv(dev);
 	tda_t tda;
 
 	/* fetch descriptor (we forgot the size ;-) */
-	isa_memcpy_fromio(&tda, dev->mem_start + priv->tdastart + (priv->currtxdescr * sizeof(tda_t)), sizeof(tda_t));
+	memcpy_fromio(&tda, priv->base + priv->tdastart + (priv->currtxdescr * sizeof(tda_t)), sizeof(tda_t));
 
 	/* update statistics */
 	priv->stat.tx_packets++;
@@ -672,11 +674,11 @@
 
 static void irqtxerr_handler(struct net_device *dev)
 {
-	ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
+	ibmlana_priv *priv = netdev_priv(dev);
 	tda_t tda;
 
 	/* fetch descriptor to check status */
-	isa_memcpy_fromio(&tda, dev->mem_start + priv->tdastart + (priv->currtxdescr * sizeof(tda_t)), sizeof(tda_t));
+	memcpy_fromio(&tda, priv->base + priv->tdastart + (priv->currtxdescr * sizeof(tda_t)), sizeof(tda_t));
 
 	/* update statistics */
 	priv->stat.tx_errors++;
@@ -753,9 +755,7 @@
 
 	if (dev == NULL)
 		return len;
-	if (dev->priv == NULL)
-		return len;
-	priv = (ibmlana_priv *) dev->priv;
+	priv = netdev_priv(dev);
 
 	/* print info */
 
@@ -778,7 +778,7 @@
 static int ibmlana_open(struct net_device *dev)
 {
 	int result;
-	ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
+	ibmlana_priv *priv = netdev_priv(dev);
 
 	/* register resources - only necessary for IRQ */
 
@@ -814,7 +814,7 @@
 
 static int ibmlana_tx(struct sk_buff *skb, struct net_device *dev)
 {
-	ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
+	ibmlana_priv *priv = netdev_priv(dev);
 	int retval = 0, tmplen, addr;
 	unsigned long flags;
 	tda_t tda;
@@ -834,7 +834,7 @@
 	if (tmplen < 60)
 		tmplen = 60;
 	baddr = priv->txbufstart + (priv->nexttxdescr * PKTSIZE);
-	isa_memcpy_toio(dev->mem_start + baddr, skb->data, skb->len);
+	memcpy_toio(priv->base + baddr, skb->data, skb->len);
 
 	/* copy filler into RAM - in case we're filling up... 
 	   we're filling a bit more than necessary, but that doesn't harm
@@ -846,16 +846,16 @@
 		unsigned int destoffs = skb->len, l = strlen(fill);
 
 		while (destoffs < tmplen) {
-			isa_memcpy_toio(dev->mem_start + baddr + destoffs, fill, l);
+			memcpy_toio(priv->base + baddr + destoffs, fill, l);
 			destoffs += l;
 		}
 	}
 
 	/* set up the new frame descriptor */
 	addr = priv->tdastart + (priv->nexttxdescr * sizeof(tda_t));
-	isa_memcpy_fromio(&tda, dev->mem_start + addr, sizeof(tda_t));
+	memcpy_fromio(&tda, priv->base + addr, sizeof(tda_t));
 	tda.length = tda.fraglength = tmplen;
-	isa_memcpy_toio(dev->mem_start + addr, &tda, sizeof(tda_t));
+	memcpy_toio(priv->base + addr, &tda, sizeof(tda_t));
 
 	/* if there were no active descriptors, trigger the SONIC */
 	spin_lock_irqsave(&priv->lock, flags);
@@ -881,7 +881,7 @@
 
 static struct net_device_stats *ibmlana_stats(struct net_device *dev)
 {
-	ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
+	ibmlana_priv *priv = netdev_priv(dev);
 	return &priv->stat;
 }
 
@@ -903,7 +903,6 @@
 
 static int ibmlana_probe(struct net_device *dev)
 {
-	int force_detect = 0;
 	int slot, z;
 	int base = 0, irq = 0, iobase = 0, memlen = 0;
 	ibmlana_priv *priv;
@@ -915,10 +914,6 @@
 	if (MCA_bus == 0)
 		return -ENODEV;
 
-	/* start address of 1 --> forced detection */
-	if (dev->mem_start == 1)
-		force_detect = 1;
-
 	base = dev->mem_start;
 	irq = dev->irq;
 
@@ -952,18 +947,12 @@
 		return -EBUSY;
 	}
 
-	/* make procfs entries */
-	mca_set_adapter_name(slot, "IBM LAN Adapter/A");
-	mca_set_adapter_procfn(slot, (MCA_ProcFn) ibmlana_getinfo, dev);
-
-	mca_mark_as_used(slot);
-
-	/* allocate structure */
-	priv = dev->priv;
+	priv = netdev_priv(dev);
 	priv->slot = slot;
 	priv->realirq = irq;
 	priv->medium = medium;
 	spin_lock_init(&priv->lock);
+		
 
 	/* set base + irq for this device (irq not allocated so far) */
 
@@ -972,6 +961,20 @@
 	dev->mem_end = base + memlen;
 	dev->base_addr = iobase;
 
+	priv->base = ioremap(base, memlen);
+	if (!priv->base) {
+		printk(KERN_ERR "%s: cannot remap memory!\n", DRV_NAME);
+		startslot = slot + 1;
+		release_region(iobase, IBM_LANA_IORANGE);
+		return -EBUSY;
+	}
+
+	/* make procfs entries */
+	mca_set_adapter_name(slot, "IBM LAN Adapter/A");
+	mca_set_adapter_procfn(slot, (MCA_ProcFn) ibmlana_getinfo, dev);
+
+	mca_mark_as_used(slot);
+
 	/* set methods */
 
 	dev->open = ibmlana_open;
@@ -1042,11 +1045,12 @@
 			break;
 		}
 		if (register_netdev(dev)) {
-			ibmlana_priv *priv = dev->priv;
+			ibmlana_priv *priv = netdev_priv(dev);
 			release_region(dev->base_addr, IBM_LANA_IORANGE);
 			mca_mark_as_unused(priv->slot);
 			mca_set_adapter_name(priv->slot, "");
 			mca_set_adapter_procfn(priv->slot, NULL, NULL);
+			iounmap(priv->base);
 			free_netdev(dev);
 			break;
 		}
@@ -1061,13 +1065,14 @@
 	for (z = 0; z < DEVMAX; z++) {
 		struct net_device *dev = moddevs[z];
 		if (dev) {
-			ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
+			ibmlana_priv *priv = netdev_priv(dev);
 			unregister_netdev(dev);
 			/*DeinitBoard(dev); */
 			release_region(dev->base_addr, IBM_LANA_IORANGE);
 			mca_mark_as_unused(priv->slot);
 			mca_set_adapter_name(priv->slot, "");
 			mca_set_adapter_procfn(priv->slot, NULL, NULL);
+			iounmap(priv->base);
 			free_netdev(dev);
 		}
 	}
diff -Nru a/drivers/net/ibmlana.h b/drivers/net/ibmlana.h
--- a/drivers/net/ibmlana.h	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/ibmlana.h	2005-03-07 12:09:08 -05:00
@@ -37,6 +37,7 @@
 		nexttxdescr,		/* last tx descriptor to be used    */
 		currtxdescr,		/* tx descriptor currently tx'ed    */
 		txused[TXBUFCNT];	/* busy flags                       */
+	void __iomem *base;
 	spinlock_t lock;
 } ibmlana_priv;
 
diff -Nru a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
--- a/drivers/net/irda/donauboe.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/irda/donauboe.c	2005-03-07 12:09:08 -05:00
@@ -1712,7 +1712,7 @@
 }
 
 static int
-toshoboe_gotosleep (struct pci_dev *pci_dev, u32 crap)
+toshoboe_gotosleep (struct pci_dev *pci_dev, pm_message_t crap)
 {
   struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
   unsigned long flags;
diff -Nru a/drivers/net/mii.c b/drivers/net/mii.c
--- a/drivers/net/mii.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/mii.c	2005-03-07 12:09:08 -05:00
@@ -37,6 +37,7 @@
 {
 	struct net_device *dev = mii->dev;
 	u32 advert, bmcr, lpa, nego;
+	u32 advert2 = 0, bmcr2 = 0, lpa2 = 0;
 
 	ecmd->supported =
 	    (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
@@ -54,6 +55,9 @@
 
 	ecmd->advertising = ADVERTISED_TP | ADVERTISED_MII;
 	advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE);
+	if (mii->supports_gmii)
+		advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
+
 	if (advert & ADVERTISE_10HALF)
 		ecmd->advertising |= ADVERTISED_10baseT_Half;
 	if (advert & ADVERTISE_10FULL)
@@ -62,19 +66,31 @@
 		ecmd->advertising |= ADVERTISED_100baseT_Half;
 	if (advert & ADVERTISE_100FULL)
 		ecmd->advertising |= ADVERTISED_100baseT_Full;
+	if (advert2 & ADVERTISE_1000HALF)
+		ecmd->advertising |= ADVERTISED_1000baseT_Half;
+	if (advert2 & ADVERTISE_1000FULL)
+		ecmd->advertising |= ADVERTISED_1000baseT_Full;
 
 	bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
 	lpa = mii->mdio_read(dev, mii->phy_id, MII_LPA);
+	if (mii->supports_gmii) {
+		bmcr2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
+		lpa2 = mii->mdio_read(dev, mii->phy_id, MII_STAT1000);
+	}
 	if (bmcr & BMCR_ANENABLE) {
 		ecmd->advertising |= ADVERTISED_Autoneg;
 		ecmd->autoneg = AUTONEG_ENABLE;
 		
 		nego = mii_nway_result(advert & lpa);
-		if (nego == LPA_100FULL || nego == LPA_100HALF)
+		if ((bmcr2 & (ADVERTISE_1000HALF | ADVERTISE_1000FULL)) & 
+		    (lpa2 >> 2))
+			ecmd->speed = SPEED_1000;
+		else if (nego == LPA_100FULL || nego == LPA_100HALF)
 			ecmd->speed = SPEED_100;
 		else
 			ecmd->speed = SPEED_10;
-		if (nego == LPA_100FULL || nego == LPA_10FULL) {
+		if ((lpa2 & LPA_1000FULL) || nego == LPA_100FULL ||
+		    nego == LPA_10FULL) {
 			ecmd->duplex = DUPLEX_FULL;
 			mii->full_duplex = 1;
 		} else {
@@ -84,7 +100,9 @@
 	} else {
 		ecmd->autoneg = AUTONEG_DISABLE;
 
-		ecmd->speed = (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10;
+		ecmd->speed = ((bmcr2 & BMCR_SPEED1000 && 
+				(bmcr & BMCR_SPEED100) == 0) ? SPEED_1000 :
+			       (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10);
 		ecmd->duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
 	}
 
@@ -97,7 +115,9 @@
 {
 	struct net_device *dev = mii->dev;
 
-	if (ecmd->speed != SPEED_10 && ecmd->speed != SPEED_100)
+	if (ecmd->speed != SPEED_10 && 
+	    ecmd->speed != SPEED_100 && 
+	    ecmd->speed != SPEED_1000)
 		return -EINVAL;
 	if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
 		return -EINVAL;
@@ -109,21 +129,30 @@
 		return -EINVAL;
 	if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE)
 		return -EINVAL;
+	if ((ecmd->speed == SPEED_1000) && (!mii->supports_gmii))
+		return -EINVAL;
 				  
 	/* ignore supported, maxtxpkt, maxrxpkt */
 	
 	if (ecmd->autoneg == AUTONEG_ENABLE) {
 		u32 bmcr, advert, tmp;
+		u32 advert2 = 0, tmp2 = 0;
 
 		if ((ecmd->advertising & (ADVERTISED_10baseT_Half |
 					  ADVERTISED_10baseT_Full |
 					  ADVERTISED_100baseT_Half |
-					  ADVERTISED_100baseT_Full)) == 0)
+					  ADVERTISED_100baseT_Full |
+					  ADVERTISED_1000baseT_Half |
+					  ADVERTISED_1000baseT_Full)) == 0)
 			return -EINVAL;
 
 		/* advertise only what has been requested */
 		advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE);
 		tmp = advert & ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
+		if (mii->supports_gmii) {
+			advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
+			tmp2 = advert2 & ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
+		}
 		if (ecmd->advertising & ADVERTISED_10baseT_Half)
 			tmp |= ADVERTISE_10HALF;
 		if (ecmd->advertising & ADVERTISED_10baseT_Full)
@@ -132,10 +161,18 @@
 			tmp |= ADVERTISE_100HALF;
 		if (ecmd->advertising & ADVERTISED_100baseT_Full)
 			tmp |= ADVERTISE_100FULL;
+		if (mii->supports_gmii) {
+			if (ecmd->advertising & ADVERTISED_1000baseT_Half)
+				advert2 |= ADVERTISE_1000HALF;
+			if (ecmd->advertising & ADVERTISED_1000baseT_Full)
+				advert2 |= ADVERTISE_1000FULL;
+		}
 		if (advert != tmp) {
 			mii->mdio_write(dev, mii->phy_id, MII_ADVERTISE, tmp);
 			mii->advertising = tmp;
 		}
+		if ((mii->supports_gmii) && (advert2 != tmp2))
+			mii->mdio_write(dev, mii->phy_id, MII_CTRL1000, tmp2);
 		
 		/* turn on autonegotiation, and force a renegotiate */
 		bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
@@ -148,8 +185,11 @@
 
 		/* turn off auto negotiation, set speed and duplexity */
 		bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
-		tmp = bmcr & ~(BMCR_ANENABLE | BMCR_SPEED100 | BMCR_FULLDPLX);
-		if (ecmd->speed == SPEED_100)
+		tmp = bmcr & ~(BMCR_ANENABLE | BMCR_SPEED100 | 
+			       BMCR_SPEED1000 | BMCR_FULLDPLX);
+		if (ecmd->speed == SPEED_1000)
+			tmp |= BMCR_SPEED1000;
+		else if (ecmd->speed == SPEED_100)
 			tmp |= BMCR_SPEED100;
 		if (ecmd->duplex == DUPLEX_FULL) {
 			tmp |= BMCR_FULLDPLX;
@@ -207,6 +247,7 @@
 {
 	unsigned int old_carrier, new_carrier;
 	int advertise, lpa, media, duplex;
+	int lpa2 = 0;
 
 	/* if forced media, go no further */
 	if (mii->force_media)
@@ -243,16 +284,20 @@
 		mii->advertising = advertise;
 	}
 	lpa = mii->mdio_read(mii->dev, mii->phy_id, MII_LPA);
+	if (mii->supports_gmii)
+		lpa2 = mii->mdio_read(mii->dev, mii->phy_id, MII_STAT1000);
 
 	/* figure out media and duplex from advertise and LPA values */
 	media = mii_nway_result(lpa & advertise);
 	duplex = (media & ADVERTISE_FULL) ? 1 : 0;
+	if (lpa2 & LPA_1000FULL)
+		duplex = 1;
 
 	if (ok_to_print)
 		printk(KERN_INFO "%s: link up, %sMbps, %s-duplex, lpa 0x%04X\n",
 		       mii->dev->name,
-		       media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ?
-		       		"100" : "10",
+		       lpa2 & (LPA_1000FULL | LPA_1000HALF) ? "1000" :
+		       media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? "100" : "10",
 		       duplex ? "full" : "half",
 		       lpa);
 
diff -Nru a/drivers/net/natsemi.c b/drivers/net/natsemi.c
--- a/drivers/net/natsemi.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/natsemi.c	2005-03-07 12:09:08 -05:00
@@ -3162,7 +3162,7 @@
  * Interrupts must be disabled, otherwise hands_off can cause irq storms.
  */
 
-static int natsemi_suspend (struct pci_dev *pdev, u32 state)
+static int natsemi_suspend (struct pci_dev *pdev, pm_message_t state)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
 	struct netdev_private *np = netdev_priv(dev);
diff -Nru a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
--- a/drivers/net/ne2k-pci.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/ne2k-pci.c	2005-03-07 12:09:08 -05:00
@@ -654,13 +654,13 @@
 }
 
 #ifdef CONFIG_PM
-static int ne2k_pci_suspend (struct pci_dev *pdev, u32 state)
+static int ne2k_pci_suspend (struct pci_dev *pdev, pm_message_t state)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
 
 	netif_device_detach(dev);
 	pci_save_state(pdev);
-	pci_set_power_state(pdev, state);
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
 
 	return 0;
 }
diff -Nru a/drivers/net/s2io.c b/drivers/net/s2io.c
--- a/drivers/net/s2io.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/s2io.c	2005-03-07 12:09:08 -05:00
@@ -699,8 +699,7 @@
 	val64 = 0;
 	writeq(val64, &bar0->sw_reset);
 	val64 = readq(&bar0->sw_reset);
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ / 2);
+	msleep(500);
 
 	/*  Enable Receiving broadcasts */
 	add = &bar0->mac_cfg;
@@ -953,8 +952,7 @@
 				  dev->name);
 			return -1;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HZ / 20);
+		msleep(50);
 		time++;
 	}
 
@@ -992,8 +990,7 @@
 			return -1;
 		}
 		time++;
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HZ / 20);
+		msleep(50);
 	}
 
 	/* 
@@ -1422,8 +1419,7 @@
 	SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_mrs, UF);
 	val64 = readq(&bar0->mc_rldram_mrs);
 
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ / 10);	/* Delay by around 100 ms. */
+	msleep(100);			/* Delay by around 100 ms. */
 
 	/* Enabling ECC Protection. */
 	val64 = readq(&bar0->adapter_control);
@@ -2438,8 +2434,7 @@
 			ret = SUCCESS;
 			break;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HZ / 20);
+		msleep(50);
 		if (cnt++ > 10)
 			break;
 	}
@@ -2478,15 +2473,13 @@
 	 * As of now I'am just giving a 250ms delay and hoping that the
 	 * PCI write to sw_reset register is done by this time.
 	 */
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ / 4);
+	msleep(250);
 
 	/* Restore the PCI state saved during initializarion. */
 	pci_restore_state(sp->pdev);
 	s2io_init_pci(sp);
 
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ / 4);
+	msleep(250);
 
 	/* SXE-002: Configure link and activity LED to turn it off */
 	subid = sp->pdev->subsystem_device;
@@ -3304,11 +3297,10 @@
 		sp->id_timer.data = (unsigned long) sp;
 	}
 	mod_timer(&sp->id_timer, jiffies);
-	set_current_state(TASK_INTERRUPTIBLE);
 	if (data)
-		schedule_timeout(data * HZ);
+		msleep(data * 1000);
 	else
-		schedule_timeout(MAX_SCHEDULE_TIMEOUT);
+		msleep(0xFFFFFFFF);
 	del_timer_sync(&sp->id_timer);
 
 	if (CARDS_WITH_FAULTY_LINK_INDICATORS(subid)) {
@@ -3411,8 +3403,7 @@
 			ret = 0;
 			break;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HZ / 20);
+		msleep(50);
 		exit_cnt++;
 	}
 
@@ -3452,8 +3443,7 @@
 				ret = 0;
 			break;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HZ / 20);
+		msleep(50);
 		exit_cnt++;
 	}
 
@@ -3709,8 +3699,7 @@
 			ret = 0;
 			break;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HZ / 10);
+		msleep(100);
 		cnt++;
 	}
 
@@ -3811,8 +3800,7 @@
 			val64 = readq(&bar0->mc_rldram_test_ctrl);
 			if (val64 & MC_RLDRAM_TEST_DONE)
 				break;
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(HZ / 5);
+			msleep(200);
 		}
 
 		if (cnt == 5)
@@ -3828,8 +3816,7 @@
 			val64 = readq(&bar0->mc_rldram_test_ctrl);
 			if (val64 & MC_RLDRAM_TEST_DONE)
 				break;
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(HZ / 2);
+			msleep(500);
 		}
 
 		if (cnt == 5)
@@ -4189,8 +4176,7 @@
 	 * Allow a small delay for the NICs self initiated 
 	 * cleanup to complete.
 	 */
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ / 10);
+	msleep(100);
 
 	val64 = readq(&bar0->adapter_status);
 	if (verify_xena_quiescence(val64, nic->device_enabled_once)) {
@@ -4244,10 +4230,8 @@
 	register u64 val64 = 0;
 
 	/* If s2io_set_link task is executing, wait till it completes. */
-	while (test_and_set_bit(0, &(sp->link_state))) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HZ / 20);
-	}
+	while (test_and_set_bit(0, &(sp->link_state)))
+		msleep(50);
 	atomic_set(&sp->card_state, CARD_DOWN);
 
 	/* disable Tx and Rx traffic on the NIC */
@@ -4263,8 +4247,7 @@
 			break;
 		}
 
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HZ / 20);
+		msleep(50);
 		cnt++;
 		if (cnt == 10) {
 			DBG_PRINT(ERR_DBG,
diff -Nru a/drivers/net/sis900.c b/drivers/net/sis900.c
--- a/drivers/net/sis900.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/sis900.c	2005-03-07 12:09:08 -05:00
@@ -2226,7 +2226,7 @@
 
 #ifdef CONFIG_PM
 
-static int sis900_suspend(struct pci_dev *pci_dev, u32 state)
+static int sis900_suspend(struct pci_dev *pci_dev, pm_message_t state)
 {
 	struct net_device *net_dev = pci_get_drvdata(pci_dev);
 	long ioaddr = net_dev->base_addr;
diff -Nru a/drivers/net/sk_mca.c b/drivers/net/sk_mca.c
--- a/drivers/net/sk_mca.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/sk_mca.c	2005-03-07 12:09:08 -05:00
@@ -127,12 +127,13 @@
 #ifdef DEBUG
 static void dumpmem(struct net_device *dev, u32 start, u32 len)
 {
+	skmca_priv *priv = netdev_priv(dev);
 	int z;
 
 	for (z = 0; z < len; z++) {
 		if ((z & 15) == 0)
 			printk("%04x:", z);
-		printk(" %02x", SKMCA_READB(dev->mem_start + start + z));
+		printk(" %02x", readb(priv->base + start + z));
 		if ((z & 15) == 15)
 			printk("\n");
 	}
@@ -220,21 +221,21 @@
 
 static void ResetBoard(struct net_device *dev)
 {
-	skmca_priv *priv = (skmca_priv *) dev->priv;
+	skmca_priv *priv = netdev_priv(dev);
 
-	SKMCA_WRITEB(CTRL_RESET_ON, priv->ctrladdr);
+	writeb(CTRL_RESET_ON, priv->ctrladdr);
 	udelay(10);
-	SKMCA_WRITEB(CTRL_RESET_OFF, priv->ctrladdr);
+	writeb(CTRL_RESET_OFF, priv->ctrladdr);
 }
 
 /* wait for LANCE interface to become not busy */
 
 static int WaitLANCE(struct net_device *dev)
 {
-	skmca_priv *priv = (skmca_priv *) dev->priv;
+	skmca_priv *priv = netdev_priv(dev);
 	int t = 0;
 
-	while ((SKMCA_READB(priv->ctrladdr) & STAT_IO_BUSY) ==
+	while ((readb(priv->ctrladdr) & STAT_IO_BUSY) ==
 	       STAT_IO_BUSY) {
 		udelay(1);
 		if (++t > 1000) {
@@ -250,7 +251,7 @@
 
 static void SetLANCE(struct net_device *dev, u16 addr, u16 value)
 {
-	skmca_priv *priv = (skmca_priv *) dev->priv;
+	skmca_priv *priv = netdev_priv(dev);
 	unsigned long flags;
 
 	/* disable interrupts */
@@ -263,19 +264,17 @@
 
 	/* transfer register address to RAP */
 
-	SKMCA_WRITEB(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_RAP,
-		     priv->ctrladdr);
-	SKMCA_WRITEW(addr, priv->ioregaddr);
-	SKMCA_WRITEB(IOCMD_GO, priv->cmdaddr);
+	writeb(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_RAP, priv->ctrladdr);
+	writew(addr, priv->ioregaddr);
+	writeb(IOCMD_GO, priv->cmdaddr);
 	udelay(1);
 	WaitLANCE(dev);
 
 	/* transfer data to register */
 
-	SKMCA_WRITEB(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_DATA,
-		     priv->ctrladdr);
-	SKMCA_WRITEW(value, priv->ioregaddr);
-	SKMCA_WRITEB(IOCMD_GO, priv->cmdaddr);
+	writeb(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_DATA, priv->ctrladdr);
+	writew(value, priv->ioregaddr);
+	writeb(IOCMD_GO, priv->cmdaddr);
 	udelay(1);
 	WaitLANCE(dev);
 
@@ -288,7 +287,7 @@
 
 static u16 GetLANCE(struct net_device *dev, u16 addr)
 {
-	skmca_priv *priv = (skmca_priv *) dev->priv;
+	skmca_priv *priv = netdev_priv(dev);
 	unsigned long flags;
 	unsigned int res;
 
@@ -302,21 +301,19 @@
 
 	/* transfer register address to RAP */
 
-	SKMCA_WRITEB(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_RAP,
-		     priv->ctrladdr);
-	SKMCA_WRITEW(addr, priv->ioregaddr);
-	SKMCA_WRITEB(IOCMD_GO, priv->cmdaddr);
+	writeb(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_RAP, priv->ctrladdr);
+	writew(addr, priv->ioregaddr);
+	writeb(IOCMD_GO, priv->cmdaddr);
 	udelay(1);
 	WaitLANCE(dev);
 
 	/* transfer data from register */
 
-	SKMCA_WRITEB(CTRL_RESET_OFF | CTRL_RW_READ | CTRL_ADR_DATA,
-		     priv->ctrladdr);
-	SKMCA_WRITEB(IOCMD_GO, priv->cmdaddr);
+	writeb(CTRL_RESET_OFF | CTRL_RW_READ | CTRL_ADR_DATA, priv->ctrladdr);
+	writeb(IOCMD_GO, priv->cmdaddr);
 	udelay(1);
 	WaitLANCE(dev);
-	res = SKMCA_READW(priv->ioregaddr);
+	res = readw(priv->ioregaddr);
 
 	/* reenable interrupts */
 
@@ -329,6 +326,7 @@
 
 static void InitDscrs(struct net_device *dev)
 {
+	skmca_priv *priv = netdev_priv(dev);
 	u32 bufaddr;
 
 	/* Set up Tx descriptors. The board has only 16K RAM so bits 16..23
@@ -344,11 +342,10 @@
 			descr.Flags = 0;
 			descr.Len = 0xf000;
 			descr.Status = 0;
-			SKMCA_TOIO(dev->mem_start + RAM_TXBASE +
+			memcpy_toio(priv->base + RAM_TXBASE +
 				   (z * sizeof(LANCE_TxDescr)), &descr,
 				   sizeof(LANCE_TxDescr));
-			SKMCA_SETIO(dev->mem_start + bufaddr, 0,
-				    RAM_BUFSIZE);
+			memset_io(priv->base + bufaddr, 0, RAM_BUFSIZE);
 			bufaddr += RAM_BUFSIZE;
 		}
 	}
@@ -364,11 +361,10 @@
 			descr.Flags = RXDSCR_FLAGS_OWN;
 			descr.MaxLen = -RAM_BUFSIZE;
 			descr.Len = 0;
-			SKMCA_TOIO(dev->mem_start + RAM_RXBASE +
+			memcpy_toio(priv->base + RAM_RXBASE +
 				   (z * sizeof(LANCE_RxDescr)), &descr,
 				   sizeof(LANCE_RxDescr));
-			SKMCA_SETIO(dev->mem_start + bufaddr, 0,
-				    RAM_BUFSIZE);
+			memset_io(priv->base + bufaddr, 0, RAM_BUFSIZE);
 			bufaddr += RAM_BUFSIZE;
 		}
 	}
@@ -425,7 +421,7 @@
 
 static void InitLANCE(struct net_device *dev)
 {
-	skmca_priv *priv = (skmca_priv *) dev->priv;
+	skmca_priv *priv = netdev_priv(dev);
 
 	/* build up descriptors. */
 
@@ -478,6 +474,7 @@
 
 static void InitBoard(struct net_device *dev)
 {
+	skmca_priv *priv = netdev_priv(dev);
 	LANCE_InitBlock block;
 
 	/* Lay out the shared RAM - first we create the init block for the LANCE.
@@ -492,7 +489,7 @@
 	block.RdrP = (RAM_RXBASE & 0xffffff) | (LRXCOUNT << 29);
 	block.TdrP = (RAM_TXBASE & 0xffffff) | (LTXCOUNT << 29);
 
-	SKMCA_TOIO(dev->mem_start + RAM_INITBASE, &block, sizeof(block));
+	memcpy_toio(priv->base + RAM_INITBASE, &block, sizeof(block));
 
 	/* initialize LANCE. Implicitly sets up other structures in RAM. */
 
@@ -572,7 +569,7 @@
 
 static u16 irqmiss_handler(struct net_device *dev, u16 oldcsr0)
 {
-	skmca_priv *priv = (skmca_priv *) dev->priv;
+	skmca_priv *priv = netdev_priv(dev);
 
 	/* update statistics */
 
@@ -588,7 +585,7 @@
 
 static u16 irqrx_handler(struct net_device *dev, u16 oldcsr0)
 {
-	skmca_priv *priv = (skmca_priv *) dev->priv;
+	skmca_priv *priv = netdev_priv(dev);
 	LANCE_RxDescr descr;
 	unsigned int descraddr;
 
@@ -597,7 +594,7 @@
 	descraddr = RAM_RXBASE + (priv->nextrx * sizeof(LANCE_RxDescr));
 	while (1) {
 		/* read descriptor */
-		SKMCA_FROMIO(&descr, dev->mem_start + descraddr,
+		memcpy_fromio(&descr, priv->base + descraddr,
 			     sizeof(LANCE_RxDescr));
 
 		/* if we reach a descriptor we do not own, we're done */
@@ -629,8 +626,8 @@
 			if (skb == NULL)
 				priv->stat.rx_dropped++;
 			else {
-				SKMCA_FROMIO(skb_put(skb, descr.Len),
-					     dev->mem_start +
+				memcpy_fromio(skb_put(skb, descr.Len),
+					     priv->base +
 					     descr.LowAddr, descr.Len);
 				skb->dev = dev;
 				skb->protocol = eth_type_trans(skb, dev);
@@ -647,7 +644,7 @@
 		descr.Flags |= RXDSCR_FLAGS_OWN;
 
 		/* update descriptor in shared RAM */
-		SKMCA_TOIO(dev->mem_start + descraddr, &descr,
+		memcpy_toio(priv->base + descraddr, &descr,
 			   sizeof(LANCE_RxDescr));
 
 		/* go to next descriptor */
@@ -669,7 +666,7 @@
 
 static u16 irqtx_handler(struct net_device *dev, u16 oldcsr0)
 {
-	skmca_priv *priv = (skmca_priv *) dev->priv;
+	skmca_priv *priv = netdev_priv(dev);
 	LANCE_TxDescr descr;
 	unsigned int descraddr;
 
@@ -679,7 +676,7 @@
 	    RAM_TXBASE + (priv->nexttxdone * sizeof(LANCE_TxDescr));
 	while (priv->txbusy > 0) {
 		/* read descriptor */
-		SKMCA_FROMIO(&descr, dev->mem_start + descraddr,
+		memcpy_fromio(&descr, priv->base + descraddr,
 			     sizeof(LANCE_TxDescr));
 
 		/* if the LANCE still owns this one, we've worked out all sent packets */
@@ -798,9 +795,7 @@
 
 	if (dev == NULL)
 		return len;
-	if (dev->priv == NULL)
-		return len;
-	priv = (skmca_priv *) dev->priv;
+	priv = netdev_priv(dev);
 
 	/* print info */
 
@@ -825,7 +820,7 @@
 static int skmca_open(struct net_device *dev)
 {
 	int result;
-	skmca_priv *priv = (skmca_priv *) dev->priv;
+	skmca_priv *priv = netdev_priv(dev);
 
 	/* register resources - only necessary for IRQ */
 	result =
@@ -868,7 +863,7 @@
 
 static int skmca_tx(struct sk_buff *skb, struct net_device *dev)
 {
-	skmca_priv *priv = (skmca_priv *) dev->priv;
+	skmca_priv *priv = netdev_priv(dev);
 	LANCE_TxDescr descr;
 	unsigned int address;
 	int tmplen, retval = 0;
@@ -894,8 +889,7 @@
 
 	/* get TX descriptor */
 	address = RAM_TXBASE + (priv->nexttxput * sizeof(LANCE_TxDescr));
-	SKMCA_FROMIO(&descr, dev->mem_start + address,
-		     sizeof(LANCE_TxDescr));
+	memcpy_fromio(&descr, priv->base + address, sizeof(LANCE_TxDescr));
 
 	/* enter packet length as 2s complement - assure minimum length */
 	tmplen = skb->len;
@@ -911,14 +905,14 @@
 		unsigned int destoffs = 0, l = strlen(fill);
 
 		while (destoffs < tmplen) {
-			SKMCA_TOIO(dev->mem_start + descr.LowAddr +
+			memcpy_toio(priv->base + descr.LowAddr +
 				   destoffs, fill, l);
 			destoffs += l;
 		}
 	}
 
 	/* do the real data copying */
-	SKMCA_TOIO(dev->mem_start + descr.LowAddr, skb->data, skb->len);
+	memcpy_toio(priv->base + descr.LowAddr, skb->data, skb->len);
 
 	/* hand descriptor over to LANCE - this is the first and last chunk */
 	descr.Flags =
@@ -945,8 +939,7 @@
 		netif_stop_queue(dev);
 
 	/* write descriptor back to RAM */
-	SKMCA_TOIO(dev->mem_start + address, &descr,
-		   sizeof(LANCE_TxDescr));
+	memcpy_toio(priv->base + address, &descr, sizeof(LANCE_TxDescr));
 
 	/* if no descriptors were active, give the LANCE a hint to read it
 	   immediately */
@@ -967,7 +960,7 @@
 
 static struct net_device_stats *skmca_stats(struct net_device *dev)
 {
-	skmca_priv *priv = (skmca_priv *) dev->priv;
+	skmca_priv *priv = netdev_priv(dev);
 
 	return &(priv->stat);
 }
@@ -977,13 +970,14 @@
 
 static void skmca_set_multicast_list(struct net_device *dev)
 {
+	skmca_priv *priv = netdev_priv(dev);
 	LANCE_InitBlock block;
 
 	/* first stop the LANCE... */
 	StopLANCE(dev);
 
 	/* ...then modify the initialization block... */
-	SKMCA_FROMIO(&block, dev->mem_start + RAM_INITBASE, sizeof(block));
+	memcpy_fromio(&block, priv->base + RAM_INITBASE, sizeof(block));
 	if (dev->flags & IFF_PROMISC)
 		block.Mode |= LANCE_INIT_PROM;
 	else
@@ -1003,7 +997,7 @@
 		}
 	}
 
-	SKMCA_TOIO(dev->mem_start + RAM_INITBASE, &block, sizeof(block));
+	memcpy_toio(priv->base + RAM_INITBASE, &block, sizeof(block));
 
 	/* ...then reinit LANCE with the correct flags */
 	InitLANCE(dev);
@@ -1017,10 +1011,11 @@
 
 static void cleanup_card(struct net_device *dev)
 {
-	skmca_priv *priv = dev->priv;
+	skmca_priv *priv = netdev_priv(dev);
 	DeinitBoard(dev);
 	if (dev->irq != 0)
 		free_irq(dev->irq, dev);
+	iounmap(priv->base);
 	mca_mark_as_unused(priv->slot);
 	mca_set_adapter_procfn(priv->slot, NULL, NULL);
 }
@@ -1104,13 +1099,20 @@
 	printk("%s: SKNet %s adapter found in slot %d\n", dev->name,
 	       junior ? "Junior MC2" : "MC2+", slot + 1);
 
-	/* allocate structure */
-	priv = dev->priv;
+	priv = netdev_priv(dev);
+	priv->base = ioremap(base, 0x4000);
+	if (!priv->base) {
+		mca_set_adapter_procfn(slot, NULL, NULL);
+		mca_mark_as_unused(slot);
+		free_netdev(dev);
+		return ERR_PTR(-ENOMEM);
+	}
+
 	priv->slot = slot;
-	priv->macbase = base + 0x3fc0;
-	priv->ioregaddr = base + 0x3ff0;
-	priv->ctrladdr = base + 0x3ff2;
-	priv->cmdaddr = base + 0x3ff3;
+	priv->macbase = priv->base + 0x3fc0;
+	priv->ioregaddr = priv->base + 0x3ff0;
+	priv->ctrladdr = priv->base + 0x3ff2;
+	priv->cmdaddr = priv->base + 0x3ff3;
 	priv->medium = medium;
 	memset(&priv->stat, 0, sizeof(struct net_device_stats));
 	spin_lock_init(&priv->lock);
@@ -1147,7 +1149,7 @@
 
 	/* copy out MAC address */
 	for (i = 0; i < 6; i++)
-		dev->dev_addr[i] = SKMCA_READB(priv->macbase + (i << 1));
+		dev->dev_addr[i] = readb(priv->macbase + (i << 1));
 
 	/* print config */
 	printk("%s: IRQ %d, memory %#lx-%#lx, "
diff -Nru a/drivers/net/sk_mca.h b/drivers/net/sk_mca.h
--- a/drivers/net/sk_mca.h	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/sk_mca.h	2005-03-07 12:09:08 -05:00
@@ -5,16 +5,6 @@
 
 #ifdef _SK_MCA_DRIVER_
 
-/* version-dependent functions/structures */
-
-#define SKMCA_READB(addr) isa_readb(addr)
-#define SKMCA_READW(addr) isa_readw(addr)
-#define SKMCA_WRITEB(data, addr) isa_writeb(data, addr)
-#define SKMCA_WRITEW(data, addr) isa_writew(data, addr)
-#define SKMCA_TOIO(dest, src, len) isa_memcpy_toio(dest, src, len)
-#define SKMCA_FROMIO(dest, src, len) isa_memcpy_fromio(dest, src, len)
-#define SKMCA_SETIO(dest, val, len) isa_memset_io(dest, val, len)
-
 /* Adapter ID's */
 #define SKNET_MCA_ID 0x6afd
 #define SKNET_JUNIOR_MCA_ID 0x6be9
@@ -29,10 +19,11 @@
 /* private structure */
 typedef struct {
 	unsigned int slot;	/* MCA-Slot-#                       */
-	unsigned int macbase;	/* base address of MAC address PROM */
-	unsigned int ioregaddr;	/* address of I/O-register (Lo)     */
-	unsigned int ctrladdr;	/* address of control/stat register */
-	unsigned int cmdaddr;	/* address of I/O-command register  */
+	void __iomem *base;
+	void __iomem *macbase;	/* base address of MAC address PROM */
+	void __iomem *ioregaddr;/* address of I/O-register (Lo)     */
+	void __iomem *ctrladdr;	/* address of control/stat register */
+	void __iomem *cmdaddr;	/* address of I/O-command register  */
 	int nextrx;		/* index of next RX descriptor to
 				   be read                          */
 	int nexttxput;		/* index of next free TX descriptor */
diff -Nru a/drivers/net/smc91x.h b/drivers/net/smc91x.h
--- a/drivers/net/smc91x.h	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/smc91x.h	2005-03-07 12:09:08 -05:00
@@ -182,6 +182,25 @@
 #define SMC_insl(a, r, p, l)	readsl((a) + (r), p, l)
 #define SMC_outsl(a, r, p, l)	writesl((a) + (r), p, l)
 
+#elif	defined(CONFIG_SH_SH4202_MICRODEV)
+
+#define SMC_CAN_USE_8BIT	0
+#define SMC_CAN_USE_16BIT	1
+#define SMC_CAN_USE_32BIT	0
+
+#define SMC_inb(a, r)		inb((a) + (r) - 0xa0000000)
+#define SMC_inw(a, r)		inw((a) + (r) - 0xa0000000)
+#define SMC_inl(a, r)		inl((a) + (r) - 0xa0000000)
+#define SMC_outb(v, a, r)	outb(v, (a) + (r) - 0xa0000000)
+#define SMC_outw(v, a, r)	outw(v, (a) + (r) - 0xa0000000)
+#define SMC_outl(v, a, r)	outl(v, (a) + (r) - 0xa0000000)
+#define SMC_insl(a, r, p, l)	insl((a) + (r) - 0xa0000000, p, l)
+#define SMC_outsl(a, r, p, l)	outsl((a) + (r) - 0xa0000000, p, l)
+#define SMC_insw(a, r, p, l)	insw((a) + (r) - 0xa0000000, p, l)
+#define SMC_outsw(a, r, p, l)	outsw((a) + (r) - 0xa0000000, p, l)
+
+#define set_irq_type(irq, type)	do {} while(0)
+
 #elif	defined(CONFIG_ISA)
 
 #define SMC_CAN_USE_8BIT	1
diff -Nru a/drivers/net/sundance.c b/drivers/net/sundance.c
--- a/drivers/net/sundance.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/sundance.c	2005-03-07 12:09:08 -05:00
@@ -1210,9 +1210,11 @@
 				}
 				/* Yup, this is a documentation bug.  It cost me *hours*. */
 				iowrite16 (0, ioaddr + TxStatus);
-				tx_status = ioread16 (ioaddr + TxStatus);
-				if (tx_cnt < 0)
+				if (tx_cnt < 0) {
+					iowrite32(5000, ioaddr + DownCounter);
 					break;
+				}
+				tx_status = ioread16 (ioaddr + TxStatus);
 			}
 			hw_frame_id = (tx_status >> 8) & 0xff;
 		} else 	{
@@ -1278,7 +1280,6 @@
 	if (netif_msg_intr(np))
 		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
 			   dev->name, ioread16(ioaddr + IntrStatus));
-	iowrite32(5000, ioaddr + DownCounter);
 	return IRQ_RETVAL(handled);
 }
 
diff -Nru a/drivers/net/sungem.c b/drivers/net/sungem.c
--- a/drivers/net/sungem.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/sungem.c	2005-03-07 12:09:08 -05:00
@@ -2356,7 +2356,7 @@
 }
 
 #ifdef CONFIG_PM
-static int gem_suspend(struct pci_dev *pdev, u32 state)
+static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct gem *gp = dev->priv;
diff -Nru a/drivers/net/tg3.c b/drivers/net/tg3.c
--- a/drivers/net/tg3.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/tg3.c	2005-03-07 12:09:08 -05:00
@@ -8948,7 +8948,7 @@
 	}
 }
 
-static int tg3_suspend(struct pci_dev *pdev, u32 state)
+static int tg3_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct tg3 *tp = netdev_priv(dev);
@@ -8975,7 +8975,7 @@
 	spin_unlock(&tp->tx_lock);
 	spin_unlock_irq(&tp->lock);
 
-	err = tg3_set_power_state(tp, state);
+	err = tg3_set_power_state(tp, pci_choose_state(pdev, state));
 	if (err) {
 		spin_lock_irq(&tp->lock);
 		spin_lock(&tp->tx_lock);
diff -Nru a/drivers/net/tg3.h b/drivers/net/tg3.h
--- a/drivers/net/tg3.h	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/tg3.h	2005-03-07 12:09:08 -05:00
@@ -1548,20 +1548,6 @@
 #define MII_TG3_INT_DUPLEXCHG		0x0008
 #define MII_TG3_INT_ANEG_PAGE_RX	0x0400
 
-/* XXX Add this to mii.h */
-#ifndef ADVERTISE_PAUSE
-#define ADVERTISE_PAUSE_CAP		0x0400
-#endif
-#ifndef ADVERTISE_PAUSE_ASYM
-#define ADVERTISE_PAUSE_ASYM		0x0800
-#endif
-#ifndef LPA_PAUSE
-#define LPA_PAUSE_CAP			0x0400
-#endif
-#ifndef LPA_PAUSE_ASYM
-#define LPA_PAUSE_ASYM			0x0800
-#endif
-
 /* There are two ways to manage the TX descriptors on the tigon3.
  * Either the descriptors are in host DMA'able memory, or they
  * exist only in the cards on-chip SRAM.  All 16 send bds are under
diff -Nru a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
--- a/drivers/net/tulip/tulip_core.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/tulip/tulip_core.c	2005-03-07 12:09:08 -05:00
@@ -1749,7 +1749,7 @@
 
 #ifdef CONFIG_PM
 
-static int tulip_suspend (struct pci_dev *pdev, u32 state)
+static int tulip_suspend (struct pci_dev *pdev, pm_message_t state)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 
diff -Nru a/drivers/net/typhoon.c b/drivers/net/typhoon.c
--- a/drivers/net/typhoon.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/typhoon.c	2005-03-07 12:09:08 -05:00
@@ -1874,7 +1874,7 @@
 }
 
 static int
-typhoon_sleep(struct typhoon *tp, int state, u16 events)
+typhoon_sleep(struct typhoon *tp, pci_power_t state, u16 events)
 {
 	struct pci_dev *pdev = tp->pdev;
 	void __iomem *ioaddr = tp->ioaddr;
@@ -2155,7 +2155,7 @@
 		goto out;
 	}
 
-	if(typhoon_sleep(tp, 3, 0) < 0) 
+	if(typhoon_sleep(tp, PCI_D3hot, 0) < 0) 
 		printk(KERN_ERR "%s: unable to go back to sleep\n", dev->name);
 
 out:
@@ -2182,7 +2182,7 @@
 	if(typhoon_boot_3XP(tp, TYPHOON_STATUS_WAITING_FOR_HOST) < 0)
 		printk(KERN_ERR "%s: unable to boot sleep image\n", dev->name);
 
-	if(typhoon_sleep(tp, 3, 0) < 0)
+	if(typhoon_sleep(tp, PCI_D3hot, 0) < 0)
 		printk(KERN_ERR "%s: unable to put card to sleep\n", dev->name);
 
 	return 0;
@@ -2222,7 +2222,7 @@
 }
 
 static int
-typhoon_suspend(struct pci_dev *pdev, u32 state)
+typhoon_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct typhoon *tp = netdev_priv(dev);
@@ -2532,7 +2532,7 @@
 	if(xp_resp[0].numDesc != 0)
 		tp->capabilities |= TYPHOON_WAKEUP_NEEDS_RESET;
 
-	if(typhoon_sleep(tp, 3, 0) < 0) {
+	if(typhoon_sleep(tp, PCI_D3hot, 0) < 0) {
 		printk(ERR_PFX "%s: cannot put adapter to sleep\n",
 		       pci_name(pdev));
 		err = -EIO;
diff -Nru a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
--- a/drivers/net/via-rhine.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/via-rhine.c	2005-03-07 12:09:08 -05:00
@@ -1937,7 +1937,7 @@
 }
 
 #ifdef CONFIG_PM
-static int rhine_suspend(struct pci_dev *pdev, u32 state)
+static int rhine_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct rhine_private *rp = netdev_priv(dev);
diff -Nru a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
--- a/drivers/net/via-velocity.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/via-velocity.c	2005-03-07 12:09:08 -05:00
@@ -263,7 +263,7 @@
 
 #ifdef CONFIG_PM
 
-static int velocity_suspend(struct pci_dev *pdev, u32 state);
+static int velocity_suspend(struct pci_dev *pdev, pm_message_t state);
 static int velocity_resume(struct pci_dev *pdev);
 
 static int velocity_netdev_event(struct notifier_block *nb, unsigned long notification, void *ptr);
@@ -3210,7 +3210,7 @@
 	return 0;
 }
 
-static int velocity_suspend(struct pci_dev *pdev, u32 state)
+static int velocity_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	struct velocity_info *vptr = pci_get_drvdata(pdev);
 	unsigned long flags;
diff -Nru a/drivers/net/wireless/arlan.h b/drivers/net/wireless/arlan.h
--- a/drivers/net/wireless/arlan.h	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/wireless/arlan.h	2005-03-07 12:09:08 -05:00
@@ -43,8 +43,8 @@
 extern int init_arlan_proc(void);
 extern void cleanup_arlan_proc(void);
 #else
-#define init_arlan_proc()	(0)
-#define cleanup_arlan_proc()	do { } while (0);
+#define init_arlan_proc()	({ 0; })
+#define cleanup_arlan_proc()	do { } while (0)
 #endif
 
 extern struct net_device *arlan_device[MAX_ARLANS];
diff -Nru a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
--- a/drivers/net/wireless/atmel.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/wireless/atmel.c	2005-03-07 12:09:08 -05:00
@@ -69,6 +69,7 @@
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
 #include "ieee802_11.h"
+#include "atmel.h"
 
 #define DRIVER_MAJOR 0
 #define DRIVER_MINOR 96
@@ -83,6 +84,23 @@
 static char *firmware = NULL;
 module_param(firmware, charp, 0);
 
+/* table of firmware file names */
+static struct { 
+	AtmelFWType fw_type;
+	const char *fw_file;
+	const char *fw_file_ext;
+} fw_table[] = {
+	{ ATMEL_FW_TYPE_502,      "atmel_at76c502",      "bin" },
+	{ ATMEL_FW_TYPE_502D,     "atmel_at76c502d",     "bin" },
+	{ ATMEL_FW_TYPE_502E,     "atmel_at76c502e",     "bin" },
+	{ ATMEL_FW_TYPE_502_3COM, "atmel_at76c502_3com", "bin" },
+	{ ATMEL_FW_TYPE_504,      "atmel_at76c504",      "bin" },
+	{ ATMEL_FW_TYPE_504_2958, "atmel_at76c504_2958", "bin" },
+	{ ATMEL_FW_TYPE_504A_2958,"atmel_at76c504a_2958","bin" },
+	{ ATMEL_FW_TYPE_506,      "atmel_at76c506",      "bin" },
+	{ ATMEL_FW_TYPE_NONE,      NULL,                  NULL }
+};
+
 #define MAX_SSID_LENGTH 32
 #define MGMT_JIFFIES (256 * HZ / 100)
 
@@ -458,8 +476,8 @@
 	void *card; /* Bus dependent stucture varies for PCcard */
 	int (*present_callback)(void *); /* And callback which uses it */
 	char firmware_id[32];
-	char firmware_template[32];
-	unsigned char *firmware;
+	AtmelFWType firmware_type;
+	u8 *firmware;
 	int firmware_length;
 	struct timer_list management_timer;
 	struct net_device *dev;
@@ -1293,17 +1311,21 @@
 	if (priv->operating_mode == IW_MODE_INFRA) {
 		if (priv->station_state != STATION_STATE_READY) {
 			priv->wstats.qual.qual = 0;
-			priv->wstats.qual.level	= 0;
+			priv->wstats.qual.level = 0;
+			priv->wstats.qual.updated = (IW_QUAL_QUAL_INVALID
+					| IW_QUAL_LEVEL_INVALID);
 		}
 		priv->wstats.qual.noise = 0;
-		priv->wstats.qual.updated = 7;
+		priv->wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
 	} else {
 		/* Quality levels cannot be determined in ad-hoc mode,
 		   because we can 'hear' more that one remote station. */
 		priv->wstats.qual.qual = 0;
 		priv->wstats.qual.level	= 0;
 		priv->wstats.qual.noise	= 0;
-		priv->wstats.qual.updated = 0;
+		priv->wstats.qual.updated = IW_QUAL_QUAL_INVALID
+					| IW_QUAL_LEVEL_INVALID
+					| IW_QUAL_NOISE_INVALID;
 		priv->wstats.miss.beacon = 0;
 	}
 	
@@ -1482,7 +1504,7 @@
         return len;
 }
 
-struct net_device *init_atmel_card( unsigned short irq, int port, char *firmware_id,  
+struct net_device *init_atmel_card( unsigned short irq, int port, const AtmelFWType fw_type,  
 				    struct device *sys_dev, int (*card_present)(void *), void *card)
 {
 	struct net_device *dev;
@@ -1507,11 +1529,9 @@
 	priv->card = card;
 	priv->firmware = NULL;
 	priv->firmware_id[0] = '\0';
-	priv->firmware_template[0] = '\0';
+	priv->firmware_type = fw_type;
 	if (firmware) /* module parameter */
 		strcpy(priv->firmware_id, firmware);
-	else if (firmware_id) /* from PCMCIA card-matching or PCI */
-		strcpy(priv->firmware_template, firmware_id);
 	priv->bus_type = card_present ? BUS_TYPE_PCCARD : BUS_TYPE_PCI;
 	priv->station_state = STATION_STATE_DOWN;
 	priv->do_rx_crc = 0;
@@ -1579,6 +1599,8 @@
 	dev->irq = irq;
 	dev->base_addr = port;
 	
+	SET_NETDEV_DEV(dev, sys_dev);
+	
 	if ((rc = request_irq(dev->irq, service_interrupt, SA_SHIRQ, dev->name, dev))) {
 		printk(KERN_ERR "%s: register interrupt %d failed, rc %d\n", dev->name, irq, rc );
 		goto err_out_free;
@@ -2218,6 +2240,13 @@
 	range->max_qual.qual = 100;
 	range->max_qual.level = 100;
 	range->max_qual.noise = 0;
+	range->max_qual.updated = IW_QUAL_NOISE_INVALID;
+
+	range->avg_qual.qual = 50;
+	range->avg_qual.level = 50;
+	range->avg_qual.noise = 0;
+	range->avg_qual.updated = IW_QUAL_NOISE_INVALID;
+
 	range->sensitivity = 0;
 
 	range->bitrate[0] =  1000000;
@@ -2247,9 +2276,6 @@
 	range->r_time_flags = 0;
 	range->min_retry = 1;
 	range->max_retry = 65535;
-	range->avg_qual.qual = 50;
-	range->avg_qual.level = 50;
-	range->avg_qual.noise = 0;
 
 	return 0;
 }
@@ -3025,16 +3051,23 @@
 static void smooth_rssi(struct atmel_private *priv, u8 rssi)
 {
 	u8 old = priv->wstats.qual.level;
+	u8 max_rssi = 42; /* 502-rmfd-revd max by experiment, default for now */
 
-	/* 502-rmfd-revd gives max signal level as 42, by experiment.
-	   This is going to break for other hardware variants. */
+	switch (priv->firmware_type) {
+		case ATMEL_FW_TYPE_502E:
+			max_rssi = 63; /* 502-rmfd-reve max by experiment */
+			break;
+		default:
+			break;
+	}
 
-	rssi = rssi * 100 / 42;
+	rssi = rssi * 100 / max_rssi;
 	if((rssi + old) % 2)
 		priv->wstats.qual.level =  ((rssi + old)/2) + 1;
 	else
 		priv->wstats.qual.level =  ((rssi + old)/2);		
-	
+	priv->wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
+	priv->wstats.qual.updated &= ~IW_QUAL_LEVEL_INVALID;
 }
 
 static void atmel_smooth_qual(struct atmel_private *priv)
@@ -3047,8 +3080,10 @@
 			priv->beacons_this_sec * priv->beacon_period * (priv->wstats.qual.level + 100) / 4000;
 		priv->beacons_this_sec = 0;
 	}
+	priv->wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
+	priv->wstats.qual.updated &= ~IW_QUAL_QUAL_INVALID;
 }
-	
+
 /* deals with incoming managment frames. */
 static void atmel_management_frame(struct atmel_private *priv, struct ieee802_11_hdr *header, 
 		      u16 frame_len, u8 rssi)
@@ -3611,8 +3646,8 @@
 		const struct firmware *fw_entry = NULL;
 		unsigned char *fw;
 		int len = priv->firmware_length;
-		if (!(fw = priv->firmware)) { 
-			if (strlen(priv->firmware_template) == 0) {	
+		if (!(fw = priv->firmware)) {
+			if (priv->firmware_type == ATMEL_FW_TYPE_NONE) {
 				if (strlen(priv->firmware_id) == 0) {
 					printk(KERN_INFO
 					       "%s: card type is unknown: assuming at76c502 firmware is OK.\n",
@@ -3627,24 +3662,36 @@
 					       "%s: firmware %s is missing, cannot continue.\n", 
 					       dev->name, priv->firmware_id);
 					return 0;
-					
-				} 
+				}
 			} else {
-				int i;
+				int fw_index = 0;
+				int success = 0;
+
+				/* get firmware filename entry based on firmware type ID */
+				while (fw_table[fw_index].fw_type != priv->firmware_type
+						&& fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE)
+					fw_index++;
 				
-				for (i = 0; firmware_modifier[i]; i++) {
-					sprintf(priv->firmware_id, priv->firmware_template, firmware_modifier[i]);
-					if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) == 0) 
-						break;
+				/* construct the actual firmware file name */
+				if (fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE) {
+					int i;
+					for (i = 0; firmware_modifier[i]; i++) {
+						snprintf(priv->firmware_id, 32, "%s%s.%s", fw_table[fw_index].fw_file,
+							firmware_modifier[i], fw_table[fw_index].fw_file_ext);
+						priv->firmware_id[31] = '\0';
+						if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) == 0) {
+							success = 1;
+							break;
+						}
+					}
 				}
-				if (!firmware_modifier[i]) {
+				if (!success) {
 					printk(KERN_ALERT 
 					       "%s: firmware %s is missing, cannot start.\n", 
 					       dev->name, priv->firmware_id);
 					priv->firmware_id[0] = '\0';
 					return 0;	
 				}
-				priv->firmware_template[0] = '\0';	
 			}
 			
 			fw = fw_entry->data;
diff -Nru a/drivers/net/wireless/atmel.h b/drivers/net/wireless/atmel.h
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/drivers/net/wireless/atmel.h	2005-03-07 12:09:08 -05:00
@@ -0,0 +1,43 @@
+/*** -*- linux-c -*- **********************************************************
+
+     Driver for Atmel at76c502 at76c504 and at76c506 wireless cards.
+
+         Copyright 2005 Dan Williams and Red Hat, Inc.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This software is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Atmel wireless lan drivers; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+******************************************************************************/
+
+#ifndef _ATMEL_H
+#define _ATMEL_H
+
+typedef enum {
+	ATMEL_FW_TYPE_NONE = 0,
+	ATMEL_FW_TYPE_502,
+	ATMEL_FW_TYPE_502D,
+	ATMEL_FW_TYPE_502E,
+	ATMEL_FW_TYPE_502_3COM,
+	ATMEL_FW_TYPE_504,
+	ATMEL_FW_TYPE_504_2958,
+	ATMEL_FW_TYPE_504A_2958,
+	ATMEL_FW_TYPE_506
+} AtmelFWType;
+
+struct net_device *init_atmel_card(unsigned short, int, const AtmelFWType, struct device *, 
+				    int (*present_func)(void *), void * );
+void stop_atmel_card( struct net_device *, int );
+int atmel_open( struct net_device * );
+
+#endif
diff -Nru a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
--- a/drivers/net/wireless/atmel_cs.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/wireless/atmel_cs.c	2005-03-07 12:09:08 -05:00
@@ -55,6 +55,7 @@
 #include <asm/system.h>
 #include <linux/wireless.h>
 
+#include "atmel.h"
 
 /*
    All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
@@ -90,11 +91,6 @@
    event handler. 
 */
 
-struct net_device *init_atmel_card(int, int, char *, struct device *, 
-				    int (*present_func)(void *), void * );
-void stop_atmel_card( struct net_device *, int );
-int atmel_open( struct net_device * );
-
 static void atmel_config(dev_link_t *link);
 static void atmel_release(dev_link_t *link);
 static int atmel_event(event_t event, int priority,
@@ -307,28 +303,29 @@
 static struct { 
 	int manf, card;
 	char *ver1;
-	char *firmware;
+	AtmelFWType firmware;
 	char *name;
 } card_table[] = {
-	{ 0, 0, "WLAN/802.11b PC CARD", "atmel_at76c502d%s.bin", "Actiontec 802CAT1" },  
-	{ 0, 0, "ATMEL/AT76C502AR", "atmel_at76c502%s.bin", "NoName-RFMD" }, 
-	{ 0, 0, "ATMEL/AT76C502AR_D", "atmel_at76c502d%s.bin", "NoName-revD" }, 
-	{ 0, 0, "ATMEL/AT76C502AR_E", "atmel_at76c502e%s.bin", "NoName-revE" },
-	{ 0, 0, "ATMEL/AT76C504", "atmel_at76c504%s.bin", "NoName-504" },
-	{ 0, 0, "ATMEL/AT76C504A", "atmel_at76c504a_2958%s.bin", "NoName-504a-2958" },
-	{ 0, 0, "ATMEL/AT76C504_R", "atmel_at76c504_2958%s.bin", "NoName-504-2958" },
-	{ MANFID_3COM, 0x0620, NULL, "atmel_at76c502_3com%s.bin", "3com 3CRWE62092B" }, 
-	{ MANFID_3COM, 0x0696, NULL, "atmel_at76c502_3com%s.bin", "3com 3CRSHPW196" }, 
-	{ 0, 0, "SMC/2632W-V2", "atmel_at76c502%s.bin", "SMC 2632W-V2" },
-        { 0, 0, "SMC/2632W", "atmel_at76c502d%s.bin", "SMC 2632W-V3" },
-	{ 0xd601, 0x0007, NULL, "atmel_at76c502%s.bin", "Sitecom WLAN-011" }, 
-	{ 0x01bf, 0x3302, NULL, "atmel_at76c502e%s.bin", "Belkin F5D6020-V2" }, 
-	{ 0, 0, "BT/Voyager 1020 Laptop Adapter", "atmel_at76c502%s.bin", "BT Voyager 1020" },
-        { 0, 0, "IEEE 802.11b/Wireless LAN PC Card", "atmel_at76c502%s.bin", "Siemens Gigaset PC Card II" },
-	{ 0, 0, "CNet/CNWLC 11Mbps Wireless PC Card V-5", "atmel_at76c502e%s.bin", "CNet CNWLC-811ARL" },
-	{ 0, 0, "Wireless/PC_CARD", "atmel_at76c502d%s.bin", "Planet WL-3552" },
-	{ 0, 0, "OEM/11Mbps Wireless LAN PC Card V-3", "atmel_at76c502%s.bin", "OEM 11Mbps WLAN PCMCIA Card" },
-	{ 0, 0, "11WAVE/11WP611AL-E", "atmel_at76c502e%s.bin", "11WAVE WaveBuddy" } 
+	{ 0, 0, "WLAN/802.11b PC CARD", ATMEL_FW_TYPE_502D, "Actiontec 802CAT1" },  
+	{ 0, 0, "ATMEL/AT76C502AR", ATMEL_FW_TYPE_502, "NoName-RFMD" }, 
+	{ 0, 0, "ATMEL/AT76C502AR_D", ATMEL_FW_TYPE_502D, "NoName-revD" }, 
+	{ 0, 0, "ATMEL/AT76C502AR_E", ATMEL_FW_TYPE_502E, "NoName-revE" },
+	{ 0, 0, "ATMEL/AT76C504", ATMEL_FW_TYPE_504, "NoName-504" },
+	{ 0, 0, "ATMEL/AT76C504A", ATMEL_FW_TYPE_504A_2958, "NoName-504a-2958" },
+	{ 0, 0, "ATMEL/AT76C504_R", ATMEL_FW_TYPE_504_2958, "NoName-504-2958" },
+	{ MANFID_3COM, 0x0620, NULL, ATMEL_FW_TYPE_502_3COM, "3com 3CRWE62092B" }, 
+	{ MANFID_3COM, 0x0696, NULL, ATMEL_FW_TYPE_502_3COM, "3com 3CRSHPW196" }, 
+	{ 0, 0, "SMC/2632W-V2", ATMEL_FW_TYPE_502, "SMC 2632W-V2" },
+	{ 0, 0, "SMC/2632W", ATMEL_FW_TYPE_502D, "SMC 2632W-V3" },
+	{ 0xd601, 0x0007, NULL, ATMEL_FW_TYPE_502, "Sitecom WLAN-011" }, 
+	{ 0x01bf, 0x3302, NULL, ATMEL_FW_TYPE_502E, "Belkin F5D6020-V2" }, 
+	{ 0, 0, "BT/Voyager 1020 Laptop Adapter", ATMEL_FW_TYPE_502, "BT Voyager 1020" },
+	{ 0, 0, "IEEE 802.11b/Wireless LAN PC Card", ATMEL_FW_TYPE_502, "Siemens Gigaset PC Card II" },
+	{ 0, 0, "CNet/CNWLC 11Mbps Wireless PC Card V-5", ATMEL_FW_TYPE_502E, "CNet CNWLC-811ARL" },
+	{ 0, 0, "Wireless/PC_CARD", ATMEL_FW_TYPE_502D, "Planet WL-3552" },
+	{ 0, 0, "OEM/11Mbps Wireless LAN PC Card V-3", ATMEL_FW_TYPE_502, "OEM 11Mbps WLAN PCMCIA Card" },
+	{ 0, 0, "11WAVE/11WP611AL-E", ATMEL_FW_TYPE_502E, "11WAVE WaveBuddy" },
+	{ 0, 0, "LG/LW2100N", ATMEL_FW_TYPE_502E, "LG LW2100N 11Mbps WLAN PCMCIA Card" },
 };
 
 static void atmel_config(dev_link_t *link)
@@ -520,7 +517,7 @@
 	((local_info_t*)link->priv)->eth_dev = 
 		init_atmel_card(link->irq.AssignedIRQ,
 				link->io.BasePort1,
-				card_index == -1 ? NULL :  card_table[card_index].firmware,
+				card_index == -1 ? ATMEL_FW_TYPE_NONE :  card_table[card_index].firmware,
 				&handle_to_dev(handle),
 				card_present, 
 				link);
diff -Nru a/drivers/net/wireless/atmel_pci.c b/drivers/net/wireless/atmel_pci.c
--- a/drivers/net/wireless/atmel_pci.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/wireless/atmel_pci.c	2005-03-07 12:09:08 -05:00
@@ -25,6 +25,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
+#include "atmel.h"
 
 MODULE_AUTHOR("Simon Kelley");
 MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
@@ -40,9 +41,6 @@
 
 static int atmel_pci_probe(struct pci_dev *, const struct pci_device_id *);
 static void atmel_pci_remove(struct pci_dev *);
-struct net_device *init_atmel_card(int, int, char *, struct device *, 
-				   int (*present_func)(void *), void * );
-void stop_atmel_card( struct net_device *, int );
 
 static struct pci_driver atmel_driver = {
 	.name     = "atmel",
@@ -63,7 +61,7 @@
 	pci_set_master(pdev);
 	
 	dev = init_atmel_card(pdev->irq, pdev->resource[1].start, 
-			      "atmel_at76c506%s.bin",
+			      ATMEL_FW_TYPE_506,
 			      &pdev->dev, NULL, NULL);
 	if (!dev)
 		return -ENODEV;
diff -Nru a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c
--- a/drivers/net/wireless/prism54/isl_38xx.c	2005-03-07 12:09:08 -05:00
+++ b/drivers/net/wireless/prism54/isl_38xx.c	2005-03-07 12:09:08 -05:00
@@ -125,11 +125,11 @@
 #if VERBOSE > SHOW_ERROR_MESSAGES
 		do_gettimeofday(&current_time);
 		DEBUG(SHOW_TRACING, "%08li.%08li Device wakeup triggered\n",
-		      current_time.tv_sec, current_time.tv_usec);
+		      current_time.tv_sec, (long)current_time.tv_usec);
 #endif
 
 		DEBUG(SHOW_TRACING, "%08li.%08li Device register read %08x\n",
-		      current_time.tv_sec, current_time.tv_usec,
+		      current_time.tv_sec, (long)current_time.tv_usec,
 		      readl(device_base + ISL38XX_CTRL_STAT_REG));
 		udelay(ISL38XX_WRITEIO_DELAY);
 
@@ -139,7 +139,7 @@
 			do_gettimeofday(&current_time);
 			DEBUG(SHOW_TRACING,
 			      "%08li.%08li Device register abadface\n",
-			      current_time.tv_sec, current_time.tv_usec);
+			      current_time.tv_sec, (long)current_time.tv_usec);
 #endif
 			/* read the Device Status Register until Sleepmode bit is set */
 			while (reg = readl(device_base + ISL38XX_CTRL_STAT_REG),
@@ -150,7 +150,7 @@
 
 			DEBUG(SHOW_TRACING,
 			      "%08li.%08li Device register read %08x\n",
-			      current_time.tv_sec, current_time.tv_usec,
+			      current_time.tv_sec, (long)current_time.tv_usec,
 			      readl(device_base + ISL38XX_CTRL_STAT_REG));
 			udelay(ISL38XX_WRITEIO_DELAY);
 
@@ -158,7 +158,7 @@
 			do_gettimeofday(&current_time);
 			DEBUG(SHOW_TRACING,
 			      "%08li.%08li Device asleep counter %i\n",
-			      current_time.tv_sec, current_time.tv_usec,
+			      current_time.tv_sec, (long)current_time.tv_usec,
 			      counter);
 #endif
 		}
@@ -174,7 +174,7 @@
 #if VERBOSE > SHOW_ERROR_MESSAGES
 		do_gettimeofday(&current_time);
 		DEBUG(SHOW_TRACING, "%08li.%08li Device register read %08x\n",
-		      current_time.tv_sec, current_time.tv_usec, reg);
+		      current_time.tv_sec, (long)current_time.tv_usec, reg);
 #endif
 	} else {
 		/* device is (still) awake  */
diff -Nru a/include/linux/mii.h b/include/linux/mii.h
--- a/include/linux/mii.h	2005-03-07 12:09:08 -05:00
+++ b/include/linux/mii.h	2005-03-07 12:09:08 -05:00
@@ -20,6 +20,8 @@
 #define MII_ADVERTISE       0x04        /* Advertisement control reg   */
 #define MII_LPA             0x05        /* Link partner ability reg    */
 #define MII_EXPANSION       0x06        /* Expansion register          */
+#define MII_CTRL1000        0x09        /* 1000BASE-T control          */
+#define MII_STAT1000        0x0a        /* 1000BASE-T status           */
 #define MII_DCOUNTER        0x12        /* Disconnect counter          */
 #define MII_FCSCOUNTER      0x13        /* False carrier counter       */
 #define MII_NWAYTEST        0x14        /* N-way auto-neg test reg     */
@@ -67,7 +69,9 @@
 #define ADVERTISE_100HALF       0x0080  /* Try for 100mbps half-duplex */
 #define ADVERTISE_100FULL       0x0100  /* Try for 100mbps full-duplex */
 #define ADVERTISE_100BASE4      0x0200  /* Try for 100mbps 4k packets  */
-#define ADVERTISE_RESV          0x1c00  /* Unused...                   */
+#define ADVERTISE_PAUSE_CAP     0x0400  /* Try for pause               */
+#define ADVERTISE_PAUSE_ASYM    0x0800  /* Try for asymetric pause     */
+#define ADVERTISE_RESV          0x1000  /* Unused...                   */
 #define ADVERTISE_RFAULT        0x2000  /* Say we can detect faults    */
 #define ADVERTISE_LPACK         0x4000  /* Ack link partners response  */
 #define ADVERTISE_NPAGE         0x8000  /* Next page bit               */
@@ -84,7 +88,9 @@
 #define LPA_100HALF             0x0080  /* Can do 100mbps half-duplex  */
 #define LPA_100FULL             0x0100  /* Can do 100mbps full-duplex  */
 #define LPA_100BASE4            0x0200  /* Can do 100mbps 4k packets   */
-#define LPA_RESV                0x1c00  /* Unused...                   */
+#define LPA_PAUSE_CAP           0x0400  /* Can pause                   */
+#define LPA_PAUSE_ASYM          0x0800  /* Can pause asymetrically     */
+#define LPA_RESV                0x1000  /* Unused...                   */
 #define LPA_RFAULT              0x2000  /* Link partner faulted        */
 #define LPA_LPACK               0x4000  /* Link partner acked us       */
 #define LPA_NPAGE               0x8000  /* Next page bit               */
@@ -105,6 +111,15 @@
 #define NWAYTEST_LOOPBACK       0x0100  /* Enable loopback for N-way   */
 #define NWAYTEST_RESV2          0xfe00  /* Unused...                   */
 
+/* 1000BASE-T Control register */
+#define ADVERTISE_1000FULL      0x0200  /* Advertise 1000BASE-T full duplex */
+#define ADVERTISE_1000HALF      0x0100  /* Advertise 1000BASE-T half duplex */
+
+/* 1000BASE-T Status register */
+#define LPA_1000LOCALRXOK       0x2000  /* Link partner local receiver status */
+#define LPA_1000REMRXOK         0x1000  /* Link partner remote receiver status */
+#define LPA_1000FULL            0x0800  /* Link partner 1000BASE-T full duplex */
+#define LPA_1000HALF            0x0400  /* Link partner 1000BASE-T half duplex */
 
 struct mii_if_info {
 	int phy_id;
@@ -114,6 +129,7 @@
 
 	unsigned int full_duplex : 1;	/* is full duplex? */
 	unsigned int force_media : 1;	/* is autoneg. disabled? */
+	unsigned int supports_gmii : 1; /* are GMII registers supported? */
 
 	struct net_device *dev;
 	int (*mdio_read) (struct net_device *dev, int phy_id, int location);
diff -Nru a/include/linux/netdevice.h b/include/linux/netdevice.h
--- a/include/linux/netdevice.h	2005-03-07 12:09:08 -05:00
+++ b/include/linux/netdevice.h	2005-03-07 12:09:08 -05:00
@@ -678,6 +678,8 @@
 extern int		dev_change_flags(struct net_device *, unsigned);
 extern int		dev_change_name(struct net_device *, char *);
 extern int		dev_set_mtu(struct net_device *, int);
+extern int		dev_set_mac_address(struct net_device *,
+					    struct sockaddr *);
 extern void		dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev);
 
 extern void		dev_init(void);
diff -Nru a/net/core/dev.c b/net/core/dev.c
--- a/net/core/dev.c	2005-03-07 12:09:08 -05:00
+++ b/net/core/dev.c	2005-03-07 12:09:08 -05:00
@@ -2300,6 +2300,21 @@
 	return err;
 }
 
+int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa)
+{
+	int err;
+
+	if (!dev->set_mac_address)
+		return -EOPNOTSUPP;
+	if (sa->sa_family != dev->type)
+		return -EINVAL;
+	if (!netif_device_present(dev))
+		return -ENODEV;
+	err = dev->set_mac_address(dev, sa);
+	if (!err)
+		notifier_call_chain(&netdev_chain, NETDEV_CHANGEADDR, dev);
+	return err;
+}
 
 /*
  *	Perform the SIOCxIFxxx calls.
@@ -2346,17 +2361,7 @@
 			return 0;
 
 		case SIOCSIFHWADDR:
-			if (!dev->set_mac_address)
-				return -EOPNOTSUPP;
-			if (ifr->ifr_hwaddr.sa_family != dev->type)
-				return -EINVAL;
-			if (!netif_device_present(dev))
-				return -ENODEV;
-			err = dev->set_mac_address(dev, &ifr->ifr_hwaddr);
-			if (!err)
-				notifier_call_chain(&netdev_chain,
-						    NETDEV_CHANGEADDR, dev);
-			return err;
+			return dev_set_mac_address(dev, &ifr->ifr_hwaddr);
 
 		case SIOCSIFHWBROADCAST:
 			if (ifr->ifr_hwaddr.sa_family != dev->type)
@@ -3322,6 +3327,7 @@
 EXPORT_SYMBOL(dev_set_promiscuity);
 EXPORT_SYMBOL(dev_change_flags);
 EXPORT_SYMBOL(dev_set_mtu);
+EXPORT_SYMBOL(dev_set_mac_address);
 EXPORT_SYMBOL(free_netdev);
 EXPORT_SYMBOL(netdev_boot_setup_check);
 EXPORT_SYMBOL(netdev_set_master);

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [BK PATCHES] 2.6.x net driver updates
@ 2005-03-06 23:38 Jeff Garzik
  0 siblings, 0 replies; 28+ messages in thread
From: Jeff Garzik @ 2005-03-06 23:38 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: Netdev, Linux Kernel

[-- Attachment #1: Type: text/plain, Size: 28 bytes --]

Mostly fixes / MIPS update.

[-- Attachment #2: changelog.txt --]
[-- Type: text/plain, Size: 2570 bytes --]

Please do a

	bk pull bk://gkernel.bkbits.net/net-drivers-2.6

This will update the following files:

 drivers/net/bagetlance.c             | 1368 -----------------------------------
 Documentation/networking/ixgb.txt    |    9 
 MAINTAINERS                          |    4 
 drivers/net/Kconfig                  |   14 
 drivers/net/Makefile                 |    1 
 drivers/net/Space.c                  |   11 
 drivers/net/amd8111e.c               |    2 
 drivers/net/au1000_eth.c             | 1361 ++++++++++++++++++++++++++++------
 drivers/net/au1000_eth.h             |   55 -
 drivers/net/dl2k.c                   |    2 
 drivers/net/gianfar.c                |    2 
 drivers/net/ibm_emac/ibm_emac.h      |    4 
 drivers/net/ibm_emac/ibm_emac_core.c |   16 
 drivers/net/ibm_emac/ibm_emac_core.h |    2 
 drivers/net/ioc3-eth.c               |   82 +-
 drivers/net/jazzsonic.c              |  217 +++--
 drivers/net/meth.c                   |  275 +++----
 drivers/net/meth.h                   |    2 
 drivers/net/mv643xx_eth.c            |    2 
 drivers/net/pcnet32.c                |   47 -
 drivers/net/s2io.c                   |   45 -
 drivers/net/sb1250-mac.c             |  109 +-
 drivers/net/sgiseeq.c                |   70 +
 drivers/net/sk98lin/skge.c           |    2 
 drivers/net/sonic.c                  |    4 
 drivers/net/wan/Kconfig              |   11 
 drivers/net/wan/hd6457x.c            |    2 
 drivers/net/wan/z85230.c             |    4 
 include/linux/pci_ids.h              |    5 
 29 files changed, 1720 insertions(+), 2008 deletions(-)

through these ChangeSets:

<takis:lumumba.luc.ac.be>:
  o Possible AMD8111e free irq issue

Don Fry:
  o pcnet32: 79c976 with fiber optic fix

Ganesh Venkatesan:
  o ixgb: Documentation/networking/ixgb.txt

John W. Linville:
  o sk98lin: add MODULE_DEVICE_TABLE entry

Krzysztof Halasa:
  o WAN drivers fix: N2, C101, PCI200SYN - quite fatal

Kumar Gala:
  o initialize a spin lock in gianfar driver

Matt Porter:
  o emac: fix skb allocation for full-size jumbo frames
  o Add PPC440SP support to IBM EMAC driver

Ralf Bächle:
  o SGI Seeq updates
  o SB1250 driver updates
  o S2IO syntax fixes
  o Meth driver updates
  o Marvell MV-64340 driver upda
  o Jazzsonic driver updates
  o IOC3 driver updates
  o Remove Baget network driver
  o Au1000 driver updates

Thierry Vignaud:
  o fix driver name in dl2k as returned by ETHTOOL_GDRVINFO

tom watson:
  o drivers/net/wan/z85230.c interrupt handling fix


[-- Attachment #3: patch --]
[-- Type: text/plain, Size: 153332 bytes --]

diff -Nru a/Documentation/networking/ixgb.txt b/Documentation/networking/ixgb.txt
--- a/Documentation/networking/ixgb.txt	2005-03-06 18:36:50 -05:00
+++ b/Documentation/networking/ixgb.txt	2005-03-06 18:36:50 -05:00
@@ -1,7 +1,7 @@
 Linux* Base Driver for the Intel(R) PRO/10GbE Family of Adapters
 ================================================================
 
-September 13, 2004
+November 17, 2004
 
 
 Contents
@@ -18,8 +18,7 @@
 ===============
 
 This file describes the Linux* Base Driver for the Intel(R) PRO/10GbE Family 
-of Adapters, version 1.0.x.  This driver includes support for Itanium(TM)2 and
-EM64T systems.
+of Adapters, version 1.0.x.  
 
 For questions related to hardware requirements, refer to the documentation 
 supplied with your Intel PRO/10GbE adapter. All hardware requirements listed 
@@ -71,8 +70,8 @@
     Ethernet PAUSE frames.
 
 RxDescriptors
-Valid Range: 64-4096
-Default Value: 1024
+Valid Range: 64-512
+Default Value: 512
     This value is the number of receive descriptors allocated by the driver. 
     Increasing this value allows the driver to buffer more incoming packets. 
     Each descriptor is 16 bytes.  A receive buffer is also allocated for 
diff -Nru a/MAINTAINERS b/MAINTAINERS
--- a/MAINTAINERS	2005-03-06 18:36:50 -05:00
+++ b/MAINTAINERS	2005-03-06 18:36:50 -05:00
@@ -910,10 +910,10 @@
 W:	http://www.icp-vortex.com/
 S:	Supported
 
-GENERIC HDLC DRIVER, N2 AND C101 DRIVERS
+GENERIC HDLC DRIVER, N2, C101, PCI200SYN and WANXL DRIVERS
 P:	Krzysztof Halasa
 M:	khc@pm.waw.pl
-W:	http://hq.pm.waw.pl/hdlc/
+W:	http://www.kernel.org/pub/linux/utils/net/hdlc/
 S:	Maintained
 
 HAYES ESP SERIAL DRIVER
diff -Nru a/drivers/net/Kconfig b/drivers/net/Kconfig
--- a/drivers/net/Kconfig	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/Kconfig	2005-03-06 18:36:50 -05:00
@@ -445,7 +445,7 @@
 
 config MIPS_JAZZ_SONIC
 	tristate "MIPS JAZZ onboard SONIC Ethernet support"
-	depends on NET_ETHERNET && MIPS_JAZZ
+	depends on NET_ETHERNET && MACH_JAZZ
 	help
 	  This is the driver for the onboard card of MIPS Magnum 4000,
 	  Acer PICA, Olivetti M700-10 and a few other identical OEM systems.
@@ -470,7 +470,7 @@
 
 config SGI_IOC3_ETH
 	bool "SGI IOC3 Ethernet"
-	depends on NET_ETHERNET && SGI_IP27
+	depends on NET_ETHERNET && PCI && SGI_IP27
 	select CRC32
 	select MII
 	help
@@ -1763,14 +1763,6 @@
 	  DEC (now Compaq) based on the AMD Lance chipset, including the
 	  DEPCA series.  (This chipset is better known via the NE2100 cards.)
 
-config BAGETLANCE
-	tristate "Baget AMD LANCE support"
-	depends on NET_ETHERNET && BAGET_MIPS
-	help
-	  Say Y to enable kernel support for AMD Lance Ethernet cards on the
-	  MIPS-32-based Baget embedded system.  This chipset is better known
-	  via the NE2100 cards.
-
 config 68360_ENET
 	bool "Motorola 68360 ethernet controller"
 	depends on M68360
@@ -2077,7 +2069,7 @@
 
 config MV643XX_ETH
 	tristate "MV-643XX Ethernet support"
-	depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX
+	depends on MOMENCO_OCELOT_C || MOMENCO_JAGUAR_ATX || MOMENCO_OCELOT_3
 	help
 	  This driver supports the gigabit Ethernet on the Marvell MV643XX
 	  chipset which is used in the Momenco Ocelot C and Jaguar ATX.
diff -Nru a/drivers/net/Makefile b/drivers/net/Makefile
--- a/drivers/net/Makefile	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/Makefile	2005-03-06 18:36:50 -05:00
@@ -162,7 +162,6 @@
 obj-$(CONFIG_MIPS_GT96100ETH) += gt96100eth.o
 obj-$(CONFIG_MIPS_AU1X00_ENET) += au1000_eth.o
 obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o
-obj-$(CONFIG_BAGETLANCE) += bagetlance.o
 obj-$(CONFIG_DECLANCE) += declance.o
 obj-$(CONFIG_ATARILANCE) += atarilance.o
 obj-$(CONFIG_ATARI_BIONET) += atari_bionet.o
diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c
--- a/drivers/net/Space.c	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/Space.c	2005-03-06 18:36:50 -05:00
@@ -302,16 +302,6 @@
 	{NULL, 0},
 };
 
-static struct devprobe2 mips_probes[] __initdata = {
-#ifdef CONFIG_MIPS_JAZZ_SONIC
-	{sonic_probe, 0},
-#endif
-#ifdef CONFIG_BAGETLANCE        /* Lance-based Baget ethernet boards */
-        {bagetlance_probe, 0},
-#endif
-	{NULL, 0},
-};
-
 /*
  * Unified ethernet device probe, segmented per architecture and
  * per bus interface. This drives the legacy devices only for now.
@@ -325,7 +315,6 @@
 		return;
 
 	(void)(	probe_list2(unit, m68k_probes, base_addr == 0) &&
-		probe_list2(unit, mips_probes, base_addr == 0) &&
 		probe_list2(unit, eisa_probes, base_addr == 0) &&
 		probe_list2(unit, mca_probes, base_addr == 0) &&
 		probe_list2(unit, isa_probes, base_addr == 0) &&
diff -Nru a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
--- a/drivers/net/amd8111e.c	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/amd8111e.c	2005-03-06 18:36:50 -05:00
@@ -1381,6 +1381,8 @@
 
 	if(amd8111e_restart(dev)){
 		spin_unlock_irq(&lp->lock);
+		if (dev->irq)
+			free_irq(dev->irq, dev);
 		return -ENOMEM;
 	}
 	/* Start ipg timer */
diff -Nru a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
--- a/drivers/net/au1000_eth.c	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/au1000_eth.c	2005-03-06 18:36:50 -05:00
@@ -1,10 +1,19 @@
 /*
- * Alchemy Semi Au1000 ethernet driver
  *
- * Copyright 2001 MontaVista Software Inc.
+ * Alchemy Au1x00 ethernet driver
+ *
+ * Copyright 2001,2002,2003 MontaVista Software Inc.
+ * Copyright 2002 TimeSys Corp.
+ * Added ethtool/mii-tool support,
+ * Copyright 2004 Matt Porter <mporter@kernel.crashing.org>
+ * Update: 2004 Bjoern Riemer, riemer@fokus.fraunhofer.de 
+ * or riemer@riemer-nt.de: fixed the link beat detection with 
+ * ioctls (SIOCGMIIPHY)
  * Author: MontaVista Software, Inc.
  *         	ppopov@mvista.com or source@mvista.com
  *
+ * ########################################################################
+ *
  *  This program is free software; you can distribute it and/or modify it
  *  under the terms of the GNU General Public License (Version 2) as
  *  published by the Free Software Foundation.
@@ -17,46 +26,59 @@
  *  You should have received a copy of the GNU General Public License along
  *  with this program; if not, write to the Free Software Foundation, Inc.,
  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * 
  */
-#include <linux/config.h>
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/in.h>
 #include <linux/ioport.h>
+#include <linux/bitops.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
 #include <linux/skbuff.h>
 #include <linux/delay.h>
-#include <linux/crc32.h>
-#include <linux/bitops.h>
-
 #include <asm/mipsregs.h>
 #include <asm/irq.h>
 #include <asm/io.h>
-#include <asm/au1000.h>
+#include <asm/processor.h>
 
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/cpu.h>
 #include "au1000_eth.h"
 
 #ifdef AU1000_ETH_DEBUG
-static int au1000_debug = 10;
+static int au1000_debug = 5;
 #else
 static int au1000_debug = 3;
 #endif
 
+#define DRV_NAME	"au1000eth"
+#define DRV_VERSION	"1.5"
+#define DRV_AUTHOR	"Pete Popov <ppopov@embeddedalley.com>"
+#define DRV_DESC	"Au1xxx on-chip Ethernet driver"
+
+MODULE_AUTHOR(DRV_AUTHOR);
+MODULE_DESCRIPTION(DRV_DESC);
+MODULE_LICENSE("GPL");
+
 // prototypes
-static void *dma_alloc(size_t, dma_addr_t *);
-static void dma_free(void *, size_t);
 static void hard_stop(struct net_device *);
 static void enable_rx_tx(struct net_device *dev);
-static int __init au1000_probe1(long, int, int);
+static struct net_device * au1000_probe(u32 ioaddr, int irq, int port_num);
 static int au1000_init(struct net_device *);
 static int au1000_open(struct net_device *);
 static int au1000_close(struct net_device *);
@@ -78,8 +100,7 @@
 // externs
 extern  void ack_rise_edge_irq(unsigned int);
 extern int get_ethernet_addr(char *ethernet_addr);
-extern inline void str2eaddr(unsigned char *ea, unsigned char *str);
-extern inline unsigned char str2hexnum(unsigned char c);
+extern void str2eaddr(unsigned char *ea, unsigned char *str);
 extern char * __init prom_getcmdline(void);
 
 /*
@@ -97,29 +118,6 @@
  * complete immediately.
  */
 
-
-/*
- * Base address and interrupt of the Au1xxx ethernet macs
- */
-static struct {
-	unsigned int port;
-	int irq;
-} au1000_iflist[NUM_INTERFACES] = {
-		{AU1000_ETH0_BASE, AU1000_ETH0_IRQ}, 
-		{AU1000_ETH1_BASE, AU1000_ETH1_IRQ}
-	},
-  au1500_iflist[NUM_INTERFACES] = {
-		{AU1500_ETH0_BASE, AU1000_ETH0_IRQ}, 
-		{AU1500_ETH1_BASE, AU1000_ETH1_IRQ}
-	},
-  au1100_iflist[NUM_INTERFACES] = {
-		{AU1000_ETH0_BASE, AU1000_ETH0_IRQ}, 
-		{0, 0}
-	};
-
-static char version[] __devinitdata =
-    "au1000eth.c:1.0 ppopov@mvista.com\n";
-
 /* These addresses are only used if yamon doesn't tell us what
  * the mac address is, and the mac address is not passed on the
  * command line.
@@ -135,18 +133,36 @@
 #define cpu_to_dma32 cpu_to_be32
 #define dma32_to_cpu be32_to_cpu
 
+struct au1000_private *au_macs[NUM_ETH_INTERFACES];
 
 /* FIXME 
  * All of the PHY code really should be detached from the MAC 
  * code.
  */
 
+/* Default advertise */
+#define GENMII_DEFAULT_ADVERTISE \
+	ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \
+	ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \
+	ADVERTISED_Autoneg
+
+#define GENMII_DEFAULT_FEATURES \
+	SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \
+	SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
+	SUPPORTED_Autoneg
+
+static char *phy_link[] = 
+{	"unknown", 
+	"10Base2", "10BaseT", 
+	"AUI",
+	"100BaseT", "100BaseTX", "100BaseFX"
+};
+
 int bcm_5201_init(struct net_device *dev, int phy_addr)
 {
 	s16 data;
 	
 	/* Stop auto-negotiation */
-	//printk("bcm_5201_init\n");
 	data = mdio_read(dev, phy_addr, MII_CONTROL);
 	mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO);
 
@@ -161,17 +177,8 @@
 	data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO;
 	mdio_write(dev, phy_addr, MII_CONTROL, data);
 
-	/* Enable TX LED instead of FDX */
-	data = mdio_read(dev, phy_addr, MII_INT);
-	data &= ~MII_FDX_LED;
-	mdio_write(dev, phy_addr, MII_INT, data);
-
-	/* Enable TX LED instead of FDX */
-	data = mdio_read(dev, phy_addr, MII_INT);
-	data &= ~MII_FDX_LED;
-	mdio_write(dev, phy_addr, MII_INT, data);
-
-	if (au1000_debug > 4) dump_mii(dev, phy_addr);
+	if (au1000_debug > 4) 
+		dump_mii(dev, phy_addr);
 	return 0;
 }
 
@@ -179,7 +186,6 @@
 {
 	s16 mii_control, timeout;
 	
-	//printk("bcm_5201_reset\n");
 	mii_control = mdio_read(dev, phy_addr, MII_CONTROL);
 	mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET);
 	mdelay(1);
@@ -242,12 +248,16 @@
 		printk("lsi_80227_init\n");
 
 	/* restart auto-negotiation */
-	mdio_write(dev, phy_addr, 0, 0x3200);
-
+	mdio_write(dev, phy_addr, MII_CONTROL,
+		   MII_CNTL_F100 | MII_CNTL_AUTO | MII_CNTL_RST_AUTO); // | MII_CNTL_FDX);
 	mdelay(1);
 
 	/* set up LEDs to correct display */
+#ifdef CONFIG_MIPS_MTX1
+	mdio_write(dev, phy_addr, 17, 0xff80);
+#else
 	mdio_write(dev, phy_addr, 17, 0xffc0);
+#endif
 
 	if (au1000_debug > 4)
 		dump_mii(dev, phy_addr);
@@ -294,9 +304,9 @@
 	mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS);
 	if (mii_data & MII_STAT_LINK) {
 		*link = 1;
-		mii_data = mdio_read(dev, aup->phy_addr, MII_LSI_STAT);
-		if (mii_data & MII_LSI_STAT_SPD) {
-			if (mii_data & MII_LSI_STAT_FDX) {
+		mii_data = mdio_read(dev, aup->phy_addr, MII_LSI_PHY_STAT);
+		if (mii_data & MII_LSI_PHY_STAT_SPD) {
+			if (mii_data & MII_LSI_PHY_STAT_FDX) {
 				*speed = IF_PORT_100BASEFX;
 				dev->if_port = IF_PORT_100BASEFX;
 			}
@@ -337,12 +347,396 @@
 	return 0;
 }
 
+int am79c874_init(struct net_device *dev, int phy_addr)
+{
+	s16 data;
+
+	/* 79c874 has quit resembled bit assignments to BCM5201 */
+	if (au1000_debug > 4)
+		printk("am79c847_init\n");
+
+	/* Stop auto-negotiation */
+	data = mdio_read(dev, phy_addr, MII_CONTROL);
+	mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO);
+
+	/* Set advertisement to 10/100 and Half/Full duplex
+	 * (full capabilities) */
+	data = mdio_read(dev, phy_addr, MII_ANADV);
+	data |= MII_NWAY_TX | MII_NWAY_TX_FDX | MII_NWAY_T_FDX | MII_NWAY_T;
+	mdio_write(dev, phy_addr, MII_ANADV, data);
+	
+	/* Restart auto-negotiation */
+	data = mdio_read(dev, phy_addr, MII_CONTROL);
+	data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO;
+
+	mdio_write(dev, phy_addr, MII_CONTROL, data);
+
+	if (au1000_debug > 4) dump_mii(dev, phy_addr);
+	return 0;
+}
+
+int am79c874_reset(struct net_device *dev, int phy_addr)
+{
+	s16 mii_control, timeout;
+	
+	if (au1000_debug > 4)
+		printk("am79c874_reset\n");
+
+	mii_control = mdio_read(dev, phy_addr, MII_CONTROL);
+	mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET);
+	mdelay(1);
+	for (timeout = 100; timeout > 0; --timeout) {
+		mii_control = mdio_read(dev, phy_addr, MII_CONTROL);
+		if ((mii_control & MII_CNTL_RESET) == 0)
+			break;
+		mdelay(1);
+	}
+	if (mii_control & MII_CNTL_RESET) {
+		printk(KERN_ERR "%s PHY reset timeout !\n", dev->name);
+		return -1;
+	}
+	return 0;
+}
+
+int 
+am79c874_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed)
+{
+	u16 mii_data;
+	struct au1000_private *aup;
+
+	// printk("am79c874_status\n");
+	if (!dev) {
+		printk(KERN_ERR "am79c874_status error: NULL dev\n");
+		return -1;
+	}
+
+	aup = (struct au1000_private *) dev->priv;
+	mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS);
+
+	if (mii_data & MII_STAT_LINK) {
+		*link = 1;
+		mii_data = mdio_read(dev, aup->phy_addr, MII_AMD_PHY_STAT);
+		if (mii_data & MII_AMD_PHY_STAT_SPD) {
+			if (mii_data & MII_AMD_PHY_STAT_FDX) {
+				*speed = IF_PORT_100BASEFX;
+				dev->if_port = IF_PORT_100BASEFX;
+			}
+			else {
+				*speed = IF_PORT_100BASETX;
+				dev->if_port = IF_PORT_100BASETX;
+			}
+		}
+		else {
+			*speed = IF_PORT_10BASET;
+			dev->if_port = IF_PORT_10BASET;
+		}
+
+	}
+	else {
+		*link = 0;
+		*speed = 0;
+		dev->if_port = IF_PORT_UNKNOWN;
+	}
+	return 0;
+}
+
+int lxt971a_init(struct net_device *dev, int phy_addr)
+{
+	if (au1000_debug > 4)
+		printk("lxt971a_init\n");
+
+	/* restart auto-negotiation */
+	mdio_write(dev, phy_addr, MII_CONTROL,
+		   MII_CNTL_F100 | MII_CNTL_AUTO | MII_CNTL_RST_AUTO | MII_CNTL_FDX);
+
+	/* set up LEDs to correct display */
+	mdio_write(dev, phy_addr, 20, 0x0422);
+
+	if (au1000_debug > 4)
+		dump_mii(dev, phy_addr);
+	return 0;
+}
+
+int lxt971a_reset(struct net_device *dev, int phy_addr)
+{
+	s16 mii_control, timeout;
+	
+	if (au1000_debug > 4) {
+		printk("lxt971a_reset\n");
+		dump_mii(dev, phy_addr);
+	}
+
+	mii_control = mdio_read(dev, phy_addr, MII_CONTROL);
+	mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET);
+	mdelay(1);
+	for (timeout = 100; timeout > 0; --timeout) {
+		mii_control = mdio_read(dev, phy_addr, MII_CONTROL);
+		if ((mii_control & MII_CNTL_RESET) == 0)
+			break;
+		mdelay(1);
+	}
+	if (mii_control & MII_CNTL_RESET) {
+		printk(KERN_ERR "%s PHY reset timeout !\n", dev->name);
+		return -1;
+	}
+	return 0;
+}
+
+int
+lxt971a_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed)
+{
+	u16 mii_data;
+	struct au1000_private *aup;
+
+	if (!dev) {
+		printk(KERN_ERR "lxt971a_status error: NULL dev\n");
+		return -1;
+	}
+	aup = (struct au1000_private *) dev->priv;
+
+	mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS);
+	if (mii_data & MII_STAT_LINK) {
+		*link = 1;
+		mii_data = mdio_read(dev, aup->phy_addr, MII_INTEL_PHY_STAT);
+		if (mii_data & MII_INTEL_PHY_STAT_SPD) {
+			if (mii_data & MII_INTEL_PHY_STAT_FDX) {
+				*speed = IF_PORT_100BASEFX;
+				dev->if_port = IF_PORT_100BASEFX;
+			}
+			else {
+				*speed = IF_PORT_100BASETX;
+				dev->if_port = IF_PORT_100BASETX;
+			}
+		}
+		else  {
+			*speed = IF_PORT_10BASET;
+			dev->if_port = IF_PORT_10BASET;
+		}
+
+	}
+	else {
+		*link = 0;
+		*speed = 0;
+		dev->if_port = IF_PORT_UNKNOWN;
+	}
+	return 0;
+}
+
+int ks8995m_init(struct net_device *dev, int phy_addr)
+{
+	s16 data;
+	
+//	printk("ks8995m_init\n");
+	/* Stop auto-negotiation */
+	data = mdio_read(dev, phy_addr, MII_CONTROL);
+	mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO);
+
+	/* Set advertisement to 10/100 and Half/Full duplex
+	 * (full capabilities) */
+	data = mdio_read(dev, phy_addr, MII_ANADV);
+	data |= MII_NWAY_TX | MII_NWAY_TX_FDX | MII_NWAY_T_FDX | MII_NWAY_T;
+	mdio_write(dev, phy_addr, MII_ANADV, data);
+	
+	/* Restart auto-negotiation */
+	data = mdio_read(dev, phy_addr, MII_CONTROL);
+	data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO;
+	mdio_write(dev, phy_addr, MII_CONTROL, data);
+
+	if (au1000_debug > 4) dump_mii(dev, phy_addr);
+
+	return 0;
+}
+
+int ks8995m_reset(struct net_device *dev, int phy_addr)
+{
+	s16 mii_control, timeout;
+	
+//	printk("ks8995m_reset\n");
+	mii_control = mdio_read(dev, phy_addr, MII_CONTROL);
+	mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET);
+	mdelay(1);
+	for (timeout = 100; timeout > 0; --timeout) {
+		mii_control = mdio_read(dev, phy_addr, MII_CONTROL);
+		if ((mii_control & MII_CNTL_RESET) == 0)
+			break;
+		mdelay(1);
+	}
+	if (mii_control & MII_CNTL_RESET) {
+		printk(KERN_ERR "%s PHY reset timeout !\n", dev->name);
+		return -1;
+	}
+	return 0;
+}
+
+int ks8995m_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed)
+{
+	u16 mii_data;
+	struct au1000_private *aup;
+
+	if (!dev) {
+		printk(KERN_ERR "ks8995m_status error: NULL dev\n");
+		return -1;
+	}
+	aup = (struct au1000_private *) dev->priv;
+
+	mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS);
+	if (mii_data & MII_STAT_LINK) {
+		*link = 1;
+		mii_data = mdio_read(dev, aup->phy_addr, MII_AUX_CNTRL);
+		if (mii_data & MII_AUX_100) {
+			if (mii_data & MII_AUX_FDX) {
+				*speed = IF_PORT_100BASEFX;
+				dev->if_port = IF_PORT_100BASEFX;
+			}
+			else {
+				*speed = IF_PORT_100BASETX;
+				dev->if_port = IF_PORT_100BASETX;
+			}
+		}
+		else  {											
+			*speed = IF_PORT_10BASET;
+			dev->if_port = IF_PORT_10BASET;
+		}
+
+	}
+	else {
+		*link = 0;
+		*speed = 0;
+		dev->if_port = IF_PORT_UNKNOWN;
+	}
+	return 0;
+}
+
+int
+smsc_83C185_init (struct net_device *dev, int phy_addr)
+{
+	s16 data;
+
+	if (au1000_debug > 4)
+		printk("smsc_83C185_init\n");
+
+	/* Stop auto-negotiation */
+	data = mdio_read(dev, phy_addr, MII_CONTROL);
+	mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO);
+
+	/* Set advertisement to 10/100 and Half/Full duplex
+	 * (full capabilities) */
+	data = mdio_read(dev, phy_addr, MII_ANADV);
+	data |= MII_NWAY_TX | MII_NWAY_TX_FDX | MII_NWAY_T_FDX | MII_NWAY_T;
+	mdio_write(dev, phy_addr, MII_ANADV, data);
+	
+	/* Restart auto-negotiation */
+	data = mdio_read(dev, phy_addr, MII_CONTROL);
+	data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO;
+
+	mdio_write(dev, phy_addr, MII_CONTROL, data);
+
+	if (au1000_debug > 4) dump_mii(dev, phy_addr);
+	return 0;
+}
+
+int
+smsc_83C185_reset (struct net_device *dev, int phy_addr)
+{
+	s16 mii_control, timeout;
+	
+	if (au1000_debug > 4)
+		printk("smsc_83C185_reset\n");
+
+	mii_control = mdio_read(dev, phy_addr, MII_CONTROL);
+	mdio_write(dev, phy_addr, MII_CONTROL, mii_control | MII_CNTL_RESET);
+	mdelay(1);
+	for (timeout = 100; timeout > 0; --timeout) {
+		mii_control = mdio_read(dev, phy_addr, MII_CONTROL);
+		if ((mii_control & MII_CNTL_RESET) == 0)
+			break;
+		mdelay(1);
+	}
+	if (mii_control & MII_CNTL_RESET) {
+		printk(KERN_ERR "%s PHY reset timeout !\n", dev->name);
+		return -1;
+	}
+	return 0;
+}
+
+int 
+smsc_83C185_status (struct net_device *dev, int phy_addr, u16 *link, u16 *speed)
+{
+	u16 mii_data;
+	struct au1000_private *aup;
+
+	if (!dev) {
+		printk(KERN_ERR "smsc_83C185_status error: NULL dev\n");
+		return -1;
+	}
+
+	aup = (struct au1000_private *) dev->priv;
+	mii_data = mdio_read(dev, aup->phy_addr, MII_STATUS);
+
+	if (mii_data & MII_STAT_LINK) {
+		*link = 1;
+		mii_data = mdio_read(dev, aup->phy_addr, 0x1f);
+		if (mii_data & (1<<3)) {
+			if (mii_data & (1<<4)) {
+				*speed = IF_PORT_100BASEFX;
+				dev->if_port = IF_PORT_100BASEFX;
+			}
+			else {
+				*speed = IF_PORT_100BASETX;
+				dev->if_port = IF_PORT_100BASETX;
+			}
+		}
+		else {
+			*speed = IF_PORT_10BASET;
+			dev->if_port = IF_PORT_10BASET;
+		}
+	}
+	else {
+		*link = 0;
+		*speed = 0;
+		dev->if_port = IF_PORT_UNKNOWN;
+	}
+	return 0;
+}
+
+
+#ifdef CONFIG_MIPS_BOSPORUS
+int stub_init(struct net_device *dev, int phy_addr)
+{
+	//printk("PHY stub_init\n");
+	return 0;
+}
+
+int stub_reset(struct net_device *dev, int phy_addr)
+{
+	//printk("PHY stub_reset\n");
+	return 0;
+}
+
+int 
+stub_status(struct net_device *dev, int phy_addr, u16 *link, u16 *speed)
+{
+	//printk("PHY stub_status\n");
+	*link = 1;
+	/* hmmm, revisit */
+	*speed = IF_PORT_100BASEFX;
+	dev->if_port = IF_PORT_100BASEFX;
+	return 0;
+}
+#endif
+
 struct phy_ops bcm_5201_ops = {
 	bcm_5201_init,
 	bcm_5201_reset,
 	bcm_5201_status,
 };
 
+struct phy_ops am79c874_ops = {
+	am79c874_init,
+	am79c874_reset,
+	am79c874_status,
+};
+
 struct phy_ops am79c901_ops = {
 	am79c901_init,
 	am79c901_reset,
@@ -355,26 +749,89 @@
 	lsi_80227_status,
 };
 
+struct phy_ops lxt971a_ops = { 
+	lxt971a_init,
+	lxt971a_reset,
+	lxt971a_status,
+};
+
+struct phy_ops ks8995m_ops = {
+	ks8995m_init,
+	ks8995m_reset,
+	ks8995m_status,
+};
+
+struct phy_ops smsc_83C185_ops = {
+	smsc_83C185_init,
+	smsc_83C185_reset,
+	smsc_83C185_status,
+};
+
+#ifdef CONFIG_MIPS_BOSPORUS
+struct phy_ops stub_ops = {
+	stub_init,
+	stub_reset,
+	stub_status,
+};
+#endif
+
 static struct mii_chip_info {
 	const char * name;
 	u16 phy_id0;
 	u16 phy_id1;
 	struct phy_ops *phy_ops;	
+	int dual_phy;
 } mii_chip_table[] = {
-	{"Broadcom BCM5201 10/100 BaseT PHY",  0x0040, 0x6212, &bcm_5201_ops },
-	{"AMD 79C901 HomePNA PHY",  0x0000, 0x35c8, &am79c901_ops },
-	{"LSI 80227 10/100 BaseT PHY", 0x0016, 0xf840, &lsi_80227_ops },
-	{"Broadcom BCM5221 10/100 BaseT PHY",  0x0040, 0x61e4, &bcm_5201_ops },
+	{"Broadcom BCM5201 10/100 BaseT PHY",0x0040,0x6212, &bcm_5201_ops,0},
+	{"Broadcom BCM5221 10/100 BaseT PHY",0x0040,0x61e4, &bcm_5201_ops,0},
+	{"Broadcom BCM5222 10/100 BaseT PHY",0x0040,0x6322, &bcm_5201_ops,1},
+	{"AMD 79C901 HomePNA PHY",0x0000,0x35c8, &am79c901_ops,0},
+	{"AMD 79C874 10/100 BaseT PHY",0x0022,0x561b, &am79c874_ops,0},
+	{"LSI 80227 10/100 BaseT PHY",0x0016,0xf840, &lsi_80227_ops,0},
+	{"Intel LXT971A Dual Speed PHY",0x0013,0x78e2, &lxt971a_ops,0},
+	{"Kendin KS8995M 10/100 BaseT PHY",0x0022,0x1450, &ks8995m_ops,0},
+	{"SMSC LAN83C185 10/100 BaseT PHY",0x0007,0xc0a3, &smsc_83C185_ops,0},
+#ifdef CONFIG_MIPS_BOSPORUS
+	{"Stub", 0x1234, 0x5678, &stub_ops },
+#endif
 	{0,},
 };
 
 static int mdio_read(struct net_device *dev, int phy_id, int reg)
 {
 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
+	volatile u32 *mii_control_reg;
+	volatile u32 *mii_data_reg;
 	u32 timedout = 20;
 	u32 mii_control;
 
-	while (aup->mac->mii_control & MAC_MII_BUSY) {
+	#ifdef CONFIG_BCM5222_DUAL_PHY
+	/* First time we probe, it's for the mac0 phy.
+	 * Since we haven't determined yet that we have a dual phy,
+	 * aup->mii->mii_control_reg won't be setup and we'll
+	 * default to the else statement.
+	 * By the time we probe for the mac1 phy, the mii_control_reg
+	 * will be setup to be the address of the mac0 phy control since
+	 * both phys are controlled through mac0.
+	 */
+	if (aup->mii && aup->mii->mii_control_reg) {
+		mii_control_reg = aup->mii->mii_control_reg;
+		mii_data_reg = aup->mii->mii_data_reg;
+	}
+	else if (au_macs[0]->mii && au_macs[0]->mii->mii_control_reg) {
+		/* assume both phys are controlled through mac0 */
+		mii_control_reg = au_macs[0]->mii->mii_control_reg;
+		mii_data_reg = au_macs[0]->mii->mii_data_reg;
+	}
+	else 
+	#endif
+	{
+		/* default control and data reg addresses */
+		mii_control_reg = &aup->mac->mii_control;
+		mii_data_reg = &aup->mac->mii_data;
+	}
+
+	while (*mii_control_reg & MAC_MII_BUSY) {
 		mdelay(1);
 		if (--timedout == 0) {
 			printk(KERN_ERR "%s: read_MII busy timeout!!\n", 
@@ -386,10 +843,10 @@
 	mii_control = MAC_SET_MII_SELECT_REG(reg) | 
 		MAC_SET_MII_SELECT_PHY(phy_id) | MAC_MII_READ;
 
-	aup->mac->mii_control = mii_control;
+	*mii_control_reg = mii_control;
 
 	timedout = 20;
-	while (aup->mac->mii_control & MAC_MII_BUSY) {
+	while (*mii_control_reg & MAC_MII_BUSY) {
 		mdelay(1);
 		if (--timedout == 0) {
 			printk(KERN_ERR "%s: mdio_read busy timeout!!\n", 
@@ -397,16 +854,36 @@
 			return -1;
 		}
 	}
-	return (int)aup->mac->mii_data;
+	return (int)*mii_data_reg;
 }
 
 static void mdio_write(struct net_device *dev, int phy_id, int reg, u16 value)
 {
 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
+	volatile u32 *mii_control_reg;
+	volatile u32 *mii_data_reg;
 	u32 timedout = 20;
 	u32 mii_control;
 
-	while (aup->mac->mii_control & MAC_MII_BUSY) {
+	#ifdef CONFIG_BCM5222_DUAL_PHY
+	if (aup->mii && aup->mii->mii_control_reg) {
+		mii_control_reg = aup->mii->mii_control_reg;
+		mii_data_reg = aup->mii->mii_data_reg;
+	}
+	else if (au_macs[0]->mii && au_macs[0]->mii->mii_control_reg) {
+		/* assume both phys are controlled through mac0 */
+		mii_control_reg = au_macs[0]->mii->mii_control_reg;
+		mii_data_reg = au_macs[0]->mii->mii_data_reg;
+	}
+	else 
+	#endif
+	{
+		/* default control and data reg addresses */
+		mii_control_reg = &aup->mac->mii_control;
+		mii_data_reg = &aup->mac->mii_data;
+	}
+
+	while (*mii_control_reg & MAC_MII_BUSY) {
 		mdelay(1);
 		if (--timedout == 0) {
 			printk(KERN_ERR "%s: mdio_write busy timeout!!\n", 
@@ -418,8 +895,8 @@
 	mii_control = MAC_SET_MII_SELECT_REG(reg) | 
 		MAC_SET_MII_SELECT_PHY(phy_id) | MAC_MII_WRITE;
 
-	aup->mac->mii_data = value;
-	aup->mac->mii_control = mii_control;
+	*mii_data_reg = value;
+	*mii_control_reg = mii_control;
 }
 
 
@@ -437,12 +914,13 @@
 	}
 }
 
-static int __init mii_probe (struct net_device * dev)
+static int mii_probe (struct net_device * dev)
 {
 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
 	int phy_addr;
-
-	aup->mii = NULL;
+#ifdef CONFIG_MIPS_BOSPORUS
+	int phy_found=0;
+#endif
 
 	/* search for total of 32 possible mii phy addresses */
 	for (phy_addr = 0; phy_addr < 32; phy_addr++) {
@@ -450,9 +928,17 @@
 		u16 phy_id0, phy_id1;
 		int i;
 
+		#ifdef CONFIG_BCM5222_DUAL_PHY
+		/* Mask the already found phy, try next one */
+		if (au_macs[0]->mii && au_macs[0]->mii->mii_control_reg) {
+			if (au_macs[0]->phy_addr == phy_addr)
+				continue;
+		}
+		#endif
+
 		mii_status = mdio_read(dev, phy_addr, MII_STATUS);
 		if (mii_status == 0xffff || mii_status == 0x0000)
-			/* the mii is not accessible, try next one */
+			/* the mii is not accessable, try next one */
 			continue;
 
 		phy_id0 = mdio_read(dev, phy_addr, MII_PHY_ID0);
@@ -462,6 +948,66 @@
 		for (i = 0; mii_chip_table[i].phy_id1; i++) {
 			if (phy_id0 == mii_chip_table[i].phy_id0 &&
 			    phy_id1 == mii_chip_table[i].phy_id1) {
+				struct mii_phy * mii_phy = aup->mii;
+
+				printk(KERN_INFO "%s: %s at phy address %d\n",
+				       dev->name, mii_chip_table[i].name, 
+				       phy_addr);
+#ifdef CONFIG_MIPS_BOSPORUS
+				phy_found = 1;
+#endif
+				mii_phy->chip_info = mii_chip_table+i;
+				aup->phy_addr = phy_addr;
+				aup->want_autoneg = 1;
+				aup->phy_ops = mii_chip_table[i].phy_ops;
+				aup->phy_ops->phy_init(dev,phy_addr);
+
+				// Check for dual-phy and then store required 
+				// values and set indicators. We need to do 
+				// this now since mdio_{read,write} need the 
+				// control and data register addresses.
+				#ifdef CONFIG_BCM5222_DUAL_PHY
+				if ( mii_chip_table[i].dual_phy) {
+
+					/* assume both phys are controlled 
+					 * through MAC0. Board specific? */
+					
+					/* sanity check */
+					if (!au_macs[0] || !au_macs[0]->mii)
+						return -1;
+					aup->mii->mii_control_reg = (u32 *)
+						&au_macs[0]->mac->mii_control;
+					aup->mii->mii_data_reg = (u32 *)
+						&au_macs[0]->mac->mii_data;
+				}
+				#endif
+				goto found;
+			}
+		}
+	}
+found:
+
+#ifdef CONFIG_MIPS_BOSPORUS
+	/* This is a workaround for the Micrel/Kendin 5 port switch
+	   The second MAC doesn't see a PHY connected... so we need to
+	   trick it into thinking we have one.
+		
+	   If this kernel is run on another Au1500 development board
+	   the stub will be found as well as the actual PHY. However,
+	   the last found PHY will be used... usually at Addr 31 (Db1500).	
+	*/
+	if ( (!phy_found) )
+	{
+		u16 phy_id0, phy_id1;
+		int i;
+
+		phy_id0 = 0x1234;
+		phy_id1 = 0x5678;
+
+		/* search our mii table for the current mii */ 
+		for (i = 0; mii_chip_table[i].phy_id1; i++) {
+			if (phy_id0 == mii_chip_table[i].phy_id0 &&
+			    phy_id1 == mii_chip_table[i].phy_id1) {
 				struct mii_phy * mii_phy;
 
 				printk(KERN_INFO "%s: %s at phy address %d\n",
@@ -471,31 +1017,39 @@
 						GFP_KERNEL);
 				if (mii_phy) {
 					mii_phy->chip_info = mii_chip_table+i;
-					mii_phy->phy_addr = phy_addr;
+					aup->phy_addr = phy_addr;
 					mii_phy->next = aup->mii;
 					aup->phy_ops = 
 						mii_chip_table[i].phy_ops;
 					aup->mii = mii_phy;
 					aup->phy_ops->phy_init(dev,phy_addr);
 				} else {
-					printk(KERN_ERR "%s: out of memory\n",
+					printk(KERN_ERR "%s: out of memory\n", 
 							dev->name);
 					return -1;
 				}
-				/* the current mii is on our mii_info_table,
-				   try next address */
+				mii_phy->chip_info = mii_chip_table+i;
+				aup->phy_addr = phy_addr;
+				aup->phy_ops = mii_chip_table[i].phy_ops;
+				aup->phy_ops->phy_init(dev,phy_addr);
 				break;
 			}
 		}
 	}
+	if (aup->mac_id == 0) {
+		/* the Bosporus phy responds to addresses 0-5 but 
+		 * 5 is the correct one.
+		 */
+		aup->phy_addr = 5;
+	}
+#endif
 
-	if (aup->mii == NULL) {
-		printk(KERN_ERR "%s: No MII transceivers found!\n", dev->name);
+	if (aup->mii->chip_info == NULL) {
+		printk(KERN_ERR "%s: Au1x No MII transceivers found!\n",
+				dev->name);
 		return -1;
 	}
 
-	/* use last PHY */
-	aup->phy_addr = aup->mii->phy_addr;
 	printk(KERN_INFO "%s: Using %s as default\n", 
 			dev->name, aup->mii->chip_info->name);
 
@@ -516,7 +1070,6 @@
 	if (pDB) {
 		aup->pDBfree = pDB->pnext;
 	}
-	//printk("GetFreeDB: %x\n", pDB);
 	return pDB;
 }
 
@@ -528,35 +1081,6 @@
 	aup->pDBfree = pDB;
 }
 
-
-/*
-  DMA memory allocation, derived from pci_alloc_consistent.
-  However, the Au1000 data cache is coherent (when programmed
-  so), therefore we return KSEG0 address, not KSEG1.
-*/
-static void *dma_alloc(size_t size, dma_addr_t * dma_handle)
-{
-	void *ret;
-	int gfp = GFP_ATOMIC | GFP_DMA;
-
-	ret = (void *) __get_free_pages(gfp, get_order(size));
-
-	if (ret != NULL) {
-		memset(ret, 0, size);
-		*dma_handle = virt_to_bus(ret);
-		ret = (void *)KSEG0ADDR(ret);
-	}
-	return ret;
-}
-
-
-static void dma_free(void *vaddr, size_t size)
-{
-	vaddr = (void *)KSEG0ADDR(vaddr);
-	free_pages((unsigned long) vaddr, get_order(size));
-}
-
-
 static void enable_rx_tx(struct net_device *dev)
 {
 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
@@ -582,6 +1106,7 @@
 
 static void reset_mac(struct net_device *dev)
 {
+	int i;
 	u32 flags;
 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
 
@@ -590,13 +1115,32 @@
 				dev->name, (unsigned)aup);
 
 	spin_lock_irqsave(&aup->lock, flags);
-	del_timer(&aup->timer);
+	if (aup->timer.function == &au1000_timer) {/* check if timer initted */
+		del_timer(&aup->timer);
+	}
+
 	hard_stop(dev);
-	*aup->enable = MAC_EN_CLOCK_ENABLE;
-	au_sync_delay(2);
-       	*aup->enable = 0;
-	au_sync_delay(2);
+	#ifdef CONFIG_BCM5222_DUAL_PHY
+	if (aup->mac_id != 0) {
+	#endif
+		/* If BCM5222, we can't leave MAC0 in reset because then 
+		 * we can't access the dual phy for ETH1 */
+		*aup->enable = MAC_EN_CLOCK_ENABLE;
+		au_sync_delay(2);
+		*aup->enable = 0;
+		au_sync_delay(2);
+	#ifdef CONFIG_BCM5222_DUAL_PHY
+	}
+	#endif
 	aup->tx_full = 0;
+	for (i = 0; i < NUM_RX_DMA; i++) {
+		/* reset control bits */
+		aup->rx_dma_ring[i]->buff_stat &= ~0xf;
+	}
+	for (i = 0; i < NUM_TX_DMA; i++) {
+		/* reset control bits */
+		aup->tx_dma_ring[i]->buff_stat &= ~0xf;
+	}
 	spin_unlock_irqrestore(&aup->lock, flags);
 }
 
@@ -611,93 +1155,348 @@
 {
 	int i;
 
-	for (i=0; i<NUM_RX_DMA; i++) {
+	for (i = 0; i < NUM_RX_DMA; i++) {
 		aup->rx_dma_ring[i] = 
 			(volatile rx_dma_t *) (rx_base + sizeof(rx_dma_t)*i);
 	}
-	for (i=0; i<NUM_TX_DMA; i++) {
+	for (i = 0; i < NUM_TX_DMA; i++) {
 		aup->tx_dma_ring[i] = 
 			(volatile tx_dma_t *) (tx_base + sizeof(tx_dma_t)*i);
 	}
 }
 
+static struct {
+	int port;
+	u32 base_addr;
+	u32 macen_addr;
+	int irq;
+	struct net_device *dev;
+} iflist[2];
+
+static int num_ifs;
+
+/*
+ * Setup the base address and interupt of the Au1xxx ethernet macs
+ * based on cpu type and whether the interface is enabled in sys_pinfunc
+ * register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0.
+ */
 static int __init au1000_init_module(void)
 {
-	int i;
-	int prid;
-	int base_addr, irq;
+	struct cpuinfo_mips *c = &current_cpu_data;
+	int ni = (int)((au_readl(SYS_PINFUNC) & (u32)(SYS_PF_NI2)) >> 4);
+	struct net_device *dev;
+	int i, found_one = 0;
 
-	prid = read_c0_prid();
-	for (i=0; i<NUM_INTERFACES; i++) {
-		if ( (prid & 0xffff0000) == 0x00030000 ) {
-			base_addr = au1000_iflist[i].port;
-			irq = au1000_iflist[i].irq;
-		} else if ( (prid & 0xffff0000) == 0x01030000 ) {
-			base_addr = au1500_iflist[i].port;
-			irq = au1500_iflist[i].irq;
-		} else if ( (prid & 0xffff0000) == 0x02030000 ) {
-			base_addr = au1100_iflist[i].port;
-			irq = au1100_iflist[i].irq;
+	switch (c->cputype) {
+#ifdef CONFIG_SOC_AU1000
+	case CPU_AU1000:
+		num_ifs = 2 - ni;
+		iflist[0].base_addr = AU1000_ETH0_BASE;
+		iflist[1].base_addr = AU1000_ETH1_BASE;
+		iflist[0].macen_addr = AU1000_MAC0_ENABLE;
+		iflist[1].macen_addr = AU1000_MAC1_ENABLE;
+		iflist[0].irq = AU1000_MAC0_DMA_INT;
+		iflist[1].irq = AU1000_MAC1_DMA_INT;
+		break;
+#endif
+#ifdef CONFIG_SOC_AU1100
+	case CPU_AU1100:
+		num_ifs = 1 - ni;
+		iflist[0].base_addr = AU1100_ETH0_BASE;
+		iflist[0].macen_addr = AU1100_MAC0_ENABLE;
+		iflist[0].irq = AU1100_MAC0_DMA_INT;
+		break;
+#endif
+#ifdef CONFIG_SOC_AU1500
+	case CPU_AU1500:
+		num_ifs = 2 - ni;
+		iflist[0].base_addr = AU1500_ETH0_BASE;
+		iflist[1].base_addr = AU1500_ETH1_BASE;
+		iflist[0].macen_addr = AU1500_MAC0_ENABLE;
+		iflist[1].macen_addr = AU1500_MAC1_ENABLE;
+		iflist[0].irq = AU1500_MAC0_DMA_INT;
+		iflist[1].irq = AU1500_MAC1_DMA_INT;
+		break;
+#endif
+#ifdef CONFIG_SOC_AU1550
+	case CPU_AU1550:
+		num_ifs = 2 - ni;
+		iflist[0].base_addr = AU1550_ETH0_BASE;
+		iflist[1].base_addr = AU1550_ETH1_BASE;
+		iflist[0].macen_addr = AU1550_MAC0_ENABLE;
+		iflist[1].macen_addr = AU1550_MAC1_ENABLE;
+		iflist[0].irq = AU1550_MAC0_DMA_INT;
+		iflist[1].irq = AU1550_MAC1_DMA_INT;
+		break;
+#endif
+	default:
+		num_ifs = 0;
+	}
+	for(i = 0; i < num_ifs; i++) {
+		dev = au1000_probe(iflist[i].base_addr, iflist[i].irq, i);
+		iflist[i].dev = dev;
+		if (dev)
+			found_one++;
+	}
+	if (!found_one)
+		return -ENODEV;
+	return 0;
+}
+
+static int au1000_setup_aneg(struct net_device *dev, u32 advertise)
+{
+	struct au1000_private *aup = (struct au1000_private *)dev->priv;
+	u16 ctl, adv;
+
+	/* Setup standard advertise */
+	adv = mdio_read(dev, aup->phy_addr, MII_ADVERTISE);
+	adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
+	if (advertise & ADVERTISED_10baseT_Half)
+		adv |= ADVERTISE_10HALF;
+	if (advertise & ADVERTISED_10baseT_Full)
+		adv |= ADVERTISE_10FULL;
+	if (advertise & ADVERTISED_100baseT_Half)
+		adv |= ADVERTISE_100HALF;
+	if (advertise & ADVERTISED_100baseT_Full)
+		adv |= ADVERTISE_100FULL;
+	mdio_write(dev, aup->phy_addr, MII_ADVERTISE, adv);
+
+	/* Start/Restart aneg */
+	ctl = mdio_read(dev, aup->phy_addr, MII_BMCR);
+	ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
+	mdio_write(dev, aup->phy_addr, MII_BMCR, ctl);
+
+	return 0;
+}
+
+static int au1000_setup_forced(struct net_device *dev, int speed, int fd)
+{
+	struct au1000_private *aup = (struct au1000_private *)dev->priv;
+	u16 ctl;
+
+	ctl = mdio_read(dev, aup->phy_addr, MII_BMCR);
+	ctl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_ANENABLE);
+
+	/* First reset the PHY */
+	mdio_write(dev, aup->phy_addr, MII_BMCR, ctl | BMCR_RESET);
+
+	/* Select speed & duplex */
+	switch (speed) {
+		case SPEED_10:
+			break;
+		case SPEED_100:
+			ctl |= BMCR_SPEED100;
+			break;
+		case SPEED_1000:
+		default:
+			return -EINVAL;
+	}
+	if (fd == DUPLEX_FULL)
+		ctl |= BMCR_FULLDPLX;
+	mdio_write(dev, aup->phy_addr, MII_BMCR, ctl);
+
+	return 0;
+}
+
+
+static void
+au1000_start_link(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct au1000_private *aup = (struct au1000_private *)dev->priv;
+	u32 advertise;
+	int autoneg;
+	int forced_speed;
+	int forced_duplex;
+
+	/* Default advertise */
+	advertise = GENMII_DEFAULT_ADVERTISE;
+	autoneg = aup->want_autoneg;
+	forced_speed = SPEED_100;
+	forced_duplex = DUPLEX_FULL;
+
+	/* Setup link parameters */
+	if (cmd) {
+		if (cmd->autoneg == AUTONEG_ENABLE) {
+			advertise = cmd->advertising;
+			autoneg = 1;
 		} else {
-			printk(KERN_ERR "au1000 eth: unknown Processor ID\n");
-			return -ENODEV;
-		}
-		// check for valid entries, au1100 only has one entry
-		if (base_addr && irq) {
-			if (au1000_probe1(base_addr, irq, i) != 0)
-				return -ENODEV;
+			autoneg = 0;
+
+			forced_speed = cmd->speed;
+			forced_duplex = cmd->duplex;
 		}
 	}
+
+	/* Configure PHY & start aneg */
+	aup->want_autoneg = autoneg;
+	if (autoneg)
+		au1000_setup_aneg(dev, advertise);
+	else
+		au1000_setup_forced(dev, forced_speed, forced_duplex);
+	mod_timer(&aup->timer, jiffies + HZ);
+}
+
+static int au1000_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct au1000_private *aup = (struct au1000_private *)dev->priv;
+	u16 link, speed;
+
+	cmd->supported = GENMII_DEFAULT_FEATURES;
+	cmd->advertising = GENMII_DEFAULT_ADVERTISE;
+	cmd->port = PORT_MII;
+	cmd->transceiver = XCVR_EXTERNAL;
+	cmd->phy_address = aup->phy_addr;
+	spin_lock_irq(&aup->lock);
+	cmd->autoneg = aup->want_autoneg;
+	aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed);
+	if ((speed == IF_PORT_100BASETX) || (speed == IF_PORT_100BASEFX))
+		cmd->speed = SPEED_100;
+	else if (speed == IF_PORT_10BASET)
+		cmd->speed = SPEED_10;
+	if (link && (dev->if_port == IF_PORT_100BASEFX))
+		cmd->duplex = DUPLEX_FULL;
+	else
+		cmd->duplex = DUPLEX_HALF;
+	spin_unlock_irq(&aup->lock);
 	return 0;
 }
 
-static int __init
-au1000_probe1(long ioaddr, int irq, int port_num)
+static int au1000_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	 struct au1000_private *aup = (struct au1000_private *)dev->priv;
+	  unsigned long features = GENMII_DEFAULT_FEATURES;
+
+	 if (!capable(CAP_NET_ADMIN))
+		 return -EPERM;
+
+	 if (cmd->autoneg != AUTONEG_ENABLE && cmd->autoneg != AUTONEG_DISABLE)
+		 return -EINVAL;
+	 if (cmd->autoneg == AUTONEG_ENABLE && cmd->advertising == 0)
+		 return -EINVAL;
+	 if (cmd->duplex != DUPLEX_HALF && cmd->duplex != DUPLEX_FULL)
+		 return -EINVAL;
+	 if (cmd->autoneg == AUTONEG_DISABLE)
+		 switch (cmd->speed) {
+		 case SPEED_10:
+			 if (cmd->duplex == DUPLEX_HALF &&
+				 (features & SUPPORTED_10baseT_Half) == 0)
+				 return -EINVAL;
+			 if (cmd->duplex == DUPLEX_FULL &&
+				 (features & SUPPORTED_10baseT_Full) == 0)
+				 return -EINVAL;
+			 break;
+		 case SPEED_100:
+			 if (cmd->duplex == DUPLEX_HALF &&
+				 (features & SUPPORTED_100baseT_Half) == 0)
+				 return -EINVAL;
+			 if (cmd->duplex == DUPLEX_FULL &&
+				 (features & SUPPORTED_100baseT_Full) == 0)
+				 return -EINVAL;
+			 break;
+		 default:
+			 return -EINVAL;
+		 }
+	 else if ((features & SUPPORTED_Autoneg) == 0)
+		 return -EINVAL;
+
+	 spin_lock_irq(&aup->lock);
+	 au1000_start_link(dev, cmd);
+	 spin_unlock_irq(&aup->lock);
+	 return 0;
+}
+
+static int au1000_nway_reset(struct net_device *dev)
+{
+	struct au1000_private *aup = (struct au1000_private *)dev->priv;
+
+	if (!aup->want_autoneg)
+		return -EINVAL;
+	spin_lock_irq(&aup->lock);
+	au1000_start_link(dev, NULL);
+	spin_unlock_irq(&aup->lock);
+	return 0;
+}
+
+static void
+au1000_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+	struct au1000_private *aup = (struct au1000_private *)dev->priv;
+
+	strcpy(info->driver, DRV_NAME);
+	strcpy(info->version, DRV_VERSION);
+	info->fw_version[0] = '\0';
+	sprintf(info->bus_info, "%s %d", DRV_NAME, aup->mac_id);
+	info->regdump_len = 0;
+}
+
+static u32 au1000_get_link(struct net_device *dev)
+{
+	return netif_carrier_ok(dev);
+}
+
+static struct ethtool_ops au1000_ethtool_ops = {
+	.get_settings = au1000_get_settings,
+	.set_settings = au1000_set_settings,
+	.get_drvinfo = au1000_get_drvinfo,
+	.nway_reset = au1000_nway_reset,
+	.get_link = au1000_get_link
+};
+
+static struct net_device *
+au1000_probe(u32 ioaddr, int irq, int port_num)
 {
-	struct net_device *dev;
 	static unsigned version_printed = 0;
 	struct au1000_private *aup = NULL;
-	int i, retval = 0;
+	struct net_device *dev = NULL;
 	db_dest_t *pDB, *pDBfree;
 	char *pmac, *argptr;
 	char ethaddr[6];
+	int i, err;
 
-	if (!request_region(PHYSADDR(ioaddr), MAC_IOSIZE, "Au1000 ENET"))
-		 return -ENODEV;
+	if (!request_mem_region(CPHYSADDR(ioaddr), MAC_IOSIZE, "Au1x00 ENET"))
+		return NULL;
 
-	if (version_printed++ == 0)
-		printk(version);
-
-	retval = -ENOMEM;
+	if (version_printed++ == 0) 
+		printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR);
 
 	dev = alloc_etherdev(sizeof(struct au1000_private));
 	if (!dev) {
 		printk (KERN_ERR "au1000 eth: alloc_etherdev failed\n");  
-		goto out;
+		return NULL;
 	}
 
-	SET_MODULE_OWNER(dev);
+	if ((err = register_netdev(dev))) {
+		printk(KERN_ERR "Au1x_eth Cannot register net device err %d\n",
+				err);
+		free_netdev(dev);
+		return NULL;
+	}
 
-	printk("%s: Au1xxx ethernet found at 0x%lx, irq %d\n", 
-	       dev->name, ioaddr, irq);
+	printk("%s: Au1x Ethernet found at 0x%x, irq %d\n", 
+			dev->name, ioaddr, irq);
 
 	aup = dev->priv;
 
 	/* Allocate the data buffers */
-	aup->vaddr = (u32)dma_alloc(MAX_BUF_SIZE * 
-			(NUM_TX_BUFFS+NUM_RX_BUFFS), &aup->dma_addr);
-	if (!aup->vaddr)
-		goto out1;
+	/* Snooping works fine with eth on all au1xxx */
+	aup->vaddr = (u32)dma_alloc_noncoherent(NULL,
+			MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS),
+			&aup->dma_addr,
+			0);
+	if (!aup->vaddr) {
+		free_netdev(dev);
+		release_mem_region(CPHYSADDR(ioaddr), MAC_IOSIZE);
+		return NULL;
+	}
 
 	/* aup->mac is the base address of the MAC's registers */
 	aup->mac = (volatile mac_reg_t *)((unsigned long)ioaddr);
 	/* Setup some variables for quick register address access */
-	switch (ioaddr) {
-	case AU1000_ETH0_BASE:
-	case AU1500_ETH0_BASE:
+	if (ioaddr == iflist[0].base_addr)
+	{
 		/* check env variables first */
 		if (!get_ethernet_addr(ethaddr)) { 
-			memcpy(au1000_mac_addr, ethaddr, sizeof(dev->dev_addr));
+			memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
 		} else {
 			/* Check command line */
 			argptr = prom_getcmdline();
@@ -708,38 +1507,32 @@
 			} else {
 				str2eaddr(ethaddr, pmac + strlen("ethaddr="));
 				memcpy(au1000_mac_addr, ethaddr, 
-						sizeof(dev->dev_addr));
+						sizeof(au1000_mac_addr));
 			}
 		}
-		if (ioaddr == AU1000_ETH0_BASE)
-			aup->enable = (volatile u32 *) 
-				((unsigned long)AU1000_MAC0_ENABLE);
-		else
 			aup->enable = (volatile u32 *) 
-				((unsigned long)AU1500_MAC0_ENABLE);
-		memcpy(dev->dev_addr, au1000_mac_addr, sizeof(dev->dev_addr));
+				((unsigned long)iflist[0].macen_addr);
+		memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr));
 		setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
-			break;
-	case AU1000_ETH1_BASE:
-	case AU1500_ETH1_BASE:
-		if (ioaddr == AU1000_ETH1_BASE)
-			aup->enable = (volatile u32 *) 
-				((unsigned long)AU1000_MAC1_ENABLE);
+		aup->mac_id = 0;
+		au_macs[0] = aup;
+	}
 		else
+	if (ioaddr == iflist[1].base_addr)
+	{
 			aup->enable = (volatile u32 *) 
-				((unsigned long)AU1500_MAC1_ENABLE);
-		memcpy(dev->dev_addr, au1000_mac_addr, sizeof(dev->dev_addr));
+				((unsigned long)iflist[1].macen_addr);
+		memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr));
 		dev->dev_addr[4] += 0x10;
 		setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
-			break;
-	default:
+		aup->mac_id = 1;
+		au_macs[1] = aup;
+	}
+	else
+	{
 		printk(KERN_ERR "%s: bad ioaddr\n", dev->name);
-		break;
-
 	}
 
-	aup->phy_addr = PHY_ADDRESS;
-
 	/* bring the device out of reset, otherwise probing the mii
 	 * will hang */
 	*aup->enable = MAC_EN_CLOCK_ENABLE;
@@ -748,15 +1541,22 @@
 		MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE;
 	au_sync_delay(2);
 
-	retval = mii_probe(dev);
-	if (retval)
-		 goto out2;
+	aup->mii = kmalloc(sizeof(struct mii_phy), GFP_KERNEL);
+	if (!aup->mii) {
+		printk(KERN_ERR "%s: out of memory\n", dev->name);
+		goto err_out;
+	}
+	aup->mii->mii_control_reg = 0;
+	aup->mii->mii_data_reg = 0;
+
+	if (mii_probe(dev) != 0) {
+		goto err_out;
+	}
 
-	retval = -EINVAL;
 	pDBfree = NULL;
 	/* setup the data buffer descriptors and attach a buffer to each one */
 	pDB = aup->db;
-	for (i=0; i<(NUM_TX_BUFFS+NUM_RX_BUFFS); i++) {
+	for (i = 0; i < (NUM_TX_BUFFS+NUM_RX_BUFFS); i++) {
 		pDB->pnext = pDBfree;
 		pDBfree = pDB;
 		pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i);
@@ -765,15 +1565,19 @@
 	}
 	aup->pDBfree = pDBfree;
 
-	for (i=0; i<NUM_RX_DMA; i++) {
+	for (i = 0; i < NUM_RX_DMA; i++) {
 		pDB = GetFreeDB(aup);
-		if (!pDB) goto out2;
+		if (!pDB) {
+			goto err_out;
+		}
 		aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
 		aup->rx_db_inuse[i] = pDB;
 	}
-	for (i=0; i<NUM_TX_DMA; i++) {
+	for (i = 0; i < NUM_TX_DMA; i++) {
 		pDB = GetFreeDB(aup);
-		if (!pDB) goto out2;
+		if (!pDB) {
+			goto err_out;
+		}
 		aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
 		aup->tx_dma_ring[i]->len = 0;
 		aup->tx_db_inuse[i] = pDB;
@@ -788,6 +1592,7 @@
 	dev->get_stats = au1000_get_stats;
 	dev->set_multicast_list = &set_rx_mode;
 	dev->do_ioctl = &au1000_ioctl;
+	SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
 	dev->set_config = &au1000_set_config;
 	dev->tx_timeout = au1000_tx_timeout;
 	dev->watchdog_timeo = ETH_TX_TIMEOUT;
@@ -798,23 +1603,32 @@
 	 */
 	reset_mac(dev);
 
-	retval = register_netdev(dev);
-	if (retval)
-		goto out2;
-	return 0;
+	return dev;
 
-out2:
-	dma_free(aup->vaddr, MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS));
-out1:
+err_out:
+	/* here we should have a valid dev plus aup-> register addresses
+	 * so we can reset the mac properly.*/
+	reset_mac(dev);
+	if (aup->mii)
+		kfree(aup->mii);
+	for (i = 0; i < NUM_RX_DMA; i++) {
+		if (aup->rx_db_inuse[i])
+			ReleaseDB(aup, aup->rx_db_inuse[i]);
+	}
+	for (i = 0; i < NUM_TX_DMA; i++) {
+		if (aup->tx_db_inuse[i])
+			ReleaseDB(aup, aup->tx_db_inuse[i]);
+	}
+	dma_free_noncoherent(NULL,
+			MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS),
+			(void *)aup->vaddr,
+			aup->dma_addr);
+	unregister_netdev(dev);
 	free_netdev(dev);
-out:
-	release_region(PHYSADDR(ioaddr), MAC_IOSIZE);
-	printk(KERN_ERR "%s: au1000_probe1 failed.  Returns %d\n",
-	       dev->name, retval);
-	return retval;
+	release_mem_region(CPHYSADDR(ioaddr), MAC_IOSIZE);
+	return NULL;
 }
 
-
 /* 
  * Initialize the interface.
  *
@@ -832,7 +1646,8 @@
 	u32 control;
 	u16 link, speed;
 
-	if (au1000_debug > 4) printk("%s: au1000_init\n", dev->name);
+	if (au1000_debug > 4) 
+		printk("%s: au1000_init\n", dev->name);
 
 	spin_lock_irqsave(&aup->lock, flags);
 
@@ -852,7 +1667,7 @@
 	aup->mac->mac_addr_low = dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 |
 		dev->dev_addr[1]<<8 | dev->dev_addr[0];
 
-	for (i=0; i<NUM_RX_DMA; i++) {
+	for (i = 0; i < NUM_RX_DMA; i++) {
 		aup->rx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE;
 	}
 	au_sync();
@@ -865,7 +1680,13 @@
 	if (link && (dev->if_port == IF_PORT_100BASEFX)) {
 		control |= MAC_FULL_DUPLEX;
 	}
+
+	/* fix for startup without cable */
+	if (!link) 
+		dev->flags &= ~IFF_RUNNING;
+
 	aup->mac->control = control;
+	aup->mac->vlan1_tag = 0x8100; /* activate vlan support */
 	au_sync();
 
 	spin_unlock_irqrestore(&aup->lock, flags);
@@ -949,6 +1770,7 @@
 		return retval;
 	}
 
+	init_timer(&aup->timer); /* used in ioctl() */
 	aup->timer.expires = RUN_AT((3*HZ)); 
 	aup->timer.data = (unsigned long)dev;
 	aup->timer.function = &au1000_timer; /* timer handler */
@@ -968,22 +1790,49 @@
 	if (au1000_debug > 4)
 		printk("%s: close: dev=%p\n", dev->name, dev);
 
+	reset_mac(dev);
+
 	spin_lock_irqsave(&aup->lock, flags);
 	
 	/* stop the device */
-	if (netif_device_present(dev))
-		netif_stop_queue(dev);
+	netif_stop_queue(dev);
 
 	/* disable the interrupt */
 	free_irq(dev->irq, dev);
 	spin_unlock_irqrestore(&aup->lock, flags);
 
-	reset_mac(dev);
 	return 0;
 }
 
 static void __exit au1000_cleanup_module(void)
 {
+	int i, j;
+	struct net_device *dev;
+	struct au1000_private *aup;
+
+	for (i = 0; i < num_ifs; i++) {
+		dev = iflist[i].dev;
+		if (dev) {
+			aup = (struct au1000_private *) dev->priv;
+			unregister_netdev(dev);
+			if (aup->mii)
+				kfree(aup->mii);
+			for (j = 0; j < NUM_RX_DMA; j++) {
+				if (aup->rx_db_inuse[j])
+					ReleaseDB(aup, aup->rx_db_inuse[j]);
+			}
+			for (j = 0; j < NUM_TX_DMA; j++) {
+				if (aup->tx_db_inuse[j])
+					ReleaseDB(aup, aup->tx_db_inuse[j]);
+			}
+			dma_free_noncoherent(NULL,
+					MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS),
+					(void *)aup->vaddr,
+					aup->dma_addr);
+			free_netdev(dev);
+			release_mem_region(CPHYSADDR(iflist[i].base_addr), MAC_IOSIZE);
+		}
+	}
 }
 
 
@@ -1028,9 +1877,8 @@
 	ptxd = aup->tx_dma_ring[aup->tx_tail];
 
 	while (ptxd->buff_stat & TX_T_DONE) {
- 		update_tx_stats(dev, ptxd->status, aup->tx_len[aup->tx_tail]  & 0x3ff);
+		update_tx_stats(dev, ptxd->status, ptxd->len & 0x3ff);
 		ptxd->buff_stat &= ~TX_T_DONE;
- 		aup->tx_len[aup->tx_tail] = 0;
 		ptxd->len = 0;
 		au_sync();
 
@@ -1056,7 +1904,7 @@
 	db_dest_t *pDB;
 	int i;
 
-	if (au1000_debug > 4)
+	if (au1000_debug > 5)
 		printk("%s: tx: aup %x len=%d, data=%p, head %d\n", 
 				dev->name, (unsigned)aup, skb->len, 
 				skb->data, aup->tx_head);
@@ -1070,8 +1918,7 @@
 		return 1;
 	}
 	else if (buff_stat & TX_T_DONE) {
- 		update_tx_stats(dev, ptxd->status, aup->tx_len[aup->tx_head] & 0x3ff);
- 		aup->tx_len[aup->tx_head] = 0;
+		update_tx_stats(dev, ptxd->status, ptxd->len & 0x3ff);
 		ptxd->len = 0;
 	}
 
@@ -1082,17 +1929,15 @@
 
 	pDB = aup->tx_db_inuse[aup->tx_head];
 	memcpy((void *)pDB->vaddr, skb->data, skb->len);
-	if (skb->len < MAC_MIN_PKT_SIZE) {
-		for (i=skb->len; i<MAC_MIN_PKT_SIZE; i++) { 
+	if (skb->len < ETH_ZLEN) {
+		for (i=skb->len; i<ETH_ZLEN; i++) { 
 			((char *)pDB->vaddr)[i] = 0;
 		}
- 		aup->tx_len[aup->tx_head] = MAC_MIN_PKT_SIZE;
-		ptxd->len = MAC_MIN_PKT_SIZE;
+		ptxd->len = ETH_ZLEN;
 	}
-	else {
- 		aup->tx_len[aup->tx_head] = skb->len;
+	else
 		ptxd->len = skb->len;
-	}
+
 	ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE;
 	au_sync();
 	dev_kfree_skb(skb);
@@ -1137,8 +1982,9 @@
 	volatile rx_dma_t *prxd;
 	u32 buff_stat, status;
 	db_dest_t *pDB;
+	u32	frmlen;
 
-	if (au1000_debug > 4)
+	if (au1000_debug > 5)
 		printk("%s: au1000_rx head %d\n", dev->name, aup->rx_head);
 
 	prxd = aup->rx_dma_ring[aup->rx_head];
@@ -1150,7 +1996,9 @@
 		if (!(status & RX_ERROR))  {
 
 			/* good frame */
-			skb = dev_alloc_skb((status & RX_FRAME_LEN_MASK) + 2);
+			frmlen = (status & RX_FRAME_LEN_MASK);
+			frmlen -= 4; /* Remove FCS */
+			skb = dev_alloc_skb(frmlen + 2);
 			if (skb == NULL) {
 				printk(KERN_ERR
 				       "%s: Memory squeeze, dropping packet.\n",
@@ -1160,9 +2008,9 @@
 			}
 			skb->dev = dev;
 			skb_reserve(skb, 2);	/* 16 byte IP header align */
-			eth_copy_and_sum(skb, (unsigned char *)pDB->vaddr, 
-					status & RX_FRAME_LEN_MASK, 0);
-			skb_put(skb, status & RX_FRAME_LEN_MASK);
+			eth_copy_and_sum(skb,
+				(unsigned char *)pDB->vaddr, frmlen, 0);
+			skb_put(skb, frmlen);
 			skb->protocol = eth_type_trans(skb, dev);
 			netif_rx(skb);	/* pass the packet to upper layers */
 		}
@@ -1206,17 +2054,20 @@
 /*
  * Au1000 interrupt service routine.
  */
-irqreturn_t au1000_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t au1000_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *) dev_id;
 
 	if (dev == NULL) {
 		printk(KERN_ERR "%s: isr: null dev ptr\n", dev->name);
-		return IRQ_NONE;
+		return IRQ_RETVAL(1);
 	}
-	au1000_tx_ack(dev);
+
+	/* Handle RX interrupts first to minimize chance of overrun */
+
 	au1000_rx(dev);
-	return IRQ_HANDLED;
+	au1000_tx_ack(dev);
+	return IRQ_RETVAL(1);
 }
 
 
@@ -1233,6 +2084,23 @@
 	netif_wake_queue(dev);
 }
 
+
+static unsigned const ethernet_polynomial = 0x04c11db7U;
+static inline u32 ether_crc(int length, unsigned char *data)
+{
+    int crc = -1;
+
+    while(--length >= 0) {
+		unsigned char current_octet = *data++;
+		int bit;
+		for (bit = 0; bit < 8; bit++, current_octet >>= 1)
+			crc = (crc << 1) ^
+				((crc < 0) ^ (current_octet & 1) ? 
+				 ethernet_polynomial : 0);
+    }
+    return crc;
+}
+
 static void set_rx_mode(struct net_device *dev)
 {
 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
@@ -1256,8 +2124,8 @@
 		mc_filter[1] = mc_filter[0] = 0;
 		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
 			 i++, mclist = mclist->next) {
-			set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr)>>26, 
-					mc_filter);
+			set_bit(ether_crc(ETH_ALEN, mclist->dmi_addr)>>26, 
+					(long *)mc_filter);
 		}
 		aup->mac->multi_hash_high = mc_filter[1];
 		aup->mac->multi_hash_low = mc_filter[0];
@@ -1269,28 +2137,28 @@
 
 static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
+	struct au1000_private *aup = (struct au1000_private *)dev->priv;
 	u16 *data = (u16 *)&rq->ifr_ifru;
 
-	/* fixme */
 	switch(cmd) { 
-	case SIOCGMIIPHY:	/* Get the address of the PHY in use. */
-		data[0] = PHY_ADDRESS;
-		return 0;
-
-	case SIOCGMIIREG:	/* Read the specified MII register. */
-		//data[3] = mdio_read(ioaddr, data[0], data[1]); 
-		return 0;
-
-	case SIOCSMIIREG:	/* Write the specified MII register */
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-
-		//mdio_write(ioaddr, data[0], data[1], data[2]);
-		return 0;
-
-	default:
-		return -EOPNOTSUPP;
+		case SIOCDEVPRIVATE:	/* Get the address of the PHY in use. */
+		case SIOCGMIIPHY:
+		        if (!netif_running(dev)) return -EINVAL;
+			data[0] = aup->phy_addr;
+		case SIOCDEVPRIVATE+1:	/* Read the specified MII register. */
+		case SIOCGMIIREG:
+			data[3] =  mdio_read(dev, data[0], data[1]); 
+			return 0;
+		case SIOCDEVPRIVATE+2:	/* Write the specified MII register */
+		case SIOCSMIIREG: 
+			if (!capable(CAP_NET_ADMIN))
+				return -EPERM;
+			mdio_write(dev, data[0], data[1],data[2]);
+			return 0;
+		default:
+			return -EOPNOTSUPP;
 	}
+
 }
 
 
@@ -1352,7 +2220,6 @@
 			/* set Speed to 100Mbps, Half Duplex */
 			/* disable auto negotiation and enable 100MBit Mode */
 			control = mdio_read(dev, aup->phy_addr, MII_CONTROL);
-			printk("read control %x\n", control);
 			control &= ~(MII_CNTL_AUTO | MII_CNTL_FDX);
 			control |= MII_CNTL_F100;
 			mdio_write(dev, aup->phy_addr, MII_CONTROL, control);
diff -Nru a/drivers/net/au1000_eth.h b/drivers/net/au1000_eth.h
--- a/drivers/net/au1000_eth.h	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/au1000_eth.h	2005-03-06 18:36:50 -05:00
@@ -1,10 +1,13 @@
 /*
- * Alchemy Semi Au1000 ethernet driver include file
+ *
+ * Alchemy Au1x00 ethernet driver include file
  *
  * Author: Pete Popov <ppopov@mvista.com>
  *
  * Copyright 2001 MontaVista Software Inc.
  *
+ * ########################################################################
+ *
  *  This program is free software; you can distribute it and/or modify it
  *  under the terms of the GNU General Public License (Version 2) as
  *  published by the Free Software Foundation.
@@ -17,14 +20,16 @@
  *  You should have received a copy of the GNU General Public License along
  *  with this program; if not, write to the Free Software Foundation, Inc.,
  *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * ########################################################################
+ *
+ * 
  */
-#include <linux/config.h>
 
 
-#define NUM_INTERFACES 2
 #define MAC_IOSIZE 0x10000
-#define NUM_RX_DMA 4       /* Au1000 has 4 rx hardware descriptors */
-#define NUM_TX_DMA 4       /* Au1000 has 4 tx hardware descriptors */
+#define NUM_RX_DMA 4       /* Au1x00 has 4 rx hardware descriptors */
+#define NUM_TX_DMA 4       /* Au1x00 has 4 tx hardware descriptors */
 
 #define NUM_RX_BUFFS 4
 #define NUM_TX_BUFFS 4
@@ -33,12 +38,6 @@
 #define ETH_TX_TIMEOUT HZ/4
 #define MAC_MIN_PKT_SIZE 64
 
-#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100)
-#define PHY_ADDRESS              0
-#define PHY_CONTROL_DEFAULT 0x3000
-#define PHY_CONTROL_REG_ADDR     0
-#endif
-
 #define MULTICAST_FILTER_LIMIT 64
 
 /* FIXME 
@@ -54,11 +53,13 @@
 #define MII_ANLPAR  0x0005
 #define MII_AEXP    0x0006
 #define MII_ANEXT   0x0007
-#define MII_LSI_CONFIG 0x0011
-#define MII_LSI_STAT   0x0012
-#define MII_AUX_CNTRL  0x0018
-#define MII_INT        0x001A
+#define MII_LSI_PHY_CONFIG 0x0011
+/* Status register */
+#define MII_LSI_PHY_STAT   0x0012
+#define MII_AMD_PHY_STAT   MII_LSI_PHY_STAT
+#define MII_INTEL_PHY_STAT 0x0011
 
+#define MII_AUX_CNTRL  0x0018
 /* mii registers specific to AMD 79C901 */
 #define	MII_STATUS_SUMMARY = 0x0018
 
@@ -121,23 +122,30 @@
 #define	MII_STSSUM_AUTO  0x0002
 #define MII_STSSUM_SPD   0x0001
 
-/* lsi status register */
-
-#define MII_LSI_STAT_FDX	0x0040
-#define MII_LSI_STAT_SPD	0x0080
+/* lsi phy status register */
+#define MII_LSI_PHY_STAT_FDX	0x0040
+#define MII_LSI_PHY_STAT_SPD	0x0080
+
+/* amd phy status register */
+#define MII_AMD_PHY_STAT_FDX	0x0800
+#define MII_AMD_PHY_STAT_SPD	0x0400
+
+/* intel phy status register */
+#define MII_INTEL_PHY_STAT_FDX	0x0200
+#define MII_INTEL_PHY_STAT_SPD	0x4000
 
 /* Auxilliary Control/Status Register */
 #define MII_AUX_FDX      0x0001
 #define MII_AUX_100      0x0002
 #define MII_AUX_F100     0x0004
 #define MII_AUX_ANEG     0x0008
-#define MII_FDX_LED	 0x8000
 
 typedef struct mii_phy {
 	struct mii_phy * next;
 	struct mii_chip_info * chip_info;
-	int phy_addr;
 	u16 status;
+	u32 *mii_control_reg;
+	u32 *mii_data_reg;
 } mii_phy_t;
 
 struct phy_ops {
@@ -197,7 +205,6 @@
 	db_dest_t db[NUM_RX_BUFFS+NUM_TX_BUFFS];
 	volatile rx_dma_t *rx_dma_ring[NUM_RX_DMA];
 	volatile tx_dma_t *tx_dma_ring[NUM_TX_DMA];
-	int tx_len[NUM_TX_DMA];
 	db_dest_t *rx_db_inuse[NUM_RX_DMA];
 	db_dest_t *tx_db_inuse[NUM_TX_DMA];
 	u32 rx_head;
@@ -205,6 +212,7 @@
 	u32 tx_tail;
 	u32 tx_full;
 
+	int mac_id;
 	mii_phy_t *mii;
 	struct phy_ops *phy_ops;
 	
@@ -218,9 +226,10 @@
 	u8 *hash_table;
 	u32 hash_mode;
 	u32 intr_work_done; /* number of Rx and Tx pkts processed in the isr */
-	u32 phy_addr;          /* PHY address */
+	int phy_addr;          /* phy address */
 	u32 options;           /* User-settable misc. driver options. */
 	u32 drv_flags;
+	int want_autoneg;
 	struct net_device_stats stats;
 	struct timer_list timer;
 	spinlock_t lock;       /* Serialise access to device */
diff -Nru a/drivers/net/bagetlance.c b/drivers/net/bagetlance.c
--- a/drivers/net/bagetlance.c	2005-03-06 18:36:50 -05:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,1368 +0,0 @@
-/*
- * bagetlance.c: Ethernet driver for VME Lance cards on Baget/MIPS
- *      This code stealed and adopted from linux/drivers/net/atarilance.c
- *      See that for author info
- *
- * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
- */
-
-/* 
- * Driver code for Baget/Lance taken from atarilance.c, which also
- * works well in case of Besta. Most significant changes made here
- * related with 16BIT-only access to A24 space.
- */
-
-static char *version = "bagetlance.c: v1.1 11/10/98\n";
-
-#include <linux/module.h>
-#include <linux/stddef.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/bitops.h>
-
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/baget/baget.h>
-
-#define BAGET_LANCE_IRQ  BAGET_IRQ_MASK(0xdf)
-
-/*
- *  Define following if you don't need 16BIT-only access to Lance memory
- *  (Normally BAGET needs it)
- */
-#undef NORMAL_MEM_ACCESS 
-
-/* Debug level:
- *  0 = silent, print only serious errors
- *  1 = normal, print error messages
- *  2 = debug, print debug infos
- *  3 = debug, print even more debug infos (packet data)
- */
-
-#define	LANCE_DEBUG	1  
-
-#ifdef LANCE_DEBUG
-static int lance_debug = LANCE_DEBUG;
-#else
-static int lance_debug = 1;
-#endif
-MODULE_PARM(lance_debug, "i");
-MODULE_PARM_DESC(lance_debug, "Lance debug level (0-3)");
-MODULE_LICENSE("GPL");
-
-/* Print debug messages on probing? */
-#undef LANCE_DEBUG_PROBE
-
-#define	DPRINTK(n,a)							\
-	do {										\
-		if (lance_debug >= n)					\
-			printk a;							\
-	} while( 0 )
-
-#ifdef LANCE_DEBUG_PROBE
-# define PROBE_PRINT(a)	printk a
-#else
-# define PROBE_PRINT(a)
-#endif
-
-/* These define the number of Rx and Tx buffers as log2. (Only powers
- * of two are valid)
- * Much more rx buffers (32) are reserved than tx buffers (8), since receiving
- * is more time critical then sending and packets may have to remain in the
- * board's memory when main memory is low.
- */
-
-/* Baget Lance has 64K on-board memory, so it looks we can't increase
-   buffer quantity (40*1.5K is about 64K) */
-
-#define TX_LOG_RING_SIZE			3
-#define RX_LOG_RING_SIZE			5
-
-/* These are the derived values */
-
-#define TX_RING_SIZE			(1 << TX_LOG_RING_SIZE)
-#define TX_RING_LEN_BITS		(TX_LOG_RING_SIZE << 5)
-#define	TX_RING_MOD_MASK		(TX_RING_SIZE - 1)
-
-#define RX_RING_SIZE			(1 << RX_LOG_RING_SIZE)
-#define RX_RING_LEN_BITS		(RX_LOG_RING_SIZE << 5)
-#define	RX_RING_MOD_MASK		(RX_RING_SIZE - 1)
-
-/* The LANCE Rx and Tx ring descriptors. */
-struct lance_rx_head {
-	volatile unsigned short	base;		/* Low word of base addr */
-#ifdef NORMAL_MEM_ACCESS
-       /* Following two fields are joined into one short to guarantee
-		  16BIT access to Baget lance registers */
-	volatile unsigned char	flag;
-	unsigned char			base_hi;	/* High word of base addr (unused) */
-#else
-/* Following macros are used as replecements to 8BIT fields */
-#define GET_FLAG(h)    (((h)->flag_base_hi >> 8) & 0xff)
-#define SET_FLAG(h,f)  (h)->flag_base_hi = ((h)->flag_base_hi & 0xff) | \
-		                                                (((unsigned)(f)) << 8)
-	volatile unsigned short flag_base_hi; 
-#endif
-	volatile short			buf_length;	/* This length is 2s complement! */
-	volatile short			msg_length;	/* This length is "normal". */
-};
-
-
-struct lance_tx_head {
-	volatile unsigned short	base;		/* Low word of base addr */
-#ifdef NORMAL_MEM_ACCESS 
-/* See comments above about 8BIT-access Baget A24-space problems */
-	volatile unsigned char	flag;
-	unsigned char			base_hi;	/* High word of base addr (unused) */
-#else
-	volatile unsigned short  flag_base_hi;
-#endif
-	volatile short			length;		/* Length is 2s complement! */
-	volatile short			misc;
-};
-
-struct ringdesc {
-	volatile unsigned short	adr_lo;		/* Low 16 bits of address */
-#ifdef NORMAL_MEM_ACCESS 
-/* See comments above about 8BIT-access Bage A24-space problems */
-	unsigned char	len;		/* Length bits */
-	unsigned char	adr_hi;		/* High 8 bits of address (unused) */
-#else
-	volatile unsigned short  len_adr_hi;
-#endif
-};
-
-/* The LANCE initialization block, described in databook. */
-struct lance_init_block {
-	unsigned short	mode;		/* Pre-set mode */
-	unsigned char	hwaddr[6];	/* Physical ethernet address */
-	unsigned		filter[2];	/* Multicast filter (unused). */
-	/* Receive and transmit ring base, along with length bits. */
-	struct ringdesc	rx_ring;
-	struct ringdesc	tx_ring;
-};
-
-/* The whole layout of the Lance shared memory */
-struct lance_memory {
-	struct lance_init_block	init;
-	struct lance_tx_head	tx_head[TX_RING_SIZE];
-	struct lance_rx_head	rx_head[RX_RING_SIZE];
-	char					packet_area[0];	/* packet data follow after the
-											 * init block and the ring
-											 * descriptors and are located
-											 * at runtime */
-};
-
-/* RieblCard specifics:
- * The original TOS driver for these cards reserves the area from offset
- * 0xee70 to 0xeebb for storing configuration data. Of interest to us is the
- * Ethernet address there, and the magic for verifying the data's validity.
- * The reserved area isn't touch by packet buffers. Furthermore, offset 0xfffe
- * is reserved for the interrupt vector number.
- */
-#define	RIEBL_RSVD_START	0xee70
-#define	RIEBL_RSVD_END		0xeec0
-#define RIEBL_MAGIC			0x09051990
-#define RIEBL_MAGIC_ADDR	((unsigned long *)(((char *)MEM) + 0xee8a))
-#define RIEBL_HWADDR_ADDR	((unsigned char *)(((char *)MEM) + 0xee8e))
-#define RIEBL_IVEC_ADDR		((unsigned short *)(((char *)MEM) + 0xfffe))
-
-/* This is a default address for the old RieblCards without a battery
- * that have no ethernet address at boot time. 00:00:36:04 is the
- * prefix for Riebl cards, the 00:00 at the end is arbitrary.
- */
-
-static unsigned char OldRieblDefHwaddr[6] = {
-	0x00, 0x00, 0x36, 0x04, 0x00, 0x00
-};
-
-/* I/O registers of the Lance chip */
-
-struct lance_ioreg {
-/* base+0x0 */	volatile unsigned short	data;
-/* base+0x2 */	volatile unsigned short	addr;
-				unsigned char			_dummy1[3];
-/* base+0x7 */	volatile unsigned char	ivec;
-				unsigned char			_dummy2[5];
-/* base+0xd */	volatile unsigned char	eeprom;
-				unsigned char			_dummy3;
-/* base+0xf */	volatile unsigned char	mem;
-};
-
-/* Types of boards this driver supports */
-
-enum lance_type {
-	OLD_RIEBL,		/* old Riebl card without battery */
-	NEW_RIEBL,		/* new Riebl card with battery */
-	PAM_CARD		/* PAM card with EEPROM */
-};
-
-static char *lance_names[] = {
-	"Riebl-Card (without battery)",
-	"Riebl-Card (with battery)",
-	"PAM intern card"
-};
-
-/* The driver's private device structure */
-
-struct lance_private {
-	enum lance_type		cardtype;
-	struct lance_ioreg	*iobase;
-	struct lance_memory	*mem;
-	int					cur_rx, cur_tx;	/* The next free ring entry */
-	int					dirty_tx;		/* Ring entries to be freed. */
-						/* copy function */
-	void				*(*memcpy_f)( void *, const void *, size_t );
-	struct net_device_stats stats;
-/* These two must be longs for set_bit() */
-	long				tx_full;
-	long				lock;
-};
-
-/* I/O register access macros */
-
-#define	MEM		lp->mem
-#define	DREG	IO->data
-#define	AREG	IO->addr
-#define	REGA(a)	( AREG = (a), DREG )
-
-/* Definitions for packet buffer access: */
-#define PKT_BUF_SZ		1544
-/* Get the address of a packet buffer corresponding to a given buffer head */
-#define	PKTBUF_ADDR(head)	(((unsigned char *)(MEM)) + (head)->base)
-
-/* Possible memory/IO addresses for probing */
-
-struct lance_addr {
-	unsigned long	memaddr;
-	unsigned long	ioaddr;
-	int				slow_flag;
-} lance_addr_list[] = {
-	{ BAGET_LANCE_MEM_BASE, BAGET_LANCE_IO_BASE, 1 }	/* Baget Lance */
-};
-
-#define	N_LANCE_ADDR	(sizeof(lance_addr_list)/sizeof(*lance_addr_list))
-
-
-#define LANCE_HI_BASE (0xff & (BAGET_LANCE_MEM_BASE >> 16))
-
-/* Definitions for the Lance */
-
-/* tx_head flags */
-#define TMD1_ENP		0x01	/* end of packet */
-#define TMD1_STP		0x02	/* start of packet */
-#define TMD1_DEF		0x04	/* deferred */
-#define TMD1_ONE		0x08	/* one retry needed */
-#define TMD1_MORE		0x10	/* more than one retry needed */
-#define TMD1_ERR		0x40	/* error summary */
-#define TMD1_OWN 		0x80	/* ownership (set: chip owns) */
-
-#define TMD1_OWN_CHIP	TMD1_OWN
-#define TMD1_OWN_HOST	0
-
-/* tx_head misc field */
-#define TMD3_TDR		0x03FF	/* Time Domain Reflectometry counter */
-#define TMD3_RTRY		0x0400	/* failed after 16 retries */
-#define TMD3_LCAR		0x0800	/* carrier lost */
-#define TMD3_LCOL		0x1000	/* late collision */
-#define TMD3_UFLO		0x4000	/* underflow (late memory) */
-#define TMD3_BUFF		0x8000	/* buffering error (no ENP) */
-
-/* rx_head flags */
-#define RMD1_ENP		0x01	/* end of packet */
-#define RMD1_STP		0x02	/* start of packet */
-#define RMD1_BUFF		0x04	/* buffer error */
-#define RMD1_CRC		0x08	/* CRC error */
-#define RMD1_OFLO		0x10	/* overflow */
-#define RMD1_FRAM		0x20	/* framing error */
-#define RMD1_ERR		0x40	/* error summary */
-#define RMD1_OWN 		0x80	/* ownership (set: ship owns) */
-
-#define RMD1_OWN_CHIP	RMD1_OWN
-#define RMD1_OWN_HOST	0
-
-/* register names */
-#define CSR0	0		/* mode/status */
-#define CSR1	1		/* init block addr (low) */
-#define CSR2	2		/* init block addr (high) */
-#define CSR3	3		/* misc */
-#define CSR8	8	  	/* address filter */
-#define CSR15	15		/* promiscuous mode */
-
-/* CSR0 */
-/* (R=readable, W=writeable, S=set on write, C=clear on write) */
-#define CSR0_INIT	0x0001		/* initialize (RS) */
-#define CSR0_STRT	0x0002		/* start (RS) */
-#define CSR0_STOP	0x0004		/* stop (RS) */
-#define CSR0_TDMD	0x0008		/* transmit demand (RS) */
-#define CSR0_TXON	0x0010		/* transmitter on (R) */
-#define CSR0_RXON	0x0020		/* receiver on (R) */
-#define CSR0_INEA	0x0040		/* interrupt enable (RW) */
-#define CSR0_INTR	0x0080		/* interrupt active (R) */
-#define CSR0_IDON	0x0100		/* initialization done (RC) */
-#define CSR0_TINT	0x0200		/* transmitter interrupt (RC) */
-#define CSR0_RINT	0x0400		/* receiver interrupt (RC) */
-#define CSR0_MERR	0x0800		/* memory error (RC) */
-#define CSR0_MISS	0x1000		/* missed frame (RC) */
-#define CSR0_CERR	0x2000		/* carrier error (no heartbeat :-) (RC) */
-#define CSR0_BABL	0x4000		/* babble: tx-ed too many bits (RC) */
-#define CSR0_ERR	0x8000		/* error (RC) */
-
-/* CSR3 */
-#define CSR3_BCON	0x0001		/* byte control */
-#define CSR3_ACON	0 // fixme: 0x0002		/* ALE control */
-#define CSR3_BSWP	0x0004		/* byte swap (1=big endian) */
-
-
-
-/***************************** Prototypes *****************************/
-
-static int addr_accessible( volatile void *regp, int wordflag, int
-                            writeflag );
-static int lance_probe1( struct net_device *dev, struct lance_addr *init_rec );
-static int lance_open( struct net_device *dev );
-static void lance_init_ring( struct net_device *dev );
-static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev );
-static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp );
-static int lance_rx( struct net_device *dev );
-static int lance_close( struct net_device *dev );
-static struct net_device_stats *lance_get_stats( struct net_device *dev );
-static void set_multicast_list( struct net_device *dev );
-static int lance_set_mac_address( struct net_device *dev, void *addr );
-
-/************************* End of Prototypes **************************/
-
-/* Network traffic statistic (bytes) */
-
-int lance_stat = 0;
-
-static void update_lance_stat (int len) {
-		lance_stat += len;
-}
-
-/* 
-   This function is used to access Baget/Lance memory to avoid 
-   8/32BIT access to VAC A24 space 
-   ALL memcpy calls was chenged to this function to avoid dbe problems
-   Don't confuse with function name -- it stays from original code
-*/
-
-void *slow_memcpy( void *dst, const void *src, size_t len )
-
-{	
-	unsigned long to     = (unsigned long)dst;
-	unsigned long from   = (unsigned long)src;
-	unsigned long to_end = to +len;
-	
-	/* Unaligned flags */
-
-	int odd_from   = from   & 1;
-	int odd_to     = to     & 1;
-	int odd_to_end = to_end & 1;
-
-	/* Align for 16BIT-access first */
-
-	register unsigned short *from_a   = (unsigned short*) (from   & ~1);
-	register unsigned short *to_a     = (unsigned short*) (to     & ~1); 
-	register unsigned short *to_end_a = (unsigned short*) (to_end & ~1);
-
-	/* Caching values -- not in loop invariant */
-
-	register unsigned short from_v; 
-	register unsigned short to_v;
-
-	/* Invariant is: from_a and to_a are pointers before or exactly to
-	   currently copying byte */
-
-	if (odd_to) { 
-			/* First byte unaligned case */
-			from_v = *from_a;
-			to_v   = *to_a;
-
-			to_v &= ~0xff;
-			to_v |=  0xff & (from_v >> (odd_from ? 0 : 8));
-			*to_a++ = to_v;
-
-			if (odd_from) from_a++;
-	}
-    if (odd_from == odd_to) {
-			/* Same parity */
-			while (to_a + 7 < to_end_a) {
-					unsigned long dummy1, dummy2;
-					unsigned long reg1, reg2, reg3, reg4;
-
-					__asm__ __volatile__(
-					".set\tnoreorder\n\t"
-					".set\tnoat\n\t"
-					"lh\t%2,0(%1)\n\t"
-					"nop\n\t"
-					 "lh\t%3,2(%1)\n\t"
-					"sh\t%2,0(%0)\n\t"
-					   "lh\t%4,4(%1)\n\t"
-					 "sh\t%3,2(%0)\n\t"
-					    "lh\t%5,6(%1)\n\t"
-					   "sh\t%4,4(%0)\n\t"
-					"lh\t%2,8(%1)\n\t"
-					    "sh\t%5,6(%0)\n\t"
-					 "lh\t%3,10(%1)\n\t"
-					"sh\t%2,8(%0)\n\t"
-					  "lh\t%4,12(%1)\n\t"
-					 "sh\t%3,10(%0)\n\t"
-					    "lh\t%5,14(%1)\n\t"
-					  "sh\t%4,12(%0)\n\t"
-					 "nop\n\t"
-					    "sh\t%5,14(%0)\n\t"
-					".set\tat\n\t"
-					".set\treorder"
-					:"=r" (dummy1), "=r" (dummy2),
-					"=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
-					:"0" (to_a), "1" (from_a)
-					:"memory");
-
-					to_a   += 8;
-					from_a += 8;
-
-			}
-			while (to_a < to_end_a) {
-					*to_a++ = *from_a++;
-			}
-	} else {
-			/* Different parity */
-			from_v = *from_a;
-			while (to_a < to_end_a) {
-					unsigned short from_v_next;
-					from_v_next = *++from_a;
-					*to_a++ = ((from_v & 0xff)<<8) | ((from_v_next>>8) & 0xff);
-					from_v = from_v_next; 
-			}
-
-	}
-	if (odd_to_end) {
-			/* Last byte unaligned case */
-			to_v = *to_a;
-			from_v = *from_a;
-
-			to_v &= ~0xff00;
-			if (odd_from == odd_to) {
-					to_v |= from_v & 0xff00;
-			} else {
-					to_v |= (from_v<<8) & 0xff00;
-			}
-
-			*to_a = to_v;
-	}
-
-	update_lance_stat( len );
-
-	return( dst );
-}
-
-
-struct net_device * __init bagetlance_probe(int unit)
-{
-	struct net_device *dev;
-	int i;
-	static int found;
-	int err = -ENODEV;
-
-	if (found)
-		/* Assume there's only one board possible... That seems true, since
-		 * the Riebl/PAM board's address cannot be changed. */
-		return ERR_PTR(-ENODEV);
-
-	dev = alloc_etherdev(sizeof(struct lance_private));
-	if (!dev)
-		return ERR_PTR(-ENOMEM);
-
-	SET_MODULE_OWNER(dev);
-
-	for( i = 0; i < N_LANCE_ADDR; ++i ) {
-		if (lance_probe1( dev, &lance_addr_list[i] )) {
-			found = 1;
-			break;
-		}
-	}
-	if (!found)
-		goto out;
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
-	return dev;
-out1:
-	free_irq(dev->irq, dev);
-out:
-	free_netdev(dev);
-	return ERR_PTR(err);
-}
-
-/* Derived from hwreg_present() in vme/config.c: */
-
-static int __init addr_accessible( volatile void *regp, 
-				   int wordflag, 
-				   int writeflag )
-{	
-		/* We have a fine function to do it */
-		extern int try_read(unsigned long, int);
-		return try_read((unsigned long)regp, sizeof(short)) != -1;   
-}
-
-
-
-/* Original atari driver uses it */
-#define IRQ_TYPE_PRIO SA_INTERRUPT
-#define IRQ_SOURCE_TO_VECTOR(x) (x)
-
-static int __init lance_probe1( struct net_device *dev,
-				struct lance_addr *init_rec )
-
-{	volatile unsigned short *memaddr =
-		(volatile unsigned short *)init_rec->memaddr;
-	volatile unsigned short *ioaddr =
-		(volatile unsigned short *)init_rec->ioaddr;
-	struct lance_private	*lp;
-	struct lance_ioreg		*IO;
-	int 					i;
-	static int 				did_version;
-	unsigned short			save1, save2;
-
-	PROBE_PRINT(( "Probing for Lance card at mem %#lx io %#lx\n",
-				  (long)memaddr, (long)ioaddr ));
-
-	/* Test whether memory readable and writable */
-	PROBE_PRINT(( "lance_probe1: testing memory to be accessible\n" ));
-	if (!addr_accessible( memaddr, 1, 1 )) goto probe_fail;
-
-	if ((unsigned long)memaddr >= KSEG2) {
-			/* FIXME: do we need to undo that on cleanup paths? */
-			extern int kseg2_alloc_io (unsigned long addr, unsigned long size);
-			if (kseg2_alloc_io((unsigned long)memaddr, BAGET_LANCE_MEM_SIZE)) {
-					printk("bagetlance: unable map lance memory\n");
-					goto probe_fail;
-			}
-	}
-
-	/* Written values should come back... */
-	PROBE_PRINT(( "lance_probe1: testing memory to be writable (1)\n" ));
-	save1 = *memaddr;
-	*memaddr = 0x0001;
-	if (*memaddr != 0x0001) goto probe_fail;
-	PROBE_PRINT(( "lance_probe1: testing memory to be writable (2)\n" ));
-	*memaddr = 0x0000;
-	if (*memaddr != 0x0000) goto probe_fail;
-	*memaddr = save1;
-
-	/* First port should be readable and writable */
-	PROBE_PRINT(( "lance_probe1: testing ioport to be accessible\n" ));
-	if (!addr_accessible( ioaddr, 1, 1 )) goto probe_fail;
-
-	/* and written values should be readable */
-	PROBE_PRINT(( "lance_probe1: testing ioport to be writeable\n" ));
-	save2 = ioaddr[1];
-	ioaddr[1] = 0x0001;
-	if (ioaddr[1] != 0x0001) goto probe_fail;
-
-	/* The CSR0_INIT bit should not be readable */
-	PROBE_PRINT(( "lance_probe1: testing CSR0 register function (1)\n" ));
-	save1 = ioaddr[0];
-	ioaddr[1] = CSR0;
-	ioaddr[0] = CSR0_INIT | CSR0_STOP;
-	if (ioaddr[0] != CSR0_STOP) {
-		ioaddr[0] = save1;
-		ioaddr[1] = save2;
-		goto probe_fail;
-	}
-	PROBE_PRINT(( "lance_probe1: testing CSR0 register function (2)\n" ));
-	ioaddr[0] = CSR0_STOP;
-	if (ioaddr[0] != CSR0_STOP) {
-		ioaddr[0] = save1;
-		ioaddr[1] = save2;
-		goto probe_fail;
-	}
-
-	/* Now ok... */
-	PROBE_PRINT(( "lance_probe1: Lance card detected\n" ));
-	goto probe_ok;
-
-  probe_fail:
-	return( 0 );
-
-  probe_ok:
-	lp = netdev_priv(dev);
-	MEM = (struct lance_memory *)memaddr;
-	IO = lp->iobase = (struct lance_ioreg *)ioaddr;
-	dev->base_addr = (unsigned long)ioaddr; /* informational only */
-	lp->memcpy_f = init_rec->slow_flag ? slow_memcpy : memcpy;
-
-	REGA( CSR0 ) = CSR0_STOP;
-
-	/* Now test for type: If the eeprom I/O port is readable, it is a
-	 * PAM card */
-	if (addr_accessible( &(IO->eeprom), 0, 0 )) {
-		/* Switch back to Ram */
-		i = IO->mem;
-		lp->cardtype = PAM_CARD;
-	}
-#ifdef NORMAL_MEM_ACCESS
-	else if (*RIEBL_MAGIC_ADDR == RIEBL_MAGIC) {
-#else
-	else if (({
-			unsigned short *a = (unsigned short*)RIEBL_MAGIC_ADDR;
-		    (((int)a[0]) << 16) + ((int)a[1]) == RIEBL_MAGIC;
-	})) {
-#endif
-		lp->cardtype = NEW_RIEBL;
-	}
-	else
-		lp->cardtype = OLD_RIEBL;
-
-	if (lp->cardtype == PAM_CARD ||
-		memaddr == (unsigned short *)0xffe00000) {
-		/* PAMs card and Riebl on ST use level 5 autovector */
-		if (request_irq(BAGET_LANCE_IRQ, lance_interrupt, IRQ_TYPE_PRIO,
-		            "PAM/Riebl-ST Ethernet", dev))
-			goto probe_fail;
-		dev->irq = (unsigned short)BAGET_LANCE_IRQ;
-	}
-	else {
-		/* For VME-RieblCards, request a free VME int;
-		 * (This must be unsigned long, since dev->irq is short and the
-		 * IRQ_MACHSPEC bit would be cut off...)
-		 */
-		unsigned long irq = BAGET_LANCE_IRQ; 
-		if (!irq) {
-			printk( "Lance: request for VME interrupt failed\n" );
-			goto probe_fail;
-		}
-		if (request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO,
-		            "Riebl-VME Ethernet", dev))
-			goto probe_fail;
-		dev->irq = irq;
-	}
-
-	printk("%s: %s at io %#lx, mem %#lx, irq %d%s, hwaddr ",
-		   dev->name, lance_names[lp->cardtype],
-		   (unsigned long)ioaddr,
-		   (unsigned long)memaddr,
-		   dev->irq,
-		   init_rec->slow_flag ? " (slow memcpy)" : "" );
-
-	/* Get the ethernet address */
-	switch( lp->cardtype ) {
-	  case OLD_RIEBL:
-		/* No ethernet address! (Set some default address) */
-		slow_memcpy( dev->dev_addr, OldRieblDefHwaddr, 6 );
-		break;
-	  case NEW_RIEBL:
-		lp->memcpy_f( dev->dev_addr, RIEBL_HWADDR_ADDR, 6 );
-		break;
-	  case PAM_CARD:
-		i = IO->eeprom;
-		for( i = 0; i < 6; ++i )
-			dev->dev_addr[i] =
-				((((unsigned short *)MEM)[i*2] & 0x0f) << 4) |
-				((((unsigned short *)MEM)[i*2+1] & 0x0f));
-		i = IO->mem;
-		break;
-	}
-	for( i = 0; i < 6; ++i )
-		printk( "%02x%s", dev->dev_addr[i], (i < 5) ? ":" : "\n" );
-	if (lp->cardtype == OLD_RIEBL) {
-		printk( "%s: Warning: This is a default ethernet address!\n",
-				dev->name );
-		printk( "      Use \"ifconfig hw ether ...\" to set the address.\n" );
-	}
-
-	MEM->init.mode = 0x0000;		/* Disable Rx and Tx. */
-
-	{
-			unsigned char hwaddr[6];
-			for( i = 0; i < 6; i++ ) 
-					hwaddr[i] = dev->dev_addr[i^1]; /* <- 16 bit swap! */
-			slow_memcpy(MEM->init.hwaddr, hwaddr, sizeof(hwaddr));
-	}
-
-	MEM->init.filter[0] = 0x00000000;
-	MEM->init.filter[1] = 0x00000000;
-	MEM->init.rx_ring.adr_lo = offsetof( struct lance_memory, rx_head );
-
-#ifdef NORMAL_MEM_ACCESS
-	MEM->init.rx_ring.adr_hi = LANCE_HI_BASE; 
-	MEM->init.rx_ring.len    = RX_RING_LEN_BITS;
-#else
-	MEM->init.rx_ring.len_adr_hi = 
-			((unsigned)RX_RING_LEN_BITS << 8) | LANCE_HI_BASE;
-#endif
-
-
-	MEM->init.tx_ring.adr_lo = offsetof( struct lance_memory, tx_head );
-
-#ifdef NORMAL_MEM_ACCESS
-	MEM->init.tx_ring.adr_hi = LANCE_HI_BASE; 
-	MEM->init.tx_ring.len    = TX_RING_LEN_BITS;
-#else
-	MEM->init.tx_ring.len_adr_hi = 
-			((unsigned)TX_RING_LEN_BITS<<8) | LANCE_HI_BASE;
-#endif
-
-	if (lp->cardtype == PAM_CARD)
-		IO->ivec = IRQ_SOURCE_TO_VECTOR(dev->irq);
-	else
-		*RIEBL_IVEC_ADDR = IRQ_SOURCE_TO_VECTOR(dev->irq);
-
-	if (did_version++ == 0)
-		DPRINTK( 1, ( version ));
-
-	/* The LANCE-specific entries in the device structure. */
-	dev->open = &lance_open;
-	dev->hard_start_xmit = &lance_start_xmit;
-	dev->stop = &lance_close;
-	dev->get_stats = &lance_get_stats;
-	dev->set_multicast_list = &set_multicast_list;
-	dev->set_mac_address = &lance_set_mac_address;
-	dev->start = 0;
-
-	memset( &lp->stats, 0, sizeof(lp->stats) );
-
-	return( 1 );
-}
-
-
-static int lance_open( struct net_device *dev )
-
-{	struct lance_private *lp = netdev_priv(dev);
-	struct lance_ioreg	 *IO = lp->iobase;
-	int i;
-
-	DPRINTK( 2, ( "%s: lance_open()\n", dev->name ));
-
-	lance_init_ring(dev);
-	/* Re-initialize the LANCE, and start it when done. */
-
-	REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0);
-	REGA( CSR2 ) = 0;
-	REGA( CSR1 ) = 0;
-	REGA( CSR0 ) = CSR0_INIT;
-	/* From now on, AREG is kept to point to CSR0 */
-
-	i = 1000000;
-	while (--i > 0)
-		if (DREG & CSR0_IDON)
-			break;
-	if (i < 0 || (DREG & CSR0_ERR)) {
-		DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n",
-					  dev->name, i, DREG ));
-		DREG = CSR0_STOP;
-		return( -EIO );
-	}
-	DREG = CSR0_IDON;
-	DREG = CSR0_STRT;
-	DREG = CSR0_INEA;
-
-	dev->tbusy = 0;
-	dev->interrupt = 0;
-	dev->start = 1;
-
-	DPRINTK( 2, ( "%s: LANCE is open, csr0 %04x\n", dev->name, DREG ));
-	return( 0 );
-}
-
-
-/* Initialize the LANCE Rx and Tx rings. */
-
-static void lance_init_ring( struct net_device *dev )
-
-{	struct lance_private *lp = netdev_priv(dev);
-	int i;
-	unsigned offset;
-
-	lp->lock = 0;
-	lp->tx_full = 0;
-	lp->cur_rx = lp->cur_tx = 0;
-	lp->dirty_tx = 0;
-
-	offset = offsetof( struct lance_memory, packet_area );
-
-/* If the packet buffer at offset 'o' would conflict with the reserved area
- * of RieblCards, advance it */
-#define	CHECK_OFFSET(o)														 \
-	do {																	 \
-		if (lp->cardtype == OLD_RIEBL || lp->cardtype == NEW_RIEBL) {		 \
-			if (((o) < RIEBL_RSVD_START) ? (o)+PKT_BUF_SZ > RIEBL_RSVD_START \
-										 : (o) < RIEBL_RSVD_END)			 \
-				(o) = RIEBL_RSVD_END;										 \
-		}																	 \
-	} while(0)
-
-	for( i = 0; i < TX_RING_SIZE; i++ ) {
-		CHECK_OFFSET(offset);
-		MEM->tx_head[i].base = offset;
-#ifdef NORMAL_MEM_ACCESS
-		MEM->tx_head[i].flag = TMD1_OWN_HOST;
- 		MEM->tx_head[i].base_hi = LANCE_HI_BASE;
-#else
-		MEM->tx_head[i].flag_base_hi = 
-				(TMD1_OWN_HOST<<8) | LANCE_HI_BASE;
-#endif
-		MEM->tx_head[i].length = 0;
-		MEM->tx_head[i].misc = 0;
-		offset += PKT_BUF_SZ;
-	}
-
-	for( i = 0; i < RX_RING_SIZE; i++ ) {
-		CHECK_OFFSET(offset);
-		MEM->rx_head[i].base = offset;
-#ifdef NORMAL_MEM_ACCESS
-		MEM->rx_head[i].flag = TMD1_OWN_CHIP;
-		MEM->rx_head[i].base_hi = LANCE_HI_BASE; 
-#else
-		MEM->rx_head[i].flag_base_hi = 
-				(TMD1_OWN_CHIP<<8) | LANCE_HI_BASE;
-#endif
-		MEM->rx_head[i].buf_length = -PKT_BUF_SZ;
-		MEM->rx_head[i].msg_length = 0;
-		offset += PKT_BUF_SZ;
-	}
-}
-
-
-static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
-
-{	struct lance_private *lp = netdev_priv(dev);
-	struct lance_ioreg	 *IO = lp->iobase;
-	int entry, len;
-	struct lance_tx_head *head;
-	unsigned long flags;
-
-	/* The old LANCE chips doesn't automatically pad buffers to min. size. */
-	len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
-	/* PAM-Card has a bug: Can only send packets with even number of bytes! */
-	if (lp->cardtype == PAM_CARD && (len & 1))
-		++len;
-
-	if (len > skb->len) {
-		skb = skb_padto(skb, len);
-		if (skb == NULL)
-			return 0;
-	}	
-
-	/* Transmitter timeout, serious problems. */
-	if (dev->tbusy) {
-		int tickssofar = jiffies - dev->trans_start;
-		if (tickssofar < 20)
-			return( 1 );
-		AREG = CSR0;
-		DPRINTK( 1, ( "%s: transmit timed out, status %04x, resetting.\n",
-					  dev->name, DREG ));
-		DREG = CSR0_STOP;
-		/*
-		 * Always set BSWP after a STOP as STOP puts it back into
-		 * little endian mode.
-		 */
-		REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0);
-		lp->stats.tx_errors++;
-#ifndef final_version
-		{	int i;
-			DPRINTK( 2, ( "Ring data: dirty_tx %d cur_tx %d%s cur_rx %d\n",
-						  lp->dirty_tx, lp->cur_tx,
-						  lp->tx_full ? " (full)" : "",
-						  lp->cur_rx ));
-			for( i = 0 ; i < RX_RING_SIZE; i++ )
-				DPRINTK( 2, ( "rx #%d: base=%04x blen=%04x mlen=%04x\n",
-							  i, MEM->rx_head[i].base,
-							  -MEM->rx_head[i].buf_length,
-							  MEM->rx_head[i].msg_length ));
-			for( i = 0 ; i < TX_RING_SIZE; i++ )
-				DPRINTK( 2, ( "tx #%d: base=%04x len=%04x misc=%04x\n",
-							  i, MEM->tx_head[i].base,
-							  -MEM->tx_head[i].length,
-							  MEM->tx_head[i].misc ));
-		}
-#endif
-		lance_init_ring(dev);
-		REGA( CSR0 ) = CSR0_INEA | CSR0_INIT | CSR0_STRT;
-
-		dev->tbusy = 0;
-		dev->trans_start = jiffies;
-
-		return( 0 );
-	}
-
-	DPRINTK( 2, ( "%s: lance_start_xmit() called, csr0 %4.4x.\n",
-				  dev->name, DREG ));
-
-	/* Block a timer-based transmit from overlapping.  This could better be
-	   done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
-	if (test_and_set_bit( 0, (void*)&dev->tbusy ) != 0) {
-		DPRINTK( 0, ( "%s: Transmitter access conflict.\n", dev->name ));
-		return 1;
-	}
-
-	if (test_and_set_bit( 0, (void*)&lp->lock ) != 0) {
-		DPRINTK( 0, ( "%s: tx queue lock!.\n", dev->name ));
-		/* don't clear dev->tbusy flag. */
-		return 1;
-	}
-
-	/* Fill in a Tx ring entry */
-	if (lance_debug >= 3) {
-		u_char *p;
-		int i;
-		printk( "%s: TX pkt type 0x%04x from ", dev->name,
-				((u_short *)skb->data)[6]);
-		for( p = &((u_char *)skb->data)[6], i = 0; i < 6; i++ )
-			printk("%02x%s", *p++, i != 5 ? ":" : "" );
-		printk(" to ");
-		for( p = (u_char *)skb->data, i = 0; i < 6; i++ )
-			printk("%02x%s", *p++, i != 5 ? ":" : "" );
-		printk(" data at 0x%08x len %d\n", (int)skb->data,
-			   (int)skb->len );
-	}
-
-	/* We're not prepared for the int until the last flags are set/reset. And
-	 * the int may happen already after setting the OWN_CHIP... */
-	save_flags(flags);
-	cli();
-
-	/* Mask to ring buffer boundary. */
-	entry = lp->cur_tx & TX_RING_MOD_MASK;
-	head  = &(MEM->tx_head[entry]);
-
-	/* Caution: the write order is important here, set the "ownership" bits
-	 * last.
-	 */
-
-	head->length = -len;
-	head->misc = 0;
-	lp->memcpy_f( PKTBUF_ADDR(head), (void *)skb->data, skb->len );
-#ifdef NORMAL_MEM_ACCESS
-	head->flag = TMD1_OWN_CHIP | TMD1_ENP | TMD1_STP;
-#else
-    SET_FLAG(head,(TMD1_OWN_CHIP | TMD1_ENP | TMD1_STP));
-#endif
-	lp->stats.tx_bytes += skb->len;
-	dev_kfree_skb( skb );
-	lp->cur_tx++;
-	while( lp->cur_tx >= TX_RING_SIZE && lp->dirty_tx >= TX_RING_SIZE ) {
-		lp->cur_tx -= TX_RING_SIZE;
-		lp->dirty_tx -= TX_RING_SIZE;
-	}
-
-	/* Trigger an immediate send poll. */
-	DREG = CSR0_INEA | CSR0_TDMD;
-	dev->trans_start = jiffies;
-
-	lp->lock = 0;
-#ifdef NORMAL_MEM_ACCESS
-	if ((MEM->tx_head[(entry+1) & TX_RING_MOD_MASK].flag & TMD1_OWN) ==
-#else
-	if ((GET_FLAG(&MEM->tx_head[(entry+1) & TX_RING_MOD_MASK]) & TMD1_OWN) ==
-#endif
-		TMD1_OWN_HOST)
-		dev->tbusy = 0;
-	else
-		lp->tx_full = 1;
-	restore_flags(flags);
-
-	return 0;
-}
-
-/* The LANCE interrupt handler. */
-
-static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp)
-{
-	struct net_device *dev = dev_id;
-	struct lance_private *lp;
-	struct lance_ioreg	 *IO;
-	int csr0, boguscnt = 10;
-	int handled = 0;
-
-	if (dev == NULL) {
-		DPRINTK( 1, ( "lance_interrupt(): interrupt for unknown device.\n" ));
-		return IRQ_NONE;
-	}
-
-	lp = netdev_priv(dev);
-	IO = lp->iobase;
-	AREG = CSR0;
-
-	if (dev->interrupt) {
-			DPRINTK( 1, ( "Re-entering CAUSE=%08x STATUS=%08x\n",  
-						  read_32bit_cp0_register(CP0_CAUSE),  
-						  read_32bit_cp0_register(CP0_STATUS) ));
-			panic("lance: interrupt handler reentered !");
-	}
-
-	dev->interrupt = 1;
-
-	while( ((csr0 = DREG) & (CSR0_ERR | CSR0_TINT | CSR0_RINT)) &&
-		   --boguscnt >= 0) {
-		handled = 1;
-		/* Acknowledge all of the current interrupt sources ASAP. */
-		DREG = csr0 & ~(CSR0_INIT | CSR0_STRT | CSR0_STOP |
-									CSR0_TDMD | CSR0_INEA);
-
-		DPRINTK( 2, ( "%s: interrupt  csr0=%04x new csr=%04x.\n",
-					  dev->name, csr0, DREG ));
-
-		if (csr0 & CSR0_RINT)			/* Rx interrupt */
-			lance_rx( dev );
-
-		if (csr0 & CSR0_TINT) {			/* Tx-done interrupt */
-			int dirty_tx = lp->dirty_tx;
-
-			while( dirty_tx < lp->cur_tx) {
-				int entry = dirty_tx & TX_RING_MOD_MASK;
-#ifdef NORMAL_MEM_ACCESS
-				int status = MEM->tx_head[entry].flag;
-#else
-				int status = GET_FLAG(&MEM->tx_head[entry]);
-#endif
-				if (status & TMD1_OWN_CHIP)
-					break;			/* It still hasn't been Txed */
-
-#ifdef NORMAL_MEM_ACCESS
-				MEM->tx_head[entry].flag = 0;
-#else
-				SET_FLAG(&MEM->tx_head[entry],0);
-#endif
-
-				if (status & TMD1_ERR) {
-					/* There was an major error, log it. */
-					int err_status = MEM->tx_head[entry].misc;
-					lp->stats.tx_errors++;
-					if (err_status & TMD3_RTRY) lp->stats.tx_aborted_errors++;
-					if (err_status & TMD3_LCAR) lp->stats.tx_carrier_errors++;
-					if (err_status & TMD3_LCOL) lp->stats.tx_window_errors++;
-					if (err_status & TMD3_UFLO) {
-						/* Ackk!  On FIFO errors the Tx unit is turned off! */
-						lp->stats.tx_fifo_errors++;
-						/* Remove this verbosity later! */
-						DPRINTK( 1, ( "%s: Tx FIFO error! Status %04x\n",
-									  dev->name, csr0 ));
-						/* Restart the chip. */
-						DREG = CSR0_STRT;
-					}
-				} else {
-					if (status & (TMD1_MORE | TMD1_ONE | TMD1_DEF))
-						lp->stats.collisions++;
-					lp->stats.tx_packets++;
-				}
-				dirty_tx++;
-			}
-
-#ifndef final_version
-			if (lp->cur_tx - dirty_tx >= TX_RING_SIZE) {
-				DPRINTK( 0, ( "out-of-sync dirty pointer,"
-							  " %d vs. %d, full=%d.\n",
-							  dirty_tx, lp->cur_tx, lp->tx_full ));
-				dirty_tx += TX_RING_SIZE;
-			}
-#endif
-
-			if (lp->tx_full && dev->tbusy
-				&& dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) {
-				/* The ring is no longer full, clear tbusy. */
-				lp->tx_full = 0;
-				dev->tbusy = 0;
-				mark_bh( NET_BH );
-			}
-
-			lp->dirty_tx = dirty_tx;
-		}
-
-		/* Log misc errors. */
-		if (csr0 & CSR0_BABL) lp->stats.tx_errors++; /* Tx babble. */
-		if (csr0 & CSR0_MISS) lp->stats.rx_errors++; /* Missed a Rx frame. */
-		if (csr0 & CSR0_MERR) {
-			DPRINTK( 1, ( "%s: Bus master arbitration failure (?!?), "
-						  "status %04x.\n", dev->name, csr0 ));
-			/* Restart the chip. */
-			DREG = CSR0_STRT;
-		}
-	}
-
-    /* Clear any other interrupt, and set interrupt enable. */
-	DREG = CSR0_BABL | CSR0_CERR | CSR0_MISS | CSR0_MERR |
-		   CSR0_IDON | CSR0_INEA;
-
-	DPRINTK( 2, ( "%s: exiting interrupt, csr0=%#04x.\n",
-				  dev->name, DREG ));
-	dev->interrupt = 0;
-	return IRQ_RETVAL(handled);
-}
-
-
-static int lance_rx( struct net_device *dev )
-
-{	struct lance_private *lp = netdev_priv(dev);
-	int entry = lp->cur_rx & RX_RING_MOD_MASK;
-	int i;
-
-#ifdef NORMAL_MEM_ACCESS
-	DPRINTK( 2, ( "%s: rx int, flag=%04x\n", dev->name,
-				  MEM->rx_head[entry].flag ));
-#else
-	DPRINTK( 2, ( "%s: rx int, flag=%04x\n", dev->name,
-				  GET_FLAG(&MEM->rx_head[entry]) ));
-#endif
-
-	/* If we own the next entry, it's a new packet. Send it up. */
-#ifdef NORMAL_MEM_ACCESS
-	while( (MEM->rx_head[entry].flag & RMD1_OWN) == RMD1_OWN_HOST ) {
-#else
-	while( (GET_FLAG(&MEM->rx_head[entry]) & RMD1_OWN) == RMD1_OWN_HOST ) {
-#endif
-		struct lance_rx_head *head = &(MEM->rx_head[entry]);
-#ifdef NORMAL_MEM_ACCESS
-		int status = head->flag;
-#else
-		int status = GET_FLAG(head);
-#endif
-
-		if (status != (RMD1_ENP|RMD1_STP)) {		/* There was an error. */
-			/* There is a tricky error noted by John Murphy,
-			   <murf@perftech.com> to Russ Nelson: Even with full-sized
-			   buffers it's possible for a jabber packet to use two
-			   buffers, with only the last correctly noting the error. */
-			if (status & RMD1_ENP)	/* Only count a general error at the */
-				lp->stats.rx_errors++; /* end of a packet.*/
-			if (status & RMD1_FRAM) lp->stats.rx_frame_errors++;
-			if (status & RMD1_OFLO) lp->stats.rx_over_errors++;
-			if (status & RMD1_CRC) lp->stats.rx_crc_errors++;
-			if (status & RMD1_BUFF) lp->stats.rx_fifo_errors++;
-#ifdef NORMAL_MEM_ACCESS
-			head->flag &= (RMD1_ENP|RMD1_STP);
-#else
-			SET_FLAG(head,GET_FLAG(head) & (RMD1_ENP|RMD1_STP));
-#endif
-		} else {
-			/* Malloc up new buffer, compatible with net-3. */
-			short pkt_len = head->msg_length & 0xfff;
-			struct sk_buff *skb;
-
-			if (pkt_len < 60) {
-				printk( "%s: Runt packet!\n", dev->name );
-				lp->stats.rx_errors++;
-			}
-			else {
-				skb = dev_alloc_skb( pkt_len+2 );
-				if (skb == NULL) {
-					DPRINTK( 1, ( "%s: Memory squeeze, deferring packet.\n",
-								  dev->name ));
-                          for( i = 0; i < RX_RING_SIZE; i++ )
-#ifdef NORMAL_MEM_ACCESS
-                        if (MEM->rx_head[(entry+i) & RX_RING_MOD_MASK].flag &
-#else
-						if (GET_FLAG(&MEM->rx_head[(entry+i) & \
-												  RX_RING_MOD_MASK]) &
-#endif
-							RMD1_OWN_CHIP)
-							break;
-
-					if (i > RX_RING_SIZE - 2) {
-						lp->stats.rx_dropped++;
-#ifdef NORMAL_MEM_ACCESS
-                        head->flag |= RMD1_OWN_CHIP;
-#else
-                        SET_FLAG(head,GET_FLAG(head) | RMD1_OWN_CHIP);
-#endif
-						lp->cur_rx++;
-					}
-					break;
-				}
-
-				if (lance_debug >= 3) {
-					u_char *data = PKTBUF_ADDR(head), *p;
-					printk( "%s: RX pkt type 0x%04x from ", dev->name,
-							((u_short *)data)[6]);
-					for( p = &data[6], i = 0; i < 6; i++ )
-						printk("%02x%s", *p++, i != 5 ? ":" : "" );
-					printk(" to ");
-					for( p = data, i = 0; i < 6; i++ )
-						printk("%02x%s", *p++, i != 5 ? ":" : "" );
-					printk(" data %02x %02x %02x %02x %02x %02x %02x %02x "
-						   "len %d\n",
-						   data[15], data[16], data[17], data[18],
-						   data[19], data[20], data[21], data[22],
-						   pkt_len );
-				}
-
-				skb->dev = dev;
-				skb_reserve( skb, 2 );	/* 16 byte align */
-				skb_put( skb, pkt_len );	/* Make room */
-				lp->memcpy_f( skb->data, PKTBUF_ADDR(head), pkt_len );
-				skb->protocol = eth_type_trans( skb, dev );
-				netif_rx( skb );
-				dev->last_rx = jiffies;
-				lp->stats.rx_packets++;
-				lp->stats.rx_bytes += pkt_len;
-			}
-		}
-
-#ifdef NORMAL_MEM_ACCESS
-		head->flag |= RMD1_OWN_CHIP;
-#else
-		SET_FLAG(head,GET_FLAG(head) | RMD1_OWN_CHIP);
-#endif
-		entry = (++lp->cur_rx) & RX_RING_MOD_MASK;
-	}
-	lp->cur_rx &= RX_RING_MOD_MASK;
-
-	/* From lance.c (Donald Becker): */
-	/* We should check that at least two ring entries are free.	 If not,
-	   we should free one and mark stats->rx_dropped++. */
-
-	return 0;
-}
-
-
-static int lance_close( struct net_device *dev )
-
-{	struct lance_private *lp = netdev_priv(dev);
-	struct lance_ioreg	 *IO = lp->iobase;
-
-	dev->start = 0;
-	dev->tbusy = 1;
-
-	AREG = CSR0;
-
-	DPRINTK( 2, ( "%s: Shutting down ethercard, status was %2.2x.\n",
-				  dev->name, DREG ));
-
-	/* We stop the LANCE here -- it occasionally polls
-	   memory if we don't. */
-	DREG = CSR0_STOP;
-
-	return 0;
-}
-
-
-static struct net_device_stats *lance_get_stats( struct net_device *dev )
-
-{	
-	struct lance_private *lp = netdev_priv(dev);
-	return &lp->stats;
-}
-
-
-/* Set or clear the multicast filter for this adaptor.
-   num_addrs == -1		Promiscuous mode, receive all packets
-   num_addrs == 0		Normal mode, clear multicast list
-   num_addrs > 0		Multicast mode, receive normal and MC packets, and do
-						best-effort filtering.
- */
-
-static void set_multicast_list( struct net_device *dev )
-
-{	struct lance_private *lp = netdev_priv(dev);
-	struct lance_ioreg	 *IO = lp->iobase;
-
-	if (!dev->start)
-		/* Only possible if board is already started */
-		return;
-
-	/* We take the simple way out and always enable promiscuous mode. */
-	DREG = CSR0_STOP; /* Temporarily stop the lance. */
-
-	if (dev->flags & IFF_PROMISC) {
-		/* Log any net taps. */
-		DPRINTK( 1, ( "%s: Promiscuous mode enabled.\n", dev->name ));
-		REGA( CSR15 ) = 0x8000; /* Set promiscuous mode */
-	} else {
-		short multicast_table[4];
-		int num_addrs = dev->mc_count;
-		int i;
-		/* We don't use the multicast table, but rely on upper-layer
-		 * filtering. */
-		memset( multicast_table, (num_addrs == 0) ? 0 : -1,
-				sizeof(multicast_table) );
-		for( i = 0; i < 4; i++ )
-			REGA( CSR8+i ) = multicast_table[i];
-		REGA( CSR15 ) = 0; /* Unset promiscuous mode */
-	}
-
-	/*
-	 * Always set BSWP after a STOP as STOP puts it back into
-	 * little endian mode.
-	 */
-	REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0);
-
-	/* Resume normal operation and reset AREG to CSR0 */
-	REGA( CSR0 ) = CSR0_IDON | CSR0_INEA | CSR0_STRT;
-}
-
-
-/* This is needed for old RieblCards and possible for new RieblCards */
-
-static int lance_set_mac_address( struct net_device *dev, void *addr )
-
-{	struct lance_private *lp = netdev_priv(dev);
-	struct sockaddr *saddr = addr;
-	int i;
-
-	if (lp->cardtype != OLD_RIEBL && lp->cardtype != NEW_RIEBL)
-		return( -EOPNOTSUPP );
-
-	if (dev->start) {
-		/* Only possible while card isn't started */
-		DPRINTK( 1, ( "%s: hwaddr can be set only while card isn't open.\n",
-					  dev->name ));
-		return( -EIO );
-	}
-
-	slow_memcpy( dev->dev_addr, saddr->sa_data, dev->addr_len );
-
-	{
-			unsigned char hwaddr[6];
-			for( i = 0; i < 6; i++ ) 
-					hwaddr[i] = dev->dev_addr[i^1]; /* <- 16 bit swap! */
-			slow_memcpy(MEM->init.hwaddr, hwaddr, sizeof(hwaddr));
-	}
-
-	lp->memcpy_f( RIEBL_HWADDR_ADDR, dev->dev_addr, 6 );
-	/* set also the magic for future sessions */
-#ifdef NORMAL_MEM_ACCESS
-	*RIEBL_MAGIC_ADDR = RIEBL_MAGIC;
-#else
-	{
-			unsigned long magic = RIEBL_MAGIC;
-			slow_memcpy(RIEBL_MAGIC_ADDR, &magic, sizeof(*RIEBL_MAGIC_ADDR));
-	}
-#endif
-	return( 0 );
-}
-
-
-#ifdef MODULE
-static struct net_device *bagetlance_dev;
-
-int init_module(void)
-{
-	bagetlance_dev = bagetlance_probe(-1);
-	if (IS_ERR(bagetlance_dev))
-		return PTR_ERR(bagetlance_dev);
-	return 0;
-}
-
-void cleanup_module(void)
-{
-	unregister_netdev(bagetlance_dev);
-	free_irq(bagetlance_dev->irq, bagetlance_dev);
-	free_netdev(bagetlance_dev);
-}
-
-#endif /* MODULE */
-
-/*
- * Local variables:
- *  c-indent-level: 4
- *  tab-width: 4
- * End:
- */
diff -Nru a/drivers/net/dl2k.c b/drivers/net/dl2k.c
--- a/drivers/net/dl2k.c	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/dl2k.c	2005-03-06 18:36:50 -05:00
@@ -1199,7 +1199,7 @@
 static void rio_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
 	struct netdev_private *np = netdev_priv(dev);
-	strcpy(info->driver, "DL2K");
+	strcpy(info->driver, "dl2k");
 	strcpy(info->version, DRV_VERSION);
 	strcpy(info->bus_info, pci_name(np->pdev));
 }	
diff -Nru a/drivers/net/gianfar.c b/drivers/net/gianfar.c
--- a/drivers/net/gianfar.c	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/gianfar.c	2005-03-06 18:36:50 -05:00
@@ -377,6 +377,8 @@
 			ADVERTISED_1000baseT_Full);
 	mii_info->autoneg = 1;
 
+	spin_lock_init(&mii_info->mdio_lock);
+
 	mii_info->mii_id = priv->einfo->phyid;
 
 	mii_info->dev = dev;
diff -Nru a/drivers/net/ibm_emac/ibm_emac.h b/drivers/net/ibm_emac/ibm_emac.h
--- a/drivers/net/ibm_emac/ibm_emac.h	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/ibm_emac/ibm_emac.h	2005-03-06 18:36:50 -05:00
@@ -237,6 +237,10 @@
 #define EMAC_RWMR_DEFAULT		0x1000a200
 #define EMAC_TMR0_DEFAULT		EMAC_TMR0_TFAE_2_32
 #define EMAC_TMR1_DEFAULT		0xa00f0000
+#elif defined(CONFIG_440SP)
+#define EMAC_RWMR_DEFAULT		0x08002000
+#define EMAC_TMR0_DEFAULT		EMAC_TMR0_TFAE_128_2048
+#define EMAC_TMR1_DEFAULT		0xf8200000
 #else
 #define EMAC_RWMR_DEFAULT		0x0f002000
 #define EMAC_TMR0_DEFAULT		0x00000000
diff -Nru a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c
--- a/drivers/net/ibm_emac/ibm_emac_core.c	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/ibm_emac/ibm_emac_core.c	2005-03-06 18:36:50 -05:00
@@ -1041,7 +1041,7 @@
 	/* set speed (default is 10Mb) */
 	switch (speed) {
 	case SPEED_1000:
-		mode_reg |= EMAC_M1_JUMBO_ENABLE | EMAC_M1_RFS_16K;
+		mode_reg |= EMAC_M1_RFS_16K;
 		if (fep->rgmii_dev) {
 			struct ibm_ocp_rgmii *rgmii = RGMII_PRIV(fep->rgmii_dev);
 
@@ -1118,6 +1118,7 @@
 {
 	struct ocp_enet_private *fep = dev->priv;
 	int old_mtu = dev->mtu;
+	unsigned long mode_reg;
 	emac_t *emacp = fep->emacp;
 	u32 em0mr0;
 	int i, full;
@@ -1160,10 +1161,17 @@
 			fep->rx_skb[i] = NULL;
 		}
 
-		/* Set new rx_buffer_size and advertise new mtu */
-		fep->rx_buffer_size =
-		    new_mtu + ENET_HEADER_SIZE + ENET_FCS_SIZE;
+		/* Set new rx_buffer_size, jumbo cap, and advertise new mtu */
+		mode_reg = in_be32(&emacp->em0mr1);
+		if (new_mtu > ENET_DEF_MTU_SIZE) {
+			mode_reg |= EMAC_M1_JUMBO_ENABLE;
+			fep->rx_buffer_size = EMAC_MAX_FRAME;
+		} else {
+			mode_reg &= ~EMAC_M1_JUMBO_ENABLE;
+			fep->rx_buffer_size = ENET_DEF_BUF_SIZE;
+		}
 		dev->mtu = new_mtu;
+		out_be32(&emacp->em0mr1, mode_reg);
 
 		/* Re-init rx skbs */
 		fep->rx_slot = 0;
diff -Nru a/drivers/net/ibm_emac/ibm_emac_core.h b/drivers/net/ibm_emac/ibm_emac_core.h
--- a/drivers/net/ibm_emac/ibm_emac_core.h	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/ibm_emac/ibm_emac_core.h	2005-03-06 18:36:50 -05:00
@@ -77,6 +77,8 @@
 
 #define ENET_HEADER_SIZE	14
 #define ENET_FCS_SIZE		4
+#define ENET_DEF_MTU_SIZE	1500
+#define ENET_DEF_BUF_SIZE	(ENET_DEF_MTU_SIZE + ENET_HEADER_SIZE + ENET_FCS_SIZE)
 #define EMAC_MIN_FRAME		64
 #define EMAC_MAX_FRAME		9018
 #define EMAC_MIN_MTU		(EMAC_MIN_FRAME - ENET_HEADER_SIZE - ENET_FCS_SIZE)
diff -Nru a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
--- a/drivers/net/ioc3-eth.c	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/ioc3-eth.c	2005-03-06 18:36:50 -05:00
@@ -463,6 +463,29 @@
 	printk(".\n");
 }
 
+static void __ioc3_set_mac_address(struct net_device *dev)
+{
+	struct ioc3_private *ip = netdev_priv(dev);
+	struct ioc3 *ioc3 = ip->regs;
+
+	ioc3_w_emar_h((dev->dev_addr[5] <<  8) | dev->dev_addr[4]);
+	ioc3_w_emar_l((dev->dev_addr[3] << 24) | (dev->dev_addr[2] << 16) |
+	              (dev->dev_addr[1] <<  8) | dev->dev_addr[0]);
+}
+
+static int ioc3_set_mac_address(struct net_device *dev, void *addr)
+{
+	struct ioc3_private *ip = netdev_priv(dev);
+	struct sockaddr *sa = addr;
+
+	memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
+
+	spin_lock_irq(&ip->ioc3_lock);
+	__ioc3_set_mac_address(dev);
+	spin_unlock_irq(&ip->ioc3_lock);
+
+	return 0;
+}
 
 /*
  * Caller must hold the ioc3_lock ever for MII readers.  This is also
@@ -1014,9 +1037,7 @@
 	(void) ioc3_r_etcdc();			/* Clear on read */
 	ioc3_w_ercsr(15);			/* RX low watermark  */
 	ioc3_w_ertr(0);				/* Interrupt immediately */
-	ioc3_w_emar_h((dev->dev_addr[5] <<  8) | dev->dev_addr[4]);
-	ioc3_w_emar_l((dev->dev_addr[3] << 24) | (dev->dev_addr[2] << 16) |
-	              (dev->dev_addr[1] <<  8) | dev->dev_addr[0]);
+	__ioc3_set_mac_address(dev);
 	ioc3_w_ehar_h(ip->ehar_h);
 	ioc3_w_ehar_l(ip->ehar_l);
 	ioc3_w_ersr(42);			/* XXX should be random */
@@ -1100,6 +1121,7 @@
 	       && dev->device == PCI_DEVICE_ID_SGI_IOC3;
 }
 
+#ifdef CONFIG_SERIAL_8250
 /*
  * Note about serial ports and consoles:
  * For console output, everyone uses the IOC3 UARTA (offset 0x178)
@@ -1121,15 +1143,14 @@
  * "device" routine referred to in this console structure
  * (ip27prom_console_dev).
  *
- * Also look in ip27-pci.c:pci_fixuop_ioc3() for some comments on working
+ * Also look in ip27-pci.c:pci_fixup_ioc3() for some comments on working
  * around ioc3 oddities in this respect.
  *
  * The IOC3 serials use a 22MHz clock rate with an additional divider by 3.
  * (IOC3_BAUD = (22000000 / (3*16)))
  */
 
-static inline void ioc3_serial_probe(struct pci_dev *pdev,
-				struct ioc3 *ioc3)
+static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3)
 {
 	struct serial_struct req;
 
@@ -1160,9 +1181,9 @@
 	req.iomem_base      = (unsigned char *) &ioc3->sregs.uartb;
 	register_serial(&req);
 }
+#endif
 
-static int __devinit ioc3_probe(struct pci_dev *pdev,
-	                        const struct pci_device_id *ent)
+static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	unsigned int sw_physid1, sw_physid2;
 	struct net_device *dev = NULL;
@@ -1170,11 +1191,39 @@
 	struct ioc3 *ioc3;
 	unsigned long ioc3_base, ioc3_size;
 	u32 vendor, model, rev;
-	int err;
+	int err, pci_using_dac;
+
+	/* Configure DMA attributes. */
+	err = pci_set_dma_mask(pdev, 0xffffffffffffffffULL);
+	if (!err) {
+		pci_using_dac = 1;
+		err = pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL);
+		if (err < 0) {
+			printk(KERN_ERR "%s: Unable to obtain 64 bit DMA "
+			       "for consistent allocations\n", pci_name(pdev));
+			goto out;
+		}
+	} else {
+		err = pci_set_dma_mask(pdev, 0xffffffffULL);
+		if (err) {
+			printk(KERN_ERR "%s: No usable DMA configuration, "
+			       "aborting.\n", pci_name(pdev));
+			goto out;
+		}
+		pci_using_dac = 0;
+	}
+
+	if (pci_enable_device(pdev))
+		return -ENODEV;
 
 	dev = alloc_etherdev(sizeof(struct ioc3_private));
-	if (!dev)
-		return -ENOMEM;
+	if (!dev) {
+		err = -ENOMEM;
+		goto out_disable;
+	}
+
+	if (pci_using_dac)
+		dev->features |= NETIF_F_HIGHDMA;
 
 	err = pci_request_regions(pdev, "ioc3");
 	if (err)
@@ -1237,6 +1286,7 @@
 	dev->get_stats		= ioc3_get_stats;
 	dev->do_ioctl		= ioc3_ioctl;
 	dev->set_multicast_list	= ioc3_set_multicast_list;
+	dev->set_mac_address	= ioc3_set_mac_address;
 	dev->ethtool_ops	= &ioc3_ethtool_ops;
 #ifdef CONFIG_SGI_IOC3_ETH_HW_TX_CSUM
 	dev->features		= NETIF_F_IP_CSUM;
@@ -1269,6 +1319,12 @@
 	pci_release_regions(pdev);
 out_free:
 	free_netdev(dev);
+out_disable:
+	/*
+	 * We should call pci_disable_device(pdev); here if the IOC3 wasn't
+	 * such a weird device ...
+	 */
+out:
 	return err;
 }
 
@@ -1282,6 +1338,10 @@
 	iounmap(ioc3);
 	pci_release_regions(pdev);
 	free_netdev(dev);
+	/*
+	 * We should call pci_disable_device(pdev); here if the IOC3 wasn't
+	 * such a weird device ...
+	 */
 }
 
 static struct pci_device_id ioc3_pci_tbl[] = {
diff -Nru a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c
--- a/drivers/net/jazzsonic.c	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/jazzsonic.c	2005-03-06 18:36:50 -05:00
@@ -14,6 +14,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/fcntl.h>
 #include <linux/interrupt.h>
@@ -28,6 +29,7 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/bitops.h>
+#include <linux/device.h>
 
 #include <asm/bootinfo.h>
 #include <asm/system.h>
@@ -37,7 +39,10 @@
 #include <asm/jazz.h>
 #include <asm/jazzdma.h>
 
-#define DRV_NAME "jazzsonic"
+static char jazz_sonic_string[] = "jazzsonic";
+static struct platform_device *jazz_sonic_device;
+
+#define SONIC_MEM_SIZE	0x100
 
 #define SREGS_PAD(n)    u16 n;
 
@@ -50,8 +55,8 @@
 
 #define SONIC_WRITE(reg,val)						\
 do {									\
-	*((volatile unsigned int *)base_addr+reg) = val;		\
-}
+	*((volatile unsigned int *)base_addr+(reg)) = (val);		\
+} while (0)
 
 
 /* use 0 for production, 1 for verification, >2 for debug */
@@ -80,70 +85,7 @@
 	0xffff			/* end of list */
 };
 
-/* Index to functions, as function prototypes. */
-
-static int sonic_probe1(struct net_device *dev, unsigned int base_addr,
-                        unsigned int irq);
-
-
-/*
- * Probe for a SONIC ethernet controller on a Mips Jazz board.
- * Actually probing is superfluous but we're paranoid.
- */
-struct net_device * __init sonic_probe(int unit)
-{
-	struct net_device *dev;
-	struct sonic_local *lp;
-	unsigned int base_addr;
-	int err = 0;
-	int i;
-
-	/*
-	 * Don't probe if we're not running on a Jazz board.
-	 */
-	if (mips_machgroup != MACH_GROUP_JAZZ)
-		return ERR_PTR(-ENODEV);
-
-	dev = alloc_etherdev(0);
-	if (!dev)
-		return ERR_PTR(-ENOMEM);
-
-	sprintf(dev->name, "eth%d", unit);
-	netdev_boot_setup_check(dev);
-	base_addr = dev->base_addr;
-
-	if (base_addr >= KSEG0)	{ /* Check a single specified location. */
-		err = sonic_probe1(dev, base_addr, dev->irq);
-	} else if (base_addr != 0) { /* Don't probe at all. */
-		err = -ENXIO;
-	} else {
-		for (i = 0; sonic_portlist[i].port; i++) {
-			int io = sonic_portlist[i].port;
-			if (sonic_probe1(dev, io, sonic_portlist[i].irq) == 0)
-				break;
-		}
-		if (!sonic_portlist[i].port)
-			err = -ENODEV;
-	}
-	if (err)
-		goto out;
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
-	return dev;
-out1:
-	lp = dev->priv;
-	vdma_free(lp->rba_laddr);
-	kfree(lp->rba);
-	vdma_free(lp->cda_laddr);
-	kfree(lp);
-	release_region(dev->base_addr, 0x100);
-out:
-	free_netdev(dev);
-	return ERR_PTR(err);
-}
-
-static int __init sonic_probe1(struct net_device *dev, unsigned int base_addr,
+static int __init sonic_probe1(struct net_device *dev, unsigned long base_addr,
                                unsigned int irq)
 {
 	static unsigned version_printed;
@@ -153,7 +95,7 @@
 	int err = -ENODEV;
 	int i;
 
-	if (!request_region(base_addr, 0x100, DRV_NAME))
+	if (!request_mem_region(base_addr, SONIC_MEM_SIZE, jazz_sonic_string))
 		return -EBUSY;
 	/*
 	 * get the Silicon Revision ID. If this is one of the known
@@ -233,7 +175,7 @@
 		memset(lp, 0, sizeof(struct sonic_local));
 
 		/* get the virtual dma address */
-		lp->cda_laddr = vdma_alloc(PHYSADDR(lp),sizeof(*lp));
+		lp->cda_laddr = vdma_alloc(CPHYSADDR(lp),sizeof(*lp));
 		if (lp->cda_laddr == ~0UL) {
 			printk("%s: couldn't get DMA page entry for "
 			       "descriptors\n", dev->name);
@@ -254,7 +196,7 @@
 		}
 
 		/* get virtual dma address */
-		lp->rba_laddr = vdma_alloc(PHYSADDR(lp->rba),
+		lp->rba_laddr = vdma_alloc(CPHYSADDR(lp->rba),
 		                           SONIC_NUM_RRS * SONIC_RBSIZE);
 		if (lp->rba_laddr == ~0UL) {
 			printk("%s: couldn't get DMA page entry for receive "
@@ -291,7 +233,66 @@
 out1:
 	kfree(lp);
 out:
-	release_region(base_addr, 0x100);
+	release_region(base_addr, SONIC_MEM_SIZE);
+	return err;
+}
+
+/*
+ * Probe for a SONIC ethernet controller on a Mips Jazz board.
+ * Actually probing is superfluous but we're paranoid.
+ */
+static int __init jazz_sonic_probe(struct device *device)
+{
+	struct net_device *dev;
+	struct sonic_local *lp;
+	unsigned long base_addr;
+	int err = 0;
+	int i;
+
+	/*
+	 * Don't probe if we're not running on a Jazz board.
+	 */
+	if (mips_machgroup != MACH_GROUP_JAZZ)
+		return -ENODEV;
+
+	dev = alloc_etherdev(0);
+	if (!dev)
+		return -ENOMEM;
+
+	netdev_boot_setup_check(dev);
+	base_addr = dev->base_addr;
+
+	if (base_addr >= KSEG0)	{ /* Check a single specified location. */
+		err = sonic_probe1(dev, base_addr, dev->irq);
+	} else if (base_addr != 0) { /* Don't probe at all. */
+		err = -ENXIO;
+	} else {
+		for (i = 0; sonic_portlist[i].port; i++) {
+			int io = sonic_portlist[i].port;
+			if (sonic_probe1(dev, io, sonic_portlist[i].irq) == 0)
+				break;
+		}
+		if (!sonic_portlist[i].port)
+			err = -ENODEV;
+	}
+	if (err)
+		goto out;
+	err = register_netdev(dev);
+	if (err)
+		goto out1;
+
+	return 0;
+
+out1:
+	lp = dev->priv;
+	vdma_free(lp->rba_laddr);
+	kfree(lp->rba);
+	vdma_free(lp->cda_laddr);
+	kfree(lp);
+	release_region(dev->base_addr, SONIC_MEM_SIZE);
+out:
+	free_netdev(dev);
+
 	return err;
 }
 
@@ -304,3 +305,77 @@
 #define sonic_chiptomem(x)      KSEG1ADDR(vdma_log2phys(x))
 
 #include "sonic.c"
+
+static int __devexit jazz_sonic_device_remove (struct device *device)
+{
+	struct net_device *dev = device->driver_data;
+
+	unregister_netdev (dev);
+	release_region (dev->base_addr, SONIC_MEM_SIZE);
+	free_netdev (dev);
+
+	return 0;
+}
+
+static struct device_driver jazz_sonic_driver = {
+	.name	= jazz_sonic_string,
+	.bus	= &platform_bus_type,
+	.probe	= jazz_sonic_probe,
+	.remove	= __devexit_p(jazz_sonic_device_remove),
+};
+                                                                                
+static void jazz_sonic_platform_release (struct device *device)
+{
+	struct platform_device *pldev;
+
+	/* free device */
+	pldev = to_platform_device (device);
+	kfree (pldev);
+}
+
+static int __init jazz_sonic_init_module(void)
+{
+	struct platform_device *pldev;
+
+	if (driver_register(&jazz_sonic_driver)) {
+		printk(KERN_ERR "Driver registration failed\n");
+		return -ENOMEM;
+	}
+
+	jazz_sonic_device = NULL;
+
+	if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) {
+		goto out_unregister;
+	}
+
+	memset(pldev, 0, sizeof (*pldev));
+	pldev->name		= jazz_sonic_string;
+	pldev->id		= 0;
+	pldev->dev.release	= jazz_sonic_platform_release;
+	jazz_sonic_device	= pldev;
+
+	if (platform_device_register (pldev)) {
+		kfree(pldev);
+		jazz_sonic_device = NULL;
+	}
+
+	return 0;
+
+out_unregister:
+	platform_device_unregister(pldev);
+
+	return -ENOMEM;
+}
+
+static void __exit jazz_sonic_cleanup_module(void)
+{
+	driver_unregister(&jazz_sonic_driver);
+
+	if (jazz_sonic_device) {
+		platform_device_unregister(jazz_sonic_device);
+		jazz_sonic_device = NULL;
+	}
+}
+
+module_init(jazz_sonic_init_module);
+module_exit(jazz_sonic_cleanup_module);
diff -Nru a/drivers/net/meth.c b/drivers/net/meth.c
--- a/drivers/net/meth.c	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/meth.c	2005-03-06 18:36:50 -05:00
@@ -27,7 +27,7 @@
 #include <linux/ip.h>          /* struct iphdr */
 #include <linux/tcp.h>         /* struct tcphdr */
 #include <linux/skbuff.h>
-#include <linux/mii.h> /*MII definitions */
+#include <linux/mii.h>         /* MII definitions */
 
 #include <asm/ip32/mace.h>
 #include <asm/ip32/ip32_ints.h>
@@ -105,27 +105,27 @@
 		(int)o2meth_eaddr[3]&0xFF,(int)o2meth_eaddr[4]&0xFF,(int)o2meth_eaddr[5]&0xFF);
 	for (i = 0; i < 6; i++)
 		dev->dev_addr[i] = o2meth_eaddr[i];
-	mace_eth_write((*(u64*)o2meth_eaddr)>>16, mac_addr);
+	mace->eth.mac_addr = (*(unsigned long*)o2meth_eaddr) >> 16;
 }
 
 /*
  * Waits for BUSY status of mdio bus to clear
  */
-#define WAIT_FOR_PHY(___rval)						\
-	while ((___rval = mace_eth_read(phy_data)) & MDIO_BUSY) {	\
-		udelay(25);						\
+#define WAIT_FOR_PHY(___rval)					\
+	while ((___rval = mace->eth.phy_data) & MDIO_BUSY) {	\
+		udelay(25);					\
 	}
 /*read phy register, return value read */
 static unsigned long mdio_read(struct meth_private *priv, unsigned long phyreg)
 {
 	unsigned long rval;
 	WAIT_FOR_PHY(rval);
-	mace_eth_write((priv->phy_addr << 5) | (phyreg & 0x1f), phy_regs);
+	mace->eth.phy_regs = (priv->phy_addr << 5) | (phyreg & 0x1f);
 	udelay(25);
-	mace_eth_write(1, phy_trans_go);
+	mace->eth.phy_trans_go = 1;
 	udelay(25);
 	WAIT_FOR_PHY(rval);
-	return rval&MDIO_DATA_MASK;
+	return rval & MDIO_DATA_MASK;
 }
 
 static int mdio_probe(struct meth_private *priv)
@@ -191,7 +191,7 @@
 			priv->mac_ctrl |= METH_PHY_FDX;
 		else
 			priv->mac_ctrl &= ~METH_PHY_FDX;
-		mace_eth_write(priv->mac_ctrl, mac_ctrl);
+		mace->eth.mac_ctrl = priv->mac_ctrl;
 	}
 
 	if ((priv->mac_ctrl & METH_100MBIT) ^ speed) {
@@ -200,7 +200,7 @@
 			priv->mac_ctrl |= METH_100MBIT;
 		else
 			priv->mac_ctrl &= ~METH_100MBIT;
-		mace_eth_write(priv->mac_ctrl, mac_ctrl);
+		mace->eth.mac_ctrl = priv->mac_ctrl;
 	}
 }
 
@@ -214,26 +214,28 @@
 		return -ENOMEM;
 	memset(priv->tx_ring, 0, TX_RING_BUFFER_SIZE);
 	priv->tx_count = priv->tx_read = priv->tx_write = 0;
-	mace_eth_write(priv->tx_ring_dma, tx_ring_base);
+	mace->eth.tx_ring_base = priv->tx_ring_dma;
 	/* Now init skb save area */
-	memset(priv->tx_skbs,0,sizeof(priv->tx_skbs));
-	memset(priv->tx_skb_dmas,0,sizeof(priv->tx_skb_dmas));
+	memset(priv->tx_skbs, 0, sizeof(priv->tx_skbs));
+	memset(priv->tx_skb_dmas, 0, sizeof(priv->tx_skb_dmas));
 	return 0;
 }
 
 static int meth_init_rx_ring(struct meth_private *priv)
 {
 	int i;
-	for(i=0;i<RX_RING_ENTRIES;i++){
-		priv->rx_skbs[i]=alloc_skb(METH_RX_BUFF_SIZE,0);
-		/* 8byte status vector+3quad padding + 2byte padding,
-		   to put data on 64bit aligned boundary */
+
+	for (i = 0; i < RX_RING_ENTRIES; i++) {
+		priv->rx_skbs[i] = alloc_skb(METH_RX_BUFF_SIZE, 0);
+		/* 8byte status vector + 3quad padding + 2byte padding,
+		 * to put data on 64bit aligned boundary */
 		skb_reserve(priv->rx_skbs[i],METH_RX_HEAD);
 		priv->rx_ring[i]=(rx_packet*)(priv->rx_skbs[i]->head);
 		/* I'll need to re-sync it after each RX */
-		priv->rx_ring_dmas[i]=dma_map_single(NULL,priv->rx_ring[i],
-						     METH_RX_BUFF_SIZE,DMA_FROM_DEVICE);
-		mace_eth_write(priv->rx_ring_dmas[i], rx_fifo);
+		priv->rx_ring_dmas[i] = 
+			dma_map_single(NULL, priv->rx_ring[i],
+				       METH_RX_BUFF_SIZE, DMA_FROM_DEVICE);
+		mace->eth.rx_fifo = priv->rx_ring_dmas[i];
 	}
         priv->rx_write = 0;
 	return 0;
@@ -257,10 +259,11 @@
 {
 	int i;
 
-	for(i=0;i<RX_RING_ENTRIES;i++) {
-		dma_unmap_single(NULL,priv->rx_ring_dmas[i],METH_RX_BUFF_SIZE,DMA_FROM_DEVICE);
-		priv->rx_ring[i]=0;
-		priv->rx_ring_dmas[i]=0;
+	for (i = 0; i < RX_RING_ENTRIES; i++) {
+		dma_unmap_single(NULL, priv->rx_ring_dmas[i],
+				 METH_RX_BUFF_SIZE, DMA_FROM_DEVICE);
+		priv->rx_ring[i] = 0;
+		priv->rx_ring_dmas[i] = 0;
 		kfree_skb(priv->rx_skbs[i]);
 	}
 }
@@ -270,8 +273,9 @@
 	struct meth_private *priv = (struct meth_private *) dev->priv;
 
 	/* Reset card */
-	mace_eth_write(SGI_MAC_RESET, mac_ctrl);
-	mace_eth_write(0, mac_ctrl);
+	mace->eth.mac_ctrl = SGI_MAC_RESET;
+	udelay(1);
+	mace->eth.mac_ctrl = 0;
 	udelay(25);
 
 	/* Load ethernet address */
@@ -279,24 +283,24 @@
 	/* Should load some "errata", but later */
 	
 	/* Check for device */
-	if(mdio_probe(priv) < 0) {
+	if (mdio_probe(priv) < 0) {
 		DPRINTK("Unable to find PHY\n");
 		return -ENODEV;
 	}
 
 	/* Initial mode: 10 | Half-duplex | Accept normal packets */
 	priv->mac_ctrl = METH_ACCEPT_MCAST | METH_DEFAULT_IPG;
-	if(dev->flags | IFF_PROMISC)
+	if (dev->flags | IFF_PROMISC)
 		priv->mac_ctrl |= METH_PROMISC;
-	mace_eth_write(priv->mac_ctrl, mac_ctrl);
+	mace->eth.mac_ctrl = priv->mac_ctrl;
 
 	/* Autonegotiate speed and duplex mode */
 	meth_check_link(dev);
 
 	/* Now set dma control, but don't enable DMA, yet */
-	priv->dma_ctrl= (4 << METH_RX_OFFSET_SHIFT) |
-		(RX_RING_ENTRIES << METH_RX_DEPTH_SHIFT);
-	mace_eth_write(priv->dma_ctrl, dma_ctrl);
+	priv->dma_ctrl = (4 << METH_RX_OFFSET_SHIFT) |
+			 (RX_RING_ENTRIES << METH_RX_DEPTH_SHIFT);
+	mace->eth.dma_ctrl = priv->dma_ctrl;
 
 	return 0;
 }
@@ -335,7 +339,7 @@
 	/* Start DMA */
 	priv->dma_ctrl |= METH_DMA_TX_EN | /*METH_DMA_TX_INT_EN |*/
 			  METH_DMA_RX_EN | METH_DMA_RX_INT_EN;
-	mace_eth_write(priv->dma_ctrl, dma_ctrl);
+	mace->eth.dma_ctrl = priv->dma_ctrl;
 
 	DPRINTK("About to start queue\n");
 	netif_start_queue(dev);
@@ -359,7 +363,7 @@
 	/* shut down DMA */
 	priv->dma_ctrl &= ~(METH_DMA_TX_EN | METH_DMA_TX_INT_EN |
 			    METH_DMA_RX_EN | METH_DMA_RX_INT_EN);
-	mace_eth_write(priv->dma_ctrl, dma_ctrl);
+	mace->eth.dma_ctrl = priv->dma_ctrl;
 	free_irq(dev->irq, dev);
 	meth_free_tx_ring(priv);
 	meth_free_rx_ring(priv);
@@ -373,56 +377,57 @@
 static void meth_rx(struct net_device* dev, unsigned long int_status)
 {
 	struct sk_buff *skb;
+	unsigned long status;
 	struct meth_private *priv = (struct meth_private *) dev->priv;
-	unsigned long fifo_rptr=(int_status&METH_INT_RX_RPTR_MASK)>>8;
+	unsigned long fifo_rptr = (int_status & METH_INT_RX_RPTR_MASK) >> 8;
+
 	spin_lock(&priv->meth_lock);
-	priv->dma_ctrl&=~METH_DMA_RX_INT_EN;
-	mace_eth_write(priv->dma_ctrl, dma_ctrl);
+	priv->dma_ctrl &= ~METH_DMA_RX_INT_EN;
+	mace->eth.dma_ctrl = priv->dma_ctrl;
 	spin_unlock(&priv->meth_lock);
 
-	if (int_status & METH_INT_RX_UNDERFLOW){
-		fifo_rptr=(fifo_rptr-1)&(0xF);
+	if (int_status & METH_INT_RX_UNDERFLOW) {
+		fifo_rptr = (fifo_rptr - 1) & 0x0f;
 	}
-	while(priv->rx_write != fifo_rptr) {
-		u64 status;
-		dma_unmap_single(NULL,priv->rx_ring_dmas[priv->rx_write],
-				 METH_RX_BUFF_SIZE,DMA_FROM_DEVICE);
-		status=priv->rx_ring[priv->rx_write]->status.raw;
+	while (priv->rx_write != fifo_rptr) {
+		dma_unmap_single(NULL, priv->rx_ring_dmas[priv->rx_write],
+				 METH_RX_BUFF_SIZE, DMA_FROM_DEVICE);
+		status = priv->rx_ring[priv->rx_write]->status.raw;
 #if MFE_DEBUG
-		if(!(status&METH_RX_ST_VALID)) {
+		if (!(status & METH_RX_ST_VALID)) {
 			DPRINTK("Not received? status=%016lx\n",status);
 		}
 #endif
-		if((!(status&METH_RX_STATUS_ERRORS))&&(status&METH_RX_ST_VALID)){
-			int len=(status&0xFFFF) - 4; /* omit CRC */
+		if ((!(status & METH_RX_STATUS_ERRORS)) && (status & METH_RX_ST_VALID)) {
+			int len = (status & 0xffff) - 4; /* omit CRC */
 			/* length sanity check */
-			if(len < 60 || len > 1518) {
-				printk(KERN_DEBUG "%s: bogus packet size: %d, status=%#2lx.\n",
+			if (len < 60 || len > 1518) {
+				printk(KERN_DEBUG "%s: bogus packet size: %ld, status=%#2lx.\n",
 				       dev->name, priv->rx_write,
 				       priv->rx_ring[priv->rx_write]->status.raw);
 				priv->stats.rx_errors++;
 				priv->stats.rx_length_errors++;
-				skb=priv->rx_skbs[priv->rx_write];
+				skb = priv->rx_skbs[priv->rx_write];
 			} else {
-				skb=alloc_skb(METH_RX_BUFF_SIZE,GFP_ATOMIC|GFP_DMA);
-				if(!skb){
+				skb = alloc_skb(METH_RX_BUFF_SIZE, GFP_ATOMIC | GFP_DMA);
+				if (!skb) {
 					/* Ouch! No memory! Drop packet on the floor */
 					DPRINTK("No mem: dropping packet\n");
 					priv->stats.rx_dropped++;
-					skb=priv->rx_skbs[priv->rx_write];
+					skb = priv->rx_skbs[priv->rx_write];
 				} else {
-					struct sk_buff *skb_c=priv->rx_skbs[priv->rx_write];
-					/* 8byte status vector+3quad padding + 2byte padding,
-					   to put data on 64bit aligned boundary */
-					skb_reserve(skb,METH_RX_HEAD);
+					struct sk_buff *skb_c = priv->rx_skbs[priv->rx_write];
+					/* 8byte status vector + 3quad padding + 2byte padding,
+					 * to put data on 64bit aligned boundary */
+					skb_reserve(skb, METH_RX_HEAD);
 					/* Write metadata, and then pass to the receive level */
-					skb_put(skb_c,len);
-					priv->rx_skbs[priv->rx_write]=skb;
+					skb_put(skb_c, len);
+					priv->rx_skbs[priv->rx_write] = skb;
 					skb_c->dev = dev;
 					skb_c->protocol = eth_type_trans(skb_c, dev);
 					dev->last_rx = jiffies;
 					priv->stats.rx_packets++;
-					priv->stats.rx_bytes+=len;
+					priv->stats.rx_bytes += len;
 					netif_rx(skb_c);
 				}
 			}
@@ -445,18 +450,19 @@
 				printk(KERN_WARNING "Carrier Event Seen\n");
 #endif
 		}
-		priv->rx_ring[priv->rx_write]=(rx_packet*)skb->head;
-		priv->rx_ring[priv->rx_write]->status.raw=0;
-		priv->rx_ring_dmas[priv->rx_write]=dma_map_single(NULL,priv->rx_ring[priv->rx_write],
-								  METH_RX_BUFF_SIZE,DMA_FROM_DEVICE);
-		mace_eth_write(priv->rx_ring_dmas[priv->rx_write], rx_fifo);
+		priv->rx_ring[priv->rx_write] = (rx_packet*)skb->head;
+		priv->rx_ring[priv->rx_write]->status.raw = 0;
+		priv->rx_ring_dmas[priv->rx_write] = 
+			dma_map_single(NULL, priv->rx_ring[priv->rx_write],
+				       METH_RX_BUFF_SIZE, DMA_FROM_DEVICE);
+		mace->eth.rx_fifo = priv->rx_ring_dmas[priv->rx_write];
 		ADVANCE_RX_PTR(priv->rx_write);
 	}
 	spin_lock(&priv->meth_lock);
 	/* In case there was underflow, and Rx DMA was disabled */
-	priv->dma_ctrl|=METH_DMA_RX_INT_EN|METH_DMA_RX_EN;
-	mace_eth_write(priv->dma_ctrl, dma_ctrl);
-	mace_eth_write(METH_INT_RX_THRESHOLD, int_stat);
+	priv->dma_ctrl |= METH_DMA_RX_INT_EN | METH_DMA_RX_EN;
+	mace->eth.dma_ctrl = priv->dma_ctrl;
+	mace->eth.int_stat = METH_INT_RX_THRESHOLD;
 	spin_unlock(&priv->meth_lock);
 }
 
@@ -464,31 +470,31 @@
 {
 	struct meth_private *priv = (struct meth_private *) dev->priv;
 
-	return(priv->tx_count >= TX_RING_ENTRIES-1);
+	return (priv->tx_count >= TX_RING_ENTRIES - 1);
 }
 
 static void meth_tx_cleanup(struct net_device* dev, unsigned long int_status)
 {
 	struct meth_private *priv = dev->priv;
-	u64 status;
+	unsigned long status;
 	struct sk_buff *skb;
-	unsigned long rptr=(int_status&TX_INFO_RPTR)>>16;
+	unsigned long rptr = (int_status&TX_INFO_RPTR) >> 16;
 
 	spin_lock(&priv->meth_lock);
 
 	/* Stop DMA notification */
 	priv->dma_ctrl &= ~(METH_DMA_TX_INT_EN);
-	mace_eth_write(priv->dma_ctrl, dma_ctrl);
+	mace->eth.dma_ctrl = priv->dma_ctrl;
 
-	while(priv->tx_read != rptr){
+	while (priv->tx_read != rptr) {
 		skb = priv->tx_skbs[priv->tx_read];
 		status = priv->tx_ring[priv->tx_read].header.raw;
 #if MFE_DEBUG>=1
-		if(priv->tx_read==priv->tx_write)
-			DPRINTK("Auchi! tx_read=%d,tx_write=%d,rptr=%d?\n",priv->tx_read,priv->tx_write,rptr);
+		if (priv->tx_read == priv->tx_write)
+			DPRINTK("Auchi! tx_read=%d,tx_write=%d,rptr=%d?\n", priv->tx_read, priv->tx_write,rptr);
 #endif
-		if(status & METH_TX_ST_DONE) {
-			if(status & METH_TX_ST_SUCCESS){
+		if (status & METH_TX_ST_DONE) {
+			if (status & METH_TX_ST_SUCCESS){
 				priv->stats.tx_packets++;
 				priv->stats.tx_bytes += skb->len;
 			} else {
@@ -518,19 +524,19 @@
 		priv->tx_skbs[priv->tx_read] = NULL;
 		priv->tx_ring[priv->tx_read].header.raw = 0;
 		priv->tx_read = (priv->tx_read+1)&(TX_RING_ENTRIES-1);
-		priv->tx_count --;
+		priv->tx_count--;
 	}
 
 	/* wake up queue if it was stopped */
-	if (netif_queue_stopped(dev) && ! meth_tx_full(dev)) {
+	if (netif_queue_stopped(dev) && !meth_tx_full(dev)) {
 		netif_wake_queue(dev);
 	}
 
-	mace_eth_write(METH_INT_TX_EMPTY | METH_INT_TX_PKT, int_stat);
+	mace->eth.int_stat = METH_INT_TX_EMPTY | METH_INT_TX_PKT;
 	spin_unlock(&priv->meth_lock);
 }
 
-static void meth_error(struct net_device* dev, u32 status)
+static void meth_error(struct net_device* dev, unsigned status)
 {
 	struct meth_private *priv = (struct meth_private *) dev->priv;
 
@@ -548,17 +554,16 @@
 	if (status & (METH_INT_RX_UNDERFLOW)) {
 		printk(KERN_WARNING "meth: Rx underflow\n");
 		spin_lock(&priv->meth_lock);
-		mace_eth_write(METH_INT_RX_UNDERFLOW, int_stat);
+		mace->eth.int_stat = METH_INT_RX_UNDERFLOW;
 		/* more underflow interrupts will be delivered, 
-		   effectively throwing us into an infinite loop.
-		   Thus I stop processing Rx in this case.
-		*/
-		priv->dma_ctrl&=~METH_DMA_RX_EN;
-		mace_eth_write(priv->dma_ctrl, dma_ctrl);
+		 * effectively throwing us into an infinite loop.
+		 *  Thus I stop processing Rx in this case. */
+		priv->dma_ctrl &= ~METH_DMA_RX_EN;
+		mace->eth.dma_ctrl = priv->dma_ctrl;
 		DPRINTK("Disabled meth Rx DMA temporarily\n");
 		spin_unlock(&priv->meth_lock);
 	}
-	mace_eth_write(METH_INT_ERROR, int_stat);
+	mace->eth.int_stat = METH_INT_ERROR;
 }
 
 /*
@@ -570,12 +575,12 @@
 	struct meth_private *priv = (struct meth_private *) dev->priv;
 	unsigned long status;
 
-	status = mace_eth_read(int_stat);
-	while (status & 0xFF) {
+	status = mace->eth.int_stat;
+	while (status & 0xff) {
 		/* First handle errors - if we get Rx underflow,
-		   Rx DMA will be disabled, and Rx handler will reenable
-		   it. I don't think it's possible to get Rx underflow,
-		   without getting Rx interrupt */
+		 * Rx DMA will be disabled, and Rx handler will reenable
+		 * it. I don't think it's possible to get Rx underflow,
+		 * without getting Rx interrupt */
 		if (status & METH_INT_ERROR) {
 			meth_error(dev, status);
 		}
@@ -589,7 +594,7 @@
 			/* send it to meth_rx for handling */
 			meth_rx(dev, status);
 		}
-		status = mace_eth_read(int_stat);
+		status = mace->eth.int_stat;
 	}
 
 	return IRQ_HANDLED;
@@ -601,45 +606,45 @@
 static void meth_tx_short_prepare(struct meth_private *priv,
 				  struct sk_buff *skb)
 {
-	tx_packet *desc=&priv->tx_ring[priv->tx_write];
-	int len = (skb->len<ETH_ZLEN)?ETH_ZLEN:skb->len;
+	tx_packet *desc = &priv->tx_ring[priv->tx_write];
+	int len = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;
 
-	desc->header.raw=METH_TX_CMD_INT_EN|(len-1)|((128-len)<<16);
+	desc->header.raw = METH_TX_CMD_INT_EN | (len-1) | ((128-len) << 16);
 	/* maybe I should set whole thing to 0 first... */
-	memcpy(desc->data.dt+(120-len),skb->data,skb->len);
-	if(skb->len < len)
-		memset(desc->data.dt+120-len+skb->len,0,len-skb->len);
+	memcpy(desc->data.dt + (120 - len), skb->data, skb->len);
+	if (skb->len < len)
+		memset(desc->data.dt + 120 - len + skb->len, 0, len-skb->len);
 }
 #define TX_CATBUF1 BIT(25)
 static void meth_tx_1page_prepare(struct meth_private *priv,
 				  struct sk_buff *skb)
 {
-	tx_packet *desc=&priv->tx_ring[priv->tx_write];
+	tx_packet *desc = &priv->tx_ring[priv->tx_write];
 	void *buffer_data = (void *)(((unsigned long)skb->data + 7) & ~7);
 	int unaligned_len = (int)((unsigned long)buffer_data - (unsigned long)skb->data);
 	int buffer_len = skb->len - unaligned_len;
 	dma_addr_t catbuf;
 
-	desc->header.raw=METH_TX_CMD_INT_EN|TX_CATBUF1|(skb->len-1);
+	desc->header.raw = METH_TX_CMD_INT_EN | TX_CATBUF1 | (skb->len - 1);
 
 	/* unaligned part */
-	if(unaligned_len){
-		memcpy(desc->data.dt+(120-unaligned_len),
+	if (unaligned_len) {
+		memcpy(desc->data.dt + (120 - unaligned_len),
 		       skb->data, unaligned_len);
-		desc->header.raw |= (128-unaligned_len) << 16;
+		desc->header.raw |= (128 - unaligned_len) << 16;
 	}
 
 	/* first page */
 	catbuf = dma_map_single(NULL, buffer_data, buffer_len,
 				DMA_TO_DEVICE);
 	desc->data.cat_buf[0].form.start_addr = catbuf >> 3;
-	desc->data.cat_buf[0].form.len = buffer_len-1;
+	desc->data.cat_buf[0].form.len = buffer_len - 1;
 }
 #define TX_CATBUF2 BIT(26)
 static void meth_tx_2page_prepare(struct meth_private *priv,
 				  struct sk_buff *skb)
 {
-	tx_packet *desc=&priv->tx_ring[priv->tx_write];
+	tx_packet *desc = &priv->tx_ring[priv->tx_write];
 	void *buffer1_data = (void *)(((unsigned long)skb->data + 7) & ~7);
 	void *buffer2_data = (void *)PAGE_ALIGN((unsigned long)skb->data);
 	int unaligned_len = (int)((unsigned long)buffer1_data - (unsigned long)skb->data);
@@ -647,44 +652,44 @@
 	int buffer2_len = skb->len - buffer1_len - unaligned_len;
 	dma_addr_t catbuf1, catbuf2;
 
-	desc->header.raw=METH_TX_CMD_INT_EN|TX_CATBUF1|TX_CATBUF2|(skb->len-1);
+	desc->header.raw = METH_TX_CMD_INT_EN | TX_CATBUF1 | TX_CATBUF2| (skb->len - 1);
 	/* unaligned part */
-	if(unaligned_len){
-		memcpy(desc->data.dt+(120-unaligned_len),
+	if (unaligned_len){
+		memcpy(desc->data.dt + (120 - unaligned_len),
 		       skb->data, unaligned_len);
-		desc->header.raw |= (128-unaligned_len) << 16;
+		desc->header.raw |= (128 - unaligned_len) << 16;
 	}
 
 	/* first page */
 	catbuf1 = dma_map_single(NULL, buffer1_data, buffer1_len,
 				 DMA_TO_DEVICE);
 	desc->data.cat_buf[0].form.start_addr = catbuf1 >> 3;
-	desc->data.cat_buf[0].form.len = buffer1_len-1;
+	desc->data.cat_buf[0].form.len = buffer1_len - 1;
 	/* second page */
 	catbuf2 = dma_map_single(NULL, buffer2_data, buffer2_len,
 				 DMA_TO_DEVICE);
 	desc->data.cat_buf[1].form.start_addr = catbuf2 >> 3;
-	desc->data.cat_buf[1].form.len = buffer2_len-1;
+	desc->data.cat_buf[1].form.len = buffer2_len - 1;
 }
 
 static void meth_add_to_tx_ring(struct meth_private *priv, struct sk_buff *skb)
 {
 	/* Remember the skb, so we can free it at interrupt time */
 	priv->tx_skbs[priv->tx_write] = skb;
-	if(skb->len <= 120) {
+	if (skb->len <= 120) {
 		/* Whole packet fits into descriptor */
-		meth_tx_short_prepare(priv,skb);
-	} else if(PAGE_ALIGN((unsigned long)skb->data) !=
-		  PAGE_ALIGN((unsigned long)skb->data+skb->len-1)) {
+		meth_tx_short_prepare(priv, skb);
+	} else if (PAGE_ALIGN((unsigned long)skb->data) !=
+		   PAGE_ALIGN((unsigned long)skb->data + skb->len - 1)) {
 		/* Packet crosses page boundary */
-		meth_tx_2page_prepare(priv,skb);
+		meth_tx_2page_prepare(priv, skb);
 	} else {
 		/* Packet is in one page */
-		meth_tx_1page_prepare(priv,skb);
+		meth_tx_1page_prepare(priv, skb);
 	}
-	priv->tx_write = (priv->tx_write+1) & (TX_RING_ENTRIES-1);
-	mace_eth_write(priv->tx_write, tx_info);
-	priv->tx_count ++;
+	priv->tx_write = (priv->tx_write + 1) & (TX_RING_ENTRIES - 1);
+	mace->eth.tx_info = priv->tx_write;
+	priv->tx_count++;
 }
 
 /*
@@ -695,10 +700,10 @@
 	struct meth_private *priv = (struct meth_private *) dev->priv;
 	unsigned long flags;
 
-	spin_lock_irqsave(&priv->meth_lock,flags);
+	spin_lock_irqsave(&priv->meth_lock, flags);
 	/* Stop DMA notification */
 	priv->dma_ctrl &= ~(METH_DMA_TX_INT_EN);
-	mace_eth_write(priv->dma_ctrl, dma_ctrl);
+	mace->eth.dma_ctrl = priv->dma_ctrl;
 
 	meth_add_to_tx_ring(priv, skb);
 	dev->trans_start = jiffies; /* save the timestamp */
@@ -711,9 +716,9 @@
 
 	/* Restart DMA notification */
 	priv->dma_ctrl |= METH_DMA_TX_INT_EN;
-	mace_eth_write(priv->dma_ctrl, dma_ctrl);
+	mace->eth.dma_ctrl = priv->dma_ctrl;
 
-	spin_unlock_irqrestore(&priv->meth_lock,flags);
+	spin_unlock_irqrestore(&priv->meth_lock, flags);
 
 	return 0;
 }
@@ -743,11 +748,11 @@
 	meth_init_rx_ring(priv);
 
 	/* Restart dma */
-	priv->dma_ctrl|=METH_DMA_TX_EN|METH_DMA_RX_EN|METH_DMA_RX_INT_EN;
-	mace_eth_write(priv->dma_ctrl, dma_ctrl);
+	priv->dma_ctrl |= METH_DMA_TX_EN | METH_DMA_RX_EN | METH_DMA_RX_INT_EN;
+	mace->eth.dma_ctrl = priv->dma_ctrl;
 
 	/* Enable interrupt */
-	spin_unlock_irqrestore(&priv->meth_lock,flags);
+	spin_unlock_irqrestore(&priv->meth_lock, flags);
 
 	dev->trans_start = jiffies;
 	netif_wake_queue(dev);
@@ -760,8 +765,14 @@
  */
 static int meth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-	DPRINTK("ioctl\n");
-	return 0;
+	/* XXX Not yet implemented */
+	switch(cmd) { 
+	case SIOCGMIIPHY:
+	case SIOCGMIIREG:
+	case SIOCSMIIREG:
+	default:
+		return -EOPNOTSUPP;
+	}
 }
 
 /*
@@ -808,7 +819,7 @@
 	}
 
 	printk(KERN_INFO "%s: SGI MACE Ethernet rev. %d\n",
-	       dev->name, (unsigned int)mace_eth_read(mac_ctrl) >> 29);
+	       dev->name, (unsigned int)(mace->eth.mac_ctrl >> 29));
 	return 0;
 }
 
diff -Nru a/drivers/net/meth.h b/drivers/net/meth.h
--- a/drivers/net/meth.h	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/meth.h	2005-03-06 18:36:50 -05:00
@@ -29,7 +29,7 @@
 #define RX_BUCKET_SIZE 256
 
 #undef BIT
-#define BIT(x)	(1 << (x))
+#define BIT(x)	(1UL << (x))
 
 /* For more detailed explanations of what each field menas,
    see Nick's great comments to #defines below (or docs, if
diff -Nru a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
--- a/drivers/net/mv643xx_eth.c	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/mv643xx_eth.c	2005-03-06 18:36:50 -05:00
@@ -1349,13 +1349,11 @@
 
 #ifdef MV64340_CHECKSUM_OFFLOAD_TX
 #ifdef MAX_SKB_FRAGS
-#ifndef CONFIG_JAGUAR_DMALOW
         /*
          * Zero copy can only work if we use Discovery II memory. Else, we will
          * have to map the buffers to ISA memory which is only 16 MB
          */
         dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_HW_CSUM;
-#endif
 #endif
 #endif
 
diff -Nru a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
--- a/drivers/net/pcnet32.c	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/pcnet32.c	2005-03-06 18:36:50 -05:00
@@ -1429,25 +1429,36 @@
 	val |= 0x10;
     lp->a.write_csr (ioaddr, 124, val);
 
-    /* 24 Jun 2004 according AMD, in order to change the PHY,
-     * DANAS (or DISPM for 79C976) must be set; then select the speed,
-     * duplex, and/or enable auto negotiation, and clear DANAS */
-    if (lp->mii && !(lp->options & PCNET32_PORT_ASEL)) {
-	lp->a.write_bcr(ioaddr, 32, lp->a.read_bcr(ioaddr, 32) | 0x0080);
-	/* disable Auto Negotiation, set 10Mpbs, HD */
-	val = lp->a.read_bcr(ioaddr, 32) & ~0xb8;
-	if (lp->options & PCNET32_PORT_FD)
-	    val |= 0x10;
-	if (lp->options & PCNET32_PORT_100)
-	    val |= 0x08;
-	lp->a.write_bcr (ioaddr, 32, val);
+    /* Allied Telesyn AT 2700/2701 FX looses the link, so skip that */
+    if (lp->pci_dev->subsystem_vendor == PCI_VENDOR_ID_AT &&
+        (lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2700FX ||
+	 lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2701FX)) {
+	printk(KERN_DEBUG "%s: Skipping PHY selection.\n", dev->name);
     } else {
-	if (lp->options & PCNET32_PORT_ASEL) {
-	    lp->a.write_bcr(ioaddr, 32, lp->a.read_bcr(ioaddr, 32) | 0x0080);
-	    /* enable auto negotiate, setup, disable fd */
-	    val = lp->a.read_bcr(ioaddr, 32) & ~0x98;
-	    val |= 0x20;
-	    lp->a.write_bcr(ioaddr, 32, val);
+	/*
+	 * 24 Jun 2004 according AMD, in order to change the PHY,
+	 * DANAS (or DISPM for 79C976) must be set; then select the speed,
+	 * duplex, and/or enable auto negotiation, and clear DANAS
+	 */
+	if (lp->mii && !(lp->options & PCNET32_PORT_ASEL)) {
+	    lp->a.write_bcr(ioaddr, 32,
+				lp->a.read_bcr(ioaddr, 32) | 0x0080);
+	    /* disable Auto Negotiation, set 10Mpbs, HD */
+	    val = lp->a.read_bcr(ioaddr, 32) & ~0xb8;
+	    if (lp->options & PCNET32_PORT_FD)
+		val |= 0x10;
+	    if (lp->options & PCNET32_PORT_100)
+		val |= 0x08;
+	    lp->a.write_bcr (ioaddr, 32, val);
+	} else {
+	    if (lp->options & PCNET32_PORT_ASEL) {
+		lp->a.write_bcr(ioaddr, 32,
+			lp->a.read_bcr(ioaddr, 32) | 0x0080);
+		/* enable auto negotiate, setup, disable fd */
+		val = lp->a.read_bcr(ioaddr, 32) & ~0x98;
+		val |= 0x20;
+		lp->a.write_bcr(ioaddr, 32, val);
+	    }
 	}
     }
 
diff -Nru a/drivers/net/s2io.c b/drivers/net/s2io.c
--- a/drivers/net/s2io.c	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/s2io.c	2005-03-06 18:36:50 -05:00
@@ -36,28 +36,29 @@
  * in PCI Configuration space.
  ************************************************************************/
 
-#include<linux/config.h>
-#include<linux/module.h>
-#include<linux/types.h>
-#include<linux/errno.h>
-#include<linux/ioport.h>
-#include<linux/pci.h>
-#include<linux/kernel.h>
-#include<linux/netdevice.h>
-#include<linux/etherdevice.h>
-#include<linux/skbuff.h>
-#include<linux/init.h>
-#include<linux/delay.h>
-#include<linux/stddef.h>
-#include<linux/ioctl.h>
-#include<linux/timex.h>
-#include<linux/sched.h>
-#include<linux/ethtool.h>
-#include<asm/system.h>
-#include<asm/uaccess.h>
-#include<linux/version.h>
-#include<asm/io.h>
-#include<linux/workqueue.h>
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/stddef.h>
+#include <linux/ioctl.h>
+#include <linux/timex.h>
+#include <linux/sched.h>
+#include <linux/ethtool.h>
+#include <linux/version.h>
+#include <linux/workqueue.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
 
 /* local include */
 #include "s2io.h"
diff -Nru a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
--- a/drivers/net/sb1250-mac.c	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/sb1250-mac.c	2005-03-06 18:36:50 -05:00
@@ -14,47 +14,11 @@
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ *
+ * This driver is designed for the Broadcom SiByte SOC built-in
+ * Ethernet controllers. Written by Mitch Lichtenberg at Broadcom Corp.
  */
-
-/*
-  This driver is designed for the Broadcom SiByte SOC built-in
-  Ethernet controllers.
-  
-  Written by Mitch Lichtenberg at Broadcom Corp.
-*/
-
-
-
-#define CONFIG_SBMAC_COALESCE
-
-/* A few user-configurable values.
-   These may be modified when a driver module is loaded. */
-
-static int debug = 1;			/* 1 normal messages, 0 quiet .. 7 verbose. */
-static int noisy_mii = 1;		/* mii status msgs */
-
-/* Used to pass the media type, etc.
-   Both 'options[]' and 'full_duplex[]' should exist for driver
-   interoperability.
-   The media type is usually passed in 'options[]'.
-*/
-
-#define MAX_UNITS 3		/* More are supported, limit only on options */
-#ifdef MODULE
-static int options[MAX_UNITS] = {-1, -1, -1};
-static int full_duplex[MAX_UNITS] = {-1, -1, -1};
-#endif
-
-#ifdef CONFIG_SBMAC_COALESCE
-static int int_pktcnt = 0;
-static int int_timeout = 0;
-#endif
-
-/* Operational parameters that usually are not changed. */
-
-/* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT  (2*HZ)
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
@@ -89,16 +53,56 @@
 #endif
 
 
+/* Operational parameters that usually are not changed. */
+
+#define CONFIG_SBMAC_COALESCE
+
+#define MAX_UNITS 3		/* More are supported, limit only on options */
+
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT  (2*HZ)
+
 
 MODULE_AUTHOR("Mitch Lichtenberg (Broadcom Corp.)");
 MODULE_DESCRIPTION("Broadcom SiByte SOC GB Ethernet driver");
-MODULE_PARM(debug, "i");
-MODULE_PARM(noisy_mii, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
 
-MODULE_PARM(int_pktcnt, "i");
-MODULE_PARM(int_timeout, "i");
+/* A few user-configurable values which may be modified when a driver
+   module is loaded. */
+
+/* 1 normal messages, 0 quiet .. 7 verbose. */
+static int debug = 1;
+module_param(debug, int, S_IRUGO);
+MODULE_PARM_DESC(debug, "Debug messages");
+
+/* mii status msgs */
+static int noisy_mii = 1;
+module_param(noisy_mii, int, S_IRUGO);
+MODULE_PARM_DESC(noisy_mii, "MII status messages");
+
+/* Used to pass the media type, etc.
+   Both 'options[]' and 'full_duplex[]' should exist for driver
+   interoperability.
+   The media type is usually passed in 'options[]'.
+*/
+#ifdef MODULE
+static int options[MAX_UNITS] = {-1, -1, -1};
+module_param_array(options, int, NULL, S_IRUGO);
+MODULE_PARM_DESC(options, "1-" __MODULE_STRING(MAX_UNITS));
+
+static int full_duplex[MAX_UNITS] = {-1, -1, -1};
+module_param_array(full_duplex, int, NULL, S_IRUGO);
+MODULE_PARM_DESC(full_duplex, "1-" __MODULE_STRING(MAX_UNITS));
+#endif
+
+#ifdef CONFIG_SBMAC_COALESCE
+static int int_pktcnt = 0;
+module_param(int_pktcnt, int, S_IRUGO);
+MODULE_PARM_DESC(int_pktcnt, "Packet count");
+
+static int int_timeout = 0;
+module_param(int_timeout, int, S_IRUGO);
+MODULE_PARM_DESC(int_timeout, "Timeout value");
+#endif
 
 #include <asm/sibyte/sb1250.h>
 #include <asm/sibyte/sb1250_defs.h>
@@ -1811,8 +1815,6 @@
 	
 	/* read system identification to determine revision */
 	if (periph_rev >= 2) {
-		printk(KERN_INFO "%s: enabling TCP rcv checksum\n",
-		       sc->sbm_dev->name);
 		sc->rx_hw_checksum = ENABLE;
 	} else {
 		sc->rx_hw_checksum = DISABLE;
@@ -2417,6 +2419,11 @@
 	if (err)
 		goto out_uninit;
 
+	if (periph_rev >= 2) {
+		printk(KERN_INFO "%s: enabling TCP rcv checksum\n",
+			sc->sbm_dev->name);
+	}
+
 	/*
 	 * Display Ethernet address (this is called during the config
 	 * process so we need to finish off the config message that
@@ -2879,12 +2886,12 @@
 		dev->mem_end = 0;
 		if (sbmac_init(dev, idx)) {
 			port = A_MAC_CHANNEL_BASE(idx);
-			SBMAC_WRITECSR(KSEG1ADDR(port+R_MAC_ETHERNET_ADDR),
-					sbmac_orig_hwaddr[idx] );
+			SBMAC_WRITECSR(IOADDR(port+R_MAC_ETHERNET_ADDR),
+				       sbmac_orig_hwaddr[idx]);
 			free_netdev(dev);
 			continue;
 		}
-		dev_sbmac[idx++] = dev;
+		dev_sbmac[idx] = dev;
 	}
 	return 0;
 }
diff -Nru a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
--- a/drivers/net/sgiseeq.c	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/sgiseeq.c	2005-03-06 18:36:50 -05:00
@@ -136,9 +136,10 @@
 	hregs->rx_ctrl = HPC3_ERXCTRL_ACTIVE;
 }
 
-static inline void seeq_load_eaddr(struct net_device *dev,
-				   struct sgiseeq_regs *sregs)
+static inline void __sgiseeq_set_mac_address(struct net_device *dev)
 {
+	struct sgiseeq_private *sp = netdev_priv(dev);
+	struct sgiseeq_regs *sregs = sp->sregs;
 	int i;
 
 	sregs->tstat = SEEQ_TCMD_RB0;
@@ -146,6 +147,20 @@
 		sregs->rw.eth_addr[i] = dev->dev_addr[i];
 }
 
+static int sgiseeq_set_mac_address(struct net_device *dev, void *addr)
+{
+	struct sgiseeq_private *sp = netdev_priv(dev);
+	struct sockaddr *sa = addr;
+
+	memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
+
+	spin_lock_irq(&sp->tx_lock);
+	__sgiseeq_set_mac_address(dev);
+	spin_unlock_irq(&sp->tx_lock);
+
+	return 0;
+}
+
 #define TCNTINFO_INIT (HPCDMA_EOX | HPCDMA_ETXD)
 #define RCNTCFG_INIT  (HPCDMA_OWN | HPCDMA_EORP | HPCDMA_XIE)
 #define RCNTINFO_INIT (RCNTCFG_INIT | (PKT_BUF_SZ & HPCDMA_BCNT))
@@ -159,13 +174,7 @@
 	sp->rx_new = sp->tx_new = 0;
 	sp->rx_old = sp->tx_old = 0;
 
-	seeq_load_eaddr(dev, sp->sregs);
-
-	/* XXX for now just accept packets directly to us
-	 * XXX and ether-broadcast.  Will do multicast and
-	 * XXX promiscuous mode later. -davem
-	 */
-	sp->mode = SEEQ_RCMD_RBCAST;
+	__sgiseeq_set_mac_address(dev);
 
 	/* Setup tx ring. */
 	for(i = 0; i < SEEQ_TX_BUFFERS; i++) {
@@ -175,7 +184,7 @@
 			buffer = (unsigned long) kmalloc(PKT_BUF_SZ, GFP_KERNEL);
 			if (!buffer)
 				return -ENOMEM;
-			sp->tx_desc[i].buf_vaddr = KSEG1ADDR(buffer);
+			sp->tx_desc[i].buf_vaddr = CKSEG1ADDR(buffer);
 			sp->tx_desc[i].tdma.pbuf = CPHYSADDR(buffer);
 		}
 		sp->tx_desc[i].tdma.cntinfo = TCNTINFO_INIT;
@@ -189,7 +198,7 @@
 			buffer = (unsigned long) kmalloc(PKT_BUF_SZ, GFP_KERNEL);
 			if (!buffer)
 				return -ENOMEM;
-			sp->rx_desc[i].buf_vaddr = KSEG1ADDR(buffer);
+			sp->rx_desc[i].buf_vaddr = CKSEG1ADDR(buffer);
 			sp->rx_desc[i].rdma.pbuf = CPHYSADDR(buffer);
 		}
 		sp->rx_desc[i].rdma.cntinfo = RCNTINFO_INIT;
@@ -331,10 +340,17 @@
 				/* Copy out of kseg1 to avoid silly cache flush. */
 				eth_copy_and_sum(skb, pkt_pointer + 2, len, 0);
 				skb->protocol = eth_type_trans(skb, dev);
-				netif_rx(skb);
-				dev->last_rx = jiffies;
-				sp->stats.rx_packets++;
-				sp->stats.rx_bytes += len;
+
+				/* We don't want to receive our own packets */
+				if (memcmp(eth_hdr(skb)->h_source, dev->dev_addr, ETH_ALEN)) {
+					netif_rx(skb);
+					dev->last_rx = jiffies;
+					sp->stats.rx_packets++;
+					sp->stats.rx_bytes += len;
+				} else {
+					/* Silently drop my own packets */
+					dev_kfree_skb_irq(skb);
+				}
 			} else {
 				printk (KERN_NOTICE "%s: Memory squeeze, deferring packet.\n",
 					dev->name);
@@ -373,7 +389,7 @@
 	 */
 	while ((td->tdma.cntinfo & (HPCDMA_XIU | HPCDMA_ETXD)) ==
 	      (HPCDMA_XIU | HPCDMA_ETXD))
-		td = (struct sgiseeq_tx_desc *)(long) KSEG1ADDR(td->tdma.pnext);
+		td = (struct sgiseeq_tx_desc *)(long) CKSEG1ADDR(td->tdma.pnext);
 	if (td->tdma.cntinfo & HPCDMA_XIU) {
 		hregs->tx_ndptr = CPHYSADDR(td);
 		hregs->tx_ctrl = HPC3_ETXCTRL_ACTIVE;
@@ -583,6 +599,22 @@
 
 static void sgiseeq_set_multicast(struct net_device *dev)
 {
+	struct sgiseeq_private *sp = (struct sgiseeq_private *) dev->priv;
+	unsigned char oldmode = sp->mode;
+
+	if(dev->flags & IFF_PROMISC)
+		sp->mode = SEEQ_RCMD_RANY;
+	else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count)
+		sp->mode = SEEQ_RCMD_RBMCAST;
+	else
+		sp->mode = SEEQ_RCMD_RBCAST;
+
+	/* XXX I know this sucks, but is there a better way to reprogram
+	 * XXX the receiver? At least, this shouldn't happen too often.
+	 */
+
+	if (oldmode != sp->mode)
+		sgiseeq_reset(dev);
 }
 
 static inline void setup_tx_ring(struct sgiseeq_tx_desc *buf, int nbufs)
@@ -651,13 +683,14 @@
 	sp->sregs = (struct sgiseeq_regs *) &hpc3c0->eth_ext[0];
 	sp->hregs = &hpc3c0->ethregs;
 	sp->name = sgiseeqstr;
+	sp->mode = SEEQ_RCMD_RBCAST;
 
 	sp->rx_desc = (struct sgiseeq_rx_desc *)
-	              KSEG1ADDR(ALIGNED(&sp->srings->rxvector[0]));
+	              CKSEG1ADDR(ALIGNED(&sp->srings->rxvector[0]));
 	dma_cache_wback_inv((unsigned long)&sp->srings->rxvector,
 	                    sizeof(sp->srings->rxvector));
 	sp->tx_desc = (struct sgiseeq_tx_desc *)
-	              KSEG1ADDR(ALIGNED(&sp->srings->txvector[0]));
+	              CKSEG1ADDR(ALIGNED(&sp->srings->txvector[0]));
 	dma_cache_wback_inv((unsigned long)&sp->srings->txvector,
 	                    sizeof(sp->srings->txvector));
 
@@ -681,6 +714,7 @@
 	dev->watchdog_timeo	= (200 * HZ) / 1000;
 	dev->get_stats		= sgiseeq_get_stats;
 	dev->set_multicast_list	= sgiseeq_set_multicast;
+	dev->set_mac_address	= sgiseeq_set_mac_address;
 	dev->irq		= irq;
 
 	if (register_netdev(dev)) {
diff -Nru a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
--- a/drivers/net/sk98lin/skge.c	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/sk98lin/skge.c	2005-03-06 18:36:50 -05:00
@@ -5152,6 +5152,8 @@
 	{ 0, }
 };
 
+MODULE_DEVICE_TABLE(pci, skge_pci_tbl);
+
 static struct pci_driver skge_driver = {
 	.name		= "skge",
 	.id_table	= skge_pci_tbl,
diff -Nru a/drivers/net/sonic.c b/drivers/net/sonic.c
--- a/drivers/net/sonic.c	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/sonic.c	2005-03-06 18:36:50 -05:00
@@ -116,7 +116,7 @@
 	/*
 	 * Map the packet data into the logical DMA address space
 	 */
-	if ((laddr = vdma_alloc(PHYSADDR(skb->data), skb->len)) == ~0UL) {
+	if ((laddr = vdma_alloc(CPHYSADDR(skb->data), skb->len)) == ~0UL) {
 		printk("%s: no VDMA entry for transmit available.\n",
 		       dev->name);
 		dev_kfree_skb(skb);
@@ -223,7 +223,7 @@
 
 			/* We must free the original skb */
 			if (lp->tx_skb[entry]) {
-				dev_kfree_skb(lp->tx_skb[entry]);
+				dev_kfree_skb_irq(lp->tx_skb[entry]);
 				lp->tx_skb[entry] = 0;
 			}
 			/* and the VDMA address */
diff -Nru a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
--- a/drivers/net/wan/Kconfig	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/wan/Kconfig	2005-03-06 18:36:50 -05:00
@@ -155,7 +155,8 @@
 	  Network) card supported by this driver and you are planning to
 	  connect the box to a WAN.
 
-	  You will need supporting software from <http://hq.pm.waw.pl/hdlc/>.
+	  You will need supporting software from
+	  <http://www.kernel.org/pub/linux/utils/net/hdlc/>.
 	  Generic HDLC driver currently supports raw HDLC, Cisco HDLC, Frame
 	  Relay, synchronous Point-to-Point Protocol (PPP) and X.25.
 
@@ -225,7 +226,7 @@
 	  Driver for PCI200SYN cards by Goramo sp. j.
 
 	  If you have such a card, say Y here and see
-	  <http://hq.pm.waw.pl/hdlc/>.
+	  <http://www.kernel.org/pub/linux/utils/net/hdlc/>.
 
 	  To compile this as a module, choose M here: the
 	  module will be called pci200syn.
@@ -239,7 +240,7 @@
 	  Driver for wanXL PCI cards by SBE Inc.
 
 	  If you have such a card, say Y here and see
-	  <http://hq.pm.waw.pl/hdlc/>.
+	  <http://www.kernel.org/pub/linux/utils/net/hdlc/>.
 
 	  To compile this as a module, choose M here: the
 	  module will be called wanxl.
@@ -292,7 +293,7 @@
 	  SDL Communications Inc.
 
 	  If you have such a card, say Y here and see
-	  <http://hq.pm.waw.pl/hdlc/>.
+	  <http://www.kernel.org/pub/linux/utils/net/hdlc/>.
 
 	  Note that N2csu and N2dds cards are not supported by this driver.
 
@@ -308,7 +309,7 @@
 	  Driver for C101 SuperSync ISA cards by Moxa Technologies Co., Ltd.
 
 	  If you have such a card, say Y here and see
-	  <http://hq.pm.waw.pl/pub/hdlc/>
+	  <http://www.kernel.org/pub/linux/utils/net/hdlc/>.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called c101.
diff -Nru a/drivers/net/wan/hd6457x.c b/drivers/net/wan/hd6457x.c
--- a/drivers/net/wan/hd6457x.c	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/wan/hd6457x.c	2005-03-06 18:36:50 -05:00
@@ -315,7 +315,7 @@
 #endif
 	stats->rx_packets++;
 	stats->rx_bytes += skb->len;
-	skb->dev->last_rx = jiffies;
+	dev->last_rx = jiffies;
 	skb->protocol = hdlc_type_trans(skb, dev);
 	netif_rx(skb);
 }
diff -Nru a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c
--- a/drivers/net/wan/z85230.c	2005-03-06 18:36:50 -05:00
+++ b/drivers/net/wan/z85230.c	2005-03-06 18:36:50 -05:00
@@ -734,7 +734,7 @@
 	u8 intr;
 	static volatile int locker=0;
 	int work=0;
-	struct z8530_irqhandler *irqs=dev->chanA.irqs;
+	struct z8530_irqhandler *irqs;
 	
 	if(locker)
 	{
@@ -758,6 +758,8 @@
 		/* Now walk the chip and see what it is wanting - it may be
 		   an IRQ for someone else remember */
 		   
+		irqs=dev->chanA.irqs;
+
 		if(intr & (CHARxIP|CHATxIP|CHAEXT))
 		{
 			if(intr&CHARxIP)
diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h
--- a/include/linux/pci_ids.h	2005-03-06 18:36:50 -05:00
+++ b/include/linux/pci_ids.h	2005-03-06 18:36:50 -05:00
@@ -1656,6 +1656,11 @@
 #define PCI_DEVICE_ID_OPTIBASE_VPLEXCC	0x2120
 #define PCI_DEVICE_ID_OPTIBASE_VQUEST	0x2130
 
+/* Allied Telesyn */
+#define PCI_VENDOR_ID_AT    		0x1259
+#define PCI_SUBDEVICE_ID_AT_2700FX	0x2701
+#define PCI_SUBDEVICE_ID_AT_2701FX	0x2703
+
 #define PCI_VENDOR_ID_ESS		0x125d
 #define PCI_DEVICE_ID_ESS_ESS1968	0x1968
 #define PCI_DEVICE_ID_ESS_AUDIOPCI	0x1969

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [BK PATCHES] 2.6.x net driver updates
@ 2005-03-05 18:44 Jeff Garzik
  0 siblings, 0 replies; 28+ messages in thread
From: Jeff Garzik @ 2005-03-05 18:44 UTC (permalink / raw)
  To: Netdev; +Cc: Linux Kernel

[-- Attachment #1: Type: text/plain, Size: 91 bytes --]

Just sent this to Andrew/Linus.  The patch was too large (500K) to send 
to mailing lists.

[-- Attachment #2: changelog.txt --]
[-- Type: text/plain, Size: 3065 bytes --]

Please do a

	bk pull bk://gkernel.bkbits.net/net-drivers-2.6

This will update the following files:

 Documentation/networking/e100.txt |    3 
 arch/arm/mach-pxa/lubbock.c       |    2 
 arch/arm/mach-sa1100/neponset.c   |    2 
 drivers/net/Kconfig               |   17 
 drivers/net/e1000/e1000.h         |    3 
 drivers/net/e1000/e1000_ethtool.c |   11 
 drivers/net/e1000/e1000_hw.c      |   86 
 drivers/net/e1000/e1000_hw.h      |   11 
 drivers/net/e1000/e1000_main.c    |  249 +
 drivers/net/eepro100.c            |    9 
 drivers/net/ixgb/ixgb.h           |    3 
 drivers/net/ixgb/ixgb_ee.c        |   16 
 drivers/net/ixgb/ixgb_ee.h        |    3 
 drivers/net/ixgb/ixgb_ethtool.c   |    5 
 drivers/net/ixgb/ixgb_hw.c        |    2 
 drivers/net/ixgb/ixgb_hw.h        |    2 
 drivers/net/ixgb/ixgb_ids.h       |    2 
 drivers/net/ixgb/ixgb_main.c      |   73 
 drivers/net/ixgb/ixgb_osdep.h     |    2 
 drivers/net/ixgb/ixgb_param.c     |    2 
 drivers/net/smc91x.c              |  275 +
 drivers/net/smc91x.h              |   79 
 drivers/net/tulip/de2104x.c       |    2 
 drivers/net/typhoon-firmware.h    | 5568 +++++++++++++++++---------------------
 drivers/net/typhoon.c             |  244 +
 drivers/net/wan/sbni.c            |    2 
 26 files changed, 3304 insertions(+), 3369 deletions(-)

through these ChangeSets:

<mallikarjuna.chilakala:intel.com>:
  o e1000: Driver version white space,
  o e1000: Fixes related to Cable length
  o e1000: Report failure code when loopback
  o e1000: Checks for desc ring/rx data
  o e1000: Patch from Peter Kjellstroem --
  o e1000: Fix WOL settings in 82544 based
  o e1000: Delay clean-up of last Tx buffer
  o e1000: Avoid race between e1000_watchdog
  o e1000: use netif_poll_{enable|disable}
  o e1000: Robert Olsson's fix and refinement
  o ixgb: Driver version, white space, other stuff
  o ixgb: Invalidate software cache, when EEPROM write occurs
  o ixgb: Robert Olsson's fix and refinement to poll
  o ixgb: Avoid race e1000_watchdog and ixgb_clean_tx_irq
  o ixgb: use netif_poll_{enable|disable}

Alexander Viro:
  o smc91x iomem annotations

David Dillow:
  o Bump version and release date
  o Version 03.001.008 of the Typhoon firmware, courtesy of 3Com
  o Fixup the version reporting to match 3Com
  o Use module_param() and add descriptions
  o Teach typhoon to use port IO on machines that need it. It will attempt to use MMIO, but if that fails (or the user asks), it will fallback to port IO.
  o Enable bus mastering before saving our state, or we'll only be able to load the modules one time.

Ian Campbell:
  o smc91x: power down PHY on suspend
  o use datacs in smc91x driver

Nicolas Pitre:
  o smc91x: allow RX of VLAN packets

Randy Dunlap:
  o tulip/de2104x: don't mix __init & __devinit sections
  o net/wan/sbni: fix section usage

Scott Feldman:
  o eepro100: remove ID for 82556
  o e100: remove reference to NAPI config option

Tony Lindgren:
  o Add OMAP support to smc91x Ethernet driver

Xose Vazquez Perez:
  o 2.6 eepro100: replace and delete duplicate ids


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [BK PATCHES] 2.6.x net driver updates
@ 2005-01-18  8:15 Jeff Garzik
  0 siblings, 0 replies; 28+ messages in thread
From: Jeff Garzik @ 2005-01-18  8:15 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: Netdev

[-- Attachment #1: Type: text/plain, Size: 61 bytes --]

iomem annotations from viro, tun/tap fixes, multicast fixes.

[-- Attachment #2: net-drivers-2.6.txt --]
[-- Type: text/plain, Size: 40177 bytes --]

Please do a

	bk pull bk://gkernel.bkbits.net/net-drivers-2.6

This will update the following files:

 drivers/net/Kconfig             |    1 
 drivers/net/atp.c               |    2 
 drivers/net/bmac.c              |   68 +++++++++---------
 drivers/net/hamachi.c           |   81 +++++++++++-----------
 drivers/net/myri_sbus.c         |   10 +-
 drivers/net/s2io.c              |  104 ++++++++++++++--------------
 drivers/net/s2io.h              |   15 +---
 drivers/net/tulip/tulip_core.c  |    2 
 drivers/net/tulip/winbond-840.c |    2 
 drivers/net/tun.c               |  145 ++++++++++++++++++++++++++++++++++------
 include/linux/if_tun.h          |    2 
 11 files changed, 271 insertions(+), 161 deletions(-)

through these ChangeSets:

Alexander Viro:
  o s2io iomem annotations and cleanups
  o bmac iomem annotations
  o hamachi iomem annotations
  o miri_sbus iomem annotations

Maksim Krasnyanskiy:
  o [TUN] Add a missing dependency on enabling the crc32 libraries
  o Use random_ether_addr() to generate TAP MAC address
  o TUN/TAP driver packet queuing fixes and improvements

Roger Luethi:
  o mc_filter on big-endian arch

diff -Nru a/drivers/net/Kconfig b/drivers/net/Kconfig
--- a/drivers/net/Kconfig	2005-01-18 03:13:47 -05:00
+++ b/drivers/net/Kconfig	2005-01-18 03:13:47 -05:00
@@ -84,6 +84,7 @@
 config TUN
 	tristate "Universal TUN/TAP device driver support"
 	depends on NETDEVICES
+	select CRC32
 	---help---
 	  TUN/TAP provides packet reception and transmission for user space
 	  programs.  It can be viewed as a simple Point-to-Point or Ethernet
diff -Nru a/drivers/net/atp.c b/drivers/net/atp.c
--- a/drivers/net/atp.c	2005-01-18 03:13:47 -05:00
+++ b/drivers/net/atp.c	2005-01-18 03:13:47 -05:00
@@ -909,7 +909,7 @@
 			 i++, mclist = mclist->next)
 		{
 			int filterbit = ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f;
-			mc_filter[filterbit >> 5] |= cpu_to_le32(1 << (filterbit & 31));
+			mc_filter[filterbit >> 5] |= 1 << (filterbit & 31);
 		}
 		new_mode = CMR2h_Normal;
 	}
diff -Nru a/drivers/net/bmac.c b/drivers/net/bmac.c
--- a/drivers/net/bmac.c	2005-01-18 03:13:47 -05:00
+++ b/drivers/net/bmac.c	2005-01-18 03:13:47 -05:00
@@ -59,9 +59,9 @@
 struct bmac_data {
 	/* volatile struct bmac *bmac; */
 	struct sk_buff_head *queue;
-	volatile struct dbdma_regs *tx_dma;
+	volatile struct dbdma_regs __iomem *tx_dma;
 	int tx_dma_intr;
-	volatile struct dbdma_regs *rx_dma;
+	volatile struct dbdma_regs __iomem *rx_dma;
 	int rx_dma_intr;
 	volatile struct dbdma_cmd *tx_cmds;	/* xmit dma command list */
 	volatile struct dbdma_cmd *rx_cmds;	/* recv dma command list */
@@ -165,35 +165,35 @@
 #define	DBDMA_CLEAR(x)	( (x) << 16)
 
 static inline void
-dbdma_st32(volatile unsigned long *a, unsigned long x)
+dbdma_st32(volatile __u32 __iomem *a, unsigned long x)
 {
 	__asm__ volatile( "stwbrx %0,0,%1" : : "r" (x), "r" (a) : "memory");
 	return;
 }
 
 static inline unsigned long
-dbdma_ld32(volatile unsigned long *a)
+dbdma_ld32(volatile __u32 __iomem *a)
 {
-	unsigned long swap;
+	__u32 swap;
 	__asm__ volatile ("lwbrx %0,0,%1" :  "=r" (swap) : "r" (a));
 	return swap;
 }
 
 static void
-dbdma_continue(volatile struct dbdma_regs *dmap)
+dbdma_continue(volatile struct dbdma_regs __iomem *dmap)
 {
-	dbdma_st32((volatile unsigned long *)&dmap->control,
+	dbdma_st32(&dmap->control,
 		   DBDMA_SET(RUN|WAKE) | DBDMA_CLEAR(PAUSE|DEAD));
 	eieio();
 }
 
 static void
-dbdma_reset(volatile struct dbdma_regs *dmap)
+dbdma_reset(volatile struct dbdma_regs __iomem *dmap)
 {
-	dbdma_st32((volatile unsigned long *)&dmap->control,
+	dbdma_st32(&dmap->control,
 		   DBDMA_CLEAR(ACTIVE|DEAD|WAKE|FLUSH|PAUSE|RUN));
 	eieio();
-	while (dbdma_ld32((volatile unsigned long *)&dmap->status) & RUN)
+	while (dbdma_ld32(&dmap->status) & RUN)
 		eieio();
 }
 
@@ -213,22 +213,22 @@
 static inline
 void bmwrite(struct net_device *dev, unsigned long reg_offset, unsigned data )
 {
-	out_le16((void *)dev->base_addr + reg_offset, data);
+	out_le16((void __iomem *)dev->base_addr + reg_offset, data);
 }
 
 
 static inline
 volatile unsigned short bmread(struct net_device *dev, unsigned long reg_offset )
 {
-	return in_le16((void *)dev->base_addr + reg_offset);
+	return in_le16((void __iomem *)dev->base_addr + reg_offset);
 }
 
 static void
 bmac_enable_and_reset_chip(struct net_device *dev)
 {
 	struct bmac_data *bp = netdev_priv(dev);
-	volatile struct dbdma_regs *rd = bp->rx_dma;
-	volatile struct dbdma_regs *td = bp->tx_dma;
+	volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
+	volatile struct dbdma_regs __iomem *td = bp->tx_dma;
 
 	if (rd)
 		dbdma_reset(rd);
@@ -406,7 +406,7 @@
 bmac_start_chip(struct net_device *dev)
 {
 	struct bmac_data *bp = netdev_priv(dev);
-	volatile struct dbdma_regs *rd = bp->rx_dma;
+	volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
 	unsigned short	oldConfig;
 
 	/* enable rx dma channel */
@@ -476,8 +476,8 @@
 	bp->sleeping = 1;
 	spin_unlock_irqrestore(&bp->lock, flags);
 	if (bp->opened) {
-		volatile struct dbdma_regs *rd = bp->rx_dma;
-		volatile struct dbdma_regs *td = bp->tx_dma;
+		volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
+		volatile struct dbdma_regs __iomem *td = bp->tx_dma;
 			
 		config = bmread(dev, RXCFG);
 		bmwrite(dev, RXCFG, (config & ~RxMACEnable));
@@ -602,7 +602,7 @@
 static void
 bmac_init_tx_ring(struct bmac_data *bp)
 {
-	volatile struct dbdma_regs *td = bp->tx_dma;
+	volatile struct dbdma_regs __iomem *td = bp->tx_dma;
 
 	memset((char *)bp->tx_cmds, 0, (N_TX_RING+1) * sizeof(struct dbdma_cmd));
 
@@ -623,7 +623,7 @@
 static int
 bmac_init_rx_ring(struct bmac_data *bp)
 {
-	volatile struct dbdma_regs *rd = bp->rx_dma;
+	volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
 	int i;
 	struct sk_buff *skb;
 
@@ -657,7 +657,7 @@
 static int bmac_transmit_packet(struct sk_buff *skb, struct net_device *dev)
 {
 	struct bmac_data *bp = netdev_priv(dev);
-	volatile struct dbdma_regs *td = bp->tx_dma;
+	volatile struct dbdma_regs __iomem *td = bp->tx_dma;
 	int i;
 
 	/* see if there's a free slot in the tx ring */
@@ -693,7 +693,7 @@
 {
 	struct net_device *dev = (struct net_device *) dev_id;
 	struct bmac_data *bp = netdev_priv(dev);
-	volatile struct dbdma_regs *rd = bp->rx_dma;
+	volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
 	volatile struct dbdma_cmd *cp;
 	int i, nb, stat;
 	struct sk_buff *skb;
@@ -1331,13 +1331,11 @@
 		goto err_out_iounmap;
 
 	bp->is_bmac_plus = is_bmac_plus;
-	bp->tx_dma = (volatile struct dbdma_regs *)
-		ioremap(macio_resource_start(mdev, 1), macio_resource_len(mdev, 1));
+	bp->tx_dma = ioremap(macio_resource_start(mdev, 1), macio_resource_len(mdev, 1));
 	if (!bp->tx_dma)
 		goto err_out_iounmap;
 	bp->tx_dma_intr = macio_irq(mdev, 1);
-	bp->rx_dma = (volatile struct dbdma_regs *)
-		ioremap(macio_resource_start(mdev, 2), macio_resource_len(mdev, 2));
+	bp->rx_dma = ioremap(macio_resource_start(mdev, 2), macio_resource_len(mdev, 2));
 	if (!bp->rx_dma)
 		goto err_out_iounmap_tx;
 	bp->rx_dma_intr = macio_irq(mdev, 2);
@@ -1392,11 +1390,11 @@
 err_out_irq0:
 	free_irq(dev->irq, dev);
 err_out_iounmap_rx:
-	iounmap((void *)bp->rx_dma);
+	iounmap(bp->rx_dma);
 err_out_iounmap_tx:
-	iounmap((void *)bp->tx_dma);
+	iounmap(bp->tx_dma);
 err_out_iounmap:
-	iounmap((void *)dev->base_addr);
+	iounmap((void __iomem *)dev->base_addr);
 out_release:
 	macio_release_resources(mdev);
 out_free:
@@ -1421,8 +1419,8 @@
 static int bmac_close(struct net_device *dev)
 {
 	struct bmac_data *bp = netdev_priv(dev);
-	volatile struct dbdma_regs *rd = bp->rx_dma;
-	volatile struct dbdma_regs *td = bp->tx_dma;
+	volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
+	volatile struct dbdma_regs __iomem *td = bp->tx_dma;
 	unsigned short config;
 	int i;
 
@@ -1505,8 +1503,8 @@
 {
 	struct net_device *dev = (struct net_device *) data;
 	struct bmac_data *bp = netdev_priv(dev);
-	volatile struct dbdma_regs *td = bp->tx_dma;
-	volatile struct dbdma_regs *rd = bp->rx_dma;
+	volatile struct dbdma_regs __iomem *td = bp->tx_dma;
+	volatile struct dbdma_regs __iomem *rd = bp->rx_dma;
 	volatile struct dbdma_cmd *cp;
 	unsigned long flags;
 	unsigned short config, oldConfig;
@@ -1638,9 +1636,9 @@
 	free_irq(bp->tx_dma_intr, dev);	
 	free_irq(bp->rx_dma_intr, dev);
 
-	iounmap((void *)dev->base_addr);
-	iounmap((void *)bp->tx_dma);
-	iounmap((void *)bp->rx_dma);
+	iounmap((void __iomem *)dev->base_addr);
+	iounmap(bp->tx_dma);
+	iounmap(bp->rx_dma);
 
 	macio_release_resources(mdev);
 
diff -Nru a/drivers/net/hamachi.c b/drivers/net/hamachi.c
--- a/drivers/net/hamachi.c	2005-01-18 03:13:47 -05:00
+++ b/drivers/net/hamachi.c	2005-01-18 03:13:47 -05:00
@@ -512,6 +512,7 @@
 	u32 rx_int_var, tx_int_var;	/* interrupt control variables */
 	u32 option;							/* Hold on to a copy of the options */
 	struct pci_dev *pci_dev;
+	void __iomem *base;
 };
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>, Eric Kasten <kasten@nscl.msu.edu>, Keith Underwood <keithu@parl.clemson.edu>");
@@ -549,7 +550,7 @@
 MODULE_PARM_DESC(full_duplex, "GNIC-II full duplex setting(s) (1)");
 MODULE_PARM_DESC(force32, "GNIC-II: Bit 0: 32 bit PCI, bit 1: disable parity, bit 2: 64 bit PCI (all boards)");
                                                                         
-static int read_eeprom(long ioaddr, int location);
+static int read_eeprom(void __iomem *ioaddr, int location);
 static int mdio_read(struct net_device *dev, int phy_id, int location);
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
 static int hamachi_open(struct net_device *dev);
@@ -575,7 +576,8 @@
 	int option, i, rx_int_var, tx_int_var, boguscnt;
 	int chip_id = ent->driver_data;
 	int irq;
-	long ioaddr;
+	void __iomem *ioaddr;
+	unsigned long base;
 	static int card_idx;
 	struct net_device *dev;
 	void *ring_space;
@@ -594,9 +596,9 @@
 		goto err_out;
 	}
 
-	ioaddr = pci_resource_start(pdev, 0);
+	base = pci_resource_start(pdev, 0);
 #ifdef __alpha__				/* Really "64 bit addrs" */
-	ioaddr |= (pci_resource_start(pdev, 1) << 32);
+	base |= (pci_resource_start(pdev, 1) << 32);
 #endif
 
 	pci_set_master(pdev);
@@ -605,7 +607,7 @@
 	if (i) return i;
 
 	irq = pdev->irq;
-	ioaddr = (long) ioremap(ioaddr, 0x400);
+	ioaddr = ioremap(base, 0x400);
 	if (!ioaddr)
 		goto err_out_release;
 
@@ -678,7 +680,8 @@
 		i = readb(ioaddr + PCIClkMeas);	
 	}
 
-	dev->base_addr = ioaddr;
+	hmp->base = ioaddr;
+	dev->base_addr = (unsigned long)ioaddr;
 	dev->irq = irq;
 	pci_set_drvdata(pdev, dev);
 
@@ -741,7 +744,7 @@
 		goto err_out_unmap_rx;
 	}
 
-	printk(KERN_INFO "%s: %s type %x at 0x%lx, ",
+	printk(KERN_INFO "%s: %s type %x at %p, ",
 		   dev->name, chip_tbl[chip_id].name, readl(ioaddr + ChipRev),
 		   ioaddr);
 	for (i = 0; i < 5; i++)
@@ -790,14 +793,14 @@
 err_out_cleardev:
 	free_netdev (dev);
 err_out_iounmap:
-	iounmap((char *)ioaddr);
+	iounmap(ioaddr);
 err_out_release:
 	pci_release_regions(pdev);
 err_out:
 	return ret;
 }
 
-static int __devinit read_eeprom(long ioaddr, int location)
+static int __devinit read_eeprom(void __iomem *ioaddr, int location)
 {
 	int bogus_cnt = 1000;
 
@@ -819,7 +822,8 @@
 
 static int mdio_read(struct net_device *dev, int phy_id, int location)
 {
-	long ioaddr = dev->base_addr;
+	struct hamachi_private *hmp = netdev_priv(dev);
+	void __iomem *ioaddr = hmp->base;
 	int i;
 
 	/* We should check busy first - per docs -KDU */
@@ -836,7 +840,8 @@
 
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
 {
-	long ioaddr = dev->base_addr;
+	struct hamachi_private *hmp = netdev_priv(dev);
+	void __iomem *ioaddr = hmp->base;
 	int i;
 
 	/* We should check busy first - per docs -KDU */
@@ -857,7 +862,7 @@
 static int hamachi_open(struct net_device *dev)
 {
 	struct hamachi_private *hmp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = hmp->base;
 	int i;
 	u32 rx_int_var, tx_int_var;
 	u16 fifo_info;
@@ -987,7 +992,7 @@
 	writew(0x001D, ioaddr + RxDMACtrl);
 	writew(0x001D, ioaddr + TxDMACtrl);
 #endif
-	writew(0x0001, dev->base_addr + RxCmd);
+	writew(0x0001, ioaddr + RxCmd);
 
 	if (hamachi_debug > 2) {
 		printk(KERN_DEBUG "%s: Done hamachi_open(), status: Rx %x Tx %x.\n",
@@ -1038,7 +1043,7 @@
 {
 	struct net_device *dev = (struct net_device *)data;
 	struct hamachi_private *hmp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = hmp->base;
 	int next_tick = 10*HZ;
 
 	if (hamachi_debug > 2) {
@@ -1063,7 +1068,7 @@
 {
 	int i;
 	struct hamachi_private *hmp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = hmp->base;
 
 	printk(KERN_WARNING "%s: Hamachi transmit timed out, status %8.8x,"
 		   " resetting...\n", dev->name, (int)readw(ioaddr + TxStatus));
@@ -1115,7 +1120,7 @@
 	}
 
 	udelay(60); /* Sleep 60 us just for safety sake */
-	writew(0x0002, dev->base_addr + RxCmd); /* STOP Rx */
+	writew(0x0002, ioaddr + RxCmd); /* STOP Rx */
 		
 	writeb(0x01, ioaddr + ChipReset);  /* Reinit the hardware */ 
 
@@ -1157,9 +1162,9 @@
 	hmp->stats.tx_errors++;
 
 	/* Restart the chip's Tx/Rx processes . */
-	writew(0x0002, dev->base_addr + TxCmd); /* STOP Tx */
-	writew(0x0001, dev->base_addr + TxCmd); /* START Tx */
-	writew(0x0001, dev->base_addr + RxCmd); /* START Rx */
+	writew(0x0002, ioaddr + TxCmd); /* STOP Tx */
+	writew(0x0001, ioaddr + TxCmd); /* START Tx */
+	writew(0x0001, ioaddr + RxCmd); /* START Rx */
 
 	netif_wake_queue(dev);
 }
@@ -1275,9 +1280,9 @@
 
 		/* Wake the potentially-idle transmit channel. */
 		/* If we don't need to read status, DON'T -KDU */
-		status=readw(dev->base_addr + TxStatus);
+		status=readw(hmp->base + TxStatus);
 		if( !(status & 0x0001) || (status & 0x0002))
-			writew(0x0001, dev->base_addr + TxCmd);
+			writew(0x0001, hmp->base + TxCmd);
 		return 1;
 	} 
 
@@ -1343,9 +1348,9 @@
 
 	/* Wake the potentially-idle transmit channel. */
 	/* If we don't need to read status, DON'T -KDU */
-	status=readw(dev->base_addr + TxStatus);
+	status=readw(hmp->base + TxStatus);
 	if( !(status & 0x0001) || (status & 0x0002))
-		writew(0x0001, dev->base_addr + TxCmd);
+		writew(0x0001, hmp->base + TxCmd);
 
 	/* Immediately before returning, let's clear as many entries as we can. */
 	hamachi_tx(dev);
@@ -1376,8 +1381,9 @@
 static irqreturn_t hamachi_interrupt(int irq, void *dev_instance, struct pt_regs *rgs)
 {
 	struct net_device *dev = dev_instance;
-	struct hamachi_private *hmp;
-	long ioaddr, boguscnt = max_interrupt_work;
+	struct hamachi_private *hmp = netdev_priv(dev);
+	void __iomem *ioaddr = hmp->base;
+	long boguscnt = max_interrupt_work;
 	int handled = 0;
 
 #ifndef final_version			/* Can never occur. */
@@ -1387,8 +1393,6 @@
 	}
 #endif
 
-	ioaddr = dev->base_addr;
-	hmp = netdev_priv(dev);
 	spin_lock(&hmp->lock);
 
 	do {
@@ -1687,8 +1691,8 @@
 
 	/* Restart Rx engine if stopped. */
 	/* If we don't need to check status, don't. -KDU */
-	if (readw(dev->base_addr + RxStatus) & 0x0002)
-		writew(0x0001, dev->base_addr + RxCmd);
+	if (readw(hmp->base + RxStatus) & 0x0002)
+		writew(0x0001, hmp->base + RxCmd);
 
 	return 0;
 }
@@ -1697,8 +1701,8 @@
    than just errors. */
 static void hamachi_error(struct net_device *dev, int intr_status)
 {
-	long ioaddr = dev->base_addr;
 	struct hamachi_private *hmp = netdev_priv(dev);
+	void __iomem *ioaddr = hmp->base;
 
 	if (intr_status & (LinkChange|NegotiationChange)) {
 		if (hamachi_debug > 1)
@@ -1731,8 +1735,8 @@
 
 static int hamachi_close(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
 	struct hamachi_private *hmp = netdev_priv(dev);
+	void __iomem *ioaddr = hmp->base;
 	struct sk_buff *skb;
 	int i;
 
@@ -1817,8 +1821,8 @@
 
 static struct net_device_stats *hamachi_get_stats(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
 	struct hamachi_private *hmp = netdev_priv(dev);
+	void __iomem *ioaddr = hmp->base;
 
 	/* We should lock this segment of code for SMP eventually, although
 	   the vulnerability window is very small and statistics are
@@ -1845,7 +1849,8 @@
 
 static void set_rx_mode(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
+	struct hamachi_private *hmp = netdev_priv(dev);
+	void __iomem *ioaddr = hmp->base;
 
 	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
 		/* Unconditionally log net taps. */
@@ -1950,11 +1955,11 @@
 		 */
 		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
-		writel(d[0], dev->base_addr + TxIntrCtrl);
-		writel(d[1], dev->base_addr + RxIntrCtrl);
+		writel(d[0], np->base + TxIntrCtrl);
+		writel(d[1], np->base + RxIntrCtrl);
 		printk(KERN_NOTICE "%s: tx %08x, rx %08x intr\n", dev->name,
-		  (u32) readl(dev->base_addr + TxIntrCtrl),
-		  (u32) readl(dev->base_addr + RxIntrCtrl));
+		  (u32) readl(np->base + TxIntrCtrl),
+		  (u32) readl(np->base + RxIntrCtrl));
 		rc = 0;
 	}
 
@@ -1980,7 +1985,7 @@
 		pci_free_consistent(pdev, TX_TOTAL_SIZE, hmp->tx_ring, 
 			hmp->tx_ring_dma);
 		unregister_netdev(dev);
-		iounmap((char *)dev->base_addr);
+		iounmap(hmp->base);
 		free_netdev(dev);
 		pci_release_regions(pdev);
 		pci_set_drvdata(pdev, NULL);
diff -Nru a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
--- a/drivers/net/myri_sbus.c	2005-01-18 03:13:47 -05:00
+++ b/drivers/net/myri_sbus.c	2005-01-18 03:13:47 -05:00
@@ -118,7 +118,7 @@
 
 static inline void bang_the_chip(struct myri_eth *mp)
 {
-	struct myri_shmem *shmem	= mp->shmem;
+	struct myri_shmem __iomem *shmem = mp->shmem;
 	void __iomem *cregs		= mp->cregs;
 
 	sbus_writel(1, &shmem->send);
@@ -127,9 +127,9 @@
 
 static int myri_do_handshake(struct myri_eth *mp)
 {
-	struct myri_shmem *shmem	= mp->shmem;
+	struct myri_shmem __iomem *shmem = mp->shmem;
 	void __iomem *cregs = mp->cregs;
-	struct myri_channel *chan	= &shmem->channel;
+	struct myri_channel __iomem *chan = &shmem->channel;
 	int tick 			= 0;
 
 	DET(("myri_do_handshake: "));
@@ -427,7 +427,7 @@
 		u32 csum		= sbus_readl(&rxdack->csum);
 		int len			= sbus_readl(&rxdack->myri_scatters[0].len);
 		int index		= sbus_readl(&rxdack->ctx);
-		struct myri_rxd __iomem *rxd	= &rq->myri_rxd[rq->tail];
+		struct myri_rxd __iomem *rxd = &rq->myri_rxd[sbus_readl(&rq->tail)];
 		struct sk_buff *skb	= mp->rx_skbs[index];
 
 		/* Ack it. */
@@ -546,7 +546,7 @@
 	struct net_device *dev		= (struct net_device *) dev_id;
 	struct myri_eth *mp		= (struct myri_eth *) dev->priv;
 	void __iomem *lregs		= mp->lregs;
-	struct myri_channel *chan	= &mp->shmem->channel;
+	struct myri_channel __iomem *chan = &mp->shmem->channel;
 	unsigned long flags;
 	u32 status;
 	int handled = 0;
diff -Nru a/drivers/net/s2io.c b/drivers/net/s2io.c
--- a/drivers/net/s2io.c	2005-01-18 03:13:47 -05:00
+++ b/drivers/net/s2io.c	2005-01-18 03:13:47 -05:00
@@ -277,7 +277,7 @@
 	int lst_size, lst_per_page;
 	struct net_device *dev = nic->dev;
 #ifdef CONFIG_2BUFF_MODE
-	u64 tmp;
+	unsigned long tmp;
 	buffAdd_t *ba;
 #endif
 
@@ -448,22 +448,22 @@
 			while (k != MAX_RXDS_PER_BLOCK) {
 				ba = &nic->ba[i][j][k];
 
-				ba->ba_0_org = (void *) kmalloc
+				ba->ba_0_org = kmalloc
 				    (BUF0_LEN + ALIGN_SIZE, GFP_KERNEL);
 				if (!ba->ba_0_org)
 					return -ENOMEM;
-				tmp = (u64) ba->ba_0_org;
+				tmp = (unsigned long) ba->ba_0_org;
 				tmp += ALIGN_SIZE;
-				tmp &= ~((u64) ALIGN_SIZE);
+				tmp &= ~((unsigned long) ALIGN_SIZE);
 				ba->ba_0 = (void *) tmp;
 
-				ba->ba_1_org = (void *) kmalloc
+				ba->ba_1_org = kmalloc
 				    (BUF1_LEN + ALIGN_SIZE, GFP_KERNEL);
 				if (!ba->ba_1_org)
 					return -ENOMEM;
-				tmp = (u64) ba->ba_1_org;
+				tmp = (unsigned long) ba->ba_1_org;
 				tmp += ALIGN_SIZE;
-				tmp &= ~((u64) ALIGN_SIZE);
+				tmp &= ~((unsigned long) ALIGN_SIZE);
 				ba->ba_1 = (void *) tmp;
 				k++;
 			}
@@ -610,10 +610,10 @@
 
 static int init_nic(struct s2io_nic *nic)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	struct net_device *dev = nic->dev;
 	register u64 val64 = 0;
-	void *add;
+	void __iomem *add;
 	u32 time;
 	int i, j;
 	mac_info_t *mac_control;
@@ -702,7 +702,7 @@
 	schedule_timeout(HZ / 2);
 
 	/*  Enable Receiving broadcasts */
-	add = (void *) &bar0->mac_cfg;
+	add = &bar0->mac_cfg;
 	val64 = readq(&bar0->mac_cfg);
 	val64 |= MAC_RMAC_BCAST_ENABLE;
 	writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
@@ -1003,7 +1003,7 @@
 	writeq(0xffbbffbbffbbffbbULL, &bar0->mc_pause_thresh_q4q7);
 
 	/* Disable RMAC PAD STRIPPING */
-	add = (void *) &bar0->mac_cfg;
+	add = &bar0->mac_cfg;
 	val64 = readq(&bar0->mac_cfg);
 	val64 &= ~(MAC_CFG_RMAC_STRIP_PAD);
 	writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
@@ -1069,7 +1069,7 @@
 
 static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	register u64 val64 = 0, temp64 = 0;
 
 	/*  Top level interrupt classification */
@@ -1354,7 +1354,7 @@
 
 void fix_mac_address(nic_t * sp)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64;
 	int i = 0;
 
@@ -1379,7 +1379,7 @@
 
 static int start_nic(struct s2io_nic *nic)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	struct net_device *dev = nic->dev;
 	register u64 val64 = 0;
 	u16 interruptible, i;
@@ -1474,7 +1474,7 @@
 		val64 |= 0x0000800000000000ULL;
 		writeq(val64, &bar0->gpio_control);
 		val64 = 0x0411040400000000ULL;
-		writeq(val64, (void *) ((u8 *) bar0 + 0x2700));
+		writeq(val64, (void __iomem *) bar0 + 0x2700);
 	}
 
 	/* 
@@ -1557,7 +1557,7 @@
 
 static void stop_nic(struct s2io_nic *nic)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	register u64 val64 = 0;
 	u16 interruptible, i;
 	mac_info_t *mac_control;
@@ -1615,7 +1615,7 @@
 #ifdef CONFIG_2BUFF_MODE
 	RxD_t *rxdpnext;
 	int nextblk;
-	u64 tmp;
+	unsigned long tmp;
 	buffAdd_t *ba;
 	dma_addr_t rxdpphys;
 #endif
@@ -1757,7 +1757,7 @@
 #else
 		ba = &nic->ba[ring_no][block_no][off];
 		skb_reserve(skb, BUF0_LEN);
-		tmp = (u64) skb->data;
+		tmp = (unsigned long) skb->data;
 		tmp += ALIGN_SIZE;
 		tmp &= ~ALIGN_SIZE;
 		skb->data = (void *) tmp;
@@ -1900,7 +1900,7 @@
 static int s2io_poll(struct net_device *dev, int *budget)
 {
 	nic_t *nic = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	int pkts_to_process = *budget, pkt_cnt = 0;
 	register u64 val64 = 0;
 	rx_curr_get_info_t get_info, put_info;
@@ -2269,7 +2269,7 @@
 
 static void tx_intr_handler(struct s2io_nic *nic)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	struct net_device *dev = (struct net_device *) nic->dev;
 	tx_curr_get_info_t get_info, put_info;
 	struct sk_buff *skb;
@@ -2376,7 +2376,7 @@
 static void alarm_intr_handler(struct s2io_nic *nic)
 {
 	struct net_device *dev = (struct net_device *) nic->dev;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	register u64 val64 = 0, err_reg = 0;
 
 	/* Handling link status change error Intr */
@@ -2427,7 +2427,7 @@
 
 int wait_for_cmd_complete(nic_t * sp)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	int ret = FAILURE, cnt = 0;
 	u64 val64;
 
@@ -2458,7 +2458,7 @@
 
 void s2io_reset(nic_t * sp)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64;
 	u16 subid;
 
@@ -2494,7 +2494,7 @@
 		val64 |= 0x0000800000000000ULL;
 		writeq(val64, &bar0->gpio_control);
 		val64 = 0x0411040400000000ULL;
-		writeq(val64, (void *) ((u8 *) bar0 + 0x2700));
+		writeq(val64, (void __iomem *) bar0 + 0x2700);
 	}
 
 	sp->device_enabled_once = FALSE;
@@ -2513,7 +2513,7 @@
 int s2io_set_swapper(nic_t * sp)
 {
 	struct net_device *dev = sp->dev;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64;
 
 	/* 
@@ -2689,14 +2689,14 @@
 	u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off;
 	register u64 val64;
 	TxD_t *txdp;
-	TxFIFO_element_t *tx_fifo;
+	TxFIFO_element_t __iomem *tx_fifo;
 	unsigned long flags;
 #ifdef NETIF_F_TSO
 	int mss;
 #endif
 	mac_info_t *mac_control;
 	struct config_param *config;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 
 	mac_control = &sp->mac_control;
 	config = &sp->config;
@@ -2813,7 +2813,7 @@
 {
 	struct net_device *dev = (struct net_device *) dev_id;
 	nic_t *sp = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 #ifndef CONFIG_S2IO_NAPI
 	int i, ret;
 #endif
@@ -2939,11 +2939,11 @@
 	int i, j, prev_cnt;
 	struct dev_mc_list *mclist;
 	nic_t *sp = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64 = 0, multi_mac = 0x010203040506ULL, mask =
 	    0xfeffffffffffULL;
 	u64 dis_addr = 0xffffffffffffULL, mac_addr = 0;
-	void *add;
+	void __iomem *add;
 
 	if ((dev->flags & IFF_ALLMULTI) && (!sp->m_cast_flg)) {
 		/*  Enable all Multicast addresses */
@@ -2977,7 +2977,7 @@
 
 	if ((dev->flags & IFF_PROMISC) && (!sp->promisc_flg)) {
 		/*  Put the NIC into promiscuous mode */
-		add = (void *) &bar0->mac_cfg;
+		add = &bar0->mac_cfg;
 		val64 = readq(&bar0->mac_cfg);
 		val64 |= MAC_CFG_RMAC_PROM_ENABLE;
 
@@ -2992,7 +2992,7 @@
 			  dev->name);
 	} else if (!(dev->flags & IFF_PROMISC) && (sp->promisc_flg)) {
 		/*  Remove the NIC from promiscuous mode */
-		add = (void *) &bar0->mac_cfg;
+		add = &bar0->mac_cfg;
 		val64 = readq(&bar0->mac_cfg);
 		val64 &= ~MAC_CFG_RMAC_PROM_ENABLE;
 
@@ -3082,7 +3082,7 @@
 int s2io_set_mac_addr(struct net_device *dev, u8 * addr)
 {
 	nic_t *sp = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	register u64 val64, mac_addr = 0;
 	int i;
 
@@ -3225,7 +3225,7 @@
 	regs->version = sp->pdev->subsystem_device;
 
 	for (i = 0; i < regs->len; i += 8) {
-		reg = readq((void *) (sp->bar0 + i));
+		reg = readq(sp->bar0 + i);
 		memcpy((reg_space + i), &reg, 8);
 	}
 }
@@ -3242,7 +3242,7 @@
 static void s2io_phy_id(unsigned long data)
 {
 	nic_t *sp = (nic_t *) data;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64 = 0;
 	u16 subid;
 
@@ -3279,7 +3279,7 @@
 {
 	u64 val64 = 0, last_gpio_ctrl_val;
 	nic_t *sp = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u16 subid;
 
 	subid = sp->pdev->subsystem_device;
@@ -3327,7 +3327,7 @@
 {
 	u64 val64;
 	nic_t *sp = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 
 	val64 = readq(&bar0->rmac_pause_cfg);
 	if (val64 & RMAC_PAUSE_GEN_ENABLE)
@@ -3354,7 +3354,7 @@
 {
 	u64 val64;
 	nic_t *sp = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 
 	val64 = readq(&bar0->rmac_pause_cfg);
 	if (ep->tx_pause)
@@ -3391,7 +3391,7 @@
 	int ret = -1;
 	u32 exit_cnt = 0;
 	u64 val64;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 
 	val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
 	    I2C_CONTROL_BYTE_CNT(0x3) | I2C_CONTROL_READ |
@@ -3432,7 +3432,7 @@
 {
 	int exit_cnt = 0, ret = -1;
 	u64 val64;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 
 	val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
 	    I2C_CONTROL_BYTE_CNT(cnt) | I2C_CONTROL_SET_DATA(data) |
@@ -3555,7 +3555,7 @@
 
 static int s2io_register_test(nic_t * sp, uint64_t * data)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64 = 0;
 	int fail = 0;
 
@@ -3726,7 +3726,7 @@
 
 static int s2io_link_test(nic_t * sp, uint64_t * data)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64;
 
 	val64 = readq(&bar0->adapter_status);
@@ -3751,7 +3751,7 @@
 
 static int s2io_rldram_test(nic_t * sp, uint64_t * data)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64;
 	int cnt, iteration = 0, test_pass = 0;
 
@@ -4092,7 +4092,7 @@
 int s2io_change_mtu(struct net_device *dev, int new_mtu)
 {
 	nic_t *sp = dev->priv;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	register u64 val64;
 
 	if (netif_running(dev)) {
@@ -4169,7 +4169,7 @@
 {
 	nic_t *nic = (nic_t *) data;
 	struct net_device *dev = nic->dev;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	register u64 val64;
 	u16 subid;
 
@@ -4233,7 +4233,7 @@
 static void s2io_card_down(nic_t * sp)
 {
 	int cnt = 0;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	unsigned long flags;
 	register u64 val64 = 0;
 
@@ -4611,7 +4611,7 @@
 	int dma_flag = FALSE;
 	u32 mac_up, mac_down;
 	u64 val64 = 0, tmp64 = 0;
-	XENA_dev_config_t *bar0 = NULL;
+	XENA_dev_config_t __iomem *bar0 = NULL;
 	u16 subid;
 	mac_info_t *mac_control;
 	struct config_param *config;
@@ -4741,7 +4741,7 @@
 		goto mem_alloc_failed;
 	}
 
-	sp->bar0 = (caddr_t) ioremap(pci_resource_start(pdev, 0),
+	sp->bar0 = ioremap(pci_resource_start(pdev, 0),
 				     pci_resource_len(pdev, 0));
 	if (!sp->bar0) {
 		DBG_PRINT(ERR_DBG, "%s: S2IO: cannot remap io mem1\n",
@@ -4750,7 +4750,7 @@
 		goto bar0_remap_failed;
 	}
 
-	sp->bar1 = (caddr_t) ioremap(pci_resource_start(pdev, 2),
+	sp->bar1 = ioremap(pci_resource_start(pdev, 2),
 				     pci_resource_len(pdev, 2));
 	if (!sp->bar1) {
 		DBG_PRINT(ERR_DBG, "%s: S2IO: cannot remap io mem2\n",
@@ -4764,7 +4764,7 @@
 
 	/* Initializing the BAR1 address as the start of the FIFO pointer. */
 	for (j = 0; j < MAX_TX_FIFOS; j++) {
-		mac_control->tx_FIFO_start[j] = (TxFIFO_element_t *)
+		mac_control->tx_FIFO_start[j] = (TxFIFO_element_t __iomem *)
 		    (sp->bar1 + (j * 0x00020000));
 	}
 
@@ -4829,7 +4829,7 @@
 	 * MAC address initialization.
 	 * For now only one mac address will be read and used.
 	 */
-	bar0 = (XENA_dev_config_t *) sp->bar0;
+	bar0 = sp->bar0;
 	val64 = RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
 	    RMAC_ADDR_CMD_MEM_OFFSET(0 + MAC_MAC_ADDR_START_OFFSET);
 	writeq(val64, &bar0->rmac_addr_cmd_mem);
@@ -4886,7 +4886,7 @@
 		val64 |= 0x0000800000000000ULL;
 		writeq(val64, &bar0->gpio_control);
 		val64 = 0x0411040400000000ULL;
-		writeq(val64, (u64 *) ((u8 *) bar0 + 0x2700));
+		writeq(val64, (void __iomem *) bar0 + 0x2700);
 		val64 = readq(&bar0->gpio_control);
 	}
 
diff -Nru a/drivers/net/s2io.h b/drivers/net/s2io.h
--- a/drivers/net/s2io.h	2005-01-18 03:13:47 -05:00
+++ b/drivers/net/s2io.h	2005-01-18 03:13:47 -05:00
@@ -583,7 +583,7 @@
 
 /* tx side stuff */
 	/* logical pointer of start of each Tx FIFO */
-	TxFIFO_element_t *tx_FIFO_start[MAX_TX_FIFOS];
+	TxFIFO_element_t __iomem *tx_FIFO_start[MAX_TX_FIFOS];
 
 /* Current offset within tx_FIFO_start, where driver would write new Tx frame*/
 	tx_curr_put_info_t tx_curr_put_info[MAX_TX_FIFOS];
@@ -623,8 +623,8 @@
 	macaddr_t pre_mac_addr[MAX_MAC_SUPPORTED];
 
 	struct net_device_stats stats;
-	caddr_t bar0;
-	caddr_t bar1;
+	void __iomem *bar0;
+	void __iomem *bar1;
 	struct config_param config;
 	mac_info_t mac_control;
 	int high_dma_flag;
@@ -736,10 +736,9 @@
 
 /*  OS related system calls */
 #ifndef readq
-static inline u64 readq(void *addr)
+static inline u64 readq(void __iomem *addr)
 {
-	u64 ret = 0;
-	ret = readl(addr + 4);
+	u64 ret = readl(addr + 4);
 	ret <<= 32;
 	ret |= readl(addr);
 
@@ -748,7 +747,7 @@
 #endif
 
 #ifndef writeq
-static inline void writeq(u64 val, void *addr)
+static inline void writeq(u64 val, void __iomem *addr)
 {
 	writel((u32) (val), addr);
 	writel((u32) (val >> 32), (addr + 4));
@@ -762,7 +761,7 @@
  */
 #define UF	1
 #define LF	2
-static inline void SPECIAL_REG_WRITE(u64 val, void *addr, int order)
+static inline void SPECIAL_REG_WRITE(u64 val, void __iomem *addr, int order)
 {
 	if (order == LF) {
 		writel((u32) (val), addr);
diff -Nru a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
--- a/drivers/net/tulip/tulip_core.c	2005-01-18 03:13:47 -05:00
+++ b/drivers/net/tulip/tulip_core.c	2005-01-18 03:13:47 -05:00
@@ -1051,7 +1051,7 @@
 				else
 					filterbit = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
 				filterbit &= 0x3f;
-				mc_filter[filterbit >> 5] |= cpu_to_le32(1 << (filterbit & 31));
+				mc_filter[filterbit >> 5] |= 1 << (filterbit & 31);
 				if (tulip_debug > 2) {
 					printk(KERN_INFO "%s: Added filter for %2.2x:%2.2x:%2.2x:"
 						   "%2.2x:%2.2x:%2.2x  %8.8x bit %d.\n", dev->name,
diff -Nru a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
--- a/drivers/net/tulip/winbond-840.c	2005-01-18 03:13:47 -05:00
+++ b/drivers/net/tulip/winbond-840.c	2005-01-18 03:13:47 -05:00
@@ -1410,7 +1410,7 @@
 			 i++, mclist = mclist->next) {
 			int filterbit = (ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26) ^ 0x3F;
 			filterbit &= 0x3f;
-			mc_filter[filterbit >> 5] |= cpu_to_le32(1 << (filterbit & 31));
+			mc_filter[filterbit >> 5] |= 1 << (filterbit & 31);
 		}
 		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
 	}
diff -Nru a/drivers/net/tun.c b/drivers/net/tun.c
--- a/drivers/net/tun.c	2005-01-18 03:13:47 -05:00
+++ b/drivers/net/tun.c	2005-01-18 03:13:47 -05:00
@@ -16,11 +16,25 @@
  */
 
 /*
+ *  Changes:
+ *
+ *  Mark Smith <markzzzsmith@yahoo.com.au>
+ *   Use random_ether_addr() for tap MAC address.
+ *
+ *  Harald Roelle <harald.roelle@ifi.lmu.de>  2004/04/20
+ *    Fixes in packet dropping, queue length setting and queue wakeup.
+ *    Increased default tx queue length.
+ *    Added ethtool API.
+ *    Minor cleanups
+ *
  *  Daniel Podlejski <underley@underley.eu.org>
  *    Modifications for 2.3.99-pre5 kernel.
  */
 
-#define TUN_VER "1.5"
+#define DRV_NAME	"tun"
+#define DRV_VERSION	"1.6"
+#define DRV_DESCRIPTION	"Universal TUN/TAP device driver"
+#define DRV_COPYRIGHT	"(C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -31,11 +45,11 @@
 #include <linux/poll.h>
 #include <linux/fcntl.h>
 #include <linux/init.h>
-#include <linux/random.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/miscdevice.h>
+#include <linux/ethtool.h>
 #include <linux/rtnetlink.h>
 #include <linux/if.h>
 #include <linux/if_arp.h>
@@ -53,6 +67,7 @@
 /* Network device part of the driver */
 
 static LIST_HEAD(tun_dev_list);
+static struct ethtool_ops tun_ethtool_ops;
 
 /* Net device open. */
 static int tun_net_open(struct net_device *dev)
@@ -79,18 +94,24 @@
 	if (!tun->attached)
 		goto drop;
 
-	/* Queue packet */
-	if (!(tun->flags & TUN_ONE_QUEUE)) {
-		/* Normal queueing mode.
-		 * Packet scheduler handles dropping. */
-		if (skb_queue_len(&tun->readq) >= TUN_READQ_SIZE)
+	/* Packet dropping */
+	if (skb_queue_len(&tun->readq) >= dev->tx_queue_len) {
+		if (!(tun->flags & TUN_ONE_QUEUE)) {
+			/* Normal queueing mode. */
+			/* Packet scheduler handles dropping of further packets. */
 			netif_stop_queue(dev);
-	} else {
-		/* Single queue mode.
-		 * Driver handles dropping itself. */
-		if (skb_queue_len(&tun->readq) >= dev->tx_queue_len)
+
+			/* We won't see all dropped packets individually, so overrun
+			 * error is more appropriate. */
+			tun->stats.tx_fifo_errors++;
+		} else {
+			/* Single queue mode.
+			 * Driver handles dropping of all packets itself. */
 			goto drop;
+		}
 	}
+
+	/* Queue packet */
 	skb_queue_tail(&tun->readq, skb);
 
 	/* Notify and wake up reader process */
@@ -164,18 +185,16 @@
 		/* Zero header length */
 		dev->type = ARPHRD_NONE; 
 		dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
-		dev->tx_queue_len = 10;
+		dev->tx_queue_len = TUN_READQ_SIZE;  /* We prefer our own queue length */
 		break;
 
 	case TUN_TAP_DEV:
 		/* Ethernet TAP Device */
 		dev->set_multicast_list = tun_net_mclist;
 
-		/* Generate random Ethernet address.  */
-		*(u16 *)dev->dev_addr = htons(0x00FF);
-		get_random_bytes(dev->dev_addr + sizeof(u16), 4);
-
 		ether_setup(dev);
+		random_ether_addr(dev->dev_addr);
+		dev->tx_queue_len = TUN_READQ_SIZE;  /* We prefer our own queue length */
 		break;
 	}
 }
@@ -354,7 +373,7 @@
 			schedule();
 			continue;
 		}
-		netif_start_queue(tun->dev);
+		netif_wake_queue(tun->dev);
 
 		/** Decide whether to accept this packet. This code is designed to
 		 * behave identically to an Ethernet interface. Accept the packet if
@@ -418,6 +437,7 @@
 	dev->hard_start_xmit = tun_net_xmit;
 	dev->stop = tun_net_close;
 	dev->get_stats = tun_net_stats;
+	dev->ethtool_ops = &tun_ethtool_ops;
 	dev->destructor = free_netdev;
 }
 
@@ -736,12 +756,97 @@
 	.devfs_name = "net/tun",
 };
 
+/* ethtool interface */
+
+static int tun_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	cmd->supported		= 0;
+	cmd->advertising	= 0;
+	cmd->speed		= SPEED_10;
+	cmd->duplex		= DUPLEX_FULL;
+	cmd->port		= PORT_TP;
+	cmd->phy_address	= 0;
+	cmd->transceiver	= XCVR_INTERNAL;
+	cmd->autoneg		= AUTONEG_DISABLE;
+	cmd->maxtxpkt		= 0;
+	cmd->maxrxpkt		= 0;
+	return 0;
+}
+
+static void tun_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+	struct tun_struct *tun = netdev_priv(dev);
+
+	strcpy(info->driver, DRV_NAME);
+	strcpy(info->version, DRV_VERSION);
+	strcpy(info->fw_version, "N/A");
+
+	switch (tun->flags & TUN_TYPE_MASK) {
+	case TUN_TUN_DEV:
+		strcpy(info->bus_info, "tun");
+		break;
+	case TUN_TAP_DEV:
+		strcpy(info->bus_info, "tap");
+		break;
+	}
+}
+
+static u32 tun_get_msglevel(struct net_device *dev)
+{
+#ifdef TUN_DEBUG
+	struct tun_struct *tun = netdev_priv(dev);
+	return tun->debug;
+#else
+	return -EOPNOTSUPP;
+#endif
+}
+
+static void tun_set_msglevel(struct net_device *dev, u32 value)
+{
+#ifdef TUN_DEBUG
+	struct tun_struct *tun = netdev_priv(dev);
+	tun->debug = value;
+#endif
+}
+
+static u32 tun_get_link(struct net_device *dev)
+{
+	struct tun_struct *tun = netdev_priv(dev);
+	return tun->attached;
+}
+
+static u32 tun_get_rx_csum(struct net_device *dev)
+{
+	struct tun_struct *tun = netdev_priv(dev);
+	return (tun->flags & TUN_NOCHECKSUM) == 0;
+}
+
+static int tun_set_rx_csum(struct net_device *dev, u32 data)
+{
+	struct tun_struct *tun = netdev_priv(dev);
+	if (data)
+		tun->flags &= ~TUN_NOCHECKSUM;
+	else
+		tun->flags |= TUN_NOCHECKSUM;
+	return 0;
+}
+
+static struct ethtool_ops tun_ethtool_ops = {
+	.get_settings	= tun_get_settings,
+	.get_drvinfo	= tun_get_drvinfo,
+	.get_msglevel	= tun_get_msglevel,
+	.set_msglevel	= tun_set_msglevel,
+	.get_link	= tun_get_link,
+	.get_rx_csum	= tun_get_rx_csum,
+	.set_rx_csum	= tun_set_rx_csum
+};
+
 int __init tun_init(void)
 {
 	int ret = 0;
 
-	printk(KERN_INFO "Universal TUN/TAP device driver %s " 
-	       "(C)1999-2002 Maxim Krasnyansky\n", TUN_VER);
+	printk(KERN_INFO "tun: %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
+	printk(KERN_INFO "tun: %s\n", DRV_COPYRIGHT);
 
 	ret = misc_register(&tun_miscdev);
 	if (ret)
@@ -766,5 +871,7 @@
 
 module_init(tun_init);
 module_exit(tun_cleanup);
+MODULE_DESCRIPTION(DRV_DESCRIPTION);
+MODULE_AUTHOR(DRV_COPYRIGHT);
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(TUN_MINOR);
diff -Nru a/include/linux/if_tun.h b/include/linux/if_tun.h
--- a/include/linux/if_tun.h	2005-01-18 03:13:47 -05:00
+++ b/include/linux/if_tun.h	2005-01-18 03:13:47 -05:00
@@ -58,7 +58,7 @@
 #endif /* __KERNEL__ */
 
 /* Read queue size */
-#define TUN_READQ_SIZE	10
+#define TUN_READQ_SIZE	500
 
 /* TUN device flags */
 #define TUN_TUN_DEV 	0x0001	

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [BK PATCHES] 2.6.x net driver updates
@ 2005-01-11  5:01 Jeff Garzik
  0 siblings, 0 replies; 28+ messages in thread
From: Jeff Garzik @ 2005-01-11  5:01 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: Netdev

[-- Attachment #1: Type: text/plain, Size: 55 bytes --]


gcc 4 fixes, driver updates: ixgb, eepro, emac, ...



[-- Attachment #2: changelog.txt --]
[-- Type: text/plain, Size: 2827 bytes --]

Please do a

	bk pull bk://gkernel.bkbits.net/net-drivers-2.6

This will update the following files:

 drivers/net/arcnet/arcnet.c          |    3 
 drivers/net/eepro.c                  |  144 +++++--
 drivers/net/ibm_emac/ibm_emac.h      |    2 
 drivers/net/ibm_emac/ibm_emac_core.c |   15 
 drivers/net/ibm_emac/ibm_emac_phy.c  |   19 
 drivers/net/ixgb/ixgb.h              |   25 +
 drivers/net/ixgb/ixgb_ee.c           |  192 +++++----
 drivers/net/ixgb/ixgb_ethtool.c      |  518 ++++++++++++++++---------
 drivers/net/ixgb/ixgb_hw.c           |  231 ++++++-----
 drivers/net/ixgb/ixgb_hw.h           |   50 +-
 drivers/net/ixgb/ixgb_ids.h          |   21 -
 drivers/net/ixgb/ixgb_main.c         |  705 +++++++++++++++++------------------
 drivers/net/ixgb/ixgb_osdep.h        |   10 
 drivers/net/ixgb/ixgb_param.c        |  316 +++++++--------
 drivers/net/s2io.c                   |   22 -
 drivers/net/s2io.h                   |    4 
 drivers/net/smc-ultra.c              |    2 
 drivers/net/smc91x.c                 |   16 
 drivers/net/wireless/orinoco.c       |  203 +++-------
 drivers/net/wireless/wl3501_cs.c     |    4 
 include/linux/arcdevice.h            |    1 
 21 files changed, 1415 insertions(+), 1088 deletions(-)

through these ChangeSets:

Andi Kleen:
  o Fix gcc4 compilation in s2io net driver

Aristeu Sergio Rozanski Filho:
  o eepro: fix auto-detection option
  o eepro: fix return value in init_module()
  o eepro: basic ethtool support
  o eepro: use module_param macros
  o eepro: cache EEPROM values

Christoph Hellwig:
  o mark arcdev_setup static

David Gibson:
  o Another trivial orinoco update

Ganesh Venkatesan:
  o ixgb: White space corrections
  o ixgb: Driver version number update
  o ixgb: Support for 2.6.x style module parameters
  o ixgb: Fix Tx cleanup logic
  o ixgb: Shrink size and fix ordering of elements in ixgb_buffer
  o ixgb: ethtool_ops support
  o ixgb: Replace kmalloc with vmalloc (one time alloc)
  o ixgb: Remove support for RAIDC interrupt mitigation
  o ixgb: Limit Rx Address Filter Array entries to 3
  o ixgb: Fix infinite loop trying to re-establish link
  o ixgb: Fix error in setting MFS register
  o ixgb: Poll Routine cleanup
  o ixgb: Fix memory leak in NAPI mode
  o ixgb: Fix VLAN filter setup errors (while running on PPC)
  o ixgb: Add support for 10GbE LR device ID
  o ixgb: Enable Message Signalled Interrupts
  o ixgb: Limit number of Rx Descriptors to 512

Hirokazu Takata:
  o net: netconsole support for smc91x

Matt Porter:
  o Add netpoll support
  o allow rx of the maximum sized VLAN tagged packets
  o EMAC: fix ibm_emac autonegotiation result parsing

Paul Gortmaker:
  o smc-ultra.c too-verbose driver

Raghavendra Koushik:
  o S2io: fixes in free_shared_mem function

Randy Dunlap:
  o wl3501: fix module_param types/warnings


[-- Attachment #3: patch --]
[-- Type: text/plain, Size: 152350 bytes --]

diff -Nru a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
--- a/drivers/net/arcnet/arcnet.c	2005-01-10 23:54:12 -05:00
+++ b/drivers/net/arcnet/arcnet.c	2005-01-10 23:54:12 -05:00
@@ -93,7 +93,6 @@
 EXPORT_SYMBOL(arc_proto_null);
 EXPORT_SYMBOL(arcnet_unregister_proto);
 EXPORT_SYMBOL(arcnet_debug);
-EXPORT_SYMBOL(arcdev_setup);
 EXPORT_SYMBOL(alloc_arcdev);
 EXPORT_SYMBOL(arcnet_interrupt);
 
@@ -317,7 +316,7 @@
 
 
 /* Setup a struct device for ARCnet. */
-void arcdev_setup(struct net_device *dev)
+static void arcdev_setup(struct net_device *dev)
 {
 	dev->type = ARPHRD_ARCNET;
 	dev->hard_header_len = sizeof(struct archdr);
diff -Nru a/drivers/net/eepro.c b/drivers/net/eepro.c
--- a/drivers/net/eepro.c	2005-01-10 23:54:12 -05:00
+++ b/drivers/net/eepro.c	2005-01-10 23:54:12 -05:00
@@ -23,6 +23,7 @@
 	This is a compatibility hardware problem.
 
 	Versions:
+	0.13b	basic ethtool support (aris, 09/13/2004)
 	0.13a   in memory shortage, drop packets also in board
 		(Michael Westermann <mw@microdata-pos.de>, 07/30/2002)
 	0.13    irq sharing, rewrote probe function, fixed a nasty bug in
@@ -104,7 +105,7 @@
 */
 
 static const char version[] =
-	"eepro.c: v0.13 11/08/2001 aris@cathedrallabs.org\n";
+	"eepro.c: v0.13b 09/13/2004 aris@cathedrallabs.org\n";
 
 #include <linux/module.h>
 
@@ -146,19 +147,21 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/bitops.h>
+#include <linux/ethtool.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 
 #define DRV_NAME "eepro"
+#define DRV_VERSION "0.13b"
 
 #define compat_dev_kfree_skb( skb, mode ) dev_kfree_skb( (skb) )
 /* I had reports of looong delays with SLOW_DOWN defined as udelay(2) */
 #define SLOW_DOWN inb(0x80)
 /* udelay(2) */
 #define compat_init_data     __initdata
-
+enum iftype { AUI=0, BNC=1, TPE=2 };
 
 /* First, a few definitions that the brave might change. */
 /* A zero-terminated list of I/O addresses to be probed. */
@@ -214,6 +217,7 @@
 	short rcv_lower_limit;
 	short rcv_upper_limit;
 	unsigned char eeprom_reg;
+	unsigned short word[8];
 };
 
 /* The station (ethernet) address prefix, used for IDing the board. */
@@ -608,16 +612,22 @@
 }
 #endif
 
-static void __init printEEPROMInfo(short ioaddr, struct net_device *dev)
+static void __init printEEPROMInfo(struct net_device *dev)
 {
+	struct eepro_local *lp = (struct eepro_local *)dev->priv;
+	int ioaddr = dev->base_addr;
 	unsigned short Word;
 	int i,j;
 
-	for (i=0, j=ee_Checksum; i<ee_SIZE; i++)
-		j+=read_eeprom(ioaddr,i,dev);
+	j = ee_Checksum;
+	for (i = 0; i < 8; i++)
+		j += lp->word[i];
+	for ( ; i < ee_SIZE; i++)
+		j += read_eeprom(ioaddr, i, dev);
+
 	printk(KERN_DEBUG "Checksum: %#x\n",j&0xffff);
 
-	Word=read_eeprom(ioaddr, 0, dev);
+	Word = lp->word[0];
 	printk(KERN_DEBUG "Word0:\n");
 	printk(KERN_DEBUG " Plug 'n Pray: %d\n",GetBit(Word,ee_PnP));
 	printk(KERN_DEBUG " Buswidth: %d\n",(GetBit(Word,ee_BusWidth)+1)*8 );
@@ -625,7 +635,7 @@
 	printk(KERN_DEBUG " IO Address: %#x\n", (Word>>ee_IO0)<<4);
 
 	if (net_debug>4)  {
-		Word=read_eeprom(ioaddr, 1, dev);
+		Word = lp->word[1];
 		printk(KERN_DEBUG "Word1:\n");
 		printk(KERN_DEBUG " INT: %d\n", Word & ee_IntMask);
 		printk(KERN_DEBUG " LI: %d\n", GetBit(Word,ee_LI));
@@ -636,7 +646,7 @@
 		printk(KERN_DEBUG " Duplex: %d\n", GetBit(Word,ee_Duplex));
 	}
 
-	Word=read_eeprom(ioaddr, 5, dev);
+	Word = lp->word[5];
 	printk(KERN_DEBUG "Word5:\n");
 	printk(KERN_DEBUG " BNC: %d\n",GetBit(Word,ee_BNC_TPE));
 	printk(KERN_DEBUG " NumConnectors: %d\n",GetBit(Word,ee_NumConn));
@@ -646,12 +656,12 @@
 	if (GetBit(Word,ee_PortAUI)) printk(KERN_DEBUG "AUI ");
 	printk(KERN_DEBUG "port(s) \n");
 
-	Word=read_eeprom(ioaddr, 6, dev);
+	Word = lp->word[6];
 	printk(KERN_DEBUG "Word6:\n");
 	printk(KERN_DEBUG " Stepping: %d\n",Word & ee_StepMask);
 	printk(KERN_DEBUG " BoardID: %d\n",Word>>ee_BoardID);
 
-	Word=read_eeprom(ioaddr, 7, dev);
+	Word = lp->word[7];
 	printk(KERN_DEBUG "Word7:\n");
 	printk(KERN_DEBUG " INT to IRQ:\n");
 
@@ -725,7 +735,7 @@
 		printk(", %s.\n", ifmap[dev->if_port]);
 
 	if (net_debug > 3) {
-		i = read_eeprom(dev->base_addr, 5, dev);
+		i = lp->word[5];
 		if (i & 0x2000) /* bit 13 of EEPROM word 5 */
 			printk(KERN_DEBUG "%s: Concurrent Processing is "
 				"enabled but not used!\n", dev->name);
@@ -733,19 +743,20 @@
 
 	/* Check the station address for the manufacturer's code */
 	if (net_debug>3)
-		printEEPROMInfo(dev->base_addr, dev);
+		printEEPROMInfo(dev);
 }
 
+static struct ethtool_ops eepro_ethtool_ops;
+
 /* This is the real probe routine.  Linux has a history of friendly device
    probes on the ISA bus.  A good device probe avoids doing writes, and
    verifies that the correct device exists and functions.  */
 
 static int __init eepro_probe1(struct net_device *dev, int autoprobe)
 {
-	unsigned short station_addr[6], id, counter;
+	unsigned short station_addr[3], id, counter;
 	int i;
 	struct eepro_local *lp;
-	enum iftype { AUI=0, BNC=1, TPE=2 };
 	int ioaddr = dev->base_addr;
 
 	/* Grab the region so we can find another board if autoIRQ fails. */
@@ -796,11 +807,16 @@
 		lp->xmt_bar = XMT_BAR_10;
 		station_addr[0] = read_eeprom(ioaddr, 2, dev);
 	}
-	station_addr[1] = read_eeprom(ioaddr, 3, dev);
-	station_addr[2] = read_eeprom(ioaddr, 4, dev);
+
+	/* get all words at once. will be used here and for ethtool */
+	for (i = 0; i < 8; i++) {
+		lp->word[i] = read_eeprom(ioaddr, i, dev);
+	}
+	station_addr[1] = lp->word[3];
+	station_addr[2] = lp->word[4];
 
 	if (!lp->eepro) {
-		if (read_eeprom(ioaddr,7,dev)== ee_FX_INT2IRQ)
+		if (lp->word[7] == ee_FX_INT2IRQ)
 			lp->eepro = 2;
 		else if (station_addr[2] == SA_ADDR1)
 			lp->eepro = 1;
@@ -817,15 +833,15 @@
 	/* calculate {xmt,rcv}_{lower,upper}_limit */
 	eepro_recalc(dev);
 
-	if (GetBit( read_eeprom(ioaddr, 5, dev),ee_BNC_TPE))
+	if (GetBit(lp->word[5], ee_BNC_TPE))
 		dev->if_port = BNC;
 	else
 		dev->if_port = TPE;
 
  	if (dev->irq < 2 && lp->eepro != 0) {
  		/* Mask off INT number */
- 		int count = read_eeprom(ioaddr, 1, dev) & 7;
- 		unsigned irqMask = read_eeprom(ioaddr, 7, dev);
+ 		int count = lp->word[1] & 7;
+ 		unsigned irqMask = lp->word[7];
  
  		while (count--)
  			irqMask &= irqMask - 1;
@@ -850,6 +866,7 @@
  	dev->set_multicast_list = &set_multicast_list;
  	dev->tx_timeout		= eepro_tx_timeout;
  	dev->watchdog_timeo	= TX_TIMEOUT;
+	dev->ethtool_ops	= &eepro_ethtool_ops;
  
 	/* print boot time info */
 	eepro_print_info(dev);
@@ -941,7 +958,7 @@
 	if (net_debug > 3)
 		printk(KERN_DEBUG "%s: entering eepro_open routine.\n", dev->name);
 
-	irqMask = read_eeprom(ioaddr,7,dev);
+	irqMask = lp->word[7];
 
 	if (lp->eepro == LAN595FX_10ISA) {
 		if (net_debug > 3) printk(KERN_DEBUG "p->eepro = 3;\n");
@@ -1070,8 +1087,6 @@
 		old9 = inb(ioaddr + 9);
 
 		if (irqMask==ee_FX_INT2IRQ) {
-			enum iftype { AUI=0, BNC=1, TPE=2 };
-
 			if (net_debug > 3) {
 				printk(KERN_DEBUG "IrqMask: %#x\n",irqMask);
 				printk(KERN_DEBUG "i82595FX detected!\n");
@@ -1701,12 +1716,72 @@
 	}
 }
 
+static int eepro_ethtool_get_settings(struct net_device *dev,
+					struct ethtool_cmd *cmd)
+{
+	struct eepro_local	*lp = (struct eepro_local *)dev->priv;
+
+	cmd->supported = 	SUPPORTED_10baseT_Half | 
+				SUPPORTED_10baseT_Full |
+				SUPPORTED_Autoneg;
+	cmd->advertising =	ADVERTISED_10baseT_Half |
+				ADVERTISED_10baseT_Full |
+				ADVERTISED_Autoneg;
+
+	if (GetBit(lp->word[5], ee_PortTPE)) {
+		cmd->supported |= SUPPORTED_TP;
+		cmd->advertising |= ADVERTISED_TP;
+	}
+	if (GetBit(lp->word[5], ee_PortBNC)) {
+		cmd->supported |= SUPPORTED_BNC;
+		cmd->advertising |= ADVERTISED_BNC;
+	}
+	if (GetBit(lp->word[5], ee_PortAUI)) {
+		cmd->supported |= SUPPORTED_AUI;
+		cmd->advertising |= ADVERTISED_AUI;
+	}
+
+	cmd->speed = SPEED_10;
+
+	if (dev->if_port == TPE && lp->word[1] & ee_Duplex) {
+		cmd->duplex = DUPLEX_FULL;
+	}
+	else {
+		cmd->duplex = DUPLEX_HALF;
+	}
+
+	cmd->port = dev->if_port;
+	cmd->phy_address = dev->base_addr;
+	cmd->transceiver = XCVR_INTERNAL;
+
+	if (lp->word[0] & ee_AutoNeg) {
+		cmd->autoneg = 1;
+	}
+
+	return 0;
+}
+
+static void eepro_ethtool_get_drvinfo(struct net_device *dev,
+					struct ethtool_drvinfo *drvinfo)
+{
+	strcpy(drvinfo->driver, DRV_NAME);
+	strcpy(drvinfo->version, DRV_VERSION);
+	sprintf(drvinfo->bus_info, "ISA 0x%lx", dev->base_addr);
+}
+
+static struct ethtool_ops eepro_ethtool_ops = {
+	.get_settings	= eepro_ethtool_get_settings,
+	.get_drvinfo 	= eepro_ethtool_get_drvinfo,
+};
+
 #ifdef MODULE
 
 #define MAX_EEPRO 8
 static struct net_device *dev_eepro[MAX_EEPRO];
 
-static int io[MAX_EEPRO];
+static int io[MAX_EEPRO] = {
+  [0 ... MAX_EEPRO-1] = -1
+};
 static int irq[MAX_EEPRO];
 static int mem[MAX_EEPRO] = {	/* Size of the rx buffer in KB */
   [0 ... MAX_EEPRO-1] = RCV_DEFAULT_RAM/1024
@@ -1716,14 +1791,15 @@
 static int n_eepro;
 /* For linux 2.1.xx */
 
-MODULE_AUTHOR("Pascal Dupuis, and aris@cathedrallabs.org");
+MODULE_AUTHOR("Pascal Dupuis and others");
 MODULE_DESCRIPTION("Intel i82595 ISA EtherExpressPro10/10+ driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_EEPRO) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_EEPRO) "i");
-MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_EEPRO) "i");
-MODULE_PARM(autodetect, "1-" __MODULE_STRING(1) "i");
+static int num_params;
+module_param_array(io, int, num_params, 0);
+module_param_array(irq, int, num_params, 0);
+module_param_array(mem, int, num_params, 0);
+module_param(autodetect, int, 0);
 MODULE_PARM_DESC(io, "EtherExpress Pro/10 I/O base addres(es)");
 MODULE_PARM_DESC(irq, "EtherExpress Pro/10 IRQ number(s)");
 MODULE_PARM_DESC(mem, "EtherExpress Pro/10 Rx buffer size(es) in kB (3-29)");
@@ -1734,19 +1810,21 @@
 {
 	struct net_device *dev;
 	int i;
-	if (io[0] == 0 && autodetect == 0) {
+	if (io[0] == -1 && autodetect == 0) {
 		printk(KERN_WARNING "eepro_init_module: Probe is very dangerous in ISA boards!\n");
 		printk(KERN_WARNING "eepro_init_module: Please add \"autodetect=1\" to force probe\n");
-		return 1;
+		return -ENODEV;
 	}
 	else if (autodetect) {
 		/* if autodetect is set then we must force detection */
-		io[0] = 0;
+		for (i = 0; i < MAX_EEPRO; i++) {
+			io[i] = 0;
+		}
 
 		printk(KERN_INFO "eepro_init_module: Auto-detecting boards (May God protect us...)\n");
 	}
 
-	for (i = 0; i < MAX_EEPRO; i++) {
+	for (i = 0; io[i] != -1 && i < MAX_EEPRO; i++) {
 		dev = alloc_etherdev(sizeof(struct eepro_local));
 		if (!dev)
 			break;
diff -Nru a/drivers/net/ibm_emac/ibm_emac.h b/drivers/net/ibm_emac/ibm_emac.h
--- a/drivers/net/ibm_emac/ibm_emac.h	2005-01-10 23:54:12 -05:00
+++ b/drivers/net/ibm_emac/ibm_emac.h	2005-01-10 23:54:12 -05:00
@@ -98,7 +98,7 @@
 #endif				/* CONFIG_IBM_EMAC4 */
 #define EMAC_M1_BASE			(EMAC_M1_TX_FIFO_2K | \
 					EMAC_M1_APP | \
-					EMAC_M1_TR)
+					EMAC_M1_TR | EMAC_M1_VLE)
 
 /* Transmit Mode Register 0 */
 #define EMAC_TMR0_GNP0			0x80000000
diff -Nru a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c
--- a/drivers/net/ibm_emac/ibm_emac_core.c	2005-01-10 23:54:12 -05:00
+++ b/drivers/net/ibm_emac/ibm_emac_core.c	2005-01-10 23:54:12 -05:00
@@ -1363,6 +1363,9 @@
 
 	/* set frame gap */
 	out_be32(&emacp->em0ipgvr, CONFIG_IBM_EMAC_FGAP);
+	
+	/* set VLAN Tag Protocol Identifier */
+	out_be32(&emacp->em0vtpid, 0x8100);
 
 	/* Init ring buffers */
 	emac_init_rings(fep->ndev);
@@ -1700,6 +1703,15 @@
 	.rxde = &emac_rxde_dev,
 };
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static int emac_netpoll(struct net_device *ndev)
+{
+	emac_rxeob_dev((void *)ndev, 0);
+	emac_txeob_dev((void *)ndev, 0);
+	return 0;
+}
+#endif
+
 static int emac_init_device(struct ocp_device *ocpdev, struct ibm_ocp_mal *mal)
 {
 	int deferred_init = 0;
@@ -1882,6 +1894,9 @@
 	SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops);
 	if (emacdata->tah_idx >= 0)
 		ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	ndev->poll_controller = emac_netpoll;
+#endif
 
 	SET_MODULE_OWNER(ndev);
 
diff -Nru a/drivers/net/ibm_emac/ibm_emac_phy.c b/drivers/net/ibm_emac/ibm_emac_phy.c
--- a/drivers/net/ibm_emac/ibm_emac_phy.c	2005-01-10 23:54:12 -05:00
+++ b/drivers/net/ibm_emac/ibm_emac_phy.c	2005-01-10 23:54:12 -05:00
@@ -191,17 +191,18 @@
 	u16 lpa;
 
 	if (phy->autoneg) {
-		lpa = phy_read(phy, MII_LPA);
+		lpa = phy_read(phy, MII_LPA) & phy_read(phy, MII_ADVERTISE);
 
-		if (lpa & (LPA_10FULL | LPA_100FULL))
-			phy->duplex = DUPLEX_FULL;
-		else
-			phy->duplex = DUPLEX_HALF;
-		if (lpa & (LPA_100FULL | LPA_100HALF))
-			phy->speed = SPEED_100;
-		else
-			phy->speed = SPEED_10;
+		phy->speed = SPEED_10;
+		phy->duplex = DUPLEX_HALF;
 		phy->pause = 0;
+
+		if (lpa & (LPA_100FULL | LPA_100HALF)) {
+			phy->speed = SPEED_100;
+			if (lpa & LPA_100FULL)
+				phy->duplex = DUPLEX_FULL;
+		} else if (lpa & LPA_10FULL)
+			phy->duplex = DUPLEX_FULL;
 	}
 	/* On non-aneg, we assume what we put in BMCR is the speed,
 	 * though magic-aneg shouldn't prevent this case from occurring
diff -Nru a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h
--- a/drivers/net/ixgb/ixgb.h	2005-01-10 23:54:12 -05:00
+++ b/drivers/net/ixgb/ixgb.h	2005-01-10 23:54:12 -05:00
@@ -46,6 +46,7 @@
 #include <linux/delay.h>
 #include <linux/timer.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 #include <linux/interrupt.h>
 #include <linux/string.h>
 #include <linux/pagemap.h>
@@ -85,6 +86,20 @@
 
 #define IXGB_ERR(args...) printk(KERN_ERR "ixgb: " args)
 
+/* TX/RX descriptor defines */
+#define DEFAULT_TXD	 256
+#define MAX_TXD   	4096
+#define MIN_TXD	  64
+
+/* hardware cannot reliably support more than 512 descriptors owned by
+ * hardware descrioptor cache otherwise an unreliable ring under heavy 
+ * recieve load may result */
+/* #define DEFAULT_RXD	   1024 */
+/* #define MAX_RXD	   4096 */
+#define DEFAULT_RXD	512
+#define MAX_RXD	512
+#define MIN_RXD	 64
+
 /* Supported Rx Buffer Sizes */
 #define IXGB_RXBUFFER_2048  2048
 #define IXGB_RXBUFFER_4096  4096
@@ -105,9 +120,9 @@
 struct ixgb_buffer {
 	struct sk_buff *skb;
 	uint64_t dma;
-	unsigned long length;
 	unsigned long time_stamp;
-	unsigned int next_to_watch;
+	uint16_t length;
+	uint16_t next_to_watch;
 };
 
 struct ixgb_desc_ring {
@@ -167,7 +182,6 @@
 	uint64_t hw_csum_rx_error;
 	uint64_t hw_csum_rx_good;
 	uint32_t rx_int_delay;
-	boolean_t raidc;
 	boolean_t rx_csum;
 
 	/* OS defined structs */
@@ -178,5 +192,8 @@
 	/* structs defined in ixgb_hw.h */
 	struct ixgb_hw hw;
 	struct ixgb_hw_stats stats;
+#ifdef CONFIG_PCI_MSI
+	boolean_t have_msi;
+#endif
 };
-#endif				/* _IXGB_H_ */
+#endif /* _IXGB_H_ */
diff -Nru a/drivers/net/ixgb/ixgb_ee.c b/drivers/net/ixgb/ixgb_ee.c
--- a/drivers/net/ixgb/ixgb_ee.c	2005-01-10 23:54:12 -05:00
+++ b/drivers/net/ixgb/ixgb_ee.c	2005-01-10 23:54:12 -05:00
@@ -32,7 +32,8 @@
 static uint16_t ixgb_shift_in_bits(struct ixgb_hw *hw);
 
 static void ixgb_shift_out_bits(struct ixgb_hw *hw,
-				uint16_t data, uint16_t count);
+				uint16_t data,
+				uint16_t count);
 static void ixgb_standby_eeprom(struct ixgb_hw *hw);
 
 static boolean_t ixgb_wait_eeprom_command(struct ixgb_hw *hw);
@@ -45,7 +46,9 @@
  * hw - Struct containing variables accessed by shared code
  * eecd_reg - EECD's current value
  *****************************************************************************/
-static void ixgb_raise_clock(struct ixgb_hw *hw, uint32_t * eecd_reg)
+static void
+ixgb_raise_clock(struct ixgb_hw *hw,
+		  uint32_t *eecd_reg)
 {
 	/* Raise the clock input to the EEPROM (by setting the SK bit), and then
 	 *  wait 50 microseconds.
@@ -62,7 +65,9 @@
  * hw - Struct containing variables accessed by shared code
  * eecd_reg - EECD's current value
  *****************************************************************************/
-static void ixgb_lower_clock(struct ixgb_hw *hw, uint32_t * eecd_reg)
+static void
+ixgb_lower_clock(struct ixgb_hw *hw,
+		  uint32_t *eecd_reg)
 {
 	/* Lower the clock input to the EEPROM (by clearing the SK bit), and then
 	 * wait 50 microseconds.
@@ -81,7 +86,9 @@
  * count - number of bits to shift out
  *****************************************************************************/
 static void
-ixgb_shift_out_bits(struct ixgb_hw *hw, uint16_t data, uint16_t count)
+ixgb_shift_out_bits(struct ixgb_hw *hw,
+					 uint16_t data,
+					 uint16_t count)
 {
 	uint32_t eecd_reg;
 	uint32_t mask;
@@ -101,7 +108,7 @@
 		 */
 		eecd_reg &= ~IXGB_EECD_DI;
 
-		if (data & mask)
+		if(data & mask)
 			eecd_reg |= IXGB_EECD_DI;
 
 		IXGB_WRITE_REG(hw, EECD, eecd_reg);
@@ -113,7 +120,7 @@
 
 		mask = mask >> 1;
 
-	} while (mask);
+	} while(mask);
 
 	/* We leave the "DI" bit set to "0" when we leave this routine. */
 	eecd_reg &= ~IXGB_EECD_DI;
@@ -126,7 +133,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static uint16_t ixgb_shift_in_bits(struct ixgb_hw *hw)
+static uint16_t
+ixgb_shift_in_bits(struct ixgb_hw *hw)
 {
 	uint32_t eecd_reg;
 	uint32_t i;
@@ -144,14 +152,14 @@
 	eecd_reg &= ~(IXGB_EECD_DO | IXGB_EECD_DI);
 	data = 0;
 
-	for (i = 0; i < 16; i++) {
+	for(i = 0; i < 16; i++) {
 		data = data << 1;
 		ixgb_raise_clock(hw, &eecd_reg);
 
 		eecd_reg = IXGB_READ_REG(hw, EECD);
 
 		eecd_reg &= ~(IXGB_EECD_DI);
-		if (eecd_reg & IXGB_EECD_DO)
+		if(eecd_reg & IXGB_EECD_DO)
 			data |= 1;
 
 		ixgb_lower_clock(hw, &eecd_reg);
@@ -168,7 +176,8 @@
  * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This
  * function should be called before issuing a command to the EEPROM.
  *****************************************************************************/
-static void ixgb_setup_eeprom(struct ixgb_hw *hw)
+static void
+ixgb_setup_eeprom(struct ixgb_hw *hw)
 {
 	uint32_t eecd_reg;
 
@@ -189,7 +198,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static void ixgb_standby_eeprom(struct ixgb_hw *hw)
+static void
+ixgb_standby_eeprom(struct ixgb_hw *hw)
 {
 	uint32_t eecd_reg;
 
@@ -222,7 +232,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static void ixgb_clock_eeprom(struct ixgb_hw *hw)
+static void
+ixgb_clock_eeprom(struct ixgb_hw *hw)
 {
 	uint32_t eecd_reg;
 
@@ -245,7 +256,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static void ixgb_cleanup_eeprom(struct ixgb_hw *hw)
+static void
+ixgb_cleanup_eeprom(struct ixgb_hw *hw)
 {
 	uint32_t eecd_reg;
 
@@ -270,7 +282,8 @@
  *      TRUE: EEPROM data pin is high before timeout.
  *      FALSE:  Time expired.
  *****************************************************************************/
-static boolean_t ixgb_wait_eeprom_command(struct ixgb_hw *hw)
+static boolean_t
+ixgb_wait_eeprom_command(struct ixgb_hw *hw)
 {
 	uint32_t eecd_reg;
 	uint32_t i;
@@ -284,10 +297,10 @@
 	 * signal that the command has been completed by raising the DO signal.
 	 * If DO does not go high in 10 milliseconds, then error out.
 	 */
-	for (i = 0; i < 200; i++) {
+	for(i = 0; i < 200; i++) {
 		eecd_reg = IXGB_READ_REG(hw, EECD);
 
-		if (eecd_reg & IXGB_EECD_DO)
+		if(eecd_reg & IXGB_EECD_DO)
 			return (TRUE);
 
 		udelay(50);
@@ -309,15 +322,16 @@
  *  TRUE: Checksum is valid
  *  FALSE: Checksum is not valid.
  *****************************************************************************/
-boolean_t ixgb_validate_eeprom_checksum(struct ixgb_hw * hw)
+boolean_t
+ixgb_validate_eeprom_checksum(struct ixgb_hw *hw)
 {
 	uint16_t checksum = 0;
 	uint16_t i;
 
-	for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++)
+	for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++)
 		checksum += ixgb_read_eeprom(hw, i);
 
-	if (checksum == (uint16_t) EEPROM_SUM)
+	if(checksum == (uint16_t) EEPROM_SUM)
 		return (TRUE);
 	else
 		return (FALSE);
@@ -331,12 +345,13 @@
  * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA.
  * Writes the difference to word offset 63 of the EEPROM.
  *****************************************************************************/
-void ixgb_update_eeprom_checksum(struct ixgb_hw *hw)
+void
+ixgb_update_eeprom_checksum(struct ixgb_hw *hw)
 {
 	uint16_t checksum = 0;
 	uint16_t i;
 
-	for (i = 0; i < EEPROM_CHECKSUM_REG; i++)
+	for(i = 0; i < EEPROM_CHECKSUM_REG; i++)
 		checksum += ixgb_read_eeprom(hw, i);
 
 	checksum = (uint16_t) EEPROM_SUM - checksum;
@@ -356,7 +371,10 @@
  * EEPROM will most likely contain an invalid checksum.
  *
  *****************************************************************************/
-void ixgb_write_eeprom(struct ixgb_hw *hw, uint16_t offset, uint16_t data)
+void
+ixgb_write_eeprom(struct ixgb_hw *hw,
+		   uint16_t offset,
+		   uint16_t data)
 {
 	/*  Prepare the EEPROM for writing  */
 	ixgb_setup_eeprom(hw);
@@ -404,7 +422,9 @@
  * Returns:
  *  The 16-bit value read from the eeprom
  *****************************************************************************/
-uint16_t ixgb_read_eeprom(struct ixgb_hw * hw, uint16_t offset)
+uint16_t
+ixgb_read_eeprom(struct ixgb_hw *hw,
+		  uint16_t offset)
 {
 	uint16_t data;
 
@@ -437,7 +457,8 @@
  *      TRUE: if eeprom read is successful
  *      FALSE: otherwise.
  *****************************************************************************/
-boolean_t ixgb_get_eeprom_data(struct ixgb_hw * hw)
+boolean_t
+ixgb_get_eeprom_data(struct ixgb_hw *hw)
 {
 	uint16_t i;
 	uint16_t checksum = 0;
@@ -448,7 +469,7 @@
 	ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
 	DEBUGOUT("ixgb_ee: Reading eeprom data\n");
-	for (i = 0; i < IXGB_EEPROM_SIZE; i++) {
+	for(i = 0; i < IXGB_EEPROM_SIZE ; i++) {
 		uint16_t ee_data;
 		ee_data = ixgb_read_eeprom(hw, i);
 		checksum += ee_data;
@@ -461,12 +482,12 @@
 	}
 
 	if ((ee_map->init_ctrl_reg_1 & le16_to_cpu(EEPROM_ICW1_SIGNATURE_MASK))
-	    != le16_to_cpu(EEPROM_ICW1_SIGNATURE_VALID)) {
+		 != le16_to_cpu(EEPROM_ICW1_SIGNATURE_VALID)) {
 		DEBUGOUT("ixgb_ee: Signature invalid.\n");
-		return (FALSE);
+		return(FALSE);
 	}
 
-	return (TRUE);
+	return(TRUE);
 }
 
 /******************************************************************************
@@ -479,7 +500,8 @@
  *      TRUE: eeprom signature was good and the eeprom read was successful
  *      FALSE: otherwise.
  ******************************************************************************/
-static boolean_t ixgb_check_and_get_eeprom_data(struct ixgb_hw *hw)
+static boolean_t
+ixgb_check_and_get_eeprom_data (struct ixgb_hw* hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
@@ -500,15 +522,16 @@
  * Returns:
  *          Word at indexed offset in eeprom, if valid, 0 otherwise.
  ******************************************************************************/
-uint16_t ixgb_get_eeprom_word(struct ixgb_hw * hw, uint16_t index)
+uint16_t
+ixgb_get_eeprom_word(struct ixgb_hw *hw, uint16_t index)
 {
 
 	if ((index < IXGB_EEPROM_SIZE) &&
-	    (ixgb_check_and_get_eeprom_data(hw) == TRUE)) {
-		return (hw->eeprom[index]);
+		(ixgb_check_and_get_eeprom_data(hw) == TRUE)) {
+	   return(hw->eeprom[index]);
 	}
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -519,7 +542,9 @@
  *
  * Returns: None.
  ******************************************************************************/
-void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t * mac_addr)
+void
+ixgb_get_ee_mac_addr(struct ixgb_hw *hw,
+			uint8_t *mac_addr)
 {
 	int i;
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
@@ -542,14 +567,15 @@
  * Returns:
  *          compatibility flags if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_compatibility(struct ixgb_hw *hw)
+uint16_t
+ixgb_get_ee_compatibility(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->compatibility);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->compatibility);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -560,13 +586,14 @@
  * Returns:
  *          PBA number if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint32_t ixgb_get_ee_pba_number(struct ixgb_hw * hw)
+uint32_t
+ixgb_get_ee_pba_number(struct ixgb_hw *hw)
 {
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
 		return (le16_to_cpu(hw->eeprom[EEPROM_PBA_1_2_REG])
-			| (le16_to_cpu(hw->eeprom[EEPROM_PBA_3_4_REG]) << 16));
+			| (le16_to_cpu(hw->eeprom[EEPROM_PBA_3_4_REG])<<16));
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -577,14 +604,15 @@
  * Returns:
  *          Initialization Control Word 1 if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw * hw)
+uint16_t
+ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->init_ctrl_reg_1);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->init_ctrl_reg_1);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -595,14 +623,15 @@
  * Returns:
  *          Initialization Control Word 2 if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_init_ctrl_reg_2(struct ixgb_hw * hw)
+uint16_t
+ixgb_get_ee_init_ctrl_reg_2(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->init_ctrl_reg_2);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->init_ctrl_reg_2);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -613,14 +642,15 @@
  * Returns:
  *          Subsystem Id if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_subsystem_id(struct ixgb_hw * hw)
+uint16_t
+ixgb_get_ee_subsystem_id(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->subsystem_id);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+	   return(ee_map->subsystem_id);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -631,14 +661,15 @@
  * Returns:
  *          Sub Vendor Id if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_subvendor_id(struct ixgb_hw * hw)
+uint16_t
+ixgb_get_ee_subvendor_id(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->subvendor_id);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->subvendor_id);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -649,14 +680,15 @@
  * Returns:
  *          Device Id if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_device_id(struct ixgb_hw * hw)
+uint16_t
+ixgb_get_ee_device_id(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->device_id);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->device_id);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -667,14 +699,15 @@
  * Returns:
  *          Device Id if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_vendor_id(struct ixgb_hw * hw)
+uint16_t
+ixgb_get_ee_vendor_id(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->vendor_id);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->vendor_id);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -685,14 +718,15 @@
  * Returns:
  *          SDP Register if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint16_t ixgb_get_ee_swdpins_reg(struct ixgb_hw * hw)
+uint16_t
+ixgb_get_ee_swdpins_reg(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->swdpins_reg);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->swdpins_reg);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -703,14 +737,15 @@
  * Returns:
  *          D3 Power Management Bits if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint8_t ixgb_get_ee_d3_power(struct ixgb_hw * hw)
+uint8_t
+ixgb_get_ee_d3_power(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->d3_power);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->d3_power);
 
-	return (0);
+	return(0);
 }
 
 /******************************************************************************
@@ -721,12 +756,13 @@
  * Returns:
  *          D0 Power Management Bits if EEPROM contents are valid, 0 otherwise
  ******************************************************************************/
-uint8_t ixgb_get_ee_d0_power(struct ixgb_hw * hw)
+uint8_t
+ixgb_get_ee_d0_power(struct ixgb_hw *hw)
 {
 	struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom;
 
-	if (ixgb_check_and_get_eeprom_data(hw) == TRUE)
-		return (ee_map->d0_power);
+	if(ixgb_check_and_get_eeprom_data(hw) == TRUE)
+		return(ee_map->d0_power);
 
-	return (0);
+	return(0);
 }
diff -Nru a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
--- a/drivers/net/ixgb/ixgb_ethtool.c	2005-01-10 23:54:12 -05:00
+++ b/drivers/net/ixgb/ixgb_ethtool.c	2005-01-10 23:54:12 -05:00
@@ -37,6 +37,12 @@
 
 extern int ixgb_up(struct ixgb_adapter *adapter);
 extern void ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog);
+extern void ixgb_reset(struct ixgb_adapter *adapter);
+extern int ixgb_setup_rx_resources(struct ixgb_adapter *adapter);
+extern int ixgb_setup_tx_resources(struct ixgb_adapter *adapter);
+extern void ixgb_free_rx_resources(struct ixgb_adapter *adapter);
+extern void ixgb_free_tx_resources(struct ixgb_adapter *adapter);
+extern void ixgb_update_stats(struct ixgb_adapter *adapter);
 
 struct ixgb_stats {
 	char stat_string[ETH_GSTRING_LEN];
@@ -89,7 +95,7 @@
 	sizeof(ixgb_gstrings_stats) / sizeof(struct ixgb_stats)
 
 static int
-ixgb_ethtool_gset(struct net_device *netdev, struct ethtool_cmd *ecmd)
+ixgb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
@@ -97,7 +103,7 @@
 	ecmd->port = PORT_FIBRE;
 	ecmd->transceiver = XCVR_EXTERNAL;
 
-	if (netif_carrier_ok(adapter->netdev)) {
+	if(netif_carrier_ok(adapter->netdev)) {
 		ecmd->speed = SPEED_10000;
 		ecmd->duplex = DUPLEX_FULL;
 	} else {
@@ -110,86 +116,140 @@
 }
 
 static int
-ixgb_ethtool_sset(struct net_device *netdev, struct ethtool_cmd *ecmd)
+ixgb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
-	if (ecmd->autoneg == AUTONEG_ENABLE ||
-	    ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)
+	if(ecmd->autoneg == AUTONEG_ENABLE ||
+	   ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)
 		return -EINVAL;
-	else {
+	
+	if(netif_running(adapter->netdev)) {
 		ixgb_down(adapter, TRUE);
+		ixgb_reset(adapter);
 		ixgb_up(adapter);
-	}
+	} else
+		ixgb_reset(adapter);
+
 	return 0;
 }
 
 static void
-ixgb_ethtool_gpause(struct net_device *dev,
-		    struct ethtool_pauseparam *epause)
+ixgb_get_pauseparam(struct net_device *netdev,
+			 struct ethtool_pauseparam *pause)
 {
-	struct ixgb_adapter *adapter = dev->priv;
+	struct ixgb_adapter *adapter = netdev->priv;
 	struct ixgb_hw *hw = &adapter->hw;
-
-	epause->autoneg = AUTONEG_DISABLE;
-
-	if (hw->fc.type == ixgb_fc_rx_pause)
-		epause->rx_pause = 1;
-	else if (hw->fc.type == ixgb_fc_tx_pause)
-		epause->tx_pause = 1;
-	else if (hw->fc.type == ixgb_fc_full) {
-		epause->rx_pause = 1;
-		epause->tx_pause = 1;
+	
+	pause->autoneg = AUTONEG_DISABLE;
+		
+	if(hw->fc.type == ixgb_fc_rx_pause)
+		pause->rx_pause = 1;
+	else if(hw->fc.type == ixgb_fc_tx_pause)
+		pause->tx_pause = 1;
+	else if(hw->fc.type == ixgb_fc_full) {
+		pause->rx_pause = 1;
+		pause->tx_pause = 1;
 	}
 }
 
 static int
-ixgb_ethtool_spause(struct net_device *dev,
-		    struct ethtool_pauseparam *epause)
+ixgb_set_pauseparam(struct net_device *netdev,
+			 struct ethtool_pauseparam *pause)
 {
-	struct ixgb_adapter *adapter = dev->priv;
+	struct ixgb_adapter *adapter = netdev->priv;
 	struct ixgb_hw *hw = &adapter->hw;
-
-	if (epause->autoneg == AUTONEG_ENABLE)
+	
+	if(pause->autoneg == AUTONEG_ENABLE)
 		return -EINVAL;
 
-	if (epause->rx_pause && epause->tx_pause)
+	if(pause->rx_pause && pause->tx_pause)
 		hw->fc.type = ixgb_fc_full;
-	else if (epause->rx_pause && !epause->tx_pause)
+	else if(pause->rx_pause && !pause->tx_pause)
 		hw->fc.type = ixgb_fc_rx_pause;
-	else if (!epause->rx_pause && epause->tx_pause)
+	else if(!pause->rx_pause && pause->tx_pause)
 		hw->fc.type = ixgb_fc_tx_pause;
-	else if (!epause->rx_pause && !epause->tx_pause)
+	else if(!pause->rx_pause && !pause->tx_pause)
 		hw->fc.type = ixgb_fc_none;
 
-	ixgb_down(adapter, TRUE);
-	ixgb_up(adapter);
-
+	if(netif_running(adapter->netdev)) {
+		ixgb_down(adapter, TRUE);
+		ixgb_up(adapter);
+	} else
+		ixgb_reset(adapter);
+		
 	return 0;
 }
 
-static void
-ixgb_ethtool_gdrvinfo(struct net_device *netdev,
-		      struct ethtool_drvinfo *drvinfo)
+static uint32_t
+ixgb_get_rx_csum(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
-	strncpy(drvinfo->driver, ixgb_driver_name, 32);
-	strncpy(drvinfo->version, ixgb_driver_version, 32);
-	strncpy(drvinfo->fw_version, "N/A", 32);
-	strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
+	return adapter->rx_csum;
 }
 
+static int
+ixgb_set_rx_csum(struct net_device *netdev, uint32_t data)
+{
+	struct ixgb_adapter *adapter = netdev->priv;
+	adapter->rx_csum = data;
+
+	if(netif_running(netdev)) {
+		ixgb_down(adapter,TRUE);
+		ixgb_up(adapter);
+	} else
+		ixgb_reset(adapter);
+	return 0;
+}
+	
+static uint32_t
+ixgb_get_tx_csum(struct net_device *netdev)
+{
+	return (netdev->features & NETIF_F_HW_CSUM) != 0;
+}
+
+static int
+ixgb_set_tx_csum(struct net_device *netdev, uint32_t data)
+{
+	if (data)
+		netdev->features |= NETIF_F_HW_CSUM;
+	else
+		netdev->features &= ~NETIF_F_HW_CSUM;
+
+	return 0;
+}
+
+#ifdef NETIF_F_TSO
+static int
+ixgb_set_tso(struct net_device *netdev, uint32_t data)
+{
+	if(data)
+		netdev->features |= NETIF_F_TSO;
+	else
+		netdev->features &= ~NETIF_F_TSO;
+	return 0;
+} 
+#endif /* NETIF_F_TSO */
+
 #define IXGB_GET_STAT(_A_, _R_) _A_->stats._R_
+
+static int 
+ixgb_get_regs_len(struct net_device *netdev)
+{
+#define IXGB_REG_DUMP_LEN  136*sizeof(uint32_t)
+	return IXGB_REG_DUMP_LEN;
+}
+
 static void
-ixgb_ethtool_gregs(struct net_device *dev, struct ethtool_regs *regs, void *buf)
+ixgb_get_regs(struct net_device *netdev,
+		   struct ethtool_regs *regs, void *p)
 {
-	struct ixgb_adapter *adapter = dev->priv;
+	struct ixgb_adapter *adapter = netdev->priv;
 	struct ixgb_hw *hw = &adapter->hw;
-	uint32_t *reg = buf;
+	uint32_t *reg = p;
 	uint32_t *reg_start = reg;
 	uint8_t i;
 
-	regs->version =
-	    (adapter->hw.device_id << 16) | adapter->hw.subsystem_id;
+	regs->version = (adapter->hw.device_id << 16) | adapter->hw.subsystem_id;
 
 	/* General Registers */
 	*reg++ = IXGB_READ_REG(hw, CTRL0);	/*   0 */
@@ -219,8 +279,8 @@
 	*reg++ = IXGB_READ_REG(hw, RXCSUM);	/*  20 */
 
 	for (i = 0; i < IXGB_RAR_ENTRIES; i++) {
-		*reg++ = IXGB_READ_REG_ARRAY(hw, RAL, (i << 1));	/*21,...,51 */
-		*reg++ = IXGB_READ_REG_ARRAY(hw, RAH, (i << 1));	/*22,...,52 */
+		*reg++ = IXGB_READ_REG_ARRAY(hw, RAL, (i << 1)); /*21,...,51 */
+		*reg++ = IXGB_READ_REG_ARRAY(hw, RAH, (i << 1)); /*22,...,52 */
 	}
 
 	/* Transmit */
@@ -316,73 +376,222 @@
 }
 
 static int
-ixgb_ethtool_geeprom(struct net_device *dev,
-		     struct ethtool_eeprom *eeprom, u8 *data)
+ixgb_get_eeprom_len(struct net_device *netdev)
 {
-	struct ixgb_adapter *adapter = dev->priv;
+	/* return size in bytes */
+	return (IXGB_EEPROM_SIZE << 1);
+}
+
+static int
+ixgb_get_eeprom(struct net_device *netdev,
+		  struct ethtool_eeprom *eeprom, uint8_t *bytes)
+{
+	struct ixgb_adapter *adapter = netdev->priv;
 	struct ixgb_hw *hw = &adapter->hw;
+	uint16_t *eeprom_buff;
+	int i, max_len, first_word, last_word;
+	int ret_val = 0;
+
+	if(eeprom->len == 0) {
+		ret_val = -EINVAL;
+		goto geeprom_error;
+	}
 
 	eeprom->magic = hw->vendor_id | (hw->device_id << 16);
 
-	/* use our function to read the eeprom and update our cache */
-	ixgb_get_eeprom_data(hw);
-	memcpy(data, (char *)hw->eeprom + eeprom->offset, eeprom->len);
-	return 0;
+	max_len = ixgb_get_eeprom_len(netdev);
+
+	if(eeprom->offset > eeprom->offset + eeprom->len) {
+		ret_val = -EINVAL;
+		goto geeprom_error;
+	}
+
+	if((eeprom->offset + eeprom->len) > max_len)
+		eeprom->len = (max_len - eeprom->offset);
+
+	first_word = eeprom->offset >> 1;
+	last_word = (eeprom->offset + eeprom->len - 1) >> 1;
+
+	eeprom_buff = kmalloc(sizeof(uint16_t) *
+			(last_word - first_word + 1), GFP_KERNEL);
+	if(!eeprom_buff)
+		return -ENOMEM;
+
+	/* note the eeprom was good because the driver loaded */
+	for(i = 0; i <= (last_word - first_word); i++) {
+		eeprom_buff[i] = ixgb_get_eeprom_word(hw, (first_word + i));
+	}
+
+	memcpy(bytes, (uint8_t *)eeprom_buff + (eeprom->offset & 1),
+			eeprom->len);
+	kfree(eeprom_buff);
+
+geeprom_error:
+	return ret_val;
 }
 
 static int
-ixgb_ethtool_seeprom(struct net_device *dev,
-		     struct ethtool_eeprom *eeprom, u8 *data)
+ixgb_set_eeprom(struct net_device *netdev,
+		  struct ethtool_eeprom *eeprom, uint8_t *bytes)
 {
-	struct ixgb_adapter *adapter = dev->priv;
+	struct ixgb_adapter *adapter = netdev->priv;
 	struct ixgb_hw *hw = &adapter->hw;
-	/* We are under rtnl, so static is OK */
-	static uint16_t eeprom_buff[IXGB_EEPROM_SIZE];
-	int i, first_word, last_word;
-	char *ptr;
+	uint16_t *eeprom_buff;
+	void *ptr;
+	int max_len, first_word, last_word;
+	uint16_t i;
+
+	if(eeprom->len == 0)
+		return -EINVAL;
 
-	if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
+	if(eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
 		return -EFAULT;
 
+	max_len = ixgb_get_eeprom_len(netdev);
+
+	if(eeprom->offset > eeprom->offset + eeprom->len)
+		return -EINVAL;
+
+	if((eeprom->offset + eeprom->len) > max_len)
+		eeprom->len = (max_len - eeprom->offset);
+
 	first_word = eeprom->offset >> 1;
 	last_word = (eeprom->offset + eeprom->len - 1) >> 1;
-	ptr = (char *)eeprom_buff;
+	eeprom_buff = kmalloc(max_len, GFP_KERNEL);
+	if(!eeprom_buff)
+		return -ENOMEM;
+
+	ptr = (void *)eeprom_buff;
 
-	if (eeprom->offset & 1) {
+	if(eeprom->offset & 1) {
 		/* need read/modify/write of first changed EEPROM word */
 		/* only the second byte of the word is being modified */
 		eeprom_buff[0] = ixgb_read_eeprom(hw, first_word);
 		ptr++;
 	}
-	if ((eeprom->offset + eeprom->len) & 1) {
+	if((eeprom->offset + eeprom->len) & 1) {
 		/* need read/modify/write of last changed EEPROM word */
 		/* only the first byte of the word is being modified */
-		eeprom_buff[last_word - first_word]
-		    = ixgb_read_eeprom(hw, last_word);
+		eeprom_buff[last_word - first_word] 
+			= ixgb_read_eeprom(hw, last_word);
 	}
-	memcpy(ptr, data, eeprom->len);
 
-	for (i = 0; i <= (last_word - first_word); i++)
+	memcpy(ptr, bytes, eeprom->len);
+	for(i = 0; i <= (last_word - first_word); i++)
 		ixgb_write_eeprom(hw, first_word + i, eeprom_buff[i]);
 
 	/* Update the checksum over the first part of the EEPROM if needed */
-	if (first_word <= EEPROM_CHECKSUM_REG)
+	if(first_word <= EEPROM_CHECKSUM_REG)
 		ixgb_update_eeprom_checksum(hw);
 
+	kfree(eeprom_buff);
 	return 0;
 }
 
+static void
+ixgb_get_drvinfo(struct net_device *netdev,
+		   struct ethtool_drvinfo *drvinfo)
+{
+	struct ixgb_adapter *adapter = netdev->priv;
+
+	strncpy(drvinfo->driver,  ixgb_driver_name, 32);
+	strncpy(drvinfo->version, ixgb_driver_version, 32);
+	strncpy(drvinfo->fw_version, "N/A", 32);
+	strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
+	drvinfo->n_stats = IXGB_STATS_LEN;
+	drvinfo->regdump_len = ixgb_get_regs_len(netdev);
+	drvinfo->eedump_len = ixgb_get_eeprom_len(netdev);
+}
+
+static void
+ixgb_get_ringparam(struct net_device *netdev,
+		struct ethtool_ringparam *ring)
+{
+	struct ixgb_adapter *adapter = netdev->priv;
+	struct ixgb_desc_ring *txdr = &adapter->tx_ring;
+	struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
+
+	ring->rx_max_pending = MAX_RXD; 
+	ring->tx_max_pending = MAX_TXD;
+	ring->rx_mini_max_pending = 0;
+	ring->rx_jumbo_max_pending = 0;
+	ring->rx_pending = rxdr->count;
+	ring->tx_pending = txdr->count;
+	ring->rx_mini_pending = 0;
+	ring->rx_jumbo_pending = 0;
+}
+
+static int 
+ixgb_set_ringparam(struct net_device *netdev,
+		struct ethtool_ringparam *ring)
+{
+	struct ixgb_adapter *adapter = netdev->priv;
+	struct ixgb_desc_ring *txdr = &adapter->tx_ring;
+	struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
+	struct ixgb_desc_ring tx_old, tx_new, rx_old, rx_new;
+	int err;
+
+	tx_old = adapter->tx_ring;
+	rx_old = adapter->rx_ring;
+
+	if((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) 
+		return -EINVAL;
+
+	if(netif_running(adapter->netdev))
+		ixgb_down(adapter,TRUE);
+
+	rxdr->count = max(ring->rx_pending,(uint32_t)MIN_RXD);
+	rxdr->count = min(rxdr->count,(uint32_t)MAX_RXD);
+	IXGB_ROUNDUP(rxdr->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE); 
+
+	txdr->count = max(ring->tx_pending,(uint32_t)MIN_TXD);
+	txdr->count = min(txdr->count,(uint32_t)MAX_TXD);
+	IXGB_ROUNDUP(txdr->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE); 
+
+	if(netif_running(adapter->netdev)) {
+		/* Try to get new resources before deleting old */
+		if((err = ixgb_setup_rx_resources(adapter)))
+			goto err_setup_rx;
+		if((err = ixgb_setup_tx_resources(adapter)))
+			goto err_setup_tx;
+
+		/* save the new, restore the old in order to free it,
+		 * then restore the new back again */
+
+		rx_new = adapter->rx_ring;
+		tx_new = adapter->tx_ring;
+		adapter->rx_ring = rx_old;
+		adapter->tx_ring = tx_old;
+		ixgb_free_rx_resources(adapter);
+		ixgb_free_tx_resources(adapter);
+		adapter->rx_ring = rx_new;
+		adapter->tx_ring = tx_new;
+		if((err = ixgb_up(adapter)))
+			return err;
+	}
+
+	return 0;
+err_setup_tx:
+	ixgb_free_rx_resources(adapter);
+err_setup_rx:
+	adapter->rx_ring = rx_old;
+	adapter->tx_ring = tx_old;
+	ixgb_up(adapter);
+	return err;
+}
+
 /* toggle LED 4 times per second = 2 "blinks" per second */
 #define IXGB_ID_INTERVAL	(HZ/4)
 
 /* bit defines for adapter->led_status */
 #define IXGB_LED_ON		0
 
-static void ixgb_led_blink_callback(unsigned long data)
+static void
+ixgb_led_blink_callback(unsigned long data)
 {
 	struct ixgb_adapter *adapter = (struct ixgb_adapter *)data;
 
-	if (test_and_change_bit(IXGB_LED_ON, &adapter->led_status))
+	if(test_and_change_bit(IXGB_LED_ON, &adapter->led_status))
 		ixgb_led_off(&adapter->hw);
 	else
 		ixgb_led_on(&adapter->hw);
@@ -391,10 +600,14 @@
 }
 
 static int
-ixgb_ethtool_led_blink(struct net_device *netdev, u32 data)
+ixgb_phys_id(struct net_device *netdev, uint32_t data)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
-	if (!adapter->blink_timer.function) {
+
+	if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ))
+		data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ);
+
+	if(!adapter->blink_timer.function) {
 		init_timer(&adapter->blink_timer);
 		adapter->blink_timer.function = ixgb_led_blink_callback;
 		adapter->blink_timer.data = (unsigned long)adapter;
@@ -403,7 +616,7 @@
 	mod_timer(&adapter->blink_timer, jiffies);
 
 	set_current_state(TASK_INTERRUPTIBLE);
-	if (data)
+	if(data)
 		schedule_timeout(data * HZ);
 	else
 		schedule_timeout(MAX_SCHEDULE_TIMEOUT);
@@ -415,141 +628,74 @@
 	return 0;
 }
 
-static int ixgb_nway_reset(struct net_device *netdev)
-{
-	if (netif_running(netdev)) {
-		struct ixgb_adapter *adapter = netdev->priv;
-		ixgb_down(adapter, TRUE);
-		ixgb_up(adapter);
-	}
-	return 0;
-}
-
-static int ixgb_get_stats_count(struct net_device *dev)
+static int 
+ixgb_get_stats_count(struct net_device *netdev)
 {
 	return IXGB_STATS_LEN;
 }
 
-static void ixgb_get_strings(struct net_device *dev, u32 stringset, u8 *data)
+static void 
+ixgb_get_ethtool_stats(struct net_device *netdev, 
+		struct ethtool_stats *stats, uint64_t *data)
 {
+	struct ixgb_adapter *adapter = netdev->priv;
 	int i;
-	for (i = 0; i < IXGB_STATS_LEN; i++) {
-		memcpy(data + i * ETH_GSTRING_LEN,
-		       ixgb_gstrings_stats[i].stat_string,
-		       ETH_GSTRING_LEN);
-	}
-}
-
-static int ixgb_get_regs_len(struct net_device *dev)
-{
-	return 136*sizeof(uint32_t);
-}
 
-static int ixgb_get_eeprom_len(struct net_device *dev)
-{
-	/* return size in bytes */
-	return (IXGB_EEPROM_SIZE << 1);
+	ixgb_update_stats(adapter);
+	for(i = 0; i < IXGB_STATS_LEN; i++) {
+		char *p = (char *)adapter+ixgb_gstrings_stats[i].stat_offset;	
+		data[i] = (ixgb_gstrings_stats[i].sizeof_stat == 
+			sizeof(uint64_t)) ? *(uint64_t *)p : *(uint32_t *)p;
+	}
 }
 
-static void get_ethtool_stats(struct net_device *dev,
-		struct ethtool_stats *stats, u64 *data)
+static void 
+ixgb_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data)
 {
-	struct ixgb_adapter *adapter = dev->priv;
 	int i;
 
-	for (i = 0; i < IXGB_STATS_LEN; i++) {
-		void *p = (char *)adapter + ixgb_gstrings_stats[i].stat_offset;
-		stats->data[i] =
-		    (ixgb_gstrings_stats[i].sizeof_stat == sizeof(uint64_t))
-		    ? *(uint64_t *) p
-		    : *(uint32_t *) p;
+	switch(stringset) {
+	case ETH_SS_STATS:
+		for(i=0; i < IXGB_STATS_LEN; i++) {
+			memcpy(data + i * ETH_GSTRING_LEN, 
+			ixgb_gstrings_stats[i].stat_string,
+			ETH_GSTRING_LEN);
+		}
+		break;
 	}
 }
 
-static u32 ixgb_get_rx_csum(struct net_device *dev)
-{
-	struct ixgb_adapter *adapter = dev->priv;
-	return adapter->rx_csum;
-}
-
-static int ixgb_set_rx_csum(struct net_device *dev, u32 sum)
-{
-	struct ixgb_adapter *adapter = dev->priv;
-	adapter->rx_csum = sum;
-	ixgb_down(adapter, TRUE);
-	ixgb_up(adapter);
-	return 0;
-}
-
-static u32 ixgb_get_tx_csum(struct net_device *dev)
-{
-	return (dev->features & NETIF_F_HW_CSUM) != 0;
-}
-
-static int ixgb_set_tx_csum(struct net_device *dev, u32 sum)
-{
-	if (sum)
-		dev->features |= NETIF_F_HW_CSUM;
-	else
-		dev->features &= ~NETIF_F_HW_CSUM;
-	return 0;
-}
-
-static u32 ixgb_get_sg(struct net_device *dev)
-{
-	return (dev->features & NETIF_F_SG) != 0;
-}
-
-static int ixgb_set_sg(struct net_device *dev, u32 sum)
-{
-	if (sum)
-		dev->features |= NETIF_F_SG;
-	else
-		dev->features &= ~NETIF_F_SG;
-	return 0;
-}
-
-#ifdef NETIF_F_TSO
-static u32 ixgb_get_tso(struct net_device *dev)
-{
-	return (dev->features & NETIF_F_TSO) != 0;
-}
-
-static int ixgb_set_tso(struct net_device *dev, u32 sum)
-{
-	if (sum)
-		dev->features |= NETIF_F_TSO;
-	else
-		dev->features &= ~NETIF_F_TSO;
-	return 0;
-}
-#endif
-
 struct ethtool_ops ixgb_ethtool_ops = {
-	.get_settings = ixgb_ethtool_gset,
-	.set_settings = ixgb_ethtool_sset,
-	.get_drvinfo = ixgb_ethtool_gdrvinfo,
-	.nway_reset = ixgb_nway_reset,
-	.get_link = ethtool_op_get_link,
-	.phys_id = ixgb_ethtool_led_blink,
-	.get_strings = ixgb_get_strings,
-	.get_stats_count = ixgb_get_stats_count,
-	.get_regs = ixgb_ethtool_gregs,
+	.get_settings = ixgb_get_settings,
+	.set_settings = ixgb_set_settings,
+	.get_drvinfo = ixgb_get_drvinfo,
 	.get_regs_len = ixgb_get_regs_len,
+	.get_regs = ixgb_get_regs,
+	.get_link = ethtool_op_get_link,
 	.get_eeprom_len = ixgb_get_eeprom_len,
-	.get_eeprom = ixgb_ethtool_geeprom,
-	.set_eeprom = ixgb_ethtool_seeprom,
-	.get_pauseparam = ixgb_ethtool_gpause,
-	.set_pauseparam = ixgb_ethtool_spause,
-	.get_ethtool_stats = get_ethtool_stats,
+	.get_eeprom = ixgb_get_eeprom,
+	.set_eeprom = ixgb_set_eeprom,
+	.get_ringparam = ixgb_get_ringparam,
+	.set_ringparam = ixgb_set_ringparam,
+	.get_pauseparam	= ixgb_get_pauseparam,
+	.set_pauseparam	= ixgb_set_pauseparam,
 	.get_rx_csum = ixgb_get_rx_csum,
 	.set_rx_csum = ixgb_set_rx_csum,
 	.get_tx_csum = ixgb_get_tx_csum,
 	.set_tx_csum = ixgb_set_tx_csum,
-	.get_sg = ixgb_get_sg,
-	.set_sg = ixgb_set_sg,
+	.get_sg	= ethtool_op_get_sg,
+	.set_sg	= ethtool_op_set_sg,
 #ifdef NETIF_F_TSO
-	.get_tso = ixgb_get_tso,
+	.get_tso = ethtool_op_get_tso,
 	.set_tso = ixgb_set_tso,
 #endif
+	.get_strings = ixgb_get_strings,
+	.phys_id = ixgb_phys_id,
+	.get_stats_count = ixgb_get_stats_count,
+	.get_ethtool_stats = ixgb_get_ethtool_stats,
 };
+
+void set_ethtool_ops(struct net_device *netdev)
+{
+	SET_ETHTOOL_OPS(netdev, &ixgb_ethtool_ops);
+}
diff -Nru a/drivers/net/ixgb/ixgb_hw.c b/drivers/net/ixgb/ixgb_hw.c
--- a/drivers/net/ixgb/ixgb_hw.c	2005-01-10 23:54:12 -05:00
+++ b/drivers/net/ixgb/ixgb_hw.c	2005-01-10 23:54:12 -05:00
@@ -53,9 +53,14 @@
 {
 	uint32_t ctrl_reg;
 
-	ctrl_reg = IXGB_CTRL0_RST | IXGB_CTRL0_SDP3_DIR |	/* All pins are Output=1 */
-	    IXGB_CTRL0_SDP2_DIR | IXGB_CTRL0_SDP1_DIR | IXGB_CTRL0_SDP0_DIR | IXGB_CTRL0_SDP3 |	/* Initial value 1101   */
-	    IXGB_CTRL0_SDP2 | IXGB_CTRL0_SDP0;
+	ctrl_reg =  IXGB_CTRL0_RST |
+				IXGB_CTRL0_SDP3_DIR |   /* All pins are Output=1 */
+				IXGB_CTRL0_SDP2_DIR |
+				IXGB_CTRL0_SDP1_DIR |
+				IXGB_CTRL0_SDP0_DIR |
+				IXGB_CTRL0_SDP3	 |   /* Initial value 1101   */
+				IXGB_CTRL0_SDP2	 |
+				IXGB_CTRL0_SDP0;
 
 #ifdef HP_ZX1
 	/* Workaround for 82597EX reset errata */
@@ -84,7 +89,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-boolean_t ixgb_adapter_stop(struct ixgb_hw * hw)
+boolean_t
+ixgb_adapter_stop(struct ixgb_hw *hw)
 {
 	uint32_t ctrl_reg;
 	uint32_t icr_reg;
@@ -94,7 +100,7 @@
 	/* If we are stopped or resetting exit gracefully and wait to be
 	 * started again before accessing the hardware.
 	 */
-	if (hw->adapter_stopped) {
+	if(hw->adapter_stopped) {
 		DEBUGOUT("Exiting because the adapter is already stopped!!!\n");
 		return FALSE;
 	}
@@ -135,6 +141,7 @@
 	return (ctrl_reg & IXGB_CTRL0_RST);
 }
 
+
 /******************************************************************************
  * Identifies the vendor of the optics module on the adapter.  The SR adapters
  * support two different types of XPAK optics, so it is necessary to determine
@@ -144,7 +151,8 @@
  *
  * Returns: the vendor of the XPAK optics module.
  *****************************************************************************/
-static ixgb_xpak_vendor ixgb_identify_xpak_vendor(struct ixgb_hw *hw)
+static ixgb_xpak_vendor
+ixgb_identify_xpak_vendor(struct ixgb_hw *hw)
 {
 	uint32_t i;
 	uint16_t vendor_name[5];
@@ -183,7 +191,8 @@
  *
  * Returns: the phy type of the adapter.
  *****************************************************************************/
-static ixgb_phy_type ixgb_identify_phy(struct ixgb_hw *hw)
+static ixgb_phy_type
+ixgb_identify_phy(struct ixgb_hw *hw)
 {
 	ixgb_phy_type phy_type;
 	ixgb_xpak_vendor xpak_vendor;
@@ -210,6 +219,11 @@
 			phy_type = ixgb_phy_type_g6005;
 		}
 		break;
+		case IXGB_DEVICE_ID_82597EX_LR:
+			DEBUGOUT("Identified G6104 optics\n");
+			phy_type = ixgb_phy_type_g6104;
+			break;
+
 
 	default:
 		DEBUGOUT("Unknown physical layer module\n");
@@ -237,7 +251,8 @@
  *      TRUE if successful,
  *      FALSE if unrecoverable problems were encountered.
  *****************************************************************************/
-boolean_t ixgb_init_hw(struct ixgb_hw * hw)
+boolean_t
+ixgb_init_hw(struct ixgb_hw *hw)
 {
 	uint32_t i;
 	uint32_t ctrl_reg;
@@ -266,7 +281,7 @@
 	msec_delay(IXGB_DELAY_AFTER_EE_RESET);
 
 	if (ixgb_get_eeprom_data(hw) == FALSE) {
-		return (FALSE);
+		return(FALSE);
 	}
 
 	/* Use the device id to determine the type of phy/transceiver. */
@@ -284,7 +299,7 @@
 	 */
 	if (!mac_addr_valid(hw->curr_mac_addr)) {
 		DEBUGOUT("MAC address invalid after ixgb_init_rx_addrs\n");
-		return (FALSE);
+		return(FALSE);
 	}
 
 	/* tell the routines in this file they can access hardware again */
@@ -295,7 +310,7 @@
 
 	/* Zero out the Multicast HASH table */
 	DEBUGOUT("Zeroing the MTA\n");
-	for (i = 0; i < IXGB_MC_TBL_SIZE; i++)
+	for(i = 0; i < IXGB_MC_TBL_SIZE; i++)
 		IXGB_WRITE_REG_ARRAY(hw, MTA, i, 0);
 
 	/* Zero out the VLAN Filter Table Array */
@@ -322,7 +337,8 @@
  * of the receive addresss registers. Clears the multicast table. Assumes
  * the receiver is in reset when the routine is called.
  *****************************************************************************/
-void ixgb_init_rx_addrs(struct ixgb_hw *hw)
+void
+ixgb_init_rx_addrs(struct ixgb_hw *hw)
 {
 	uint32_t i;
 
@@ -360,7 +376,7 @@
 
 	/* Zero out the other 15 receive addresses. */
 	DEBUGOUT("Clearing RAR[1-15]\n");
-	for (i = 1; i < IXGB_RAR_ENTRIES; i++) {
+	for(i = 1; i < IXGB_RAR_ENTRIES; i++) {
 		IXGB_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
 		IXGB_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
 	}
@@ -383,12 +399,13 @@
  *****************************************************************************/
 void
 ixgb_mc_addr_list_update(struct ixgb_hw *hw,
-			 uint8_t * mc_addr_list,
-			 uint32_t mc_addr_count, uint32_t pad)
+			  uint8_t *mc_addr_list,
+			  uint32_t mc_addr_count,
+			  uint32_t pad)
 {
 	uint32_t hash_value;
 	uint32_t i;
-	uint32_t rar_used_count = 1;	/* RAR[0] is used for our MAC address */
+	uint32_t rar_used_count = 1;		/* RAR[0] is used for our MAC address */
 
 	DEBUGFUNC("ixgb_mc_addr_list_update");
 
@@ -397,19 +414,19 @@
 
 	/* Clear RAR[1-15] */
 	DEBUGOUT(" Clearing RAR[1-15]\n");
-	for (i = rar_used_count; i < IXGB_RAR_ENTRIES; i++) {
+	for(i = rar_used_count; i < IXGB_RAR_ENTRIES; i++) {
 		IXGB_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
 		IXGB_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
 	}
 
 	/* Clear the MTA */
 	DEBUGOUT(" Clearing MTA\n");
-	for (i = 0; i < IXGB_MC_TBL_SIZE; i++) {
+	for(i = 0; i < IXGB_MC_TBL_SIZE; i++) {
 		IXGB_WRITE_REG_ARRAY(hw, MTA, i, 0);
 	}
 
 	/* Add the new addresses */
-	for (i = 0; i < mc_addr_count; i++) {
+	for(i = 0; i < mc_addr_count; i++) {
 		DEBUGOUT(" Adding the multicast addresses:\n");
 		DEBUGOUT7(" MC Addr #%d =%.2X %.2X %.2X %.2X %.2X %.2X\n", i,
 			  mc_addr_list[i * (IXGB_ETH_LENGTH_OF_ADDRESS + pad)],
@@ -427,7 +444,7 @@
 		/* Place this multicast address in the RAR if there is room, *
 		 * else put it in the MTA
 		 */
-		if (rar_used_count < IXGB_RAR_ENTRIES) {
+		if(rar_used_count < IXGB_RAR_ENTRIES) {
 			ixgb_rar_set(hw,
 				     mc_addr_list +
 				     (i * (IXGB_ETH_LENGTH_OF_ADDRESS + pad)),
@@ -460,7 +477,9 @@
  * Returns:
  *      The hash value
  *****************************************************************************/
-static uint32_t ixgb_hash_mc_addr(struct ixgb_hw *hw, uint8_t * mc_addr)
+static uint32_t
+ixgb_hash_mc_addr(struct ixgb_hw *hw,
+		   uint8_t *mc_addr)
 {
 	uint32_t hash_value = 0;
 
@@ -506,7 +525,9 @@
  * hw - Struct containing variables accessed by shared code
  * hash_value - Multicast address hash value
  *****************************************************************************/
-static void ixgb_mta_set(struct ixgb_hw *hw, uint32_t hash_value)
+static void
+ixgb_mta_set(struct ixgb_hw *hw,
+		  uint32_t hash_value)
 {
 	uint32_t hash_bit, hash_reg;
 	uint32_t mta_reg;
@@ -538,7 +559,10 @@
  * addr - Address to put into receive address register
  * index - Receive address register to write
  *****************************************************************************/
-void ixgb_rar_set(struct ixgb_hw *hw, uint8_t * addr, uint32_t index)
+void
+ixgb_rar_set(struct ixgb_hw *hw,
+		  uint8_t *addr,
+		  uint32_t index)
 {
 	uint32_t rar_low, rar_high;
 
@@ -548,11 +572,13 @@
 	 * from network order (big endian) to little endian
 	 */
 	rar_low = ((uint32_t) addr[0] |
-		   ((uint32_t) addr[1] << 8) |
-		   ((uint32_t) addr[2] << 16) | ((uint32_t) addr[3] << 24));
+		   ((uint32_t)addr[1] << 8) |
+		   ((uint32_t)addr[2] << 16) |
+		   ((uint32_t)addr[3] << 24));
 
 	rar_high = ((uint32_t) addr[4] |
-		    ((uint32_t) addr[5] << 8) | IXGB_RAH_AV);
+			((uint32_t)addr[5] << 8) |
+			IXGB_RAH_AV);
 
 	IXGB_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low);
 	IXGB_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high);
@@ -566,7 +592,10 @@
  * offset - Offset in VLAN filer table to write
  * value - Value to write into VLAN filter table
  *****************************************************************************/
-void ixgb_write_vfta(struct ixgb_hw *hw, uint32_t offset, uint32_t value)
+void
+ixgb_write_vfta(struct ixgb_hw *hw,
+		 uint32_t offset,
+		 uint32_t value)
 {
 	IXGB_WRITE_REG_ARRAY(hw, VFTA, offset, value);
 	return;
@@ -577,11 +606,12 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void ixgb_clear_vfta(struct ixgb_hw *hw)
+void
+ixgb_clear_vfta(struct ixgb_hw *hw)
 {
 	uint32_t offset;
 
-	for (offset = 0; offset < IXGB_VLAN_FILTER_TBL_SIZE; offset++)
+	for(offset = 0; offset < IXGB_VLAN_FILTER_TBL_SIZE; offset++)
 		IXGB_WRITE_REG_ARRAY(hw, VFTA, offset, 0);
 	return;
 }
@@ -592,10 +622,11 @@
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
 
-boolean_t ixgb_setup_fc(struct ixgb_hw * hw)
+boolean_t
+ixgb_setup_fc(struct ixgb_hw *hw)
 {
 	uint32_t ctrl_reg;
-	uint32_t pap_reg = 0;	/* by default, assume no pause time */
+	uint32_t pap_reg = 0;   /* by default, assume no pause time */
 	boolean_t status = TRUE;
 
 	DEBUGFUNC("ixgb_setup_fc");
@@ -660,16 +691,16 @@
 	 * ability to transmit pause frames in not enabled, then these
 	 * registers will be set to 0.
 	 */
-	if (!(hw->fc.type & ixgb_fc_tx_pause)) {
+	if(!(hw->fc.type & ixgb_fc_tx_pause)) {
 		IXGB_WRITE_REG(hw, FCRTL, 0);
 		IXGB_WRITE_REG(hw, FCRTH, 0);
 	} else {
-		/* We need to set up the Receive Threshold high and low water
-		 * marks as well as (optionally) enabling the transmission of XON frames.
-		 */
-		if (hw->fc.send_xon) {
+	   /* We need to set up the Receive Threshold high and low water
+	    * marks as well as (optionally) enabling the transmission of XON
+	    * frames. */
+		if(hw->fc.send_xon) {
 			IXGB_WRITE_REG(hw, FCRTL,
-				       (hw->fc.low_water | IXGB_FCRTL_XONE));
+				(hw->fc.low_water | IXGB_FCRTL_XONE));
 		} else {
 			IXGB_WRITE_REG(hw, FCRTL, hw->fc.low_water);
 		}
@@ -694,9 +725,10 @@
  * read command.
  *****************************************************************************/
 uint16_t
-ixgb_read_phy_reg(struct ixgb_hw * hw,
-		  uint32_t reg_address,
-		  uint32_t phy_address, uint32_t device_type)
+ixgb_read_phy_reg(struct ixgb_hw *hw,
+		uint32_t reg_address,
+		uint32_t phy_address,
+		uint32_t device_type)
 {
 	uint32_t i;
 	uint32_t data;
@@ -721,7 +753,8 @@
     ** from the CPU Write to the Ready bit assertion.
     **************************************************************/
 
-	for (i = 0; i < 10; i++) {
+	for(i = 0; i < 10; i++)
+	{
 		udelay(10);
 
 		command = IXGB_READ_REG(hw, MSCA);
@@ -747,7 +780,8 @@
     ** from the CPU Write to the Ready bit assertion.
     **************************************************************/
 
-	for (i = 0; i < 10; i++) {
+	for(i = 0; i < 10; i++)
+	{
 		udelay(10);
 
 		command = IXGB_READ_REG(hw, MSCA);
@@ -763,7 +797,7 @@
 	 */
 	data = IXGB_READ_REG(hw, MSRWD);
 	data >>= IXGB_MSRWD_READ_DATA_SHIFT;
-	return ((uint16_t) data);
+	return((uint16_t) data);
 }
 
 /******************************************************************************
@@ -785,8 +819,10 @@
  *****************************************************************************/
 void
 ixgb_write_phy_reg(struct ixgb_hw *hw,
-		   uint32_t reg_address,
-		   uint32_t phy_address, uint32_t device_type, uint16_t data)
+			uint32_t reg_address,
+			uint32_t phy_address,
+			uint32_t device_type,
+			uint16_t data)
 {
 	uint32_t i;
 	uint32_t command = 0;
@@ -796,24 +832,25 @@
 	ASSERT(device_type <= IXGB_MAX_PHY_DEV_TYPE);
 
 	/* Put the data in the MDIO Read/Write Data register */
-	IXGB_WRITE_REG(hw, MSRWD, (uint32_t) data);
+	IXGB_WRITE_REG(hw, MSRWD, (uint32_t)data);
 
 	/* Setup and write the address cycle command */
-	command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT) |
-		   (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) |
-		   (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) |
-		   (IXGB_MSCA_ADDR_CYCLE | IXGB_MSCA_MDI_COMMAND));
+	command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT)  |
+			   (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) |
+			   (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) |
+			   (IXGB_MSCA_ADDR_CYCLE | IXGB_MSCA_MDI_COMMAND));
 
 	IXGB_WRITE_REG(hw, MSCA, command);
 
-    /**************************************************************
-    ** Check every 10 usec to see if the address cycle completed
-    ** The COMMAND bit will clear when the operation is complete.
-    ** This may take as long as 64 usecs (we'll wait 100 usecs max)
-    ** from the CPU Write to the Ready bit assertion.
-    **************************************************************/
+	/**************************************************************
+	** Check every 10 usec to see if the address cycle completed
+	** The COMMAND bit will clear when the operation is complete.
+	** This may take as long as 64 usecs (we'll wait 100 usecs max)
+	** from the CPU Write to the Ready bit assertion.
+	**************************************************************/
 
-	for (i = 0; i < 10; i++) {
+	for(i = 0; i < 10; i++)
+	{
 		udelay(10);
 
 		command = IXGB_READ_REG(hw, MSCA);
@@ -825,21 +862,22 @@
 	ASSERT((command & IXGB_MSCA_MDI_COMMAND) == 0);
 
 	/* Address cycle complete, setup and write the write command */
-	command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT) |
-		   (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) |
-		   (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) |
-		   (IXGB_MSCA_WRITE | IXGB_MSCA_MDI_COMMAND));
+	command = ((reg_address << IXGB_MSCA_NP_ADDR_SHIFT)  |
+			   (device_type << IXGB_MSCA_DEV_TYPE_SHIFT) |
+			   (phy_address << IXGB_MSCA_PHY_ADDR_SHIFT) |
+			   (IXGB_MSCA_WRITE | IXGB_MSCA_MDI_COMMAND));
 
 	IXGB_WRITE_REG(hw, MSCA, command);
 
-    /**************************************************************
-    ** Check every 10 usec to see if the read command completed
-    ** The COMMAND bit will clear when the operation is complete.
-    ** The write may take as long as 64 usecs (we'll wait 100 usecs max)
-    ** from the CPU Write to the Ready bit assertion.
-    **************************************************************/
+	/**************************************************************
+	** Check every 10 usec to see if the read command completed
+	** The COMMAND bit will clear when the operation is complete.
+	** The write may take as long as 64 usecs (we'll wait 100 usecs max)
+	** from the CPU Write to the Ready bit assertion.
+	**************************************************************/
 
-	for (i = 0; i < 10; i++) {
+	for(i = 0; i < 10; i++)
+	{
 		udelay(10);
 
 		command = IXGB_READ_REG(hw, MSCA);
@@ -860,7 +898,8 @@
  *
  * Called by any function that needs to check the link status of the adapter.
  *****************************************************************************/
-void ixgb_check_for_link(struct ixgb_hw *hw)
+void
+ixgb_check_for_link(struct ixgb_hw *hw)
 {
 	uint32_t status_reg;
 	uint32_t xpcss_reg;
@@ -922,14 +961,15 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void ixgb_clear_hw_cntrs(struct ixgb_hw *hw)
+void
+ixgb_clear_hw_cntrs(struct ixgb_hw *hw)
 {
 	volatile uint32_t temp_reg;
 
 	DEBUGFUNC("ixgb_clear_hw_cntrs");
 
 	/* if we are stopped or resetting exit gracefully */
-	if (hw->adapter_stopped) {
+	if(hw->adapter_stopped) {
 		DEBUGOUT("Exiting because the adapter is stopped!!!\n");
 		return;
 	}
@@ -1002,7 +1042,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void ixgb_led_on(struct ixgb_hw *hw)
+void
+ixgb_led_on(struct ixgb_hw *hw)
 {
 	uint32_t ctrl0_reg = IXGB_READ_REG(hw, CTRL0);
 
@@ -1017,7 +1058,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void ixgb_led_off(struct ixgb_hw *hw)
+void
+ixgb_led_off(struct ixgb_hw *hw)
 {
 	uint32_t ctrl0_reg = IXGB_READ_REG(hw, CTRL0);
 
@@ -1032,18 +1074,19 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-static void ixgb_get_bus_info(struct ixgb_hw *hw)
+static void
+ixgb_get_bus_info(struct ixgb_hw *hw)
 {
 	uint32_t status_reg;
 
 	status_reg = IXGB_READ_REG(hw, STATUS);
 
 	hw->bus.type = (status_reg & IXGB_STATUS_PCIX_MODE) ?
-	    ixgb_bus_type_pcix : ixgb_bus_type_pci;
+		ixgb_bus_type_pcix : ixgb_bus_type_pci;
 
 	if (hw->bus.type == ixgb_bus_type_pci) {
 		hw->bus.speed = (status_reg & IXGB_STATUS_PCI_SPD) ?
-		    ixgb_bus_speed_66 : ixgb_bus_speed_33;
+			ixgb_bus_speed_66 : ixgb_bus_speed_33;
 	} else {
 		switch (status_reg & IXGB_STATUS_PCIX_SPD_MASK) {
 		case IXGB_STATUS_PCIX_SPD_66:
@@ -1062,7 +1105,7 @@
 	}
 
 	hw->bus.width = (status_reg & IXGB_STATUS_BUS64) ?
-	    ixgb_bus_width_64 : ixgb_bus_width_32;
+		ixgb_bus_width_64 : ixgb_bus_width_32;
 
 	return;
 }
@@ -1073,7 +1116,8 @@
  * mac_addr - pointer to MAC address.
  *
  *****************************************************************************/
-boolean_t mac_addr_valid(uint8_t * mac_addr)
+boolean_t
+mac_addr_valid(uint8_t *mac_addr)
 {
 	boolean_t is_valid = TRUE;
 	DEBUGFUNC("mac_addr_valid");
@@ -1090,9 +1134,11 @@
 	}
 	/* Reject the zero address */
 	else if (mac_addr[0] == 0 &&
-		 mac_addr[1] == 0 &&
-		 mac_addr[2] == 0 &&
-		 mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) {
+			 mac_addr[1] == 0 &&
+			 mac_addr[2] == 0 &&
+			 mac_addr[3] == 0 &&
+			 mac_addr[4] == 0 &&
+			 mac_addr[5] == 0) {
 		DEBUGOUT("MAC address is all zeros\n");
 		is_valid = FALSE;
 	}
@@ -1105,7 +1151,8 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-boolean_t ixgb_link_reset(struct ixgb_hw * hw)
+boolean_t
+ixgb_link_reset(struct ixgb_hw *hw)
 {
 	boolean_t link_status = FALSE;
 	uint8_t wait_retries = MAX_RESET_ITERATIONS;
@@ -1135,20 +1182,22 @@
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void ixgb_optics_reset(struct ixgb_hw *hw)
+void
+ixgb_optics_reset(struct ixgb_hw *hw)
 {
 	if (hw->phy_type == ixgb_phy_type_txn17401) {
 		uint16_t mdio_reg;
 
 		ixgb_write_phy_reg(hw,
-				   MDIO_PMA_PMD_CR1,
-				   IXGB_PHY_ADDRESS,
-				   MDIO_PMA_PMD_DID, MDIO_PMA_PMD_CR1_RESET);
-
-		mdio_reg = ixgb_read_phy_reg(hw,
-					     MDIO_PMA_PMD_CR1,
-					     IXGB_PHY_ADDRESS,
-					     MDIO_PMA_PMD_DID);
+					MDIO_PMA_PMD_CR1,
+					IXGB_PHY_ADDRESS,
+					MDIO_PMA_PMD_DID,
+					MDIO_PMA_PMD_CR1_RESET);
+
+		mdio_reg = ixgb_read_phy_reg( hw,
+						MDIO_PMA_PMD_CR1,
+						IXGB_PHY_ADDRESS,
+						MDIO_PMA_PMD_DID);
 	}
 
 	return;
diff -Nru a/drivers/net/ixgb/ixgb_hw.h b/drivers/net/ixgb/ixgb_hw.h
--- a/drivers/net/ixgb/ixgb_hw.h	2005-01-10 23:54:12 -05:00
+++ b/drivers/net/ixgb/ixgb_hw.h	2005-01-10 23:54:12 -05:00
@@ -616,17 +616,17 @@
 #define IXGB_CONTEXT_DESC_STATUS_DD 0x01
 
 /* Filters */
-#define IXGB_RAR_ENTRIES          16	/* Number of entries in Rx Address array */
 #define IXGB_MC_TBL_SIZE          128	/* Multicast Filter Table (4096 bits) */
 #define IXGB_VLAN_FILTER_TBL_SIZE 128	/* VLAN Filter Table (4096 bits) */
+#define IXGB_RAR_ENTRIES		  3	/* Number of entries in Rx Address array */
 
 #define IXGB_MEMORY_REGISTER_BASE_ADDRESS   0
-#define ENET_HEADER_SIZE            14
-#define ENET_FCS_LENGTH             4
-#define IXGB_MAX_NUM_MULTICAST_ADDRESSES    128
-#define IXGB_MIN_ENET_FRAME_SIZE_WITHOUT_FCS    60
-#define IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS    1514
-#define IXGB_MAX_JUMBO_FRAME_SIZE       0x3F00
+#define ENET_HEADER_SIZE			14
+#define ENET_FCS_LENGTH			 4
+#define IXGB_MAX_NUM_MULTICAST_ADDRESSES	128
+#define IXGB_MIN_ENET_FRAME_SIZE_WITHOUT_FCS	60
+#define IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS	1514
+#define IXGB_MAX_JUMBO_FRAME_SIZE		0x3F00
 
 /* Phy Addresses */
 #define IXGB_OPTICAL_PHY_ADDR 0x0	/* Optical Module phy address */
@@ -789,32 +789,39 @@
 extern boolean_t ixgb_check_for_bad_link(struct ixgb_hw *hw);
 extern boolean_t ixgb_setup_fc(struct ixgb_hw *hw);
 extern void ixgb_clear_hw_cntrs(struct ixgb_hw *hw);
-extern boolean_t mac_addr_valid(uint8_t * mac_addr);
+extern boolean_t mac_addr_valid(uint8_t *mac_addr);
 
 extern uint16_t ixgb_read_phy_reg(struct ixgb_hw *hw,
-				  uint32_t reg_addr,
-				  uint32_t phy_addr, uint32_t device_type);
+				uint32_t reg_addr,
+				uint32_t phy_addr,
+				uint32_t device_type);
 
 extern void ixgb_write_phy_reg(struct ixgb_hw *hw,
-			       uint32_t reg_addr,
-			       uint32_t phy_addr,
-			       uint32_t device_type, uint16_t data);
+				uint32_t reg_addr,
+				uint32_t phy_addr,
+				uint32_t device_type,
+				uint16_t data);
+
+extern void ixgb_rar_set(struct ixgb_hw *hw,
+				uint8_t *addr,
+				uint32_t index);
 
-extern void ixgb_rar_set(struct ixgb_hw *hw, uint8_t * addr, uint32_t index);
 
 /* Filters (multicast, vlan, receive) */
 extern void ixgb_mc_addr_list_update(struct ixgb_hw *hw,
-				     uint8_t * mc_addr_list,
-				     uint32_t mc_addr_count, uint32_t pad);
+				   uint8_t *mc_addr_list,
+				   uint32_t mc_addr_count,
+				   uint32_t pad);
 
 /* Vfta functions */
 extern void ixgb_write_vfta(struct ixgb_hw *hw,
-			    uint32_t offset, uint32_t value);
+				 uint32_t offset,
+				 uint32_t value);
 
 extern void ixgb_clear_vfta(struct ixgb_hw *hw);
 
 /* Access functions to eeprom data */
-void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t * mac_addr);
+void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t *mac_addr);
 uint16_t ixgb_get_ee_compatibility(struct ixgb_hw *hw);
 uint32_t ixgb_get_ee_pba_number(struct ixgb_hw *hw);
 uint16_t ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw *hw);
@@ -832,6 +839,9 @@
 /* Everything else */
 void ixgb_led_on(struct ixgb_hw *hw);
 void ixgb_led_off(struct ixgb_hw *hw);
-void ixgb_write_pci_cfg(struct ixgb_hw *hw, uint32_t reg, uint16_t * value);
+void ixgb_write_pci_cfg(struct ixgb_hw *hw,
+			 uint32_t reg,
+			 uint16_t * value);
 
-#endif				/* _IXGB_HW_H_ */
+
+#endif /* _IXGB_HW_H_ */
diff -Nru a/drivers/net/ixgb/ixgb_ids.h b/drivers/net/ixgb/ixgb_ids.h
--- a/drivers/net/ixgb/ixgb_ids.h	2005-01-10 23:54:12 -05:00
+++ b/drivers/net/ixgb/ixgb_ids.h	2005-01-10 23:54:12 -05:00
@@ -33,21 +33,16 @@
 ** The Device and Vendor IDs for 10 Gigabit MACs
 **********************************************************************/
 
-#define INTEL_VENDOR_ID         0x8086
-#define INTEL_SUBVENDOR_ID      0x8086
+#define INTEL_VENDOR_ID             0x8086
+#define INTEL_SUBVENDOR_ID          0x8086
 
-#define IXGB_DEVICE_ID_82597EX      0x1048
-#define IXGB_DEVICE_ID_82597EX_SR   0x1A48
 
-#define IXGB_SUBDEVICE_ID_A11F  0xA11F
-#define IXGB_SUBDEVICE_ID_A01F  0xA01F
+#define IXGB_DEVICE_ID_82597EX      0x1048   
+#define IXGB_DEVICE_ID_82597EX_SR   0x1A48   
+#define IXGB_DEVICE_ID_82597EX_LR   0x1B48
+#define IXGB_SUBDEVICE_ID_A11F      0xA11F   
+#define IXGB_SUBDEVICE_ID_A01F      0xA01F   
 
-#define IXGB_SUBDEVICE_ID_A15F  0xA15F
-#define IXGB_SUBDEVICE_ID_A05F  0xA05F
-
-#define IXGB_SUBDEVICE_ID_A12F  0xA12F
-#define IXGB_SUBDEVICE_ID_A02F  0xA02F
-
-#endif				/* #ifndef _IXGB_IDS_H_ */
+#endif /* #ifndef _IXGB_IDS_H_ */
 
 /* End of File */
diff -Nru a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
--- a/drivers/net/ixgb/ixgb_main.c	2005-01-10 23:54:12 -05:00
+++ b/drivers/net/ixgb/ixgb_main.c	2005-01-10 23:54:12 -05:00
@@ -28,10 +28,23 @@
 
 #include "ixgb.h"
 
+/* Change Log
+ * 1.0.84 10/26/04
+ * - reset buffer_info->dma in Tx resource cleanup logic
+ * 1.0.83 10/12/04
+ * - sparse cleanup - shemminger@osdl.org
+ * - fix tx resource cleanup logic
+ */
+
 char ixgb_driver_name[] = "ixgb";
 char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver";
-char ixgb_driver_version[] = "1.0.66-k2";
-char ixgb_copyright[] = "Copyright (c) 2001-2004 Intel Corporation.";
+#ifndef CONFIG_IXGB_NAPI
+#define DRIVERNAPI
+#else
+#define DRIVERNAPI "-NAPI"
+#endif
+char ixgb_driver_version[] = "1.0.87-k2"DRIVERNAPI;
+char ixgb_copyright[] = "Copyright (c) 1999-2004 Intel Corporation.";
 
 /* ixgb_pci_tbl - PCI Device ID Table
  *
@@ -46,6 +59,8 @@
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX_SR,
 	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{INTEL_VENDOR_ID, IXGB_DEVICE_ID_82597EX_LR,  
+	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 
 	/* required last entry */
 	{0,}
@@ -55,11 +70,14 @@
 
 /* Local Function Prototypes */
 
-static inline void ixgb_irq_disable(struct ixgb_adapter *adapter);
-static inline void ixgb_irq_enable(struct ixgb_adapter *adapter);
 int ixgb_up(struct ixgb_adapter *adapter);
 void ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog);
 void ixgb_reset(struct ixgb_adapter *adapter);
+int ixgb_setup_tx_resources(struct ixgb_adapter *adapter);
+int ixgb_setup_rx_resources(struct ixgb_adapter *adapter);
+void ixgb_free_tx_resources(struct ixgb_adapter *adapter);
+void ixgb_free_rx_resources(struct ixgb_adapter *adapter);
+void ixgb_update_stats(struct ixgb_adapter *adapter);
 
 static int ixgb_init_module(void);
 static void ixgb_exit_module(void);
@@ -68,27 +86,19 @@
 static int ixgb_sw_init(struct ixgb_adapter *adapter);
 static int ixgb_open(struct net_device *netdev);
 static int ixgb_close(struct net_device *netdev);
-static int ixgb_setup_tx_resources(struct ixgb_adapter *adapter);
-static int ixgb_setup_rx_resources(struct ixgb_adapter *adapter);
 static void ixgb_configure_tx(struct ixgb_adapter *adapter);
 static void ixgb_configure_rx(struct ixgb_adapter *adapter);
 static void ixgb_setup_rctl(struct ixgb_adapter *adapter);
 static void ixgb_clean_tx_ring(struct ixgb_adapter *adapter);
 static void ixgb_clean_rx_ring(struct ixgb_adapter *adapter);
-static void ixgb_free_tx_resources(struct ixgb_adapter *adapter);
-static void ixgb_free_rx_resources(struct ixgb_adapter *adapter);
 static void ixgb_set_multi(struct net_device *netdev);
 static void ixgb_watchdog(unsigned long data);
 static int ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
 static struct net_device_stats *ixgb_get_stats(struct net_device *netdev);
 static int ixgb_change_mtu(struct net_device *netdev, int new_mtu);
 static int ixgb_set_mac(struct net_device *netdev, void *p);
-static void ixgb_update_stats(struct ixgb_adapter *adapter);
 static irqreturn_t ixgb_intr(int irq, void *data, struct pt_regs *regs);
 static boolean_t ixgb_clean_tx_irq(struct ixgb_adapter *adapter);
-static inline void ixgb_rx_checksum(struct ixgb_adapter *adapter,
-				    struct ixgb_rx_desc *rx_desc,
-				    struct sk_buff *skb);
 #ifdef CONFIG_IXGB_NAPI
 static int ixgb_clean(struct net_device *netdev, int *budget);
 static boolean_t ixgb_clean_rx_irq(struct ixgb_adapter *adapter,
@@ -97,6 +107,7 @@
 static boolean_t ixgb_clean_rx_irq(struct ixgb_adapter *adapter);
 #endif
 static void ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter);
+void set_ethtool_ops(struct net_device *netdev);
 static void ixgb_tx_timeout(struct net_device *dev);
 static void ixgb_tx_timeout_task(struct net_device *dev);
 static void ixgb_vlan_rx_register(struct net_device *netdev,
@@ -123,7 +134,6 @@
 /* Exported from other modules */
 
 extern void ixgb_check_options(struct ixgb_adapter *adapter);
-extern struct ethtool_ops ixgb_ethtool_ops;
 
 static struct pci_driver ixgb_driver = {
 	.name = ixgb_driver_name,
@@ -152,7 +162,8 @@
  * loaded. All it does is register with the PCI subsystem.
  **/
 
-static int __init ixgb_init_module(void)
+static int __init
+ixgb_init_module(void)
 {
 	int ret;
 	printk(KERN_INFO "%s - version %s\n",
@@ -161,7 +172,7 @@
 	printk(KERN_INFO "%s\n", ixgb_copyright);
 
 	ret = pci_module_init(&ixgb_driver);
-	if (ret >= 0) {
+	if(ret >= 0) {
 		register_reboot_notifier(&ixgb_notifier_reboot);
 	}
 	return ret;
@@ -176,7 +187,8 @@
  * from memory.
  **/
 
-static void __exit ixgb_exit_module(void)
+static void __exit
+ixgb_exit_module(void)
 {
 	unregister_reboot_notifier(&ixgb_notifier_reboot);
 	pci_unregister_driver(&ixgb_driver);
@@ -189,7 +201,8 @@
  * @adapter: board private structure
  **/
 
-static inline void ixgb_irq_disable(struct ixgb_adapter *adapter)
+static inline void
+ixgb_irq_disable(struct ixgb_adapter *adapter)
 {
 	atomic_inc(&adapter->irq_sem);
 	IXGB_WRITE_REG(&adapter->hw, IMC, ~0);
@@ -202,17 +215,19 @@
  * @adapter: board private structure
  **/
 
-static inline void ixgb_irq_enable(struct ixgb_adapter *adapter)
+static inline void
+ixgb_irq_enable(struct ixgb_adapter *adapter)
 {
-	if (atomic_dec_and_test(&adapter->irq_sem)) {
+	if(atomic_dec_and_test(&adapter->irq_sem)) {
 		IXGB_WRITE_REG(&adapter->hw, IMS,
-			       IXGB_INT_RXT0 | IXGB_INT_RXDMT0 | IXGB_INT_TXDW |
-			       IXGB_INT_RXO | IXGB_INT_LSC);
+			   IXGB_INT_RXT0 | IXGB_INT_RXDMT0 | IXGB_INT_TXDW |
+			   IXGB_INT_RXO | IXGB_INT_LSC);
 		IXGB_WRITE_FLUSH(&adapter->hw);
 	}
 }
 
-int ixgb_up(struct ixgb_adapter *adapter)
+int
+ixgb_up(struct ixgb_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
 	int err;
@@ -230,27 +245,44 @@
 	ixgb_configure_rx(adapter);
 	ixgb_alloc_rx_buffers(adapter);
 
-	if ((err = request_irq(adapter->pdev->irq, &ixgb_intr,
-			       SA_SHIRQ | SA_SAMPLE_RANDOM,
-			       netdev->name, netdev)))
+#ifdef CONFIG_PCI_MSI
+	{
+	boolean_t pcix = (IXGB_READ_REG(&adapter->hw, STATUS) & 
+						  IXGB_STATUS_PCIX_MODE) ? TRUE : FALSE;
+	adapter->have_msi = TRUE;
+
+	if (!pcix)
+	   adapter->have_msi = FALSE;
+	else if((err = pci_enable_msi(adapter->pdev))) {
+		printk (KERN_ERR
+		 "Unable to allocate MSI interrupt Error: %d\n", err);
+		adapter->have_msi = FALSE;
+		/* proceed to try to request regular interrupt */
+	}
+	}
+
+#endif
+	if((err = request_irq(adapter->pdev->irq, &ixgb_intr,
+				  SA_SHIRQ | SA_SAMPLE_RANDOM,
+				  netdev->name, netdev)))
 		return err;
 
 	/* disable interrupts and get the hardware into a known state */
 	IXGB_WRITE_REG(&adapter->hw, IMC, 0xffffffff);
 
-	if ((hw->max_frame_size != max_frame) ||
-	    (hw->max_frame_size !=
-	     (IXGB_READ_REG(hw, MFS) >> IXGB_MFS_SHIFT))) {
+	if((hw->max_frame_size != max_frame) ||
+		(hw->max_frame_size !=
+		(IXGB_READ_REG(hw, MFS) >> IXGB_MFS_SHIFT))) {
 
 		hw->max_frame_size = max_frame;
 
 		IXGB_WRITE_REG(hw, MFS, hw->max_frame_size << IXGB_MFS_SHIFT);
 
-		if (hw->max_frame_size >
-		    IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH) {
+		if(hw->max_frame_size >
+		   IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH) {
 			uint32_t ctrl0 = IXGB_READ_REG(hw, CTRL0);
 
-			if (!(ctrl0 & IXGB_CTRL0_JFE)) {
+			if(!(ctrl0 & IXGB_CTRL0_JFE)) {
 				ctrl0 |= IXGB_CTRL0_JFE;
 				IXGB_WRITE_REG(hw, CTRL0, ctrl0);
 			}
@@ -263,13 +295,19 @@
 	return 0;
 }
 
-void ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog)
+void
+ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog)
 {
 	struct net_device *netdev = adapter->netdev;
 
 	ixgb_irq_disable(adapter);
 	free_irq(adapter->pdev->irq, netdev);
-	if (kill_watchdog)
+#ifdef CONFIG_PCI_MSI
+	if(adapter->have_msi == TRUE)
+		pci_disable_msi(adapter->pdev);
+
+#endif
+	if(kill_watchdog)
 		del_timer_sync(&adapter->watchdog_timer);
 	adapter->link_speed = 0;
 	adapter->link_duplex = 0;
@@ -281,11 +319,12 @@
 	ixgb_clean_rx_ring(adapter);
 }
 
-void ixgb_reset(struct ixgb_adapter *adapter)
+void
+ixgb_reset(struct ixgb_adapter *adapter)
 {
 
 	ixgb_adapter_stop(&adapter->hw);
-	if (!ixgb_init_hw(&adapter->hw))
+	if(!ixgb_init_hw(&adapter->hw))
 		IXGB_DBG("ixgb_init_hw failed.\n");
 }
 
@@ -302,7 +341,8 @@
  **/
 
 static int __devinit
-ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ixgb_probe(struct pci_dev *pdev,
+		const struct pci_device_id *ent)
 {
 	struct net_device *netdev = NULL;
 	struct ixgb_adapter *adapter;
@@ -313,26 +353,26 @@
 	int i;
 	int err;
 
-	if ((err = pci_enable_device(pdev)))
+	if((err = pci_enable_device(pdev)))
 		return err;
 
-	if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
+	if(!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
 		pci_using_dac = 1;
 	} else {
-		if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {
+		if((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {
 			IXGB_ERR("No usable DMA configuration, aborting\n");
 			return err;
 		}
 		pci_using_dac = 0;
 	}
 
-	if ((err = pci_request_regions(pdev, ixgb_driver_name)))
+	if((err = pci_request_regions(pdev, ixgb_driver_name)))
 		return err;
 
 	pci_set_master(pdev);
 
 	netdev = alloc_etherdev(sizeof(struct ixgb_adapter));
-	if (!netdev) {
+	if(!netdev) {
 		err = -ENOMEM;
 		goto err_alloc_etherdev;
 	}
@@ -350,15 +390,15 @@
 	mmio_len = pci_resource_len(pdev, BAR_0);
 
 	adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
-	if (!adapter->hw.hw_addr) {
+	if(!adapter->hw.hw_addr) {
 		err = -EIO;
 		goto err_ioremap;
 	}
 
-	for (i = BAR_1; i <= BAR_5; i++) {
-		if (pci_resource_len(pdev, i) == 0)
+	for(i = BAR_1; i <= BAR_5; i++) {
+		if(pci_resource_len(pdev, i) == 0)
 			continue;
-		if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
+		if(pci_resource_flags(pdev, i) & IORESOURCE_IO) {
 			adapter->hw.io_base = pci_resource_start(pdev, i);
 			break;
 		}
@@ -371,9 +411,9 @@
 	netdev->set_multicast_list = &ixgb_set_multi;
 	netdev->set_mac_address = &ixgb_set_mac;
 	netdev->change_mtu = &ixgb_change_mtu;
+	set_ethtool_ops(netdev);
 	netdev->tx_timeout = &ixgb_tx_timeout;
 	netdev->watchdog_timeo = HZ;
-	SET_ETHTOOL_OPS(netdev, &ixgb_ethtool_ops);
 #ifdef CONFIG_IXGB_NAPI
 	netdev->poll = &ixgb_clean;
 	netdev->weight = 64;
@@ -395,22 +435,24 @@
 
 	/* setup the private structure */
 
-	if ((err = ixgb_sw_init(adapter)))
+	if((err = ixgb_sw_init(adapter)))
 		goto err_sw_init;
 
 	netdev->features = NETIF_F_SG |
-	    NETIF_F_HW_CSUM |
-	    NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
+			   NETIF_F_HW_CSUM |
+			   NETIF_F_HW_VLAN_TX |
+			   NETIF_F_HW_VLAN_RX |
+			   NETIF_F_HW_VLAN_FILTER;
 #ifdef NETIF_F_TSO
 	netdev->features |= NETIF_F_TSO;
 #endif
 
-	if (pci_using_dac)
+	if(pci_using_dac)
 		netdev->features |= NETIF_F_HIGHDMA;
 
 	/* make sure the EEPROM is good */
 
-	if (!ixgb_validate_eeprom_checksum(&adapter->hw)) {
+	if(!ixgb_validate_eeprom_checksum(&adapter->hw)) {
 		printk(KERN_ERR "The EEPROM Checksum Is Not Valid\n");
 		err = -EIO;
 		goto err_eeprom;
@@ -418,7 +460,7 @@
 
 	ixgb_get_ee_mac_addr(&adapter->hw, netdev->dev_addr);
 
-	if (!is_valid_ether_addr(netdev->dev_addr)) {
+	if(!is_valid_ether_addr(netdev->dev_addr)) {
 		err = -EIO;
 		goto err_eeprom;
 	}
@@ -432,7 +474,7 @@
 	INIT_WORK(&adapter->tx_timeout_task,
 		  (void (*)(void *))ixgb_tx_timeout_task, netdev);
 
-	if ((err = register_netdev(netdev)))
+	if((err = register_netdev(netdev)))
 		goto err_register;
 
 	/* we're going to reset, so assume we have no link for now */
@@ -441,7 +483,7 @@
 	netif_stop_queue(netdev);
 
 	printk(KERN_INFO "%s: Intel(R) PRO/10GbE Network Connection\n",
-	       netdev->name);
+		   netdev->name);
 	ixgb_check_options(adapter);
 	/* reset the hardware with the new settings */
 
@@ -450,13 +492,13 @@
 	cards_found++;
 	return 0;
 
-      err_register:
-      err_sw_init:
-      err_eeprom:
+err_register:
+err_sw_init:
+err_eeprom:
 	iounmap(adapter->hw.hw_addr);
-      err_ioremap:
+err_ioremap:
 	free_netdev(netdev);
-      err_alloc_etherdev:
+err_alloc_etherdev:
 	pci_release_regions(pdev);
 	return err;
 }
@@ -471,7 +513,8 @@
  * memory.
  **/
 
-static void __devexit ixgb_remove(struct pci_dev *pdev)
+static void __devexit
+ixgb_remove(struct pci_dev *pdev)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct ixgb_adapter *adapter = netdev->priv;
@@ -493,7 +536,8 @@
  * OS network device settings (MTU size).
  **/
 
-static int __devinit ixgb_sw_init(struct ixgb_adapter *adapter)
+static int __devinit
+ixgb_sw_init(struct ixgb_adapter *adapter)
 {
 	struct ixgb_hw *hw = &adapter->hw;
 	struct net_device *netdev = adapter->netdev;
@@ -510,9 +554,10 @@
 
 	hw->max_frame_size = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH;
 
-	if ((hw->device_id == IXGB_DEVICE_ID_82597EX)
-	    || (hw->device_id == IXGB_DEVICE_ID_82597EX_SR))
-		hw->mac_type = ixgb_82597;
+	if((hw->device_id == IXGB_DEVICE_ID_82597EX)
+	   ||(hw->device_id == IXGB_DEVICE_ID_82597EX_LR)
+	   ||(hw->device_id == IXGB_DEVICE_ID_82597EX_SR))
+			hw->mac_type = ixgb_82597;
 	else {
 		/* should never have loaded on this device */
 		printk(KERN_ERR "ixgb: unsupported device id\n");
@@ -540,31 +585,32 @@
  * and the stack is notified that the interface is ready.
  **/
 
-static int ixgb_open(struct net_device *netdev)
+static int
+ixgb_open(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	int err;
 
 	/* allocate transmit descriptors */
 
-	if ((err = ixgb_setup_tx_resources(adapter)))
+	if((err = ixgb_setup_tx_resources(adapter)))
 		goto err_setup_tx;
 
 	/* allocate receive descriptors */
 
-	if ((err = ixgb_setup_rx_resources(adapter)))
+	if((err = ixgb_setup_rx_resources(adapter)))
 		goto err_setup_rx;
 
-	if ((err = ixgb_up(adapter)))
+	if((err = ixgb_up(adapter)))
 		goto err_up;
 
 	return 0;
 
-      err_up:
+err_up:
 	ixgb_free_rx_resources(adapter);
-      err_setup_rx:
+err_setup_rx:
 	ixgb_free_tx_resources(adapter);
-      err_setup_tx:
+err_setup_tx:
 	ixgb_reset(adapter);
 
 	return err;
@@ -582,7 +628,8 @@
  * hardware, and all transmit and receive resources are freed.
  **/
 
-static int ixgb_close(struct net_device *netdev)
+static int
+ixgb_close(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 
@@ -601,15 +648,16 @@
  * Return 0 on success, negative on failure
  **/
 
-static int ixgb_setup_tx_resources(struct ixgb_adapter *adapter)
+int
+ixgb_setup_tx_resources(struct ixgb_adapter *adapter)
 {
 	struct ixgb_desc_ring *txdr = &adapter->tx_ring;
 	struct pci_dev *pdev = adapter->pdev;
 	int size;
 
 	size = sizeof(struct ixgb_buffer) * txdr->count;
-	txdr->buffer_info = kmalloc(size, GFP_KERNEL);
-	if (!txdr->buffer_info) {
+	txdr->buffer_info = vmalloc(size);
+	if(!txdr->buffer_info) {
 		return -ENOMEM;
 	}
 	memset(txdr->buffer_info, 0, size);
@@ -620,8 +668,8 @@
 	IXGB_ROUNDUP(txdr->size, 4096);
 
 	txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
-	if (!txdr->desc) {
-		kfree(txdr->buffer_info);
+	if(!txdr->desc) {
+		vfree(txdr->buffer_info);
 		return -ENOMEM;
 	}
 	memset(txdr->desc, 0, txdr->size);
@@ -639,7 +687,8 @@
  * Configure the Tx unit of the MAC after a reset.
  **/
 
-static void ixgb_configure_tx(struct ixgb_adapter *adapter)
+static void
+ixgb_configure_tx(struct ixgb_adapter *adapter)
 {
 	uint64_t tdba = adapter->tx_ring.dma;
 	uint32_t tdlen = adapter->tx_ring.count * sizeof(struct ixgb_tx_desc);
@@ -679,8 +728,8 @@
 
 	/* Setup Transmit Descriptor Settings for this adapter */
 	adapter->tx_cmd_type =
-	    IXGB_TX_DESC_TYPE
-	    | (adapter->tx_int_delay_enable ? IXGB_TX_DESC_CMD_IDE : 0);
+		IXGB_TX_DESC_TYPE 
+		| (adapter->tx_int_delay_enable ? IXGB_TX_DESC_CMD_IDE : 0);
 }
 
 /**
@@ -690,15 +739,16 @@
  * Returns 0 on success, negative on failure
  **/
 
-static int ixgb_setup_rx_resources(struct ixgb_adapter *adapter)
+int
+ixgb_setup_rx_resources(struct ixgb_adapter *adapter)
 {
 	struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
 	struct pci_dev *pdev = adapter->pdev;
 	int size;
 
 	size = sizeof(struct ixgb_buffer) * rxdr->count;
-	rxdr->buffer_info = kmalloc(size, GFP_KERNEL);
-	if (!rxdr->buffer_info) {
+	rxdr->buffer_info = vmalloc(size);
+	if(!rxdr->buffer_info) {
 		return -ENOMEM;
 	}
 	memset(rxdr->buffer_info, 0, size);
@@ -710,8 +760,8 @@
 
 	rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
 
-	if (!rxdr->desc) {
-		kfree(rxdr->buffer_info);
+	if(!rxdr->desc) {
+		vfree(rxdr->buffer_info);
 		return -ENOMEM;
 	}
 	memset(rxdr->desc, 0, rxdr->size);
@@ -727,7 +777,8 @@
  * @adapter: Board private structure
  **/
 
-static void ixgb_setup_rctl(struct ixgb_adapter *adapter)
+static void
+ixgb_setup_rctl(struct ixgb_adapter *adapter)
 {
 	uint32_t rctl;
 
@@ -736,9 +787,9 @@
 	rctl &= ~(3 << IXGB_RCTL_MO_SHIFT);
 
 	rctl |=
-	    IXGB_RCTL_BAM | IXGB_RCTL_RDMTS_1_2 |
-	    IXGB_RCTL_RXEN | IXGB_RCTL_CFF |
-	    (adapter->hw.mc_filter_type << IXGB_RCTL_MO_SHIFT);
+		IXGB_RCTL_BAM | IXGB_RCTL_RDMTS_1_2 | 
+		IXGB_RCTL_RXEN | IXGB_RCTL_CFF | 
+		(adapter->hw.mc_filter_type << IXGB_RCTL_MO_SHIFT);
 
 	rctl |= IXGB_RCTL_SECRC;
 
@@ -768,7 +819,8 @@
  * Configure the Rx unit of the MAC after a reset.
  **/
 
-static void ixgb_configure_rx(struct ixgb_adapter *adapter)
+static void
+ixgb_configure_rx(struct ixgb_adapter *adapter)
 {
 	uint64_t rdba = adapter->rx_ring.dma;
 	uint32_t rdlen = adapter->rx_ring.count * sizeof(struct ixgb_rx_desc);
@@ -797,51 +849,14 @@
 	IXGB_WRITE_REG(hw, RDH, 0);
 	IXGB_WRITE_REG(hw, RDT, 0);
 
-	/* burst 16 or burst when RXT0 */
-	rxdctl = RXDCTL_WTHRESH_DEFAULT << IXGB_RXDCTL_WTHRESH_SHIFT
-	    | RXDCTL_HTHRESH_DEFAULT << IXGB_RXDCTL_HTHRESH_SHIFT
-	    | RXDCTL_PTHRESH_DEFAULT << IXGB_RXDCTL_PTHRESH_SHIFT;
+						/* burst 16 or burst when RXT0*/
+	rxdctl =  RXDCTL_WTHRESH_DEFAULT << IXGB_RXDCTL_WTHRESH_SHIFT 
+			| RXDCTL_HTHRESH_DEFAULT << IXGB_RXDCTL_HTHRESH_SHIFT 
+			| RXDCTL_PTHRESH_DEFAULT << IXGB_RXDCTL_PTHRESH_SHIFT;
 	IXGB_WRITE_REG(hw, RXDCTL, rxdctl);
 
-	if (adapter->raidc) {
-		uint32_t raidc;
-		uint8_t poll_threshold;
-
-		/* Poll every rx_int_delay period, if RBD exists
-		 * Receive Backlog Detection is set to <threshold> 
-		 * Rx Descriptors
-		 * max is 0x3F == set to poll when 504 RxDesc left 
-		 * min is 0 */
-
-		/* polling times are 1 == 0.8192us
-		   2 == 1.6384us
-		   3 == 3.2768us etc
-		   ...
-		   511 == 418 us
-		 */
-#define IXGB_RAIDC_POLL_DEFAULT 122	/* set to poll every ~100 us under load 
-					   also known as 10000 interrupts / sec */
-
-		/* divide this by 2^3 (8) to get a register size count */
-		poll_threshold = ((adapter->rx_ring.count - 1) >> 3);
-		/* poll at half of that size */
-		poll_threshold >>= 1;
-		/* make sure its not bigger than our max */
-		poll_threshold &= 0x3F;
-
-		raidc = IXGB_RAIDC_EN |	/* turn on raidc style moderation */
-		    IXGB_RAIDC_RXT_GATE |	/* don't interrupt with rxt0 while
-						   in RBD mode (polling) */
-		    (IXGB_RAIDC_POLL_DEFAULT << IXGB_RAIDC_POLL_SHIFT) |
-		    /* this sets the regular "min interrupt delay" */
-		    (adapter->rx_int_delay << IXGB_RAIDC_DELAY_SHIFT) |
-		    poll_threshold;
-
-		IXGB_WRITE_REG(hw, RAIDC, raidc);
-	}
-
 	/* Enable Receive Checksum Offload for TCP and UDP */
-	if (adapter->rx_csum == TRUE) {
+	if(adapter->rx_csum == TRUE) {
 		rxcsum = IXGB_READ_REG(hw, RXCSUM);
 		rxcsum |= IXGB_RXCSUM_TUOFL;
 		IXGB_WRITE_REG(hw, RXCSUM, rxcsum);
@@ -859,13 +874,14 @@
  * Free all transmit software resources
  **/
 
-static void ixgb_free_tx_resources(struct ixgb_adapter *adapter)
+void
+ixgb_free_tx_resources(struct ixgb_adapter *adapter)
 {
 	struct pci_dev *pdev = adapter->pdev;
 
 	ixgb_clean_tx_ring(adapter);
 
-	kfree(adapter->tx_ring.buffer_info);
+	vfree(adapter->tx_ring.buffer_info);
 	adapter->tx_ring.buffer_info = NULL;
 
 	pci_free_consistent(pdev, adapter->tx_ring.size,
@@ -874,33 +890,42 @@
 	adapter->tx_ring.desc = NULL;
 }
 
+static inline void
+ixgb_unmap_and_free_tx_resource(struct ixgb_adapter *adapter,
+					struct ixgb_buffer *buffer_info)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	if(buffer_info->dma) {
+		pci_unmap_page(pdev,
+			   buffer_info->dma,
+			   buffer_info->length,
+			   PCI_DMA_TODEVICE);
+		buffer_info->dma = 0;
+	}
+	if(buffer_info->skb) {
+		dev_kfree_skb_any(buffer_info->skb);
+		buffer_info->skb = NULL;
+	}
+}
+
 /**
  * ixgb_clean_tx_ring - Free Tx Buffers
  * @adapter: board private structure
  **/
 
-static void ixgb_clean_tx_ring(struct ixgb_adapter *adapter)
+static void
+ixgb_clean_tx_ring(struct ixgb_adapter *adapter)
 {
 	struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
 	struct ixgb_buffer *buffer_info;
-	struct pci_dev *pdev = adapter->pdev;
 	unsigned long size;
 	unsigned int i;
 
 	/* Free all the Tx ring sk_buffs */
 
-	for (i = 0; i < tx_ring->count; i++) {
+	for(i = 0; i < tx_ring->count; i++) {
 		buffer_info = &tx_ring->buffer_info[i];
-		if (buffer_info->skb) {
-
-			pci_unmap_page(pdev,
-				       buffer_info->dma,
-				       buffer_info->length, PCI_DMA_TODEVICE);
-
-			dev_kfree_skb(buffer_info->skb);
-
-			buffer_info->skb = NULL;
-		}
+		ixgb_unmap_and_free_tx_resource(adapter, buffer_info);
 	}
 
 	size = sizeof(struct ixgb_buffer) * tx_ring->count;
@@ -924,14 +949,15 @@
  * Free all receive software resources
  **/
 
-static void ixgb_free_rx_resources(struct ixgb_adapter *adapter)
+void
+ixgb_free_rx_resources(struct ixgb_adapter *adapter)
 {
 	struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
 	struct pci_dev *pdev = adapter->pdev;
 
 	ixgb_clean_rx_ring(adapter);
 
-	kfree(rx_ring->buffer_info);
+	vfree(rx_ring->buffer_info);
 	rx_ring->buffer_info = NULL;
 
 	pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
@@ -944,7 +970,8 @@
  * @adapter: board private structure
  **/
 
-static void ixgb_clean_rx_ring(struct ixgb_adapter *adapter)
+static void
+ixgb_clean_rx_ring(struct ixgb_adapter *adapter)
 {
 	struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
 	struct ixgb_buffer *buffer_info;
@@ -954,9 +981,9 @@
 
 	/* Free all the Rx ring sk_buffs */
 
-	for (i = 0; i < rx_ring->count; i++) {
+	for(i = 0; i < rx_ring->count; i++) {
 		buffer_info = &rx_ring->buffer_info[i];
-		if (buffer_info->skb) {
+		if(buffer_info->skb) {
 
 			pci_unmap_single(pdev,
 					 buffer_info->dma,
@@ -991,12 +1018,13 @@
  * Returns 0 on success, negative on failure
  **/
 
-static int ixgb_set_mac(struct net_device *netdev, void *p)
+static int
+ixgb_set_mac(struct net_device *netdev, void *p)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	struct sockaddr *addr = p;
 
-	if (!is_valid_ether_addr(addr->sa_data))
+	if(!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
 
 	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
@@ -1016,7 +1044,8 @@
  * promiscuous mode, and all-multi behavior.
  **/
 
-static void ixgb_set_multi(struct net_device *netdev)
+static void
+ixgb_set_multi(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	struct ixgb_hw *hw = &adapter->hw;
@@ -1028,16 +1057,16 @@
 
 	rctl = IXGB_READ_REG(hw, RCTL);
 
-	if (netdev->flags & IFF_PROMISC) {
+	if(netdev->flags & IFF_PROMISC) {
 		rctl |= (IXGB_RCTL_UPE | IXGB_RCTL_MPE);
-	} else if (netdev->flags & IFF_ALLMULTI) {
+	} else if(netdev->flags & IFF_ALLMULTI) {
 		rctl |= IXGB_RCTL_MPE;
 		rctl &= ~IXGB_RCTL_UPE;
 	} else {
 		rctl &= ~(IXGB_RCTL_UPE | IXGB_RCTL_MPE);
 	}
 
-	if (netdev->mc_count > IXGB_MAX_NUM_MULTICAST_ADDRESSES) {
+	if(netdev->mc_count > IXGB_MAX_NUM_MULTICAST_ADDRESSES) {
 		rctl |= IXGB_RCTL_MPE;
 		IXGB_WRITE_REG(hw, RCTL, rctl);
 	} else {
@@ -1045,10 +1074,10 @@
 
 		IXGB_WRITE_REG(hw, RCTL, rctl);
 
-		for (i = 0, mc_ptr = netdev->mc_list; mc_ptr;
-		     i++, mc_ptr = mc_ptr->next)
+		for(i = 0, mc_ptr = netdev->mc_list; mc_ptr;
+			i++, mc_ptr = mc_ptr->next)
 			memcpy(&mta[i * IXGB_ETH_LENGTH_OF_ADDRESS],
-			       mc_ptr->dmi_addr, IXGB_ETH_LENGTH_OF_ADDRESS);
+				   mc_ptr->dmi_addr, IXGB_ETH_LENGTH_OF_ADDRESS);
 
 		ixgb_mc_addr_list_update(hw, mta, netdev->mc_count, 0);
 	}
@@ -1059,7 +1088,8 @@
  * @data: pointer to netdev cast into an unsigned long
  **/
 
-static void ixgb_watchdog(unsigned long data)
+static void
+ixgb_watchdog(unsigned long data)
 {
 	struct ixgb_adapter *adapter = (struct ixgb_adapter *)data;
 	struct net_device *netdev = adapter->netdev;
@@ -1073,21 +1103,22 @@
 		netif_stop_queue(netdev);
 	}
 
-	if (adapter->hw.link_up) {
-		if (!netif_carrier_ok(netdev)) {
+	if(adapter->hw.link_up) {
+		if(!netif_carrier_ok(netdev)) {
 			printk(KERN_INFO "ixgb: %s NIC Link is Up %d Mbps %s\n",
-			       netdev->name, 10000, "Full Duplex");
+				   netdev->name, 10000, "Full Duplex");
 			adapter->link_speed = 10000;
 			adapter->link_duplex = FULL_DUPLEX;
 			netif_carrier_on(netdev);
 			netif_wake_queue(netdev);
 		}
 	} else {
-		if (netif_carrier_ok(netdev)) {
+		if(netif_carrier_ok(netdev)) {
 			adapter->link_speed = 0;
 			adapter->link_duplex = 0;
 			printk(KERN_INFO
-			       "ixgb: %s NIC Link is Down\n", netdev->name);
+				   "ixgb: %s NIC Link is Down\n",
+				   netdev->name);
 			netif_carrier_off(netdev);
 			netif_stop_queue(netdev);
 
@@ -1096,8 +1127,8 @@
 
 	ixgb_update_stats(adapter);
 
-	if (!netif_carrier_ok(netdev)) {
-		if (IXGB_DESC_UNUSED(txdr) + 1 < txdr->count) {
+	if(!netif_carrier_ok(netdev)) {
+		if(IXGB_DESC_UNUSED(txdr) + 1 < txdr->count) {
 			/* We've lost link, so the controller stops DMA,
 			 * but we've got queued Tx work that's never going
 			 * to get done, so reset controller to flush Tx.
@@ -1108,9 +1139,9 @@
 
 	/* Early detection of hung controller */
 	i = txdr->next_to_clean;
-	if (txdr->buffer_info[i].dma &&
-	    time_after(jiffies, txdr->buffer_info[i].time_stamp + HZ) &&
-	    !(IXGB_READ_REG(&adapter->hw, STATUS) & IXGB_STATUS_TXOFF))
+	if(txdr->buffer_info[i].dma &&
+	   time_after(jiffies, txdr->buffer_info[i].time_stamp + HZ) &&
+	   !(IXGB_READ_REG(&adapter->hw, STATUS) & IXGB_STATUS_TXOFF))
 		netif_stop_queue(netdev);
 
 	/* generate an interrupt to force clean up of any stragglers */
@@ -1133,7 +1164,7 @@
 	uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
 	uint16_t ipcse, tucse, mss;
 
-	if (likely(skb_shinfo(skb)->tso_size)) {
+	if(likely(skb_shinfo(skb)->tso_size)) {
 		hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
 		mss = skb_shinfo(skb)->tso_size;
 		skb->nh.iph->tot_len = 0;
@@ -1160,22 +1191,16 @@
 		context_desc->mss = cpu_to_le16(mss);
 		context_desc->hdr_len = hdr_len;
 		context_desc->status = 0;
-		context_desc->cmd_type_len = cpu_to_le32(IXGB_CONTEXT_DESC_TYPE
-							 |
-							 IXGB_CONTEXT_DESC_CMD_TSE
-							 |
-							 IXGB_CONTEXT_DESC_CMD_IP
-							 |
-							 IXGB_CONTEXT_DESC_CMD_TCP
-							 |
-							 IXGB_CONTEXT_DESC_CMD_RS
-							 |
-							 IXGB_CONTEXT_DESC_CMD_IDE
-							 | (skb->len -
-							    (hdr_len)));
+		context_desc->cmd_type_len = cpu_to_le32(
+						  IXGB_CONTEXT_DESC_TYPE 
+						| IXGB_CONTEXT_DESC_CMD_TSE
+						| IXGB_CONTEXT_DESC_CMD_IP
+						| IXGB_CONTEXT_DESC_CMD_TCP
+						| IXGB_CONTEXT_DESC_CMD_RS
+						| IXGB_CONTEXT_DESC_CMD_IDE
+						| (skb->len - (hdr_len)));
 
-		if (++i == adapter->tx_ring.count)
-			i = 0;
+		if(++i == adapter->tx_ring.count) i = 0;
 		adapter->tx_ring.next_to_use = i;
 
 		return TRUE;
@@ -1192,7 +1217,7 @@
 	unsigned int i;
 	uint8_t css, cso;
 
-	if (likely(skb->ip_summed == CHECKSUM_HW)) {
+	if(likely(skb->ip_summed == CHECKSUM_HW)) {
 		css = skb->h.raw - skb->data;
 		cso = (skb->h.raw + skb->csum) - skb->data;
 
@@ -1203,16 +1228,16 @@
 		context_desc->tucso = cso;
 		context_desc->tucse = 0;
 		/* zero out any previously existing data in one instruction */
-		*(uint32_t *) & (context_desc->ipcss) = 0;
+		*(uint32_t *)&(context_desc->ipcss) = 0;
 		context_desc->status = 0;
 		context_desc->hdr_len = 0;
 		context_desc->mss = 0;
 		context_desc->cmd_type_len =
-		    cpu_to_le32(IXGB_CONTEXT_DESC_TYPE
-				| IXGB_TX_DESC_CMD_RS | IXGB_TX_DESC_CMD_IDE);
+			cpu_to_le32(IXGB_CONTEXT_DESC_TYPE
+					| IXGB_TX_DESC_CMD_RS 
+					| IXGB_TX_DESC_CMD_IDE);
 
-		if (++i == adapter->tx_ring.count)
-			i = 0;
+		if(++i == adapter->tx_ring.count) i = 0;
 		adapter->tx_ring.next_to_use = i;
 
 		return TRUE;
@@ -1239,45 +1264,46 @@
 
 	i = tx_ring->next_to_use;
 
-	while (len) {
+	while(len) {
 		buffer_info = &tx_ring->buffer_info[i];
 		size = min(len, IXGB_MAX_JUMBO_FRAME_SIZE);
 		buffer_info->length = size;
 		buffer_info->dma =
-		    pci_map_single(adapter->pdev,
-				   skb->data + offset, size, PCI_DMA_TODEVICE);
+			pci_map_single(adapter->pdev,
+				skb->data + offset,
+				size,
+				PCI_DMA_TODEVICE);
 		buffer_info->time_stamp = jiffies;
 
 		len -= size;
 		offset += size;
 		count++;
-		if (++i == tx_ring->count)
-			i = 0;
+		if(++i == tx_ring->count) i = 0;
 	}
 
-	for (f = 0; f < nr_frags; f++) {
+	for(f = 0; f < nr_frags; f++) {
 		struct skb_frag_struct *frag;
 
 		frag = &skb_shinfo(skb)->frags[f];
 		len = frag->size;
 		offset = 0;
 
-		while (len) {
+		while(len) {
 			buffer_info = &tx_ring->buffer_info[i];
 			size = min(len, IXGB_MAX_JUMBO_FRAME_SIZE);
 			buffer_info->length = size;
 			buffer_info->dma =
-			    pci_map_page(adapter->pdev,
-					 frag->page,
-					 frag->page_offset + offset,
-					 size, PCI_DMA_TODEVICE);
+				pci_map_page(adapter->pdev,
+					frag->page,
+					frag->page_offset + offset,
+					size,
+					PCI_DMA_TODEVICE);
 			buffer_info->time_stamp = jiffies;
 
 			len -= size;
 			offset += size;
 			count++;
-			if (++i == tx_ring->count)
-				i = 0;
+			if(++i == tx_ring->count) i = 0;
 		}
 	}
 	i = (i == 0) ? tx_ring->count - 1 : i - 1;
@@ -1288,8 +1314,7 @@
 }
 
 static inline void
-ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id,
-	      int tx_flags)
+ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id,int tx_flags)
 {
 	struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
 	struct ixgb_tx_desc *tx_desc = NULL;
@@ -1299,36 +1324,35 @@
 	uint8_t popts = 0;
 	unsigned int i;
 
-	if (tx_flags & IXGB_TX_FLAGS_TSO) {
+	if(tx_flags & IXGB_TX_FLAGS_TSO) {
 		cmd_type_len |= IXGB_TX_DESC_CMD_TSE;
 		popts |= (IXGB_TX_DESC_POPTS_IXSM | IXGB_TX_DESC_POPTS_TXSM);
 	}
 
-	if (tx_flags & IXGB_TX_FLAGS_CSUM)
+	if(tx_flags & IXGB_TX_FLAGS_CSUM)
 		popts |= IXGB_TX_DESC_POPTS_TXSM;
 
-	if (tx_flags & IXGB_TX_FLAGS_VLAN) {
+	if(tx_flags & IXGB_TX_FLAGS_VLAN) {
 		cmd_type_len |= IXGB_TX_DESC_CMD_VLE;
 	}
 
 	i = tx_ring->next_to_use;
 
-	while (count--) {
+	while(count--) {
 		buffer_info = &tx_ring->buffer_info[i];
 		tx_desc = IXGB_TX_DESC(*tx_ring, i);
 		tx_desc->buff_addr = cpu_to_le64(buffer_info->dma);
 		tx_desc->cmd_type_len =
-		    cpu_to_le32(cmd_type_len | buffer_info->length);
+			cpu_to_le32(cmd_type_len | buffer_info->length);
 		tx_desc->status = status;
 		tx_desc->popts = popts;
 		tx_desc->vlan = cpu_to_le16(vlan_id);
 
-		if (++i == tx_ring->count)
-			i = 0;
+		if(++i == tx_ring->count) i = 0;
 	}
 
-	tx_desc->cmd_type_len |= cpu_to_le32(IXGB_TX_DESC_CMD_EOP
-					     | IXGB_TX_DESC_CMD_RS);
+	tx_desc->cmd_type_len |= cpu_to_le32(IXGB_TX_DESC_CMD_EOP 
+				| IXGB_TX_DESC_CMD_RS );
 
 	/* Force memory writes to complete before letting h/w
 	 * know there are new descriptors to fetch.  (Only
@@ -1346,7 +1370,8 @@
 #define DESC_NEEDED TXD_USE_COUNT(IXGB_MAX_DATA_PER_TXD) + \
 	MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1
 
-static int ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+static int
+ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	unsigned int first;
@@ -1354,33 +1379,33 @@
 	unsigned long flags;
 	int vlan_id = 0;
 
-	if (skb->len <= 0) {
+	if(skb->len <= 0) {
 		dev_kfree_skb_any(skb);
 		return 0;
 	}
 
 	spin_lock_irqsave(&adapter->tx_lock, flags);
-	if (unlikely(IXGB_DESC_UNUSED(&adapter->tx_ring) < DESC_NEEDED)) {
+	if(unlikely(IXGB_DESC_UNUSED(&adapter->tx_ring) < DESC_NEEDED)) {
 		netif_stop_queue(netdev);
 		spin_unlock_irqrestore(&adapter->tx_lock, flags);
 		return 1;
 	}
 	spin_unlock_irqrestore(&adapter->tx_lock, flags);
 
-	if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+	if(adapter->vlgrp && vlan_tx_tag_present(skb)) {
 		tx_flags |= IXGB_TX_FLAGS_VLAN;
 		vlan_id = vlan_tx_tag_get(skb);
 	}
 
 	first = adapter->tx_ring.next_to_use;
-
-	if (ixgb_tso(adapter, skb))
+	
+	if(ixgb_tso(adapter, skb))
 		tx_flags |= IXGB_TX_FLAGS_TSO;
-	else if (ixgb_tx_csum(adapter, skb))
+	else if(ixgb_tx_csum(adapter, skb))
 		tx_flags |= IXGB_TX_FLAGS_CSUM;
 
 	ixgb_tx_queue(adapter, ixgb_tx_map(adapter, skb, first), vlan_id,
-		      tx_flags);
+			tx_flags);
 
 	netdev->trans_start = jiffies;
 
@@ -1392,7 +1417,8 @@
  * @netdev: network interface device structure
  **/
 
-static void ixgb_tx_timeout(struct net_device *netdev)
+static void
+ixgb_tx_timeout(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 
@@ -1400,14 +1426,13 @@
 	schedule_work(&adapter->tx_timeout_task);
 }
 
-static void ixgb_tx_timeout_task(struct net_device *netdev)
+static void
+ixgb_tx_timeout_task(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 
-	netif_device_detach(netdev);
 	ixgb_down(adapter, TRUE);
 	ixgb_up(adapter);
-	netif_device_attach(netdev);
 }
 
 /**
@@ -1418,7 +1443,8 @@
  * The statistics are actually updated from the timer callback.
  **/
 
-static struct net_device_stats *ixgb_get_stats(struct net_device *netdev)
+static struct net_device_stats *
+ixgb_get_stats(struct net_device *netdev)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 
@@ -1433,27 +1459,28 @@
  * Returns 0 on success, negative on failure
  **/
 
-static int ixgb_change_mtu(struct net_device *netdev, int new_mtu)
+static int
+ixgb_change_mtu(struct net_device *netdev, int new_mtu)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
-	uint32_t old_mtu = adapter->rx_buffer_len;
 	int max_frame = new_mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH;
+	int old_max_frame = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH;
+
 
-	if ((max_frame < IXGB_MIN_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH)
-	    || (max_frame > IXGB_MAX_JUMBO_FRAME_SIZE + ENET_FCS_LENGTH)) {
+	if((max_frame < IXGB_MIN_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH)
+	   || (max_frame > IXGB_MAX_JUMBO_FRAME_SIZE + ENET_FCS_LENGTH)) {
 		IXGB_ERR("Invalid MTU setting\n");
 		return -EINVAL;
 	}
 
-	if ((max_frame <=
-	     IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH)
-	    || (max_frame <= IXGB_RXBUFFER_2048)) {
+	if((max_frame <= IXGB_MAX_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH)
+	   || (max_frame <= IXGB_RXBUFFER_2048)) {
 		adapter->rx_buffer_len = IXGB_RXBUFFER_2048;
 
-	} else if (max_frame <= IXGB_RXBUFFER_4096) {
+	} else if(max_frame <= IXGB_RXBUFFER_4096) {
 		adapter->rx_buffer_len = IXGB_RXBUFFER_4096;
 
-	} else if (max_frame <= IXGB_RXBUFFER_8192) {
+	} else if(max_frame <= IXGB_RXBUFFER_8192) {
 		adapter->rx_buffer_len = IXGB_RXBUFFER_8192;
 
 	} else {
@@ -1462,7 +1489,7 @@
 
 	netdev->mtu = new_mtu;
 
-	if (old_mtu != adapter->rx_buffer_len && netif_running(netdev)) {
+	if(old_max_frame != max_frame && netif_running(netdev)) {
 
 		ixgb_down(adapter, TRUE);
 		ixgb_up(adapter);
@@ -1476,7 +1503,8 @@
  * @adapter: board private structure
  **/
 
-static void ixgb_update_stats(struct ixgb_adapter *adapter)
+void
+ixgb_update_stats(struct ixgb_adapter *adapter)
 {
 	adapter->stats.tprl += IXGB_READ_REG(&adapter->hw, TPRL);
 	adapter->stats.tprh += IXGB_READ_REG(&adapter->hw, TPRH);
@@ -1585,31 +1613,33 @@
  * @pt_regs: CPU registers structure
  **/
 
-static irqreturn_t ixgb_intr(int irq, void *data, struct pt_regs *regs)
+static irqreturn_t
+ixgb_intr(int irq, void *data, struct pt_regs *regs)
 {
 	struct net_device *netdev = data;
 	struct ixgb_adapter *adapter = netdev->priv;
 	struct ixgb_hw *hw = &adapter->hw;
-	uint32_t icr = IXGB_READ_REG(&adapter->hw, ICR);
+	uint32_t icr = IXGB_READ_REG(hw, ICR);
 #ifndef CONFIG_IXGB_NAPI
 	unsigned int i;
 #endif
 
-	if (unlikely(!icr))
-		return IRQ_NONE;	/* Not our interrupt */
+	if(unlikely(!icr))
+		return IRQ_NONE;  /* Not our interrupt */
 
-	if (unlikely(icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC))) {
+	if(unlikely(icr & (IXGB_INT_RXSEQ | IXGB_INT_LSC))) {
 		mod_timer(&adapter->watchdog_timer, jiffies);
 	}
+
 #ifdef CONFIG_IXGB_NAPI
-	if (netif_rx_schedule_prep(netdev)) {
+	if(netif_rx_schedule_prep(netdev)) {
 
 		/* Disable interrupts and register for poll. The flush 
-		   of the posted write is intentionally left out.
-		 */
+		  of the posted write is intentionally left out.
+		*/
 
 		atomic_inc(&adapter->irq_sem);
-		IXGB_WRITE_REG(hw, IMC, ~0);
+		IXGB_WRITE_REG(&adapter->hw, IMC, ~0);
 		__netif_rx_schedule(netdev);
 	}
 #else
@@ -1621,16 +1651,7 @@
 		if(!ixgb_clean_rx_irq(adapter) &
 		   !ixgb_clean_tx_irq(adapter))
 			break;
-	/* if RAIDC:EN == 1 and ICR:RXDMT0 == 1, we need to
-	 * set IMS:RXDMT0 to 1 to restart the RBD timer (POLL)
-	 */
-	if ((icr & IXGB_INT_RXDMT0) && adapter->raidc) {
-		/* ready the timer by writing the clear reg */
-		IXGB_WRITE_REG(hw, IMC, IXGB_INT_RXDMT0);
-		/* now restart it, h/w will decide if its necessary */
-		IXGB_WRITE_REG(hw, IMS, IXGB_INT_RXDMT0);
-	}
-#endif
+#endif 
 	return IRQ_HANDLED;
 }
 
@@ -1640,25 +1661,32 @@
  * @adapter: board private structure
  **/
 
-static int ixgb_clean(struct net_device *netdev, int *budget)
+static int
+ixgb_clean(struct net_device *netdev, int *budget)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	int work_to_do = min(*budget, netdev->quota);
+	int tx_cleaned;
 	int work_done = 0;
+	
+	if (!netif_carrier_ok(netdev))
+		goto quit_polling;
 
-	ixgb_clean_tx_irq(adapter);
+	tx_cleaned = ixgb_clean_tx_irq(adapter);
 	ixgb_clean_rx_irq(adapter, &work_done, work_to_do);
 
 	*budget -= work_done;
 	netdev->quota -= work_done;
-
-	if (work_done < work_to_do || !netif_running(netdev)) {
-		netif_rx_complete(netdev);
-		/* RAIDC will be automatically restarted by irq_enable */
+	
+	/* if no Tx cleanup and not enough Rx work done, exit the polling mode */
+	if((!tx_cleaned && (work_done < work_to_do)) || 
+				!netif_running(netdev)) {
+quit_polling:	netif_rx_complete(netdev);
 		ixgb_irq_enable(adapter);
+		return 0;
 	}
 
-	return (work_done >= work_to_do);
+	return 1;
 }
 #endif
 
@@ -1667,11 +1695,11 @@
  * @adapter: board private structure
  **/
 
-static boolean_t ixgb_clean_tx_irq(struct ixgb_adapter *adapter)
+static boolean_t
+ixgb_clean_tx_irq(struct ixgb_adapter *adapter)
 {
 	struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
 	struct net_device *netdev = adapter->netdev;
-	struct pci_dev *pdev = adapter->pdev;
 	struct ixgb_tx_desc *tx_desc, *eop_desc;
 	struct ixgb_buffer *buffer_info;
 	unsigned int i, eop;
@@ -1681,9 +1709,9 @@
 	eop = tx_ring->buffer_info[i].next_to_watch;
 	eop_desc = IXGB_TX_DESC(*tx_ring, eop);
 
-	while (eop_desc->status & IXGB_TX_DESC_STATUS_DD) {
+	while(eop_desc->status & IXGB_TX_DESC_STATUS_DD) {
 
-		for (cleaned = FALSE; !cleaned;) {
+		for(cleaned = FALSE; !cleaned; ) {
 			tx_desc = IXGB_TX_DESC(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
 
@@ -1692,28 +1720,12 @@
 			       IXGB_TX_DESC_POPTS_IXSM))
 				adapter->hw_csum_tx_good++;
 
-			if (buffer_info->dma) {
-
-				pci_unmap_page(pdev,
-					       buffer_info->dma,
-					       buffer_info->length,
-					       PCI_DMA_TODEVICE);
-
-				buffer_info->dma = 0;
-			}
-
-			if (buffer_info->skb) {
-
-				dev_kfree_skb_any(buffer_info->skb);
+			ixgb_unmap_and_free_tx_resource(adapter, buffer_info);
 
-				buffer_info->skb = NULL;
-			}
-
-			*(uint32_t *) & (tx_desc->status) = 0;
+			*(uint32_t *)&(tx_desc->status) = 0;
 
 			cleaned = (i == eop);
-			if (++i == tx_ring->count)
-				i = 0;
+			if(++i == tx_ring->count) i = 0;
 		}
 
 		eop = tx_ring->buffer_info[i].next_to_watch;
@@ -1723,8 +1735,8 @@
 	tx_ring->next_to_clean = i;
 
 	spin_lock(&adapter->tx_lock);
-	if (cleaned && netif_queue_stopped(netdev) && netif_carrier_ok(netdev)
-	    && (IXGB_DESC_UNUSED(tx_ring) > IXGB_TX_QUEUE_WAKE)) {
+	if(cleaned && netif_queue_stopped(netdev) && netif_carrier_ok(netdev) &&
+	   (IXGB_DESC_UNUSED(tx_ring) > IXGB_TX_QUEUE_WAKE)) {
 
 		netif_wake_queue(netdev);
 	}
@@ -1742,20 +1754,21 @@
 
 static inline void
 ixgb_rx_checksum(struct ixgb_adapter *adapter,
-		 struct ixgb_rx_desc *rx_desc, struct sk_buff *skb)
+		 struct ixgb_rx_desc *rx_desc,
+		 struct sk_buff *skb)
 {
 	/* Ignore Checksum bit is set OR
 	 * TCP Checksum has not been calculated
 	 */
-	if ((rx_desc->status & IXGB_RX_DESC_STATUS_IXSM) ||
-	    (!(rx_desc->status & IXGB_RX_DESC_STATUS_TCPCS))) {
+	if((rx_desc->status & IXGB_RX_DESC_STATUS_IXSM) ||
+	   (!(rx_desc->status & IXGB_RX_DESC_STATUS_TCPCS))) {
 		skb->ip_summed = CHECKSUM_NONE;
 		return;
 	}
 
 	/* At this point we know the hardware did the TCP checksum */
 	/* now look at the TCP checksum error bit */
-	if (rx_desc->errors & IXGB_RX_DESC_ERRORS_TCPE) {
+	if(rx_desc->errors & IXGB_RX_DESC_ERRORS_TCPE) {
 		/* let the stack verify checksum errors */
 		skb->ip_summed = CHECKSUM_NONE;
 		adapter->hw_csum_rx_error++;
@@ -1792,18 +1805,22 @@
 	rx_desc = IXGB_RX_DESC(*rx_ring, i);
 	buffer_info = &rx_ring->buffer_info[i];
 
-	while (rx_desc->status & IXGB_RX_DESC_STATUS_DD) {
+	while(rx_desc->status & IXGB_RX_DESC_STATUS_DD) {
 
+#ifdef CONFIG_IXGB_NAPI
+		if(*work_done >= work_to_do)
+			break;
+
+		(*work_done)++;
+#endif
 		skb = buffer_info->skb;
 		prefetch(skb->data);
 
-		if (++i == rx_ring->count)
-			i = 0;
+		if(++i == rx_ring->count) i = 0;
 		next_rxd = IXGB_RX_DESC(*rx_ring, i);
 		prefetch(next_rxd);
 
-		if ((j = i + 1) == rx_ring->count)
-			j = 0;
+		if((j = i + 1) == rx_ring->count) j = 0;
 		next2_buffer = &rx_ring->buffer_info[j];
 		prefetch(next2_buffer);
 
@@ -1811,27 +1828,22 @@
 		next_skb = next_buffer->skb;
 		prefetch(next_skb);
 
-#ifdef CONFIG_IXGB_NAPI
-		if (*work_done >= work_to_do)
-			break;
-
-		(*work_done)++;
-#endif
 
 		cleaned = TRUE;
 
 		pci_unmap_single(pdev,
 				 buffer_info->dma,
-				 buffer_info->length, PCI_DMA_FROMDEVICE);
+				 buffer_info->length,
+				 PCI_DMA_FROMDEVICE);
 
 		length = le16_to_cpu(rx_desc->length);
 
-		if (unlikely(!(rx_desc->status & IXGB_RX_DESC_STATUS_EOP))) {
+		if(unlikely(!(rx_desc->status & IXGB_RX_DESC_STATUS_EOP))) {
 
 			/* All receives must fit into a single buffer */
 
 			IXGB_DBG("Receive packet consumed multiple buffers "
-				 "length<%x>\n", length);
+					 "length<%x>\n", length);
 
 			dev_kfree_skb_irq(skb);
 			rx_desc->status = 0;
@@ -1864,26 +1876,22 @@
 
 		skb->protocol = eth_type_trans(skb, netdev);
 #ifdef CONFIG_IXGB_NAPI
-		if (adapter->vlgrp
-		    && (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) {
+		if(adapter->vlgrp && (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) {
 			vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
-						 le16_to_cpu(rx_desc->
-							     special &
-							     IXGB_RX_DESC_SPECIAL_VLAN_MASK));
+				le16_to_cpu(rx_desc->special) &
+					IXGB_RX_DESC_SPECIAL_VLAN_MASK);
 		} else {
 			netif_receive_skb(skb);
 		}
-#else				/* CONFIG_IXGB_NAPI */
-		if (adapter->vlgrp
-		    && (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) {
+#else /* CONFIG_IXGB_NAPI */
+		if(adapter->vlgrp && (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) {
 			vlan_hwaccel_rx(skb, adapter->vlgrp,
-					le16_to_cpu(rx_desc->
-						    special &
-						    IXGB_RX_DESC_SPECIAL_VLAN_MASK));
+				le16_to_cpu(rx_desc->special) &
+					IXGB_RX_DESC_SPECIAL_VLAN_MASK);
 		} else {
 			netif_rx(skb);
 		}
-#endif				/* CONFIG_IXGB_NAPI */
+#endif /* CONFIG_IXGB_NAPI */
 		netdev->last_rx = jiffies;
 
 		rx_desc->status = 0;
@@ -1905,7 +1913,8 @@
  * @adapter: address of board private structure
  **/
 
-static void ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
+static void
+ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
 {
 	struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
 	struct net_device *netdev = adapter->netdev;
@@ -1921,19 +1930,15 @@
 	buffer_info = &rx_ring->buffer_info[i];
 	cleancount = IXGB_DESC_UNUSED(rx_ring);
 
-	/* lessen this to 4 if we're
-	 * in the midst of raidc and rbd is occuring
-	 * because we don't want to delay returning buffers when low
-	 */
-	num_group_tail_writes = adapter->raidc ? 4 : IXGB_RX_BUFFER_WRITE;
+	num_group_tail_writes = IXGB_RX_BUFFER_WRITE;
 
 	/* leave one descriptor unused */
-	while (--cleancount > 0) {
+	while(--cleancount > 0) {
 		rx_desc = IXGB_RX_DESC(*rx_ring, i);
 
 		skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN);
 
-		if (unlikely(!skb)) {
+		if(unlikely(!skb)) {
 			/* Better luck next round */
 			break;
 		}
@@ -1949,13 +1954,14 @@
 		buffer_info->skb = skb;
 		buffer_info->length = adapter->rx_buffer_len;
 		buffer_info->dma =
-		    pci_map_single(pdev,
+			pci_map_single(pdev,
 				   skb->data,
-				   adapter->rx_buffer_len, PCI_DMA_FROMDEVICE);
+				   adapter->rx_buffer_len,
+				   PCI_DMA_FROMDEVICE);
 
 		rx_desc->buff_addr = cpu_to_le64(buffer_info->dma);
 
-		if ((i & ~(num_group_tail_writes - 1)) == i) {
+		if((i & ~(num_group_tail_writes- 1)) == i) {
 			/* Force memory writes to complete before letting h/w
 			 * know there are new descriptors to fetch.  (Only
 			 * applicable for weak-ordered memory model archs,
@@ -1965,8 +1971,7 @@
 			IXGB_WRITE_REG(&adapter->hw, RDT, i);
 		}
 
-		if (++i == rx_ring->count)
-			i = 0;
+		if(++i == rx_ring->count) i = 0;
 		buffer_info = &rx_ring->buffer_info[i];
 	}
 
@@ -1988,7 +1993,7 @@
 	ixgb_irq_disable(adapter);
 	adapter->vlgrp = grp;
 
-	if (grp) {
+	if(grp) {
 		/* enable VLAN tag insert/strip */
 		ctrl = IXGB_READ_REG(&adapter->hw, CTRL0);
 		ctrl |= IXGB_CTRL0_VME;
@@ -2017,7 +2022,8 @@
 	ixgb_irq_enable(adapter);
 }
 
-static void ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid)
+static void
+ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	uint32_t vfta, index;
@@ -2030,19 +2036,20 @@
 	ixgb_write_vfta(&adapter->hw, index, vfta);
 }
 
-static void ixgb_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid)
+static void
+ixgb_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid)
 {
 	struct ixgb_adapter *adapter = netdev->priv;
 	uint32_t vfta, index;
 
 	ixgb_irq_disable(adapter);
 
-	if (adapter->vlgrp)
+	if(adapter->vlgrp)
 		adapter->vlgrp->vlan_devices[vid] = NULL;
 
 	ixgb_irq_enable(adapter);
 
-	/* remove VID from filter table */
+	/* remove VID from filter table*/
 
 	index = (vid >> 5) & 0x7F;
 	vfta = IXGB_READ_REG_ARRAY(&adapter->hw, VFTA, index);
@@ -2050,14 +2057,15 @@
 	ixgb_write_vfta(&adapter->hw, index, vfta);
 }
 
-static void ixgb_restore_vlan(struct ixgb_adapter *adapter)
+static void
+ixgb_restore_vlan(struct ixgb_adapter *adapter)
 {
 	ixgb_vlan_rx_register(adapter->netdev, adapter->vlgrp);
 
-	if (adapter->vlgrp) {
+	if(adapter->vlgrp) {
 		uint16_t vid;
-		for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
-			if (!adapter->vlgrp->vlan_devices[vid])
+		for(vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+			if(!adapter->vlgrp->vlan_devices[vid])
 				continue;
 			ixgb_vlan_rx_add_vid(adapter->netdev, vid);
 		}
@@ -2075,7 +2083,7 @@
 {
 	struct pci_dev *pdev = NULL;
 
-	switch (event) {
+	switch(event) {
 	case SYS_DOWN:
 	case SYS_HALT:
 	case SYS_POWER_OFF:
@@ -2092,14 +2100,15 @@
  * @param pdev pci driver structure used for passing to
  * @param state power state to enter 
  **/
-static int ixgb_suspend(struct pci_dev *pdev, uint32_t state)
+static int
+ixgb_suspend(struct pci_dev *pdev, uint32_t state)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct ixgb_adapter *adapter = netdev->priv;
 
 	netif_device_detach(netdev);
 
-	if (netif_running(netdev))
+	if(netif_running(netdev))
 		ixgb_down(adapter, TRUE);
 
 	pci_save_state(pdev);
diff -Nru a/drivers/net/ixgb/ixgb_osdep.h b/drivers/net/ixgb/ixgb_osdep.h
--- a/drivers/net/ixgb/ixgb_osdep.h	2005-01-10 23:54:12 -05:00
+++ b/drivers/net/ixgb/ixgb_osdep.h	2005-01-10 23:54:12 -05:00
@@ -78,19 +78,19 @@
 #define DEBUGOUT7 DEBUGOUT3
 
 #define IXGB_WRITE_REG(a, reg, value) ( \
-    writel((value), ((a)->hw_addr + IXGB_##reg)))
+	writel((value), ((a)->hw_addr + IXGB_##reg)))
 
 #define IXGB_READ_REG(a, reg) ( \
-    readl((a)->hw_addr + IXGB_##reg))
+	readl((a)->hw_addr + IXGB_##reg))
 
 #define IXGB_WRITE_REG_ARRAY(a, reg, offset, value) ( \
-    writel((value), ((a)->hw_addr + IXGB_##reg + ((offset) << 2))))
+	writel((value), ((a)->hw_addr + IXGB_##reg + ((offset) << 2))))
 
 #define IXGB_READ_REG_ARRAY(a, reg, offset) ( \
-    readl((a)->hw_addr + IXGB_##reg + ((offset) << 2)))
+	readl((a)->hw_addr + IXGB_##reg + ((offset) << 2)))
 
 #define IXGB_WRITE_FLUSH(a) IXGB_READ_REG(a, STATUS)
 
 #define IXGB_MEMCPY memcpy
 
-#endif				/* _IXGB_OSDEP_H_ */
+#endif /* _IXGB_OSDEP_H_ */
diff -Nru a/drivers/net/ixgb/ixgb_param.c b/drivers/net/ixgb/ixgb_param.c
--- a/drivers/net/ixgb/ixgb_param.c	2005-01-10 23:54:12 -05:00
+++ b/drivers/net/ixgb/ixgb_param.c	2005-01-10 23:54:12 -05:00
@@ -34,31 +34,21 @@
 
 #define IXGB_MAX_NIC 8
 
-#define OPTION_UNSET    -1
+#define OPTION_UNSET	-1
 #define OPTION_DISABLED 0
 #define OPTION_ENABLED  1
 
-/* Module Parameters are always initialized to -1, so that the driver
- * can tell the difference between no user specified value or the
- * user asking for the default value.
- * The true default values are loaded in when ixgb_check_options is called.
- *
- * This is a GCC extension to ANSI C.
- * See the item "Labeled Elements in Initializers" in the section
- * "Extensions to the C Language Family" of the GCC documentation.
- */
-
-#define IXGB_PARAM_INIT { [0 ... IXGB_MAX_NIC] = OPTION_UNSET }
-
 /* All parameters are treated the same, as an integer array of values.
  * This macro just reduces the need to repeat the same declaration code
  * over and over (plus this helps to avoid typo bugs).
  */
 
-#define IXGB_PARAM(X, S) \
-static int __devinitdata X[IXGB_MAX_NIC + 1] = IXGB_PARAM_INIT; \
-module_param_array(X, int, NULL, 0); \
-MODULE_PARM_DESC(X, S);
+#define IXGB_PARAM_INIT { [0 ... IXGB_MAX_NIC] = OPTION_UNSET }
+#define IXGB_PARAM(X, desc) \
+	static int __devinitdata X[IXGB_MAX_NIC+1] = IXGB_PARAM_INIT; \
+	static int num_##X = 0; \
+	module_param_array_named(X, X, int, &num_##X, 0); \
+	MODULE_PARM_DESC(X, desc);
 
 /* Transmit Descriptor Count
  *
@@ -121,15 +111,6 @@
 
 IXGB_PARAM(RxIntDelay, "Receive Interrupt Delay");
 
-/* Receive Interrupt Moderation enable (uses RxIntDelay too)
- *
- * Valid Range: 0,1
- *
- * Default Value: 1
- */
-
-IXGB_PARAM(RAIDC, "Disable or enable Receive Interrupt Moderation");
-
 /* Receive Flow control high threshold (when we send a pause frame)
  * (FCRTH)
  *
@@ -173,13 +154,6 @@
 
 IXGB_PARAM(IntDelayEnable, "Transmit Interrupt Delay Enable");
 
-#define DEFAULT_TXD			    256
-#define MAX_TXD				   4096
-#define MIN_TXD				     64
-
-#define DEFAULT_RXD			   1024
-#define MAX_RXD				   4096
-#define MIN_RXD				     64
 
 #define DEFAULT_TIDV	   		     32
 #define MAX_TIDV			 0xFFFF
@@ -224,9 +198,10 @@
 	} arg;
 };
 
-static int __devinit ixgb_validate_option(int *value, struct ixgb_option *opt)
+static int __devinit
+ixgb_validate_option(int *value, struct ixgb_option *opt)
 {
-	if (*value == OPTION_UNSET) {
+	if(*value == OPTION_UNSET) {
 		*value = opt->def;
 		return 0;
 	}
@@ -243,32 +218,31 @@
 		}
 		break;
 	case range_option:
-		if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
+		if(*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
 			printk(KERN_INFO "%s set to %i\n", opt->name, *value);
 			return 0;
 		}
 		break;
-	case list_option:{
-			int i;
-			struct ixgb_opt_list *ent;
-
-			for (i = 0; i < opt->arg.l.nr; i++) {
-				ent = &opt->arg.l.p[i];
-				if (*value == ent->i) {
-					if (ent->str[0] != '\0')
-						printk(KERN_INFO "%s\n",
-						       ent->str);
-					return 0;
-				}
+	case list_option: {
+		int i;
+		struct ixgb_opt_list *ent;
+
+		for(i = 0; i < opt->arg.l.nr; i++) {
+			ent = &opt->arg.l.p[i];
+			if(*value == ent->i) {
+				if(ent->str[0] != '\0')
+					printk(KERN_INFO "%s\n", ent->str);
+				return 0;
 			}
 		}
+	}
 		break;
 	default:
 		BUG();
 	}
 
 	printk(KERN_INFO "Invalid %s specified (%i) %s\n",
-	       opt->name, *value, opt->err);
+		   opt->name, *value, opt->err);
 	*value = opt->def;
 	return -1;
 }
@@ -285,198 +259,218 @@
  * in a variable in the adapter structure.
  **/
 
-void __devinit ixgb_check_options(struct ixgb_adapter *adapter)
+void __devinit
+ixgb_check_options(struct ixgb_adapter *adapter)
 {
 	int bd = adapter->bd_number;
-	if (bd >= IXGB_MAX_NIC) {
+	if(bd >= IXGB_MAX_NIC) {
 		printk(KERN_NOTICE
-		       "Warning: no configuration for board #%i\n", bd);
+			   "Warning: no configuration for board #%i\n", bd);
 		printk(KERN_NOTICE "Using defaults for all values\n");
-		bd = IXGB_MAX_NIC;
 	}
 
-	{			/* Transmit Descriptor Count */
+	{ /* Transmit Descriptor Count */
 		struct ixgb_option opt = {
 			.type = range_option,
 			.name = "Transmit Descriptors",
-			.err = "using default of " __MODULE_STRING(DEFAULT_TXD),
-			.def = DEFAULT_TXD,
-			.arg = {.r = {.min = MIN_TXD,
-				      .max = MAX_TXD}}
+			.err  = "using default of " __MODULE_STRING(DEFAULT_TXD),
+			.def  = DEFAULT_TXD,
+			.arg  = { .r = { .min = MIN_TXD,
+					 .max = MAX_TXD}}
 		};
 		struct ixgb_desc_ring *tx_ring = &adapter->tx_ring;
 
-		tx_ring->count = TxDescriptors[bd];
-		ixgb_validate_option(&tx_ring->count, &opt);
+		if(num_TxDescriptors > bd) {
+			tx_ring->count = TxDescriptors[bd];
+			ixgb_validate_option(&tx_ring->count, &opt);
+		} else {
+			tx_ring->count = opt.def;
+		}
 		IXGB_ROUNDUP(tx_ring->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE);
 	}
-	{			/* Receive Descriptor Count */
+	{ /* Receive Descriptor Count */
 		struct ixgb_option opt = {
 			.type = range_option,
 			.name = "Receive Descriptors",
-			.err = "using default of " __MODULE_STRING(DEFAULT_RXD),
-			.def = DEFAULT_RXD,
-			.arg = {.r = {.min = MIN_RXD,
-				      .max = MAX_RXD}}
+			.err  = "using default of " __MODULE_STRING(DEFAULT_RXD),
+			.def  = DEFAULT_RXD,
+			.arg  = { .r = { .min = MIN_RXD,
+					 .max = MAX_RXD}}
 		};
 		struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
 
-		rx_ring->count = RxDescriptors[bd];
-		ixgb_validate_option(&rx_ring->count, &opt);
+		if(num_RxDescriptors > bd) {
+			rx_ring->count = RxDescriptors[bd];
+			ixgb_validate_option(&rx_ring->count, &opt);
+		} else {
+			rx_ring->count = opt.def;
+		}
 		IXGB_ROUNDUP(rx_ring->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE);
 	}
-	{			/* Receive Checksum Offload Enable */
+	{ /* Receive Checksum Offload Enable */
 		struct ixgb_option opt = {
 			.type = enable_option,
 			.name = "Receive Checksum Offload",
-			.err = "defaulting to Enabled",
-			.def = OPTION_ENABLED
+			.err  = "defaulting to Enabled",
+			.def  = OPTION_ENABLED
 		};
 
-		int rx_csum = XsumRX[bd];
-		ixgb_validate_option(&rx_csum, &opt);
-		adapter->rx_csum = rx_csum;
+		if(num_XsumRX > bd) {
+			int rx_csum = XsumRX[bd];
+			ixgb_validate_option(&rx_csum, &opt);
+			adapter->rx_csum = rx_csum;
+		} else {
+			adapter->rx_csum = opt.def;
+		}
 	}
-	{			/* Flow Control */
+	{ /* Flow Control */
 
 		struct ixgb_opt_list fc_list[] =
-		    { {ixgb_fc_none, "Flow Control Disabled"},
-		{ixgb_fc_rx_pause, "Flow Control Receive Only"},
-		{ixgb_fc_tx_pause, "Flow Control Transmit Only"},
-		{ixgb_fc_full, "Flow Control Enabled"},
-		{ixgb_fc_default, "Flow Control Hardware Default"}
-		};
+			{{ ixgb_fc_none,	"Flow Control Disabled" },
+			 { ixgb_fc_rx_pause,"Flow Control Receive Only" },
+			 { ixgb_fc_tx_pause,"Flow Control Transmit Only" },
+			 { ixgb_fc_full,	"Flow Control Enabled" },
+			 { ixgb_fc_default, "Flow Control Hardware Default" }};
 
 		struct ixgb_option opt = {
 			.type = list_option,
 			.name = "Flow Control",
-			.err = "reading default settings from EEPROM",
-			.def = ixgb_fc_full,
-			.arg = {.l = {.nr = LIST_LEN(fc_list),
-				      .p = fc_list}}
+			.err  = "reading default settings from EEPROM",
+			.def  = ixgb_fc_full,
+			.arg  = { .l = { .nr = LIST_LEN(fc_list),
+					 .p = fc_list }}
 		};
 
-		int fc = FlowControl[bd];
-		ixgb_validate_option(&fc, &opt);
-		adapter->hw.fc.type = fc;
+		if(num_FlowControl > bd) {
+			int fc = FlowControl[bd];
+			ixgb_validate_option(&fc, &opt);
+			adapter->hw.fc.type = fc;
+		} else {
+			adapter->hw.fc.type = opt.def;
+		}
 	}
-	{			/* Receive Flow Control High Threshold */
+	{ /* Receive Flow Control High Threshold */
 		struct ixgb_option opt = {
 			.type = range_option,
 			.name = "Rx Flow Control High Threshold",
-			.err =
-			    "using default of " __MODULE_STRING(DEFAULT_FCRTH),
-			.def = DEFAULT_FCRTH,
-			.arg = {.r = {.min = MIN_FCRTH,
-				      .max = MAX_FCRTH}}
+			.err  = "using default of " __MODULE_STRING(DEFAULT_FCRTH),
+			.def  = DEFAULT_FCRTH,
+			.arg  = { .r = { .min = MIN_FCRTH,
+					 .max = MAX_FCRTH}}
 		};
 
-		adapter->hw.fc.high_water = RxFCHighThresh[bd];
-		ixgb_validate_option(&adapter->hw.fc.high_water, &opt);
-		if (!(adapter->hw.fc.type & ixgb_fc_rx_pause))
-			printk(KERN_INFO
-			       "Ignoring RxFCHighThresh when no RxFC\n");
+		if(num_RxFCHighThresh > bd) {
+			adapter->hw.fc.high_water = RxFCHighThresh[bd];
+			ixgb_validate_option(&adapter->hw.fc.high_water, &opt);
+		} else {
+			adapter->hw.fc.high_water = opt.def;
+		}
+		if(!(adapter->hw.fc.type & ixgb_fc_rx_pause) )
+			printk (KERN_INFO 
+				"Ignoring RxFCHighThresh when no RxFC\n");
 	}
-	{			/* Receive Flow Control Low Threshold */
+	{ /* Receive Flow Control Low Threshold */
 		struct ixgb_option opt = {
 			.type = range_option,
 			.name = "Rx Flow Control Low Threshold",
-			.err =
-			    "using default of " __MODULE_STRING(DEFAULT_FCRTL),
-			.def = DEFAULT_FCRTL,
-			.arg = {.r = {.min = MIN_FCRTL,
-				      .max = MAX_FCRTL}}
+			.err  = "using default of " __MODULE_STRING(DEFAULT_FCRTL),
+			.def  = DEFAULT_FCRTL,
+			.arg  = { .r = { .min = MIN_FCRTL,
+					 .max = MAX_FCRTL}}
 		};
 
-		adapter->hw.fc.low_water = RxFCLowThresh[bd];
-		ixgb_validate_option(&adapter->hw.fc.low_water, &opt);
-		if (!(adapter->hw.fc.type & ixgb_fc_rx_pause))
-			printk(KERN_INFO
-			       "Ignoring RxFCLowThresh when no RxFC\n");
+		if(num_RxFCLowThresh > bd) {
+			adapter->hw.fc.low_water = RxFCLowThresh[bd];
+			ixgb_validate_option(&adapter->hw.fc.low_water, &opt);
+		} else {
+			adapter->hw.fc.low_water = opt.def;
+		}
+		if(!(adapter->hw.fc.type & ixgb_fc_rx_pause) )
+			printk (KERN_INFO 
+				"Ignoring RxFCLowThresh when no RxFC\n");
 	}
-	{			/* Flow Control Pause Time Request */
+	{ /* Flow Control Pause Time Request*/
 		struct ixgb_option opt = {
 			.type = range_option,
 			.name = "Flow Control Pause Time Request",
-			.err =
-			    "using default of "
-			    __MODULE_STRING(DEFAULT_FCPAUSE),
-			.def = DEFAULT_FCPAUSE,
-			.arg = {.r = {.min = MIN_FCPAUSE,
-				      .max = MAX_FCPAUSE}}
+			.err  = "using default of "__MODULE_STRING(DEFAULT_FCPAUSE),
+			.def  = DEFAULT_FCPAUSE,
+			.arg = { .r = { .min = MIN_FCPAUSE,
+					.max = MAX_FCPAUSE}}
 		};
 
-		int pause_time = FCReqTimeout[bd];
-
-		ixgb_validate_option(&pause_time, &opt);
-		if (!(adapter->hw.fc.type & ixgb_fc_rx_pause))
-			printk(KERN_INFO
-			       "Ignoring FCReqTimeout when no RxFC\n");
-		adapter->hw.fc.pause_time = pause_time;
+		if(num_FCReqTimeout > bd) {
+			int pause_time = FCReqTimeout[bd];
+			ixgb_validate_option(&pause_time, &opt);
+			adapter->hw.fc.pause_time = pause_time;
+		} else {
+			adapter->hw.fc.pause_time = opt.def;
+		}
+		if(!(adapter->hw.fc.type & ixgb_fc_rx_pause) )
+			printk (KERN_INFO 
+				"Ignoring FCReqTimeout when no RxFC\n");
 	}
 	/* high low and spacing check for rx flow control thresholds */
 	if (adapter->hw.fc.type & ixgb_fc_rx_pause) {
 		/* high must be greater than low */
 		if (adapter->hw.fc.high_water < (adapter->hw.fc.low_water + 8)) {
 			/* set defaults */
-			printk(KERN_INFO
-			       "RxFCHighThresh must be >= (RxFCLowThresh + 8), "
-			       "Using Defaults\n");
+			printk (KERN_INFO 
+				"RxFCHighThresh must be >= (RxFCLowThresh + 8), "
+				"Using Defaults\n");
 			adapter->hw.fc.high_water = DEFAULT_FCRTH;
-			adapter->hw.fc.low_water = DEFAULT_FCRTL;
+			adapter->hw.fc.low_water  = DEFAULT_FCRTL;
 		}
 	}
-	{			/* Receive Interrupt Delay */
+	{ /* Receive Interrupt Delay */
 		struct ixgb_option opt = {
 			.type = range_option,
 			.name = "Receive Interrupt Delay",
-			.err =
-			    "using default of " __MODULE_STRING(DEFAULT_RDTR),
-			.def = DEFAULT_RDTR,
-			.arg = {.r = {.min = MIN_RDTR,
-				      .max = MAX_RDTR}}
-		};
-
-		adapter->rx_int_delay = RxIntDelay[bd];
-		ixgb_validate_option(&adapter->rx_int_delay, &opt);
-	}
-	{			/* Receive Interrupt Moderation */
-		struct ixgb_option opt = {
-			.type = enable_option,
-			.name = "Advanced Receive Interrupt Moderation",
-			.err = "defaulting to Enabled",
-			.def = OPTION_ENABLED
+			.err  = "using default of " __MODULE_STRING(DEFAULT_RDTR),
+			.def  = DEFAULT_RDTR,
+			.arg  = { .r = { .min = MIN_RDTR,
+					 .max = MAX_RDTR}}
 		};
-		int raidc = RAIDC[bd];
 
-		ixgb_validate_option(&raidc, &opt);
-		adapter->raidc = raidc;
+		if(num_RxIntDelay > bd) {
+			adapter->rx_int_delay = RxIntDelay[bd];
+			ixgb_validate_option(&adapter->rx_int_delay, &opt);
+		} else {
+			adapter->rx_int_delay = opt.def;
+		}
 	}
-	{			/* Transmit Interrupt Delay */
+	{ /* Transmit Interrupt Delay */
 		struct ixgb_option opt = {
 			.type = range_option,
 			.name = "Transmit Interrupt Delay",
-			.err =
-			    "using default of " __MODULE_STRING(DEFAULT_TIDV),
-			.def = DEFAULT_TIDV,
-			.arg = {.r = {.min = MIN_TIDV,
-				      .max = MAX_TIDV}}
+			.err  = "using default of " __MODULE_STRING(DEFAULT_TIDV),
+			.def  = DEFAULT_TIDV,
+			.arg  = { .r = { .min = MIN_TIDV,
+					 .max = MAX_TIDV}}
 		};
 
-		adapter->tx_int_delay = TxIntDelay[bd];
-		ixgb_validate_option(&adapter->tx_int_delay, &opt);
+		if(num_TxIntDelay > bd) {
+			adapter->tx_int_delay = TxIntDelay[bd];
+			ixgb_validate_option(&adapter->tx_int_delay, &opt);
+		} else {
+			adapter->tx_int_delay = opt.def;
+		}
 	}
 
-	{			/* Transmit Interrupt Delay Enable */
+	{ /* Transmit Interrupt Delay Enable */
 		struct ixgb_option opt = {
 			.type = enable_option,
 			.name = "Tx Interrupt Delay Enable",
-			.err = "defaulting to Enabled",
-			.def = OPTION_ENABLED
+			.err  = "defaulting to Enabled",
+			.def  = OPTION_ENABLED
 		};
-		int ide = IntDelayEnable[bd];
 
-		ixgb_validate_option(&ide, &opt);
-		adapter->tx_int_delay_enable = ide;
+		if(num_IntDelayEnable > bd) {
+			int ide = IntDelayEnable[bd];
+			ixgb_validate_option(&ide, &opt);
+			adapter->tx_int_delay_enable = ide;
+		} else {
+			adapter->tx_int_delay_enable = opt.def;
+		}
 	}
 }
diff -Nru a/drivers/net/s2io.c b/drivers/net/s2io.c
--- a/drivers/net/s2io.c	2005-01-10 23:54:12 -05:00
+++ b/drivers/net/s2io.c	2005-01-10 23:54:12 -05:00
@@ -560,21 +560,35 @@
 	for (i = 0; i < config->rx_ring_num; i++) {
 		blk_cnt =
 		    config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1);
+		if (!nic->ba[i])
+			goto end_free;
 		for (j = 0; j < blk_cnt; j++) {
 			int k = 0;
-			if (!nic->ba[i][j])
-				continue;
+			if (!nic->ba[i][j]) {
+				kfree(nic->ba[i]);
+				goto end_free;
+			}
 			while (k != MAX_RXDS_PER_BLOCK) {
 				buffAdd_t *ba = &nic->ba[i][j][k];
+				if (!ba || !ba->ba_0_org || !ba->ba_1_org)
+				{
+					kfree(nic->ba[i]);
+					kfree(nic->ba[i][j]);
+					if(ba->ba_0_org)
+						kfree(ba->ba_0_org);
+					if(ba->ba_1_org)
+						kfree(ba->ba_1_org);
+					goto end_free;
+				}
 				kfree(ba->ba_0_org);
 				kfree(ba->ba_1_org);
 				k++;
 			}
 			kfree(nic->ba[i][j]);
 		}
-		if (nic->ba[i])
-			kfree(nic->ba[i]);
+		kfree(nic->ba[i]);
 	}
+end_free:
 #endif
 
 	if (mac_control->stats_mem) {
diff -Nru a/drivers/net/s2io.h b/drivers/net/s2io.h
--- a/drivers/net/s2io.h	2005-01-10 23:54:12 -05:00
+++ b/drivers/net/s2io.h	2005-01-10 23:54:12 -05:00
@@ -740,8 +740,8 @@
 {
 	u64 ret = 0;
 	ret = readl(addr + 4);
-	(u64) ret <<= 32;
-	(u64) ret |= readl(addr);
+	ret <<= 32;
+	ret |= readl(addr);
 
 	return ret;
 }
diff -Nru a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c
--- a/drivers/net/smc-ultra.c	2005-01-10 23:54:12 -05:00
+++ b/drivers/net/smc-ultra.c	2005-01-10 23:54:12 -05:00
@@ -156,8 +156,6 @@
 	/* Look for any installed ISAPnP cards */
 	if (isapnp_present() && (ultra_probe_isapnp(dev) == 0))
 		return 0;
-
-	printk(KERN_NOTICE "smc-ultra.c: No ISAPnP cards found, trying standard ones...\n");
 #endif
 
 	for (i = 0; ultra_portlist[i]; i++) {
diff -Nru a/drivers/net/smc91x.c b/drivers/net/smc91x.c
--- a/drivers/net/smc91x.c	2005-01-10 23:54:12 -05:00
+++ b/drivers/net/smc91x.c	2005-01-10 23:54:12 -05:00
@@ -1333,6 +1333,19 @@
 	return IRQ_HANDLED;
 }
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling receive - used by netconsole and other diagnostic tools
+ * to allow network i/o with interrupts disabled.
+ */
+static void smc_poll_controller(struct net_device *dev)
+{
+	disable_irq(dev->irq);
+	smc_interrupt(dev->irq, dev, NULL);
+	enable_irq(dev->irq);
+}
+#endif
+
 /* Our watchdog timed out. Called by the networking layer */
 static void smc_timeout(struct net_device *dev)
 {
@@ -1912,6 +1925,9 @@
 	dev->get_stats = smc_query_statistics;
 	dev->set_multicast_list = smc_set_multicast_list;
 	dev->ethtool_ops = &smc_ethtool_ops;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	dev->poll_controller = smc_poll_controller;
+#endif
 
 	tasklet_init(&lp->tx_task, smc_hardware_send_pkt, (unsigned long)dev);
 	INIT_WORK(&lp->phy_configure, smc_phy_configure, dev);
diff -Nru a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
--- a/drivers/net/wireless/orinoco.c	2005-01-10 23:54:12 -05:00
+++ b/drivers/net/wireless/orinoco.c	2005-01-10 23:54:12 -05:00
@@ -617,9 +617,8 @@
 	unsigned long flags;
 	int err;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	err = __orinoco_up(dev);
 
@@ -671,10 +670,9 @@
 		return NULL; /* FIXME: Can we do better than this? */
 	}
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return NULL; /* FIXME: Erg, we've been signalled, how
-			      * do we propagate this back up? */
+	if (orinoco_lock(priv, &flags) != 0)
+		return NULL;  /* FIXME: Erg, we've been signalled, how
+			       * do we propagate this back up? */
 
 	if (priv->iw_mode == IW_MODE_ADHOC) {
 		memset(&wstats->qual, 0, sizeof(wstats->qual));
@@ -1819,10 +1817,8 @@
 		return 0;
 	}
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
-
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 		
 	err = hermes_disable_port(hw, 0);
 	if (err) {
@@ -1864,11 +1860,10 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	struct hermes *hw = &priv->hw;
-	int err;
+	int err = 0;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
+	if (orinoco_lock(priv, &flags) != 0)
 		/* When the hardware becomes available again, whatever
 		 * detects that is responsible for re-initializing
 		 * it. So no need for anything further */
@@ -2411,9 +2406,8 @@
 	int err = 0;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
 			      ETH_ALEN, NULL, buf);
@@ -2433,9 +2427,8 @@
 	int len;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	if (strlen(priv->desired_essid) > 0) {
 		/* We read the desired SSID from the hardware rather
@@ -2486,9 +2479,8 @@
 	long freq = 0;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	
 	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL, &channel);
 	if (err)
@@ -2528,9 +2520,8 @@
 	int i;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
 			      sizeof(list), NULL, &list);
@@ -2568,9 +2559,8 @@
 
 	rrq->length = sizeof(range);
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	mode = priv->iw_mode;
 	orinoco_unlock(priv, &flags);
@@ -2639,9 +2629,8 @@
 	range.min_frag = 256;
 	range.max_frag = 2346;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	if (priv->has_wep) {
 		range.max_encoding_tokens = ORINOCO_MAX_KEYS;
 
@@ -2706,10 +2695,9 @@
 		if (copy_from_user(keybuf, erq->pointer, erq->length))
 			return -EFAULT;
 	}
-	
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	
 	if (erq->pointer) {
 		if (erq->length > ORINOCO_MAX_KEY_SIZE) {
@@ -2788,12 +2776,10 @@
 	int index = (erq->flags & IW_ENCODE_INDEX) - 1;
 	u16 xlen = 0;
 	char keybuf[ORINOCO_MAX_KEY_SIZE];
-	int err;
 	unsigned long flags;
-	
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	if ((index < 0) || (index >= ORINOCO_MAX_KEYS))
 		index = priv->tx_key;
@@ -2833,7 +2819,6 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	char essidbuf[IW_ESSID_MAX_SIZE+1];
-	int err;
 	unsigned long flags;
 
 	/* Note : ESSID is ignored in Ad-Hoc demo mode, but we can set it
@@ -2851,9 +2836,8 @@
 		essidbuf[erq->length] = '\0';
 	}
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	memcpy(priv->desired_essid, essidbuf, sizeof(priv->desired_essid));
 
@@ -2877,9 +2861,8 @@
 		if (err)
 			return err;
 	} else {
-		err = orinoco_lock(priv, &flags);
-		if (err)
-			return err;
+		if (orinoco_lock(priv, &flags) != 0)
+			return -EBUSY;
 		memcpy(essidbuf, priv->desired_essid, sizeof(essidbuf));
 		orinoco_unlock(priv, &flags);
 	}
@@ -2899,7 +2882,6 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	char nickbuf[IW_ESSID_MAX_SIZE+1];
-	int err;
 	unsigned long flags;
 
 	if (nrq->length > IW_ESSID_MAX_SIZE)
@@ -2912,9 +2894,8 @@
 
 	nickbuf[nrq->length] = '\0';
 	
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	memcpy(priv->nick, nickbuf, sizeof(priv->nick));
 
@@ -2927,12 +2908,10 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	char nickbuf[IW_ESSID_MAX_SIZE+1];
-	int err;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1);
 	orinoco_unlock(priv, &flags);
@@ -2949,7 +2928,6 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int chan = -1;
-	int err;
 	unsigned long flags;
 
 	/* We can only use this in Ad-Hoc demo mode to set the operating
@@ -2978,9 +2956,8 @@
 	     ! (priv->channel_mask & (1 << (chan-1)) ) )
 		return -EINVAL;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	priv->channel = chan;
 	orinoco_unlock(priv, &flags);
 
@@ -2998,9 +2975,8 @@
 	if (!priv->has_sensitivity)
 		return -EOPNOTSUPP;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	err = hermes_read_wordrec(hw, USER_BAP,
 				  HERMES_RID_CNFSYSTEMSCALE, &val);
 	orinoco_unlock(priv, &flags);
@@ -3018,7 +2994,6 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int val = srq->value;
-	int err;
 	unsigned long flags;
 
 	if (!priv->has_sensitivity)
@@ -3027,9 +3002,8 @@
 	if ((val < 1) || (val > 3))
 		return -EINVAL;
 	
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	priv->ap_density = val;
 	orinoco_unlock(priv, &flags);
 
@@ -3040,7 +3014,6 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int val = rrq->value;
-	int err;
 	unsigned long flags;
 
 	if (rrq->disabled)
@@ -3049,9 +3022,8 @@
 	if ( (val < 0) || (val > 2347) )
 		return -EINVAL;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	priv->rts_thresh = val;
 	orinoco_unlock(priv, &flags);
@@ -3065,9 +3037,8 @@
 	int err = 0;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	if (priv->has_mwo) {
 		if (frq->disabled)
@@ -3102,9 +3073,8 @@
 	u16 val;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	
 	if (priv->has_mwo) {
 		err = hermes_read_wordrec(hw, USER_BAP,
@@ -3166,9 +3136,8 @@
 	if (ratemode == -1)
 		return -EINVAL;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	priv->bitratemode = ratemode;
 	orinoco_unlock(priv, &flags);
 
@@ -3185,9 +3154,8 @@
 	u16 val;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	ratemode = priv->bitratemode;
 
@@ -3247,9 +3215,8 @@
 	int err = 0;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	if (prq->disabled) {
 		priv->pm_on = 0;
@@ -3302,9 +3269,8 @@
 	u16 enable, period, timeout, mcast;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	
 	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFPMENABLED, &enable);
 	if (err)
@@ -3351,9 +3317,8 @@
 	u16 short_limit, long_limit, lifetime;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 	
 	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
 				  &short_limit);
@@ -3399,12 +3364,10 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int val = *( (int *) wrq->u.name );
-	int err;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	priv->ibss_port = val ;
 
@@ -3419,12 +3382,10 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int *val = (int *)wrq->u.name;
-	int err;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	*val = priv->ibss_port;
 	orinoco_unlock(priv, &flags);
@@ -3439,9 +3400,8 @@
 	int err = 0;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	switch (val) {
 	case 0: /* Try to do IEEE ad-hoc mode */
@@ -3478,12 +3438,10 @@
 {
 	struct orinoco_private *priv = netdev_priv(dev);
 	int *val = (int *)wrq->u.name;
-	int err;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	*val = priv->prefer_port3;
 	orinoco_unlock(priv, &flags);
@@ -3513,9 +3471,8 @@
 	}
 
 	/* Make sure nobody mess with the structure while we do */
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	/* orinoco_lock() doesn't disable interrupts, so make sure the
 	 * interrupt rx path don't get confused while we copy */
@@ -3546,12 +3503,10 @@
 	struct iw_quality spy_stat[IW_MAX_SPY];
 	int number;
 	int i;
-	int err;
 	unsigned long flags;
 
-	err = orinoco_lock(priv, &flags);
-	if (err)
-		return err;
+	if (orinoco_lock(priv, &flags) != 0)
+		return -EBUSY;
 
 	number = priv->spy_number;
 	if ((number > 0) && (srq->pointer)) {
@@ -3621,9 +3576,8 @@
 		break;
 
 	case SIOCSIWMODE:
-		err = orinoco_lock(priv, &flags);
-		if (err)
-			return err;
+		if (orinoco_lock(priv, &flags) != 0)
+			return -EBUSY;
 		switch (wrq->u.mode) {
 		case IW_MODE_ADHOC:
 			if (! (priv->has_ibss || priv->has_port3) )
@@ -3648,9 +3602,8 @@
 		break;
 
 	case SIOCGIWMODE:
-		err = orinoco_lock(priv, &flags);
-		if (err)
-			return err;
+		if (orinoco_lock(priv, &flags) != 0)
+			return -EBUSY;
 		wrq->u.mode = priv->iw_mode;
 		orinoco_unlock(priv, &flags);
 		break;
@@ -3865,9 +3818,8 @@
 		if(priv->has_preamble) {
 			int val = *( (int *) wrq->u.name );
 
-			err = orinoco_lock(priv, &flags);
-			if (err)
-				return err;
+			if (orinoco_lock(priv, &flags) != 0)
+				return -EBUSY;
 			if (val)
 				priv->preamble = 1;
 			else
@@ -3882,9 +3834,8 @@
 		if(priv->has_preamble) {
 			int *val = (int *)wrq->u.name;
 
-			err = orinoco_lock(priv, &flags);
-			if (err)
-				return err;
+			if (orinoco_lock(priv, &flags) != 0)
+				return -EBUSY;
 			*val = priv->preamble;
 			orinoco_unlock(priv, &flags);
 		} else
diff -Nru a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
--- a/drivers/net/wireless/wl3501_cs.c	2005-01-10 23:54:12 -05:00
+++ b/drivers/net/wireless/wl3501_cs.c	2005-01-10 23:54:12 -05:00
@@ -100,7 +100,7 @@
 /* Parameters that can be set with 'insmod' */
 /* Bit map of interrupts to choose from */
 /* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
-static unsigned long wl3501_irq_mask = 0xdeb8;
+static unsigned int wl3501_irq_mask = 0xdeb8;
 static int wl3501_irq_list[4] = { -1 };
 
 /*
@@ -2279,7 +2279,7 @@
 module_init(wl3501_init_module);
 module_exit(wl3501_exit_module);
 
-module_param(wl3501_irq_mask, int, 0);
+module_param(wl3501_irq_mask, uint, 0);
 module_param_array(wl3501_irq_list, int, NULL, 0);
 MODULE_AUTHOR("Fox Chen <mhchen@golf.ccl.itri.org.tw>, "
 	      "Arnaldo Carvalho de Melo <acme@conectiva.com.br>,"
diff -Nru a/include/linux/arcdevice.h b/include/linux/arcdevice.h
--- a/include/linux/arcdevice.h	2005-01-10 23:54:12 -05:00
+++ b/include/linux/arcdevice.h	2005-01-10 23:54:12 -05:00
@@ -343,7 +343,6 @@
 
 void arcnet_unregister_proto(struct ArcProto *proto);
 irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-void arcdev_setup(struct net_device *dev);
 struct net_device *alloc_arcdev(char *name);
 void arcnet_rx(struct net_device *dev, int bufnum);
 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [BK PATCHES] 2.6.x net driver updates
@ 2004-11-05  8:22 Jeff Garzik
  0 siblings, 0 replies; 28+ messages in thread
From: Jeff Garzik @ 2004-11-05  8:22 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev


Please do a

	bk pull bk://gkernel.bkbits.net/net-drivers-2.6

This will update the following files:

 include/net/iw_handler.h |    8 ++++----
 net/core/wireless.c      |    9 +++++++--
 2 files changed, 11 insertions(+), 6 deletions(-)

through these ChangeSets:

<jt@bougret.hpl.hp.com> (04/11/05 1.2465)
   [PATCH] Wireless Extension dropped patchlet
   
   	This tiny bit of the last WE-17 patch was lost between me and
   you. I initially decided to wait to resubmit, but Chris Wedgwood
   reported that the MadWifi driver needs it. Sorry for not having pushed
   harder.
   	I recreated this patch, and tested with 2.6.10-rc1, and Chris
   tested it with MadWifi. Would you mind pushing that up to Linus ?
   
   Changelog :
   	o remove unneeded const
   	o spelling + comments
   
   Signed-off-by: Jean Tourrilhes <jt@hpl.hp.com>
   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>

diff -Nru a/include/net/iw_handler.h b/include/net/iw_handler.h
--- a/include/net/iw_handler.h	2004-11-05 03:21:48 -05:00
+++ b/include/net/iw_handler.h	2004-11-05 03:21:48 -05:00
@@ -314,10 +314,10 @@
 {
 	/* Number of handlers defined (more precisely, index of the
 	 * last defined handler + 1) */
-	const __u16		num_standard;
-	const __u16		num_private;
+	__u16			num_standard;
+	__u16			num_private;
 	/* Number of private arg description */
-	const __u16		num_private_args;
+	__u16			num_private_args;
 
 	/* Array of handlers for standard ioctls
 	 * We will call dev->wireless_handlers->standard[ioctl - SIOCSIWNAME]
@@ -335,7 +335,7 @@
 	const struct iw_priv_args *	private_args;
 
 	/* This field will be *removed* in the next version of WE */
-	const long		spy_offset;	/* DO NOT USE */
+	long			spy_offset;	/* DO NOT USE */
 
 	/* New location of get_wireless_stats, to de-bloat struct net_device.
 	 * The old pointer in struct net_device will be gradually phased
diff -Nru a/net/core/wireless.c b/net/core/wireless.c
--- a/net/core/wireless.c	2004-11-05 03:21:48 -05:00
+++ b/net/core/wireless.c	2004-11-05 03:21:48 -05:00
@@ -52,7 +52,8 @@
  * v6 - 18.06.04 - Jean II
  *	o Change get_spydata() method for added safety
  *	o Remove spy #ifdef, they are always on -> cleaner code
- *	o Allow any size GET request is user specifies length > max
+ *	o Allow any size GET request if user specifies length > max
+ *		and if request has IW_DESCR_FLAG_NOMAX flag or is SIOCGIWPRIV
  *	o Start migrating get_wireless_stats to struct iw_handler_def
  *	o Add wmb() in iw_handler_set_spy() for non-coherent archs/cpus
  * Based on patch from Pavel Roskin <proski@gnu.org> :
@@ -690,6 +691,10 @@
 				 * we can support any size GET requests.
 				 * There is still a limit : -ENOMEM. */
 				extra_size = user_length * descr->token_size;
+				/* Note : user_length is originally a __u16,
+				 * and token_size is controlled by us,
+				 * so extra_size won't get negative and
+				 * won't overflow... */
 			}
 		}
 
@@ -1227,7 +1232,7 @@
 
 	/* We want to operate without locking, because wireless_spy_update()
 	 * most likely will happen in the interrupt handler, and therefore
-	 * have it own locking constraints and needs performance.
+	 * have its own locking constraints and needs performance.
 	 * The rtnl_lock() make sure we don't race with the other iw_handlers.
 	 * This make sure wireless_spy_update() "see" that the spy list
 	 * is temporarily disabled. */

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [BK PATCHES] 2.6.x net driver updates
@ 2004-10-30 13:32 Jeff Garzik
  0 siblings, 0 replies; 28+ messages in thread
From: Jeff Garzik @ 2004-10-30 13:32 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev, linux-kernel


Please do a

	bk pull bk://gkernel.bkbits.net/net-drivers-2.6

This will update the following files:

 MAINTAINERS             |    4 
 drivers/net/8390.c      |    2 
 drivers/net/amd8111e.c  |  220 +++++++++++++++++++++++++++---------------------
 drivers/net/amd8111e.h  |    3 
 drivers/net/smc91x.h    |    4 
 drivers/net/via-rhine.c |    2 
 6 files changed, 132 insertions(+), 103 deletions(-)

through these ChangeSets:

<rddunlap@osdl.org> (04/10/30 1.2350)
   [PATCH] via-rhine: references __init code during resume
   
   Fix __init section usage:
   rhine_resume calls enable_mmio, so latter cannot be __devinit;
   Error: ./drivers/net/via-rhine.o .text refers to 0000000000000925 R_X86_64_PC32
   .init.text+0xfffffffffffffffc
   
   Signed-off-by: Randy Dunlap <rddunlap@osdl.org>
   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>

<benh@kernel.crashing.org> (04/10/30 1.2349)
   [PATCH] amd8111e: Add support for ppc64 eval board
   
   This patch adds a few memory barriers, cleans up a little bit the
   use of the "status" field in the rx & tx routines, and adds probing
   for the external PHY to the driver.
   
   Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>

<benh@kernel.crashing.org> (04/10/30 1.2348)
   [PATCH] amd8111e: Fix identation of amd8111e_rx_poll()
   
   This patch does an indentation fix to amd8111e_rx_poll() which was
   incorrectly shifting left in the middle of a while() loop, thus
   rendering the function difficult to read. There is no actual code
   change.
   
   Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>

<sfeldma@pobox.com> (04/10/30 1.2347)
   [PATCH] e100: update maintainer
   
   My intel.com address will bounce.
   
   Signed-off-by: Scott Feldman <sfeldma@pobox.com>
   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>

<nico@cam.org> (04/10/30 1.2346)
   [PATCH] fix smc91x compilation error
   
   It looks like this bit got mismerged (pci.h removed but DMA arguments
   convertion missing).
   
   Signed-off-by: Nicolas Pitre <nico@cam.org>
   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>

<rmk+lkml@arm.linux.org.uk> (04/10/30 1.2345)
   [PATCH] 8390.c: Use mdelay(10) rather than udelay(10*1000)
   
   ARM udelay can't cope with >2ms delays.
   
   Signed-off-by: Russell King <rmk@arm.linux.org.uk>
   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>

diff -Nru a/MAINTAINERS b/MAINTAINERS
--- a/MAINTAINERS	2004-10-30 09:31:01 -04:00
+++ b/MAINTAINERS	2004-10-30 09:31:01 -04:00
@@ -1110,8 +1110,8 @@
 M:	john.ronciak@intel.com
 P:	Ganesh Venkatesan
 M:	ganesh.venkatesan@intel.com
-P:	Scott Feldman
-M:	scott.feldman@intel.com
+P:	Jesse Brandeburg
+M:	jesse.brandeburg@intel.com
 W:	http://sourceforge.net/projects/e1000/
 S:	Supported
 
diff -Nru a/drivers/net/8390.c b/drivers/net/8390.c
--- a/drivers/net/8390.c	2004-10-30 09:31:01 -04:00
+++ b/drivers/net/8390.c	2004-10-30 09:31:01 -04:00
@@ -813,7 +813,7 @@
 	 * We wait at least 10ms.
 	 */
 
-	udelay(10*1000);
+	mdelay(10);
 
 	/*
 	 * Reset RBCR[01] back to zero as per magic incantation.
diff -Nru a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
--- a/drivers/net/amd8111e.c	2004-10-30 09:31:01 -04:00
+++ b/drivers/net/amd8111e.c	2004-10-30 09:31:01 -04:00
@@ -211,7 +211,7 @@
 	u32 bmcr,advert,tmp;
 	
 	/* Determine mii register values to set the speed */
-	advert = amd8111e_mdio_read(dev, PHY_ID, MII_ADVERTISE);
+	advert = amd8111e_mdio_read(dev, lp->ext_phy_addr, MII_ADVERTISE);
 	tmp = advert & ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
 	switch (lp->ext_phy_option){
 
@@ -235,11 +235,11 @@
 	}
 
 	if(advert != tmp)
-		amd8111e_mdio_write(dev, PHY_ID, MII_ADVERTISE, tmp);
+		amd8111e_mdio_write(dev, lp->ext_phy_addr, MII_ADVERTISE, tmp);
 	/* Restart auto negotiation */
-	bmcr = amd8111e_mdio_read(dev, PHY_ID, MII_BMCR);
+	bmcr = amd8111e_mdio_read(dev, lp->ext_phy_addr, MII_BMCR);
 	bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART);
-	amd8111e_mdio_write(dev, PHY_ID, MII_BMCR, bmcr);
+	amd8111e_mdio_write(dev, lp->ext_phy_addr, MII_BMCR, bmcr);
 
 }
 
@@ -350,6 +350,7 @@
 
 		lp->rx_ring[i].buff_phy_addr = cpu_to_le32(lp->rx_dma_addr[i]);
 		lp->rx_ring[i].buff_count = cpu_to_le16(lp->rx_buff_len-2);
+		wmb();
 		lp->rx_ring[i].rx_flags = cpu_to_le16(OWN_BIT);
 	}
 
@@ -529,7 +530,7 @@
 	writel(RUN, mmio + CMD0);
 
 	/* AUTOPOLL0 Register *//*TBD default value is 8100 in FPS */
-	writew( 0x8101, mmio + AUTOPOLL0);
+	writew( 0x8100 | lp->ext_phy_addr, mmio + AUTOPOLL0);
 
 	/* Clear RCV_RING_BASE_ADDR */
 	writel(0, mmio + RCV_RING_BASE_ADDR0);
@@ -740,11 +741,11 @@
 	do{   
 		/* process receive packets until we use the quota*/
 		/* If we own the next entry, it's a new packet. Send it up. */
-		while(!(lp->rx_ring[rx_index].rx_flags & OWN_BIT)){
-	       
-			/* check if err summary bit is set */ 
-			if(le16_to_cpu(lp->rx_ring[rx_index].rx_flags) 
-								& ERR_BIT){
+		while(1) {
+			status = le16_to_cpu(lp->rx_ring[rx_index].rx_flags);
+			if (status & OWN_BIT)
+				break;
+
 			/* 
 			 * There is a tricky error noted by John Murphy,
 			 * <murf@perftech.com> to Russ Nelson: Even with
@@ -753,89 +754,88 @@
 			 * the last correctly noting the error.
 			 */
 
-			/* reseting flags */
-			lp->rx_ring[rx_index].rx_flags &=RESET_RX_FLAGS;
-			goto err_next_pkt;
-
+			if(status & ERR_BIT) {
+				/* reseting flags */
+				lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS;
+				goto err_next_pkt;
 			}
 			/* check for STP and ENP */
-		status = le16_to_cpu(lp->rx_ring[rx_index].rx_flags);
-		if(!((status & STP_BIT) && (status & ENP_BIT))){
-			/* reseting flags */
-			lp->rx_ring[rx_index].rx_flags &=RESET_RX_FLAGS;
-			goto err_next_pkt;
-		}
-		pkt_len = le16_to_cpu(lp->rx_ring[rx_index].msg_count) - 4;
+			if(!((status & STP_BIT) && (status & ENP_BIT))){
+				/* reseting flags */
+				lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS;
+				goto err_next_pkt;
+			}
+			pkt_len = le16_to_cpu(lp->rx_ring[rx_index].msg_count) - 4;
 
 #if AMD8111E_VLAN_TAG_USED		
-		vtag = le16_to_cpu(lp->rx_ring[rx_index].rx_flags) & TT_MASK;
-		/*MAC will strip vlan tag*/ 
-		if(lp->vlgrp != NULL && vtag !=0)
-			min_pkt_len =MIN_PKT_LEN - 4;
-		else
+			vtag = status & TT_MASK;
+			/*MAC will strip vlan tag*/ 
+			if(lp->vlgrp != NULL && vtag !=0)
+				min_pkt_len =MIN_PKT_LEN - 4;
+			else
 #endif
-			min_pkt_len =MIN_PKT_LEN;
+				min_pkt_len =MIN_PKT_LEN;
 
-		if (pkt_len < min_pkt_len) {
-			lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS;
-			lp->drv_rx_errors++;
-			goto err_next_pkt;
-		}
-		if(--rx_pkt_limit < 0)
-			goto rx_not_empty;
-		if(!(new_skb = dev_alloc_skb(lp->rx_buff_len))){
-			/* if allocation fail, 
-				ignore that pkt and go to next one */
-			lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS;
-			lp->drv_rx_errors++;
-			goto err_next_pkt;
-		}
+			if (pkt_len < min_pkt_len) {
+				lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS;
+				lp->drv_rx_errors++;
+				goto err_next_pkt;
+			}
+			if(--rx_pkt_limit < 0)
+				goto rx_not_empty;
+			if(!(new_skb = dev_alloc_skb(lp->rx_buff_len))){
+				/* if allocation fail, 
+				   ignore that pkt and go to next one */
+				lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS;
+				lp->drv_rx_errors++;
+				goto err_next_pkt;
+			}
 		
-		skb_reserve(new_skb, 2);
-		skb = lp->rx_skbuff[rx_index];
-		pci_unmap_single(lp->pci_dev,lp->rx_dma_addr[rx_index],
-			lp->rx_buff_len-2, PCI_DMA_FROMDEVICE);
-		skb_put(skb, pkt_len);
-		skb->dev = dev;
-		lp->rx_skbuff[rx_index] = new_skb;
-		new_skb->dev = dev;
-		lp->rx_dma_addr[rx_index] = pci_map_single(lp->pci_dev,
-			new_skb->data, lp->rx_buff_len-2,PCI_DMA_FROMDEVICE);
+			skb_reserve(new_skb, 2);
+			skb = lp->rx_skbuff[rx_index];
+			pci_unmap_single(lp->pci_dev,lp->rx_dma_addr[rx_index],
+					 lp->rx_buff_len-2, PCI_DMA_FROMDEVICE);
+			skb_put(skb, pkt_len);
+			skb->dev = dev;
+			lp->rx_skbuff[rx_index] = new_skb;
+			new_skb->dev = dev;
+			lp->rx_dma_addr[rx_index] = pci_map_single(lp->pci_dev,
+								   new_skb->data,
+								   lp->rx_buff_len-2,
+								   PCI_DMA_FROMDEVICE);
 	
-		skb->protocol = eth_type_trans(skb, dev);
+			skb->protocol = eth_type_trans(skb, dev);
 
 #if AMD8111E_VLAN_TAG_USED		
-		
-		vtag = lp->rx_ring[rx_index].rx_flags & TT_MASK;
-		if(lp->vlgrp != NULL && (vtag == TT_VLAN_TAGGED)){
-			amd8111e_vlan_rx(lp, skb,
-				    lp->rx_ring[rx_index].tag_ctrl_info);
-		} else
+			if(lp->vlgrp != NULL && (vtag == TT_VLAN_TAGGED)){
+				amd8111e_vlan_rx(lp, skb,
+					 le16_to_cpy(lp->rx_ring[rx_index].tag_ctrl_info));
+			} else
 #endif
-			
-			netif_receive_skb(skb);
-		/*COAL update rx coalescing parameters*/
-		lp->coal_conf.rx_packets++;
-		lp->coal_conf.rx_bytes += pkt_len;	
-		num_rx_pkt++;
-		dev->last_rx = jiffies;
+				netif_receive_skb(skb);
+			/*COAL update rx coalescing parameters*/
+			lp->coal_conf.rx_packets++;
+			lp->coal_conf.rx_bytes += pkt_len;	
+			num_rx_pkt++;
+			dev->last_rx = jiffies;
 	
-err_next_pkt:	
-		lp->rx_ring[rx_index].buff_phy_addr
-			 = cpu_to_le32(lp->rx_dma_addr[rx_index]);
-		lp->rx_ring[rx_index].buff_count = 
+		err_next_pkt:	
+			lp->rx_ring[rx_index].buff_phy_addr
+				= cpu_to_le32(lp->rx_dma_addr[rx_index]);
+			lp->rx_ring[rx_index].buff_count = 
 				cpu_to_le16(lp->rx_buff_len-2);
-		lp->rx_ring[rx_index].rx_flags |= cpu_to_le16(OWN_BIT);
-		rx_index = (++lp->rx_idx) & RX_RING_DR_MOD_MASK;
-	}
-	/* Check the interrupt status register for more packets in the 
-	mean time. Process them since we have not used up our quota.*/
+			wmb();
+			lp->rx_ring[rx_index].rx_flags |= cpu_to_le16(OWN_BIT);
+			rx_index = (++lp->rx_idx) & RX_RING_DR_MOD_MASK;
+		}
+		/* Check the interrupt status register for more packets in the 
+		   mean time. Process them since we have not used up our quota.*/
+
+		intr0 = readl(mmio + INT0);
+		/*Ack receive packets */
+		writel(intr0 & RINT0,mmio + INT0);
 
-	intr0 = readl(mmio + INT0);
-	/*Ack receive packets */
-	writel(intr0 & RINT0,mmio + INT0);
-
-	}while(intr0 & RINT0);
+	} while(intr0 & RINT0);
 
 	/* Receive descriptor is empty now */
 	dev->quota -= num_rx_pkt;
@@ -873,11 +873,12 @@
 	
 	/* If we own the next entry, it's a new packet. Send it up. */
 	while(++num_rx_pkt <= max_rx_pkt){
-		if(lp->rx_ring[rx_index].rx_flags & OWN_BIT)
+		status = le16_to_cpu(lp->rx_ring[rx_index].rx_flags);
+		if(status & OWN_BIT)
 			return 0;
 	       
 		/* check if err summary bit is set */ 
-		if(le16_to_cpu(lp->rx_ring[rx_index].rx_flags) & ERR_BIT){
+		if(status & ERR_BIT){
 			/* 
 			 * There is a tricky error noted by John Murphy,
 			 * <murf@perftech.com> to Russ Nelson: Even with full-sized
@@ -888,7 +889,6 @@
 			goto err_next_pkt;
 		}
 		/* check for STP and ENP */
-		status = le16_to_cpu(lp->rx_ring[rx_index].rx_flags);
 		if(!((status & STP_BIT) && (status & ENP_BIT))){
 			/* reseting flags */
 			lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS;
@@ -897,7 +897,7 @@
 		pkt_len = le16_to_cpu(lp->rx_ring[rx_index].msg_count) - 4;
 
 #if AMD8111E_VLAN_TAG_USED		
-		vtag = le16_to_cpu(lp->rx_ring[rx_index].rx_flags) & TT_MASK;
+		vtag = status & TT_MASK;
 		/*MAC will strip vlan tag*/ 
 		if(lp->vlgrp != NULL && vtag !=0)
 			min_pkt_len =MIN_PKT_LEN - 4;
@@ -931,12 +931,10 @@
 	
 		skb->protocol = eth_type_trans(skb, dev);
 
-#if AMD8111E_VLAN_TAG_USED		
-		
-		vtag = lp->rx_ring[rx_index].rx_flags & TT_MASK;
+#if AMD8111E_VLAN_TAG_USED				
 		if(lp->vlgrp != NULL && (vtag == TT_VLAN_TAGGED)){
 			amd8111e_vlan_rx(lp, skb,
-				    lp->rx_ring[rx_index].tag_ctrl_info);
+				 le16_to_cpu(lp->rx_ring[rx_index].tag_ctrl_info));
 		} else
 #endif
 			
@@ -952,6 +950,7 @@
 			 = cpu_to_le32(lp->rx_dma_addr[rx_index]);
 		lp->rx_ring[rx_index].buff_count = 
 				cpu_to_le16(lp->rx_buff_len-2);
+		wmb();
 		lp->rx_ring[rx_index].rx_flags |= cpu_to_le16(OWN_BIT);
 		rx_index = (++lp->rx_idx) & RX_RING_DR_MOD_MASK;
 	}
@@ -1432,7 +1431,7 @@
 #if AMD8111E_VLAN_TAG_USED
 	if((lp->vlgrp != NULL) && vlan_tx_tag_present(skb)){
 		lp->tx_ring[tx_index].tag_ctrl_cmd |= 
-				cpu_to_le32(TCC_VLAN_INSERT);	
+				cpu_to_le16(TCC_VLAN_INSERT);	
 		lp->tx_ring[tx_index].tag_ctrl_info = 
 				cpu_to_le16(vlan_tx_tag_get(skb));
 
@@ -1444,6 +1443,7 @@
 	    (u32) cpu_to_le32(lp->tx_dma_addr[tx_index]);
 
 	/*  Set FCS and LTINT bits */
+	wmb();
 	lp->tx_ring[tx_index].tx_flags |=
 	    cpu_to_le16(OWN_BIT | STP_BIT | ENP_BIT|ADD_FCS_BIT|LTINT_BIT);
 
@@ -1667,7 +1667,7 @@
 
 	switch(cmd) {
 	case SIOCGMIIPHY:
-		data->phy_id = PHY_ID;
+		data->phy_id = lp->ext_phy_addr;
 
 	/* fallthru */
 	case SIOCGMIIREG: 
@@ -1940,6 +1940,26 @@
 
 }
 
+static void __devinit amd8111e_probe_ext_phy(struct net_device* dev)
+{
+	struct amd8111e_priv *lp = netdev_priv(dev);
+	int i;
+
+	for (i = 0x1e; i >= 0; i--) {
+		u32 id1, id2;
+
+		if (amd8111e_read_phy(lp, i, MII_PHYSID1, &id1))
+			continue;
+		if (amd8111e_read_phy(lp, i, MII_PHYSID2, &id2))
+			continue;
+		lp->ext_phy_id = (id1 << 16) | id2;
+		lp->ext_phy_addr = i;
+		return;
+	}
+	lp->ext_phy_id = 0;
+	lp->ext_phy_addr = 1;
+}
+
 static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
 				  const struct pci_device_id *ent)
 {
@@ -2010,12 +2030,6 @@
 	lp->amd8111e_net_dev = dev;
 	lp->pm_cap = pm_cap;
 
-	/* setting mii default values */
-	lp->mii_if.dev = dev;
-	lp->mii_if.mdio_read = amd8111e_mdio_read;
-	lp->mii_if.mdio_write = amd8111e_mdio_write;
-	lp->mii_if.phy_id = PHY_ID;
-
 	spin_lock_init(&lp->lock);
 
 	lp->mmio = ioremap(reg_addr, reg_len);
@@ -2063,7 +2077,15 @@
 	dev->vlan_rx_register =amd8111e_vlan_rx_register;
 	dev->vlan_rx_kill_vid = amd8111e_vlan_rx_kill_vid;
 #endif	
-	
+	/* Probe the external PHY */
+	amd8111e_probe_ext_phy(dev);
+
+	/* setting mii default values */
+	lp->mii_if.dev = dev;
+	lp->mii_if.mdio_read = amd8111e_mdio_read;
+	lp->mii_if.mdio_write = amd8111e_mdio_write;
+	lp->mii_if.phy_id = lp->ext_phy_addr;
+
 	/* Set receive buffer length and set jumbo option*/
 	amd8111e_set_rx_buff_len(dev);
 
@@ -2096,6 +2118,12 @@
     	for (i = 0; i < 6; i++)
 		printk("%2.2x%c",dev->dev_addr[i],i == 5 ? ' ' : ':');
     	printk( "\n");	
+	if (lp->ext_phy_id)
+		printk(KERN_INFO "%s: Found MII PHY ID 0x%08x at address 0x%02x\n",
+		       dev->name, lp->ext_phy_id, lp->ext_phy_addr);
+	else
+		printk(KERN_INFO "%s: Couldn't detect MII PHY, assuming address 0x01\n",
+		       dev->name);
     	return 0;
 err_iounmap:
 	iounmap(lp->mmio);
diff -Nru a/drivers/net/amd8111e.h b/drivers/net/amd8111e.h
--- a/drivers/net/amd8111e.h	2004-10-30 09:31:01 -04:00
+++ b/drivers/net/amd8111e.h	2004-10-30 09:31:01 -04:00
@@ -649,7 +649,6 @@
 #define TCC_MASK		0x0003
 
 /* driver ioctl parameters */
-#define PHY_ID 			0x01	/* currently it is fixed */
 #define AMD8111E_REG_DUMP_LEN	 13*sizeof(u32) 
 
 /* crc generator constants */
@@ -777,6 +776,8 @@
 	int options;		/* Options enabled/disabled for the device */
 
 	unsigned long ext_phy_option;
+	int ext_phy_addr;
+	u32 ext_phy_id;
 	
 	struct amd8111e_link_config link_config;
 	int pm_cap;
diff -Nru a/drivers/net/smc91x.h b/drivers/net/smc91x.h
--- a/drivers/net/smc91x.h	2004-10-30 09:31:01 -04:00
+++ b/drivers/net/smc91x.h	2004-10-30 09:31:01 -04:00
@@ -245,7 +245,7 @@
 	while (!(DCSR(dma) & DCSR_STOPSTATE))
 		cpu_relax();
 	DCSR(dma) = 0;
-	dma_unmap_single(NULL, dmabuf, len, PCI_DMA_FROMDEVICE);
+	dma_unmap_single(NULL, dmabuf, len, DMA_FROM_DEVICE);
 }
 #endif
 
@@ -273,7 +273,7 @@
 	}
 
 	len *= 2;
-	dmabuf = dma_map_single(NULL, buf, len, PCI_DMA_FROMDEVICE);
+	dmabuf = dma_map_single(NULL, buf, len, DMA_FROM_DEVICE);
 	DCSR(dma) = DCSR_NODESC;
 	DTADR(dma) = dmabuf;
 	DSADR(dma) = physaddr + reg;
diff -Nru a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
--- a/drivers/net/via-rhine.c	2004-10-30 09:31:01 -04:00
+++ b/drivers/net/via-rhine.c	2004-10-30 09:31:01 -04:00
@@ -627,7 +627,7 @@
 }
 
 #ifdef USE_MMIO
-static void __devinit enable_mmio(long pioaddr, u32 quirks)
+static void enable_mmio(long pioaddr, u32 quirks)
 {
 	int n;
 	if (quirks & rqRhineI) {

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [BK PATCHES] 2.6.x net driver updates
@ 2004-10-26  5:37 Jeff Garzik
  0 siblings, 0 replies; 28+ messages in thread
From: Jeff Garzik @ 2004-10-26  5:37 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev


Still pushing pending stuff... this time, the "e1000", "janitor", and "misc" piles.

Please do a

	bk pull bk://gkernel.bkbits.net/net-drivers-2.6

This will update the following files:

 Documentation/networking/e100.txt  |  137 +++++++++++++++++++++--
 Documentation/networking/e1000.txt |  218 ++++++++++++++++++++++++++-----------
 Documentation/networking/ixgb.txt  |   36 ++----
 drivers/net/3c59x.c                |    2 
 drivers/net/Kconfig                |  120 +++-----------------
 drivers/net/dummy.c                |    4 
 drivers/net/e1000/e1000.h          |    2 
 drivers/net/e1000/e1000_ethtool.c  |   13 +-
 drivers/net/e1000/e1000_hw.c       |  128 ++++++++++++++++++---
 drivers/net/e1000/e1000_main.c     |   43 ++-----
 drivers/net/e1000/e1000_osdep.h    |    6 +
 drivers/net/e1000/e1000_param.c    |  167 +++++++++++++++++-----------
 drivers/net/eql.c                  |   26 ++--
 drivers/net/hamradio/hdlcdrv.c     |    2 
 drivers/net/ixgb/ixgb_main.c       |   10 +
 drivers/net/mac8390.c              |    4 
 drivers/net/ne2k-pci.c             |   31 +++++
 drivers/net/ns83820.c              |  121 ++++++++++++++++++--
 drivers/net/pcnet32.c              |    6 -
 drivers/net/sis900.c               |   18 +--
 drivers/net/skfp/hwmtm.c           |    3 
 drivers/net/slip.c                 |   39 +++---
 drivers/net/tokenring/olympic.c    |    1 
 drivers/net/tulip/de2104x.c        |    3 
 drivers/net/tulip/de4x5.c          |    2 
 drivers/net/tulip/tulip_core.c     |   21 ++-
 drivers/net/tulip/xircom_cb.c      |   14 ++
 include/linux/netdevice.h          |    2 
 net/Kconfig                        |   18 ---
 net/core/dev.c                     |   93 ---------------
 net/irda/irlan/irlan_client.c      |    2 
 31 files changed, 791 insertions(+), 501 deletions(-)

through these ChangeSets:

<arjan:infradead.org>:
  o remove NET_HW_FLOWCONTROL

<pekon:fi.muni.cz>:
  o netpoll with xircom_cb

<sfeldma:pobox.com>:
  o janitor: net/tulip: pci_find_device to pci_dev_present
  o janitor: net/sis900: pci_find_device to pci_get_device

Adrian Bunk:
  o net/tokenring/olympic.c: remove unused variable

Andrew Morton:
  o e1000 module_param build fix
  o ne2k-pci pci build fix
  o e1000 sparc64 dma_mapping build fix
  o igxb speedup
  o de4x5 warning fix

François Romieu:
  o via-velocity: wrong module name in Kconfig documentation

Ganesh Venkatesan:
  o ixgb: Configuration and user guide update
  o e100: Configuration and user guide update
  o e1000: Configuration and user guide update
  o e1000: white space corrections
  o e1000: driver version update
  o e1000: fix set ringparam for ethtool returning error code on bad input
  o e1000: remove unused function e1000_enable_mng_pass_thru
  o e1000:  modified ethtool_set_pauseparam to use e1000_setup_link for flow control settings for fiber serdes link
  o e1000 update -- fix MODULE_PARM, module_param, module_param_array
  o e1000 - Ethtool -- 82545 do not support WoL
  o e1000 - Polarity reversal workaround for 10F/10H links
  o e1000 - Fix VLAN filter setup errors (while running on PPC)
  o e1000 Check value returned by from pci_enable_device
  o e1000 - Removed support for advanced TCO features
  o e1000 - use pci_device_name for syslog messages till registering netdevice.

Jeff Garzik:
  o Cset exclude: elf@buici.com|ChangeSet|20040920183610|08290

Jesse Brandeburg:
  o ixgb: fix endianness issue for tx cleanup

John W. Linville:
  o 3c59x: style change in vortex_ethtool_ops declaration

Kenji Kaneshige:
  o add missing pci_disable_device for e1000

Marc Singer:
  o adding smc91x ethernet to lpd7a40x

Mika Kukkonen:
  o sparse: fix warnings in net/irda/*

Neil Horman:
  o ns83820: add vlan tag hardware acceleration support

Nishanth Aravamudan:
  o net/de2104x: replace schedule_timeout() with msleep()

Olaf Hering:
  o remove old version check from mac8390

Pavel Machek:
  o swsuspend for ne2k-pci cards

Ralf Bächle:
  o Stop queue on close in hdlcdrv

Randy Dunlap:
  o skfp: remove assignment expression in conditional (sparse)(v2)
  o pcnet32: use unsigned 1-bit fields

Stephen Hemminger:
  o slip: use netdev_priv
  o slip: use module_param
  o dummy: use netdev_priv
  o eql: use netdev_priv
  o ns83820: use module_param

diff -Nru a/Documentation/networking/e100.txt b/Documentation/networking/e100.txt
--- a/Documentation/networking/e100.txt	2004-10-26 01:30:56 -04:00
+++ b/Documentation/networking/e100.txt	2004-10-26 01:30:56 -04:00
@@ -1,14 +1,16 @@
 Linux* Base Driver for the Intel(R) PRO/100 Family of Adapters
 ==============================================================
 
-March 15, 2004
+September 13, 2004
 
 
 Contents
 ========
 
 - In This Release
-- Supported Adapters
+- Identifying Your Adapter
+- Driver Configuration Parameters
+- Additional Configurations
 - Support
 
 
@@ -16,26 +18,140 @@
 ===============
 
 This file describes the Linux* Base Driver for the Intel(R) PRO/100 Family of
-Adapters, version 3.x.x.  This driver includes support for Itanium(TM)-based 
-systems.
+Adapters, version 3.2.x.  This driver includes support for Itanium(TM)2 and
+EM64T systems.
 
 
-Supported Adapters
-==================
-
-To verify that your adapter is supported, find the board ID number on the 
-adapter. Look for a label that has a barcode and a number in the format 
-A12345-001. Match this to the list of numbers above.
+Identifying Your Adapter
+========================
 
 For more information on how to identify your adapter, go to the Adapter & 
 Driver ID Guide at:
 
   http://support.intel.com/support/network/adapter/pro100/21397.htm
 
-For the latest Intel PRO/100 network driver for Linux, see:
+For the latest Intel network drivers for Linux, refer to the following 
+website. In the search field, enter your adapter name or type, or use the 
+networking link on the left to search for your adapter:
 
   http://downloadfinder.intel.com/scripts-df/support_intel.asp
 
+Driver Configuration Parameters
+===============================
+
+The default value for each parameter is generally the recommended setting,
+unless otherwise noted.
+
+Rx Descriptors: Number of receive descriptors. A receive descriptor is a data 
+   structure that describes a receive buffer and its attributes to the network 
+   controller. The data in the descriptor is used by the controller to write 
+   data from the controller to host memory. In the 3.0.x driver the valid
+   range for this parameter is 64-256. The default value is 64. This parameter 
+   can be changed using the command 
+ 
+   ethtool -G eth? rx n, where n is the number of desired rx descriptors.
+
+Tx Descriptors: Number of transmit descriptors. A transmit descriptor is a
+   data structure that describes a transmit buffer and its attributes to the
+   network controller. The data in the descriptor is used by the controller to 
+   read data from the host memory to the controller. In the 3.0.x driver the 
+   valid range for this parameter is 64-256. The default value is 64. This 
+   parameter can be changed using the command 
+
+   ethtool -G eth? tx n, where n is the number of desired tx descriptors.
+
+Speed/Duplex: The driver auto-negotiates the link speed and duplex settings by 
+   default. Ethtool can be used as follows to force speed/duplex. 
+
+   ethtool -s eth?  autoneg off speed {10|100} duplex {full|half}
+
+   NOTE: setting the speed/duplex to incorrect values will cause the link to
+   fail.
+
+Event Log Message Level:  The driver uses the message level flag to log events 
+   to syslog. The message level can be set at driver load time. It can also be 
+   set using the command
+
+   ethtool -s eth? msglvl n
+
+Additional Configurations
+=========================
+
+  Configuring the Driver on Different Distributions
+  -------------------------------------------------
+
+  Configuring a network driver to load properly when the system is started is 
+  distribution dependent. Typically, the configuration process involves adding 
+  an alias line to /etc/modules.conf as well as editing other system startup 
+  scripts and/or configuration files.  Many popular Linux distributions ship 
+  with tools to make these changes for you. To learn the proper way to 
+  configure a network device for your system, refer to your distribution 
+  documentation. If during this process you are asked for the driver or module 
+  name, the name for the Linux Base Driver for the Intel PRO/100 Family of 
+  Adapters is e100.
+
+  As an example, if you install the e100 driver for two PRO/100 adapters 
+  (eth0 and eth1), add the following to modules.conf:
+
+       alias eth0 e100
+       alias eth1 e100
+
+  Viewing Link Messages
+  ---------------------
+  In order to see link messages and other Intel driver information on your 
+  console, you must set the dmesg level up to six. This can be done by 
+  entering the following on the command line before loading the e100 driver: 
+
+       dmesg -n 8
+
+  If you wish to see all messages issued by the driver, including debug 
+  messages, set the dmesg level to eight.
+
+  NOTE: This setting is not saved across reboots.
+
+  Ethtool
+  -------
+
+  The driver utilizes the ethtool interface for driver configuration and
+  diagnostics, as well as displaying statistical information.  Ethtool
+  version 1.6 or later is required for this functionality.
+
+  The latest release of ethtool can be found at:
+  http://sf.net/projects/gkernel.  
+
+  After ethtool is installed, ethtool-copy.h must be copied and renamed to
+  ethtool.h in your kernel source tree at <linux_kernel_src>/include/linux.  
+  Backup the original ethtool.h as needed before copying.  The driver then 
+  must be recompiled in order to take advantage of the latest ethtool 
+  features.
+
+  NOTE: This driver uses mii support from the kernel. As a result, when 
+  there is no link, ethtool will report speed/duplex to be 10/half.
+
+  NOTE: Ethtool 1.6 only supports a limited set of ethtool options. Support 
+  for a more complete ethtool feature set can be enabled by upgrading 
+  ethtool to ethtool-1.8.1. 
+
+  Enabling Wake on LAN* (WoL)
+  ---------------------------
+  WoL is provided through the Ethtool* utility. Ethtool is included with Red 
+  Hat* 8.0. For other Linux distributions, download and install Ethtool from 
+  the following website: http://sourceforge.net/projects/gkernel. 
+
+  For instructions on enabling WoL with Ethtool, refer to the Ethtool man
+  page.
+
+  WoL will be enabled on the system during the next shut down or reboot. For
+  this driver version, in order to enable WoL, the e100 driver must be 
+  loaded when shutting down or rebooting the system.
+
+  NAPI
+  ----
+
+  NAPI (Rx polling mode) is supported in the e100 driver. NAPI is enabled
+  or disabled based on the configuration of the kernel. 
+
+  See www.cyberus.ca/~hadi/usenix-paper.tgz for more information on NAPI.
 
 Support
 =======
diff -Nru a/Documentation/networking/e1000.txt b/Documentation/networking/e1000.txt
--- a/Documentation/networking/e1000.txt	2004-10-26 01:30:56 -04:00
+++ b/Documentation/networking/e1000.txt	2004-10-26 01:30:56 -04:00
@@ -1,14 +1,14 @@
 Linux* Base Driver for the Intel(R) PRO/1000 Family of Adapters
 ===============================================================
 
-January 8, 2003
+September 13, 2004
 
 
 Contents
 ========
 
 - In This Release
-- Supported Adapters
+- Identifying Your Adapter
 - Command Line Parameters
 - Speed and Duplex Configuration
 - Additional Configurations
@@ -20,63 +20,29 @@
 ===============
 
 This file describes the Linux* Base Driver for the Intel(R) PRO/1000 Family
-of Adapters, version 5.0.x.  This driver includes support for 
-Itanium(TM)-based systems.
+of Adapters, version 5.x.x.  This driver includes support for Itanium(TM)2 
+and EM64T systems.
 
+For questions related to hardware requirements, refer to the documentation 
+supplied with your Intel PRO/1000 adapter. All hardware requirements listed 
+apply to use with Linux.
 
 Native VLANs are now available with supported kernels.
 
-
-Supported Adapters
-==================
-
-The following Intel network adapters are compatible with the drivers in this 
-release:
-
-   Controller  Adapter Name                         Board IDs
-   ----------  ------------                         ---------
-
-   82542       PRO/1000 Gigabit Server Adapter      700262-xxx, 717037-xxx
-
-   82543       PRO/1000 F Server Adapter            738640-xxx, A38888-xxx
-
-   82543       PRO/1000 T Server Adapter            A19845-xxx, A33948-xxx
-
-   82544       PRO/1000 XT Server Adapter           A51580-xxx
-
-   82544       PRO/1000 XF Server Adapter           A50484-xxx
-
-   82544       PRO/1000 T Desktop Adapter           A62947-xxx
-
-   82540       PRO/1000 MT Desktop Adapter          A78408-xxx
-   82541                                            C91016-xxx
-
-   82545       PRO/1000 MT Server Adapter           A92165-xxx
-
-   82546       PRO/1000 MT Dual Port Server Adapter A92111-xxx
-
-   82545       PRO/1000 MF Server Adapter           A91622-xxx
-
-   82545       PRO/1000 MF Server Adapter(LX)       A91624-xxx
-
-   82546       PRO/1000 MF Dual Port Server Adapter A91620-xxx
-
-
-
-To verify your Intel adapter is supported, find the board ID number on the 
-adapter. Look for a label that has a barcode and a number in the format  
-A12345-001. Match this to the list of numbers above.
+Identifying Your Adapter
+========================
 
 For more information on how to identify your adapter, go to the Adapter & 
 Driver ID Guide at:
 
     http://support.intel.com/support/network/adapter/pro100/21397.htm
 
-For the latest Intel network drivers for Linux, refer to the following
+For the latest Intel network drivers for Linux, refer to the following 
+website. In the search field, enter your adapter name or type, or use the 
+networking link on the left to search for your adapter:
 
     http://downloadfinder.intel.com/scripts-df/support_intel.asp
 
-
 Command Line Parameters
 =======================
 
@@ -92,27 +58,39 @@
 
      insmod e1000 TxDescriptors=80,128
 
-loads the e1000 driver with 80 TX resources for the first adapter and 128 TX 
-resources for the second adapter.
+loads the e1000 driver with 80 TX descriptors for the first adapter and 128 TX 
+descriptors for the second adapter.
 
 The default value for each parameter is generally the recommended setting,
-unless otherwise noted.
-
-For more information about the AutoNeg, Duplex, and Speed parameters, see the
-"Speed and Duplex Configuration" section in this document.
+unless otherwise noted. Also, if the driver is statically built into the
+kernel, the driver is loaded with the default values for all the parameters.
+Ethtool can be used to change some of the parameters at runtime.
+
+    NOTES: For more information about the AutoNeg, Duplex, and Speed
+           parameters, see the "Speed and Duplex Configuration" section in 
+           this document.
+
+           For more information about the InterruptThrottleRate, RxIntDelay, 
+           TxIntDelay, RxAbsIntDelay, and TxAbsIntDelay parameters, see the 
+           application note at:
+           http://www.intel.com/design/network/applnots/ap450.htm
 
+           A descriptor describes a data buffer and attributes related to the 
+           data buffer. This information is accessed by the hardware.
 
 AutoNeg (adapters using copper connections only)
 Valid Range: 0x01-0x0F, 0x20-0x2F
 Default Value: 0x2F
     This parameter is a bit mask that specifies which speed and duplex
     settings the board advertises. When this parameter is used, the Speed and
-    Duplex parameters must not be specified.  
+    Duplex parameters must not be specified.
+    NOTE: Refer to the Speed and Duplex section of this readme for more 
+          information on the AutoNeg parameter.  
 
 Duplex (adapters using copper connections only)
 Valid Range: 0-2 (0=auto-negotiate, 1=half, 2=full)
 Default Value: 0
-    Defines the direction in which data is allowed to flow. Can by either one 
+    Defines the direction in which data is allowed to flow. Can be either one 
     or two-directional. If both Duplex and the link partner are set to auto-
     negotiate, the board auto-detects the correct duplex. If the link partner
     is forced (either full or half), Duplex defaults to half-duplex.
@@ -125,22 +103,46 @@
 
 InterruptThrottleRate
 Valid Range: 100-100000 (0=off, 1=dynamic)
-Default Value: 1
+Default Value: 8000
     This value represents the maximum number of interrupts per second the 
     controller generates. InterruptThrottleRate is another setting used in 
     interrupt moderation. Dynamic mode uses a heuristic algorithm to adjust 
     InterruptThrottleRate based on the current traffic load.
+Un-supported Adapters: InterruptThrottleRate is NOT supported by 82542, 82543
+    or 82544-based adapters.
 
     NOTE: InterruptThrottleRate takes precedence over the TxAbsIntDelay and 
           RxAbsIntDelay parameters. In other words, minimizing the receive 
           and/or transmit absolute delays does not force the controller to 
           generate more interrupts than what the Interrupt Throttle Rate 
           allows.
+    CAUTION: If you are using the Intel PRO/1000 CT Network Connection 
+             (controller 82547), setting InterruptThrottleRate to a value 
+             greater than 75,000, may hang (stop transmitting) adapters under 
+             certain network conditions. If this occurs a NETDEV WATCHDOG 
+             message is logged in the system event log. In addition, the 
+             controller is automatically reset, restoring the network 
+             connection. To eliminate the potential for the hang, ensure 
+             that InterruptThrottleRate is set no greater than 75,000 and is 
+             not set to 0.
+    NOTE: When e1000 is loaded with default settings and multiple adapters are 
+          in use simultaneously, the CPU utilization may increase non-linearly. 
+          In order to limit the CPU utilization without impacting the overall 
+          throughput, we recommend that you load the driver as follows:
+
+              insmod e1000.o InterruptThrottleRate=3000,3000,3000
+
+          This sets the InterruptThrottleRate to 3000 interrupts/sec for the 
+          first, second, and third instances of the driver. The range of 2000 to 
+          3000 interrupts per second works on a majority of systems and is a 
+          good starting point, but the optimal value will be platform-specific. 
+          If CPU utilization is not a concern, use RX_POLLING (NAPI) and default 
+          driver settings.
 
 RxDescriptors
 Valid Range: 80-256 for 82542 and 82543-based adapters
-             80-4096 for 82540, 82544, 82545, and 82546-based adapters
-Default Value: 80
+             80-4096 for all other supported adapters
+Default Value: 256
     This value is the number of receive descriptors allocated by the driver. 
     Increasing this value allows the driver to buffer more incoming packets. 
     Each descriptor is 16 bytes.  A receive buffer is also allocated for each
@@ -149,6 +151,9 @@
 
     NOTE: MTU designates the frame size. It only needs to be set for Jumbo 
           Frames.
+    NOTE: Depending on the available system resources, the request for a
+    higher number of receive descriptors may be denied.  In this case,
+    use a lower number.
 
 RxIntDelay
 Valid Range: 0-65535 (0=off)
@@ -168,11 +173,11 @@
              restoring the network connection. To eliminate the potential for
              the hang ensure that RxIntDelay is set to 0.
 
-RxAbsIntDelay (82540, 82545, and 82546-based adapters only)
+RxAbsIntDelay (82540, 82545 and later adapters only)
 Valid Range: 0-65535 (0=off)
 Default Value: 128
     This value, in units of 1.024 microseconds, limits the delay in which a 
-    transmit interrupt is generated. Useful only if RxIntDelay is non-zero, 
+    receive interrupt is generated. Useful only if RxIntDelay is non-zero, 
     this value ensures that an interrupt is generated after the initial 
     packet is received within the set amount of time.  Proper tuning,
     along with RxIntDelay, may improve traffic throughput in specific network
@@ -188,12 +193,16 @@
 
 TxDescriptors
 Valid Range: 80-256 for 82542 and 82543-based adapters
-             80-4096 for 82540, 82544, 82545, and 82546-based adapters
+             80-4096 for all other supported adapters
 Default Value: 256
     This value is the number of transmit descriptors allocated by the driver.
     Increasing this value allows the driver to queue more transmits. Each 
     descriptor is 16 bytes.
 
+    NOTE: Depending on the available system resources, the request for a
+    higher number of transmit descriptors may be denied.  In this case,
+    use a lower number.
+
 TxIntDelay
 Valid Range: 0-65535 (0=off)
 Default Value: 64
@@ -203,7 +212,7 @@
     system is reporting dropped transmits, this value may be set too high
     causing the driver to run out of available transmit descriptors.
 
-TxAbsIntDelay (82540, 82545, and 82546-based adapters only)
+TxAbsIntDelay (82540, 82545 and later adapters only)
 Valid Range: 0-65535 (0=off)
 Default Value: 64
     This value, in units of 1.024 microseconds, limits the delay in which a 
@@ -219,7 +228,6 @@
     A value of '1' indicates that the driver should enable IP checksum
     offload for received packets (both UDP and TCP) to the adapter hardware.
 
-
 Speed and Duplex Configuration
 ==============================
 
@@ -251,6 +259,10 @@
 Speed (Mbps)   N/A    N/A    1000    N/A     100    100    10      10
 Duplex                       Full            Full   Half   Full    Half
 
+For example to limit the negotiated speed/duplex on the interface to 10 Mbps 
+Half or Full duplex, set AutoNeg to 0x02: 
+    insmod e1000 AutoNeg=0x02
+
 Note that setting AutoNeg does not guarantee that the board will link at the 
 highest specified speed or duplex mode, but the board will link at the 
 highest possible speed/duplex of the link partner IF the link partner is also
@@ -261,6 +273,38 @@
 Additional Configurations
 =========================
 
+  Configuring the Driver on Different Distributions
+  -------------------------------------------------
+
+  Configuring a network driver to load properly when the system is started is
+  distribution dependent. Typically, the configuration process involves adding
+  an alias line to /etc/modules.conf as well as editing other system startup 
+  scripts and/or configuration files. Many popular Linux distributions ship 
+  with tools to make these changes for you. To learn the proper way to 
+  configure a network device for your system, refer to your distribution 
+  documentation. If during this process you are asked for the driver or module 
+  name, the name for the Linux Base Driver for the Intel PRO/1000 Family of 
+  Adapters is e1000.
+
+  As an example, if you install the e1000 driver for two PRO/1000 adapters 
+  (eth0 and eth1) and set the speed and duplex to 10full and 100half, add the 
+  following to modules.conf:
+
+       alias eth0 e1000
+       alias eth1 e1000
+       options e1000 Speed=10,100 Duplex=2,1
+
+  Viewing Link Messages
+  ---------------------
+
+  Link messages will not be displayed to the console if the distribution is 
+  restricting system messages. In order to see network driver link messages on 
+  your console, set dmesg to eight by entering the following:
+
+       dmesg -n 8
+
+  NOTE: This setting is not saved across reboots.
+
   Jumbo Frames
   ------------
 
@@ -278,6 +322,51 @@
   10 or 100 Mbps may result in poor performance or loss of link.
 
 
+  NOTE: MTU designates the frame size. To enable Jumbo Frames, increase the
+  MTU size on the interface beyond 1500.
+
+  Ethtool
+  -------
+
+  The driver utilizes the ethtool interface for driver configuration and
+  diagnostics, as well as displaying statistical information.  Ethtool
+  version 1.6 or later is required for this functionality.
+
+  The latest release of ethtool can be found from
+  http://sf.net/projects/gkernel.  After ethtool is installed,
+  ethtool-copy.h must be copied and renamed to ethtool.h in your kernel
+  source tree at <linux_kernel_src>/include/linux.  Backup the original
+  ethtool.h as needed before copying.  The driver then must be recompiled
+  in order to take advantage of the latest ethtool features.
+
+  NOTE: Ethtool 1.6 only supports a limited set of ethtool options. Support 
+  for a more complete ethtool feature set can be enabled by upgrading 
+  ethtool to ethtool-1.8.1. 
+
+  Enabling Wake on LAN* (WoL)
+  ---------------------------
+
+  WoL is configured through the Ethtool* utility. Ethtool is included with
+  all versions of Red Hat after Red Hat 7.2. For other Linux distributions, 
+  download and install Ethtool from the following website: 
+  http://sourceforge.net/projects/gkernel.
+
+  For instructions on enabling WoL with Ethtool, refer to the website listed 
+  above.
+
+  WoL will be enabled on the system during the next shut down or reboot. 
+  For this driver version, in order to enable WoL, the e1000 driver must be 
+  loaded when shutting down or rebooting the system.
+
+  NAPI
+  ----
+
+  NAPI (Rx polling mode) is supported in the e1000 driver. NAPI is enabled
+  or disabled based on the configuration of the kernel. 
+
+  See www.cyberus.ca/~hadi/usenix-paper.tgz for more information on NAPI.
+
+
 Known Issues
 ============
 
@@ -285,9 +374,9 @@
   -------------------------------
 
   Memory allocation failures have been observed on Linux systems with 64 MB 
-  of RAM or less that are running Jumbo Frames. If you are using Jumbo 
-  Frames, your system may require more than the advertised minimum 
-  requirement of 64 MB of system memory.
+  of RAM or less that are running Jumbo Frames. If you are using Jumbo Frames,
+  your system may require more than the advertised minimum requirement of 64 MB
+  of system memory.
 
 
 Support
diff -Nru a/Documentation/networking/ixgb.txt b/Documentation/networking/ixgb.txt
--- a/Documentation/networking/ixgb.txt	2004-10-26 01:30:56 -04:00
+++ b/Documentation/networking/ixgb.txt	2004-10-26 01:30:56 -04:00
@@ -1,14 +1,14 @@
 Linux* Base Driver for the Intel(R) PRO/10GbE Family of Adapters
 ================================================================
 
-January 06, 2003
+September 13, 2004
 
 
 Contents
 ========
 
 - In This Release
-- Supported Adapters
+- Identifying Your Adapter
 - Command Line Parameters
 - Improving Performance
 - Support
@@ -18,36 +18,23 @@
 ===============
 
 This file describes the Linux* Base Driver for the Intel(R) PRO/10GbE Family 
-of Adapters, version 1.0.x. This driver is intended for 2.4.x kernels; it is 
-known to build properly on 2.4.x kernels through 2.4.18. Intel focused 
-testing on Intel architectures running kernels 2.4.18. This driver includes 
-support for Itanium(TM)-based systems.
+of Adapters, version 1.0.x.  This driver includes support for Itanium(TM)2 and
+EM64T systems.
 
 For questions related to hardware requirements, refer to the documentation 
 supplied with your Intel PRO/10GbE adapter. All hardware requirements listed 
 apply to use with Linux.
 
-
-Supported Adapters
-==================
-
-The following Intel network adapters are compatible with the drivers in this 
-release:
-
-   Controller  Adapter Name                           Board IDs
-   ----------  ------------                           ---------
-
-   82597EX     Intel(R) PRO/10GbE LR Server Adapter   A82505-xxx
-
+Identifying Your Adapter
+========================
 
 To verify your Intel adapter is supported, find the board ID number on the 
 adapter. Look for a label that has a barcode and a number in the format  
-A12345-001. Match this to the list of numbers above.
+A12345-001. 
 
-For more information on how to identify your adapter, go to the Adapter & 
-Driver ID Guide at:
+Use the above information and the Adapter & Driver ID Guide at:
 
-    http://support.intel.com/support/network/adapter/pro100/21397.htm
+  http://support.intel.com/support/network/adapter/pro100/21397.htm
 
 For the latest Intel network drivers for Linux, go to:
 
@@ -72,8 +59,9 @@
 resources for the second adapter.
 
 The default value for each parameter is generally the recommended setting,
-unless otherwise noted.
-
+unless otherwise noted. Also, if the driver is statically built into the
+kernel, the driver is loaded with the default values for all the parameters.
+Ethtool can be used to change some of the parameters at runtime.
 
 FlowControl
 Valid Range: 0-3 (0=none, 1=Rx only, 2=Tx only, 3=Rx&Tx)
@@ -124,7 +112,6 @@
     A value of '1' indicates that the driver should enable IP checksum
     offload for transmitted packets (both UDP and TCP) to the adapter 
     hardware.
-
 
 Improving Performance
 =====================
diff -Nru a/drivers/net/3c59x.c b/drivers/net/3c59x.c
--- a/drivers/net/3c59x.c	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/3c59x.c	2004-10-26 01:30:56 -04:00
@@ -2887,7 +2887,7 @@
 }
 
 static struct ethtool_ops vortex_ethtool_ops = {
-	.get_drvinfo =		vortex_get_drvinfo,
+	.get_drvinfo		= vortex_get_drvinfo,
 };
 
 #ifdef CONFIG_PCI
diff -Nru a/drivers/net/Kconfig b/drivers/net/Kconfig
--- a/drivers/net/Kconfig	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/Kconfig	2004-10-26 01:30:56 -04:00
@@ -1413,66 +1413,17 @@
 	depends on NET_PCI && PCI
 	select MII
 	---help---
-	  This driver supports Intel(R) PRO/100 family of adapters, which 
-	  includes:
-
-	  Controller  Adapter Name                       Board IDs
-	  ----------  ------------                       ---------
-
-	  82558       PRO/100+ PCI Adapter               668081-xxx, 
-	  689661-xxx
-	  82558       PRO/100+ Management Adapter        691334-xxx, 
-	  701738-xxx,
-	  721383-xxx
-	  82558       PRO/100+ Dual Port Server Adapter  714303-xxx, 
-	  711269-xxx, 
-	  A28276-xxx
-	  82558       PRO/100+ PCI Server Adapter        710550-xxx
-	  82550       PRO/100 S Server Adapter           752438-xxx
-	  82559                                          A56831-xxx, 
-	  A10563-xxx,
-	  A12171-xxx, 
-	  A12321-xxx, 
-	  A12320-xxx, 
-	  A12170-xxx
-	  748568-xxx
-	  748565-xxx
-	  82550       PRO/100 S Desktop Adapter          751767-xxx
-	  82559                                          748592-xxx, 
-	  A12167-xxx, 
-	  A12318-xxx, 
-	  A12317-xxx, 
-	  A12165-xxx,
-	  748569-xxx 
-	  82559       PRO/100+ Server Adapter            729757-xxx
-	  82559       PRO/100 S Management Adapter       748566-xxx, 
-	  748564-xxx
-	  82550       PRO/100 S Dual Port Server Adapter A56831-xxx
-	  82551       PRO/100 M Desktop Adapter          A80897-xxx
-	  PRO/100 S Advanced Management Adapter 
-	  747842-xxx, 
-	  745171-xxx
-	  CNR         PRO/100 VE Desktop Adapter         A10386-xxx, 
-	  A10725-xxx, 
-	  A23801-xxx, 
-	  A19716-xxx
-	  PRO/100 VM Desktop Adapter         A14323-xxx, 
-	  A19725-xxx, 
-	  A23801-xxx, 
-	  A22220-xxx, 
-	  A23796-xxx
-
-
+	  This driver supports Intel(R) PRO/100 family of adapters.
 	  To verify that your adapter is supported, find the board ID number 
 	  on the adapter. Look for a label that has a barcode and a number 
-	  in the format 123456-001 (six digits hyphen three digits). Match 
-	  this to the list of numbers above.
+	  in the format 123456-001 (six digits hyphen three digits). 
 
-	  For more information on how to identify your adapter, go to the 
-	  Adapter & Driver ID Guide at:
+	  Use the above information and the Adapter & Driver ID Guide at:
 
 	  http://support.intel.com/support/network/adapter/pro100/21397.htm
 
+          to identify the adapter.
+
 	  For the latest Intel PRO/100 network driver for Linux, see:
 
 	  http://appsr.intel.com/scripts-df/support_intel.asp
@@ -1730,7 +1681,7 @@
 	  (e.g. VT8235).
 
 	  To compile this driver as a module, choose M here. The module
-	  will be called via-rhine.
+	  will be called via-velocity.
 
 config VIA_RHINE_MMIO
 	bool "Use MMIO instead of PIO"
@@ -1742,18 +1693,6 @@
 
 	  If unsure, say Y.
 
-config VIA_VELOCITY
-	tristate "VIA Velocity support"
-	depends on NET_PCI && PCI
-	select CRC32
-	select CRC_CCITT
-	select MII
-	help
-	  If you have a VIA "Velocity" based network card say Y here.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called via-velocity.
-
 config LAN_SAA9730
 	bool "Philips SAA9730 Ethernet support (EXPERIMENTAL)"
 	depends on NET_PCI && EXPERIMENTAL && MIPS
@@ -1933,29 +1872,8 @@
 	depends on PCI
 	---help---
 	  This driver supports Intel(R) PRO/1000 gigabit ethernet family of
-	  adapters, which includes:
-
-	  Controller  Adapter Name                         Board IDs
-	  ----------  ------------                         ---------
-	  82542       PRO/1000 Gigabit Server Adapter      700262-xxx,
-	  717037-xxx
-	  82543       PRO/1000 F Server Adapter            738640-xxx,
-	  A38888-xxx
-	  82543       PRO/1000 T Server Adapter            A19845-xxx,
-	  A33948-xxx
-	  82544       PRO/1000 XT Server Adapter           A51580-xxx
-	  82544       PRO/1000 XF Server Adapter           A50484-xxx
-	  82544       PRO/1000 T Desktop Adapter           A62947-xxx
-	  82540       PRO/1000 MT Desktop Adapter          A78408-xxx
-	  82541       PRO/1000 MT Desktop Adapter          C91016-xxx
-	  82545       PRO/1000 MT Server Adapter           A92165-xxx
-	  82546       PRO/1000 MT Dual Port Server Adapter A92111-xxx
-	  82545       PRO/1000 MF Server Adapter           A91622-xxx
-	  82545       PRO/1000 MF Server Adapter(LX)       A91624-xxx
-	  82546       PRO/1000 MF Dual Port Server Adapter A91620-xxx 
-
-	  For more information on how to identify your adapter, go to the
-	  Adapter & Driver ID Guide at:
+	  adapters.  For more information on how to identify your adapter, go 
+	  to the Adapter & Driver ID Guide at:
 
 	  <http://support.intel.com/support/network/adapter/pro100/21397.htm>
 
@@ -2140,6 +2058,18 @@
 	  say M here and read Documentation/kbuild/modules.txt. The module will
 	  be called sk98lin. This is recommended.
 
+config VIA_VELOCITY
+	tristate "VIA Velocity support"
+	depends on NET_PCI && PCI
+	select CRC32
+	select CRC_CCITT
+	select MII
+	help
+	  If you have a VIA "Velocity" based network card say Y here.
+
+	  To compile this driver as a module, choose M here. The module
+	  will be called via-velocity.
+
 config TIGON3
 	tristate "Broadcom Tigon3 support"
 	depends on PCI
@@ -2202,14 +2132,8 @@
 	depends on PCI
 	---help---
 	  This driver supports Intel(R) PRO/10GbE family of
-	  adapters, which includes:
-
-	  Controller  Adapter Name                           Board IDs
-	  ----------  ------------                           ---------
-	  82597EX     Intel(R) PRO/10GbE LR Server Adapter   A82505-xxx
-
-	  For more information on how to identify your adapter, go to the
-	  Adapter & Driver ID Guide at:
+	  adapters.  For more information on how to identify your adapter, go
+	  to the Adapter & Driver ID Guide at:
 
 	  <http://support.intel.com/support/network/adapter/pro100/21397.htm>
 
diff -Nru a/drivers/net/dummy.c b/drivers/net/dummy.c
--- a/drivers/net/dummy.c	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/dummy.c	2004-10-26 01:30:56 -04:00
@@ -77,7 +77,7 @@
 
 static int dummy_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct net_device_stats *stats = dev->priv;
+	struct net_device_stats *stats = netdev_priv(dev);
 
 	stats->tx_packets++;
 	stats->tx_bytes+=skb->len;
@@ -88,7 +88,7 @@
 
 static struct net_device_stats *dummy_get_stats(struct net_device *dev)
 {
-	return dev->priv;
+	return netdev_priv(dev);
 }
 
 static struct net_device **dummies;
diff -Nru a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
--- a/drivers/net/e1000/e1000.h	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/e1000/e1000.h	2004-10-26 01:30:56 -04:00
@@ -64,7 +64,6 @@
 #include <linux/udp.h>
 #include <net/pkt_sched.h>
 #include <linux/list.h>
-#include <linux/rtnetlink.h>
 #include <linux/reboot.h>
 #ifdef NETIF_F_TSO
 #include <net/checksum.h>
@@ -73,7 +72,6 @@
 #include <linux/mii.h>
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
-#include <linux/moduleparam.h>
 
 #define BAR_0		0
 #define BAR_1		1
diff -Nru a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
--- a/drivers/net/e1000/e1000_ethtool.c	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/e1000/e1000_ethtool.c	2004-10-26 01:30:56 -04:00
@@ -249,7 +249,8 @@
 			e1000_reset(adapter);
 	}
 	else
-		return e1000_force_mac_fc(hw);
+		return ((hw->media_type == e1000_media_type_fiber) ?
+			e1000_setup_link(hw) : e1000_force_mac_fc(hw));
 	
 	return 0;
 }
@@ -592,6 +593,9 @@
 	tx_old = adapter->tx_ring;
 	rx_old = adapter->rx_ring;
 
+	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) 
+		return -EINVAL;
+
 	if(netif_running(adapter->netdev))
 		e1000_down(adapter);
 
@@ -637,7 +641,6 @@
 	return err;
 }
 
-
 #define REG_PATTERN_TEST(R, M, W)                                              \
 {                                                                              \
 	uint32_t pat, value;                                                   \
@@ -1017,8 +1020,8 @@
 		struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rxdr, i);
 		struct sk_buff *skb;
 
-		if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN,
-				     GFP_KERNEL))) {
+		if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN, 
+				GFP_KERNEL))) {
 			ret_val = 6;
 			goto err_nomem;
 		}
@@ -1442,6 +1445,8 @@
 	case E1000_DEV_ID_82543GC_COPPER:
 	case E1000_DEV_ID_82544EI_FIBER:
 	case E1000_DEV_ID_82546EB_QUAD_COPPER:
+	case E1000_DEV_ID_82545EM_FIBER:
+	case E1000_DEV_ID_82545EM_COPPER:
 		wol->supported = 0;
 		wol->wolopts   = 0;
 		return;
diff -Nru a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
--- a/drivers/net/e1000/e1000_hw.c	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/e1000/e1000_hw.c	2004-10-26 01:30:56 -04:00
@@ -65,6 +65,7 @@
 static void e1000_standby_eeprom(struct e1000_hw *hw);
 static int32_t e1000_id_led_init(struct e1000_hw * hw);
 static int32_t e1000_set_vco_speed(struct e1000_hw *hw);
+static int32_t e1000_polarity_reversal_workaround(struct e1000_hw *hw);
 static int32_t e1000_set_phy_mode(struct e1000_hw *hw);
 
 /* IGP cable length table */
@@ -1594,6 +1595,15 @@
         ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
         if(ret_val)
             return ret_val;
+
+        if((hw->mac_type == e1000_82544 || hw->mac_type == e1000_82543) &&
+           (!hw->autoneg) &&
+           (hw->forced_speed_duplex == e1000_10_full ||
+            hw->forced_speed_duplex == e1000_10_half)) {
+            ret_val = e1000_polarity_reversal_workaround(hw);
+            if(ret_val)
+                return ret_val;
+        }
     }
     return E1000_SUCCESS;
 }
@@ -1983,6 +1993,7 @@
     uint32_t ctrl;
     uint32_t status;
     uint32_t rctl;
+    uint32_t icr;
     uint32_t signal = 0;
     int32_t ret_val;
     uint16_t phy_data;
@@ -2032,6 +2043,25 @@
              * link-up */
             e1000_check_downshift(hw);
 
+            /* If we are on 82544 or 82543 silicon and speed/duplex
+             * are forced to 10H or 10F, then we will implement the polarity
+             * reversal workaround.  We disable interrupts first, and upon
+             * returning, place the devices interrupt state to its previous
+             * value except for the link status change interrupt which will
+             * happen due to the execution of this workaround.
+             */
+
+            if((hw->mac_type == e1000_82544 || hw->mac_type == e1000_82543) &&
+               (!hw->autoneg) &&
+               (hw->forced_speed_duplex == e1000_10_full ||
+                hw->forced_speed_duplex == e1000_10_half)) {
+                E1000_WRITE_REG(hw, IMC, 0xffffffff);
+                ret_val = e1000_polarity_reversal_workaround(hw);
+                icr = E1000_READ_REG(hw, ICR);
+                E1000_WRITE_REG(hw, ICS, (icr & ~E1000_ICS_LSC));
+                E1000_WRITE_REG(hw, IMS, IMS_ENABLE_MASK);
+            }
+
         } else {
             /* No link detected */
             e1000_config_dsp_after_link_change(hw, FALSE);
@@ -5191,28 +5221,88 @@
     return E1000_SUCCESS;
 }
 
-/******************************************************************************
- * Verifies the hardware needs to allow ARPs to be processed by the host
- *
- * hw - Struct containing variables accessed by shared code
- *
- * returns: - TRUE/FALSE
- *
- *****************************************************************************/
-uint32_t
-e1000_enable_mng_pass_thru(struct e1000_hw *hw)
+static int32_t
+e1000_polarity_reversal_workaround(struct e1000_hw *hw)
 {
-    uint32_t manc;
+    int32_t ret_val;
+    uint16_t mii_status_reg;
+    uint16_t i;
 
-    if (hw->asf_firmware_present) {
-        manc = E1000_READ_REG(hw, MANC);
+    /* Polarity reversal workaround for forced 10F/10H links. */
+
+    /* Disable the transmitter on the PHY */
+
+    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
+    if(ret_val)
+        return ret_val;
+    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF);
+    if(ret_val)
+        return ret_val;
+
+    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
+    if(ret_val)
+        return ret_val;
+
+    /* This loop will early-out if the NO link condition has been met. */
+    for(i = PHY_FORCE_TIME; i > 0; i--) {
+        /* Read the MII Status Register and wait for Link Status bit
+         * to be clear.
+         */
+
+        ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
+        if(ret_val)
+            return ret_val;
+
+        ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
+        if(ret_val)
+            return ret_val;
+
+        if((mii_status_reg & ~MII_SR_LINK_STATUS) == 0) break;
+        msec_delay_irq(100);
+    }
+
+    /* Recommended delay time after link has been lost */
+    msec_delay_irq(1000);
+
+    /* Now we will re-enable th transmitter on the PHY */
+
+    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
+    if(ret_val)
+        return ret_val;
+    msec_delay_irq(50);
+    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFF0);
+    if(ret_val)
+        return ret_val;
+    msec_delay_irq(50);
+    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFF00);
+    if(ret_val)
+        return ret_val;
+    msec_delay_irq(50);
+    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x0000);
+    if(ret_val)
+        return ret_val;
 
-        if (!(manc & E1000_MANC_RCV_TCO_EN) ||
-            !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
-            return FALSE;
-        if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN))
-            return TRUE;
+    ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
+    if(ret_val)
+        return ret_val;
+
+    /* This loop will early-out if the link condition has been met. */
+    for(i = PHY_FORCE_TIME; i > 0; i--) {
+        /* Read the MII Status Register and wait for Link Status bit
+         * to be set.
+         */
+
+        ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
+        if(ret_val)
+            return ret_val;
+
+        ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
+        if(ret_val)
+            return ret_val;
+
+        if(mii_status_reg & MII_SR_LINK_STATUS) break;
+        msec_delay_irq(100);
     }
-    return FALSE;
+    return E1000_SUCCESS;
 }
 
diff -Nru a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
--- a/drivers/net/e1000/e1000_main.c	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/e1000/e1000_main.c	2004-10-26 01:30:56 -04:00
@@ -48,7 +48,7 @@
 #else
 #define DRIVERNAPI "-NAPI"
 #endif
-char e1000_driver_version[] = "5.3.19-k2"DRIVERNAPI;
+char e1000_driver_version[] = "5.5.4-k2"DRIVERNAPI;
 char e1000_copyright[] = "Copyright (c) 1999-2004 Intel Corporation.";
 
 /* e1000_pci_tbl - PCI Device ID Table
@@ -311,7 +311,8 @@
 void
 e1000_reset(struct e1000_adapter *adapter)
 {
-	uint32_t pba, manc;
+	uint32_t pba;
+
 	/* Repartition Pba for greater than 9k mtu
 	 * To take effect CTRL.RST is required.
 	 */
@@ -354,12 +355,6 @@
 
 	e1000_reset_adaptive(&adapter->hw);
 	e1000_phy_get_info(&adapter->hw, &adapter->phy_info);
-
-	if(adapter->en_mng_pt) {
-		manc = E1000_READ_REG(&adapter->hw, MANC);
-		manc |= (E1000_MANC_ARP_EN | E1000_MANC_EN_MNG2HOST);
-		E1000_WRITE_REG(&adapter->hw, MANC, manc);
-	}
 }
 
 /**
@@ -422,11 +417,6 @@
 	adapter->hw.back = adapter;
 	adapter->msg_enable = (1 << debug) - 1;
 
-	rtnl_lock();
-	/* we need to set the name early for the DPRINTK macro */
-	if(dev_alloc_name(netdev, netdev->name) < 0)
-		goto err_free_unlock;
-
 	mmio_start = pci_resource_start(pdev, BAR_0);
 	mmio_len = pci_resource_len(pdev, BAR_0);
 
@@ -466,6 +456,7 @@
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	netdev->poll_controller = e1000_netpoll;
 #endif
+	strcpy(netdev->name, pci_name(pdev));
 
 	netdev->mem_start = mmio_start;
 	netdev->mem_end = mmio_start + mmio_len;
@@ -502,8 +493,6 @@
  	/* hard_start_xmit is safe against parallel locking */
  	netdev->features |= NETIF_F_LLTX; 
  
-	adapter->en_mng_pt = e1000_enable_mng_pass_thru(&adapter->hw);
-
 	/* before reading the EEPROM, reset the controller to 
 	 * put the device in a known good starting state */
 	
@@ -553,7 +542,6 @@
 	netif_carrier_off(netdev);
 	netif_stop_queue(netdev);
 
-	DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
 	e1000_check_options(adapter);
 
 	/* Initial Wake on LAN setting
@@ -586,12 +574,13 @@
 	/* reset the hardware with the new settings */
 	e1000_reset(adapter);
 
-	/* We're already holding the rtnl lock; call the no-lock version */
-	if((err = register_netdevice(netdev)))
+	strcpy(netdev->name, "eth%d");
+	if((err = register_netdev(netdev)))
 		goto err_register;
 
+	DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
+
 	cards_found++;
-	rtnl_unlock();
 	return 0;
 
 err_register:
@@ -599,8 +588,6 @@
 err_eeprom:
 	iounmap(adapter->hw.hw_addr);
 err_ioremap:
-err_free_unlock:
-	rtnl_unlock();
 	free_netdev(netdev);
 err_alloc_etherdev:
 	pci_release_regions(pdev);
@@ -641,6 +628,8 @@
 	pci_release_regions(pdev);
 
 	free_netdev(netdev);
+
+	pci_disable_device(pdev);
 }
 
 /**
@@ -2335,8 +2324,8 @@
 		if(unlikely(adapter->vlgrp &&
 			    (rx_desc->status & E1000_RXD_STAT_VP))) {
 			vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
-						 le16_to_cpu(rx_desc->special &
-						 E1000_RXD_SPC_VLAN_MASK));
+					le16_to_cpu(rx_desc->special) &
+					E1000_RXD_SPC_VLAN_MASK);
 		} else {
 			netif_receive_skb(skb);
 		}
@@ -2344,8 +2333,8 @@
 		if(unlikely(adapter->vlgrp &&
 			    (rx_desc->status & E1000_RXD_STAT_VP))) {
 			vlan_hwaccel_rx(skb, adapter->vlgrp,
-					le16_to_cpu(rx_desc->special &
-					E1000_RXD_SPC_VLAN_MASK));
+					le16_to_cpu(rx_desc->special) &
+					E1000_RXD_SPC_VLAN_MASK);
 		} else {
 			netif_rx(skb);
 		}
@@ -2894,9 +2883,9 @@
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct e1000_adapter *adapter = netdev->priv;
-	uint32_t manc;
+	uint32_t manc, ret;
 
-	pci_enable_device(pdev);
+	ret = pci_enable_device(pdev);
 	pci_set_power_state(pdev, 0);
 	pci_restore_state(pdev);
 
diff -Nru a/drivers/net/e1000/e1000_osdep.h b/drivers/net/e1000/e1000_osdep.h
--- a/drivers/net/e1000/e1000_osdep.h	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/e1000/e1000_osdep.h	2004-10-26 01:30:56 -04:00
@@ -49,6 +49,12 @@
 				set_current_state(TASK_UNINTERRUPTIBLE); \
 				schedule_timeout((x * HZ)/1000 + 2); \
 			} } while(0)
+/* Some workarounds require millisecond delays and are run during interrupt
+ * context.  Most notably, when establishing link, the phy may need tweaking
+ * but cannot process phy register reads/writes faster than millisecond
+ * intervals...and we establish link due to a "link status change" interrupt.
+ */
+#define msec_delay_irq(x) mdelay(x)
 #endif
 
 #define PCI_COMMAND_REGISTER   PCI_COMMAND
diff -Nru a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c
--- a/drivers/net/e1000/e1000_param.c	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/e1000/e1000_param.c	2004-10-26 01:30:56 -04:00
@@ -34,31 +34,21 @@
 
 #define E1000_MAX_NIC 32
 
-#define OPTION_UNSET    -1
+#define OPTION_UNSET   -1
 #define OPTION_DISABLED 0
 #define OPTION_ENABLED  1
 
-/* Module Parameters are always initialized to -1, so that the driver
- * can tell the difference between no user specified value or the
- * user asking for the default value.
- * The true default values are loaded in when e1000_check_options is called.
- *
- * This is a GCC extension to ANSI C.
- * See the item "Labeled Elements in Initializers" in the section
- * "Extensions to the C Language Family" of the GCC documentation.
- */
-
-#define E1000_PARAM_INIT { [0 ... E1000_MAX_NIC] = OPTION_UNSET }
-
 /* All parameters are treated the same, as an integer array of values.
  * This macro just reduces the need to repeat the same declaration code
  * over and over (plus this helps to avoid typo bugs).
  */
 
-#define E1000_PARAM(X, S) \
-static const int __devinitdata X[E1000_MAX_NIC + 1] = E1000_PARAM_INIT; \
-MODULE_PARM(X, "1-" __MODULE_STRING(E1000_MAX_NIC) "i"); \
-MODULE_PARM_DESC(X, S);
+#define E1000_PARAM_INIT { [0 ... E1000_MAX_NIC] = OPTION_UNSET }
+#define E1000_PARAM(X, desc) \
+	static int __devinitdata X[E1000_MAX_NIC+1] = E1000_PARAM_INIT; \
+	static int num_##X = 0; \
+	module_param_array(X, int, &num_##X, 0); \
+	MODULE_PARM_DESC(X, desc);
 
 /* Transmit Descriptor Count
  *
@@ -305,7 +295,6 @@
 		DPRINTK(PROBE, NOTICE,
 		       "Warning: no configuration for board #%i\n", bd);
 		DPRINTK(PROBE, NOTICE, "Using defaults for all values\n");
-		bd = E1000_MAX_NIC;
 	}
 
 	{ /* Transmit Descriptor Count */
@@ -322,9 +311,14 @@
 		opt.arg.r.max = mac_type < e1000_82544 ?
 			E1000_MAX_TXD : E1000_MAX_82544_TXD;
 
-		tx_ring->count = TxDescriptors[bd];
-		e1000_validate_option(&tx_ring->count, &opt, adapter);
-		E1000_ROUNDUP(tx_ring->count, REQ_TX_DESCRIPTOR_MULTIPLE);
+		if (num_TxDescriptors > bd) {
+			tx_ring->count = TxDescriptors[bd];
+			e1000_validate_option(&tx_ring->count, &opt, adapter);
+			E1000_ROUNDUP(tx_ring->count, 
+						REQ_TX_DESCRIPTOR_MULTIPLE);
+		} else {
+			tx_ring->count = opt.def;
+		}
 	}
 	{ /* Receive Descriptor Count */
 		struct e1000_option opt = {
@@ -340,9 +334,14 @@
 		opt.arg.r.max = mac_type < e1000_82544 ? E1000_MAX_RXD :
 			E1000_MAX_82544_RXD;
 
-		rx_ring->count = RxDescriptors[bd];
-		e1000_validate_option(&rx_ring->count, &opt, adapter);
-		E1000_ROUNDUP(rx_ring->count, REQ_RX_DESCRIPTOR_MULTIPLE);
+		if (num_RxDescriptors > bd) {
+			rx_ring->count = RxDescriptors[bd];
+			e1000_validate_option(&rx_ring->count, &opt, adapter);
+			E1000_ROUNDUP(rx_ring->count, 
+						REQ_RX_DESCRIPTOR_MULTIPLE);
+		} else {
+			rx_ring->count = opt.def;
+		}
 	}
 	{ /* Checksum Offload Enable/Disable */
 		struct e1000_option opt = {
@@ -352,9 +351,13 @@
 			.def  = OPTION_ENABLED
 		};
 
-		int rx_csum = XsumRX[bd];
-		e1000_validate_option(&rx_csum, &opt, adapter);
-		adapter->rx_csum = rx_csum;
+		if (num_XsumRX > bd) {
+			int rx_csum = XsumRX[bd];
+			e1000_validate_option(&rx_csum, &opt, adapter);
+			adapter->rx_csum = rx_csum;
+		} else {
+			adapter->rx_csum = opt.def;
+		}
 	}
 	{ /* Flow Control */
 
@@ -374,9 +377,13 @@
 					 .p = fc_list }}
 		};
 
-		int fc = FlowControl[bd];
-		e1000_validate_option(&fc, &opt, adapter);
-		adapter->hw.fc = adapter->hw.original_fc = fc;
+		if (num_FlowControl > bd) {
+			int fc = FlowControl[bd];
+			e1000_validate_option(&fc, &opt, adapter);
+			adapter->hw.fc = adapter->hw.original_fc = fc;
+		} else {
+			adapter->hw.fc = opt.def;
+		}
 	}
 	{ /* Transmit Interrupt Delay */
 		struct e1000_option opt = {
@@ -388,8 +395,13 @@
 					 .max = MAX_TXDELAY }}
 		};
 
-		adapter->tx_int_delay = TxIntDelay[bd];
-		e1000_validate_option(&adapter->tx_int_delay, &opt, adapter);
+		if (num_TxIntDelay > bd) {
+			adapter->tx_int_delay = TxIntDelay[bd];
+			e1000_validate_option(&adapter->tx_int_delay, &opt, 
+								adapter);
+		} else {
+			adapter->tx_int_delay = opt.def;
+		}
 	}
 	{ /* Transmit Absolute Interrupt Delay */
 		struct e1000_option opt = {
@@ -401,8 +413,13 @@
 					 .max = MAX_TXABSDELAY }}
 		};
 
-		adapter->tx_abs_int_delay = TxAbsIntDelay[bd];
-		e1000_validate_option(&adapter->tx_abs_int_delay, &opt, adapter);
+		if (num_TxAbsIntDelay > bd) {
+			adapter->tx_abs_int_delay = TxAbsIntDelay[bd];
+			e1000_validate_option(&adapter->tx_abs_int_delay, &opt, 
+								adapter);
+		} else {
+			adapter->tx_abs_int_delay = opt.def;
+		}
 	}
 	{ /* Receive Interrupt Delay */
 		struct e1000_option opt = {
@@ -414,8 +431,13 @@
 					 .max = MAX_RXDELAY }}
 		};
 
-		adapter->rx_int_delay = RxIntDelay[bd];
-		e1000_validate_option(&adapter->rx_int_delay, &opt, adapter);
+		if (num_RxIntDelay > bd) {
+			adapter->rx_int_delay = RxIntDelay[bd];
+			e1000_validate_option(&adapter->rx_int_delay, &opt, 
+								adapter);
+		} else {
+			adapter->rx_int_delay = opt.def;
+		}
 	}
 	{ /* Receive Absolute Interrupt Delay */
 		struct e1000_option opt = {
@@ -427,8 +449,13 @@
 					 .max = MAX_RXABSDELAY }}
 		};
 
-		adapter->rx_abs_int_delay = RxAbsIntDelay[bd];
-		e1000_validate_option(&adapter->rx_abs_int_delay, &opt, adapter);
+		if (num_RxAbsIntDelay > bd) {
+			adapter->rx_abs_int_delay = RxAbsIntDelay[bd];
+			e1000_validate_option(&adapter->rx_abs_int_delay, &opt, 
+								adapter);
+		} else {
+			adapter->rx_abs_int_delay = opt.def;
+		}
 	}
 	{ /* Interrupt Throttling Rate */
 		struct e1000_option opt = {
@@ -440,20 +467,27 @@
 					 .max = MAX_ITR }}
 		};
 
-		adapter->itr = InterruptThrottleRate[bd];
-		switch(adapter->itr) {
-		case -1:
+		if (num_InterruptThrottleRate > bd) {
+			adapter->itr = InterruptThrottleRate[bd];
+			switch(adapter->itr) {
+			case -1:
+				adapter->itr = 1;
+				break;
+			case 0:
+				DPRINTK(PROBE, INFO, "%s turned off\n", 
+					opt.name);
+				break;
+			case 1:
+				DPRINTK(PROBE, INFO, "%s set to dynamic mode\n", 
+					opt.name);
+				break;
+			default:
+				e1000_validate_option(&adapter->itr, &opt, 
+					adapter);
+				break;
+			}
+		} else {
 			adapter->itr = 1;
-			break;
-		case 0:
-			DPRINTK(PROBE, INFO, "%s turned off\n", opt.name);
-			break;
-		case 1:
-			DPRINTK(PROBE, INFO, "%s set to dynamic mode\n", opt.name);
-			break;
-		default:
-			e1000_validate_option(&adapter->itr, &opt, adapter);
-			break;
 		}
 	}
 
@@ -481,17 +515,17 @@
 e1000_check_fiber_options(struct e1000_adapter *adapter)
 {
 	int bd = adapter->bd_number;
-	bd = bd > E1000_MAX_NIC ? E1000_MAX_NIC : bd;
-
-	if((Speed[bd] != OPTION_UNSET)) {
+	if(num_Speed > bd) {
 		DPRINTK(PROBE, INFO, "Speed not valid for fiber adapters, "
 		       "parameter ignored\n");
 	}
-	if((Duplex[bd] != OPTION_UNSET)) {
+
+	if(num_Duplex > bd) {
 		DPRINTK(PROBE, INFO, "Duplex not valid for fiber adapters, "
 		       "parameter ignored\n");
 	}
-	if((AutoNeg[bd] != OPTION_UNSET) && (AutoNeg[bd] != 0x20)) {
+
+	if((num_AutoNeg > bd) && (AutoNeg[bd] != 0x20)) {
 		DPRINTK(PROBE, INFO, "AutoNeg other than 1000/Full is "
 				 "not valid for fiber adapters, "
 				 "parameter ignored\n");
@@ -510,7 +544,6 @@
 {
 	int speed, dplx;
 	int bd = adapter->bd_number;
-	bd = bd > E1000_MAX_NIC ? E1000_MAX_NIC : bd;
 
 	{ /* Speed */
 		struct e1000_opt_list speed_list[] = {{          0, "" },
@@ -527,8 +560,12 @@
 					 .p = speed_list }}
 		};
 
-		speed = Speed[bd];
-		e1000_validate_option(&speed, &opt, adapter);
+		if (num_Speed > bd) {
+			speed = Speed[bd];
+			e1000_validate_option(&speed, &opt, adapter);
+		} else {
+			speed = opt.def;
+		}
 	}
 	{ /* Duplex */
 		struct e1000_opt_list dplx_list[] = {{           0, "" },
@@ -544,11 +581,15 @@
 					 .p = dplx_list }}
 		};
 
-		dplx = Duplex[bd];
-		e1000_validate_option(&dplx, &opt, adapter);
+		if (num_Duplex > bd) {
+			dplx = Duplex[bd];
+			e1000_validate_option(&dplx, &opt, adapter);
+		} else {
+			dplx = opt.def;
+		}
 	}
 
-	if(AutoNeg[bd] != OPTION_UNSET && (speed != 0 || dplx != 0)) {
+	if((num_AutoNeg > bd) && (speed != 0 || dplx != 0)) {
 		DPRINTK(PROBE, INFO,
 		       "AutoNeg specified along with Speed or Duplex, "
 		       "parameter ignored\n");
@@ -605,7 +646,7 @@
 	switch (speed + dplx) {
 	case 0:
 		adapter->hw.autoneg = adapter->fc_autoneg = 1;
-		if(Speed[bd] != OPTION_UNSET || Duplex[bd] != OPTION_UNSET)
+		if((num_Speed > bd) && (speed != 0 || dplx != 0))
 			DPRINTK(PROBE, INFO,
 			       "Speed and duplex autonegotiation enabled\n");
 		break;
diff -Nru a/drivers/net/eql.c b/drivers/net/eql.c
--- a/drivers/net/eql.c	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/eql.c	2004-10-26 01:30:56 -04:00
@@ -164,12 +164,12 @@
 
 static void __init eql_setup(struct net_device *dev)
 {
-	equalizer_t *eql = dev->priv;
+	equalizer_t *eql = netdev_priv(dev);
 
 	SET_MODULE_OWNER(dev);
 
 	init_timer(&eql->timer);
-	eql->timer.data     	= (unsigned long) dev->priv;
+	eql->timer.data     	= (unsigned long) eql;
 	eql->timer.expires  	= jiffies + EQL_DEFAULT_RESCHED_IVAL;
 	eql->timer.function 	= eql_timer;
 
@@ -197,7 +197,7 @@
 
 static int eql_open(struct net_device *dev)
 {
-	equalizer_t *eql = dev->priv;
+	equalizer_t *eql = netdev_priv(dev);
 
 	/* XXX We should force this off automatically for the user. */
 	printk(KERN_INFO "%s: remember to turn off Van-Jacobson compression on "
@@ -241,7 +241,7 @@
 
 static int eql_close(struct net_device *dev)
 {
-	equalizer_t *eql = dev->priv;
+	equalizer_t *eql = netdev_priv(dev);
 
 	/*
 	 *	The timer has to be stopped first before we start hacking away
@@ -326,7 +326,7 @@
 
 static int eql_slave_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	equalizer_t *eql = dev->priv;
+	equalizer_t *eql = netdev_priv(dev);
 	slave_t *slave;
 
 	spin_lock(&eql->queue.lock);
@@ -352,7 +352,7 @@
 
 static struct net_device_stats * eql_get_stats(struct net_device *dev)
 {
-	equalizer_t *eql = dev->priv;
+	equalizer_t *eql = netdev_priv(dev);
 	return &eql->stats;
 }
 
@@ -378,7 +378,7 @@
 
 static inline int eql_is_full(slave_queue_t *queue)
 {
-	equalizer_t *eql = queue->master_dev->priv;
+	equalizer_t *eql = netdev_priv(queue->master_dev);
 
 	if (queue->num_slaves >= eql->max_slaves)
 		return 1;
@@ -420,7 +420,7 @@
 			if (!eql_is_master(slave_dev) &&
 			    !eql_is_slave(slave_dev)) {
 				slave_t *s = kmalloc(sizeof(*s), GFP_KERNEL);
-				equalizer_t *eql = master_dev->priv;
+				equalizer_t *eql = netdev_priv(master_dev);
 				int ret;
 
 				if (!s) {
@@ -453,7 +453,7 @@
 
 static int eql_emancipate(struct net_device *master_dev, slaving_request_t __user *srqp)
 {
-	equalizer_t *eql = master_dev->priv;
+	equalizer_t *eql = netdev_priv(master_dev);
 	struct net_device *slave_dev;
 	slaving_request_t srq;
 	int ret;
@@ -485,7 +485,7 @@
 
 static int eql_g_slave_cfg(struct net_device *dev, slave_config_t __user *scp)
 {
-	equalizer_t *eql = dev->priv;
+	equalizer_t *eql = netdev_priv(dev);
 	slave_t *slave;
 	struct net_device *slave_dev;
 	slave_config_t sc;
@@ -539,7 +539,7 @@
 	if (!slave_dev)
 		return ret;
 
-	eql = dev->priv;
+	eql = netdev_priv(dev);
 	spin_lock_bh(&eql->queue.lock);
 	if (eql_is_slave(slave_dev)) {
 		slave = __eql_find_slave_dev(&eql->queue, slave_dev);
@@ -561,7 +561,7 @@
 	master_config_t mc;
 
 	if (eql_is_master(dev)) {
-		eql = dev->priv;
+		eql = netdev_priv(dev);
 		mc.max_slaves = eql->max_slaves;
 		mc.min_slaves = eql->min_slaves;
 		if (copy_to_user(mcp, &mc, sizeof (master_config_t)))
@@ -580,7 +580,7 @@
 		return -EFAULT;
 
 	if (eql_is_master(dev)) {
-		eql = dev->priv;
+		eql = netdev_priv(dev);
 		eql->max_slaves = mc.max_slaves;
 		eql->min_slaves = mc.min_slaves;
 		return 0;
diff -Nru a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c
--- a/drivers/net/hamradio/hdlcdrv.c	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/hamradio/hdlcdrv.c	2004-10-26 01:30:56 -04:00
@@ -549,6 +549,8 @@
 
 	netif_stop_queue(dev);
 
+	netif_stop_queue(dev);
+
 	if (s->ops && s->ops->close)
 		i = s->ops->close(dev);
 	if (s->skb)
diff -Nru a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
--- a/drivers/net/ixgb/ixgb_main.c	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/ixgb/ixgb_main.c	2004-10-26 01:30:56 -04:00
@@ -30,7 +30,7 @@
 
 char ixgb_driver_name[] = "ixgb";
 char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver";
-char ixgb_driver_version[] = "1.0.66";
+char ixgb_driver_version[] = "1.0.66-k2";
 char ixgb_copyright[] = "Copyright (c) 2001-2004 Intel Corporation.";
 
 /* ixgb_pci_tbl - PCI Device ID Table
@@ -1614,8 +1614,12 @@
 	}
 #else
 	for (i = 0; i < IXGB_MAX_INTR; i++)
-		if (!ixgb_clean_rx_irq(adapter) & !ixgb_clean_tx_irq(adapter))
+		if (ixgb_clean_rx_irq(adapter) == FALSE)
 			break;
+	for (i = 0; i < IXGB_MAX_INTR; i++)
+		if (ixgb_clean_tx_irq(adapter) == FALSE)
+			break;
+
 	/* if RAIDC:EN == 1 and ICR:RXDMT0 == 1, we need to
 	 * set IMS:RXDMT0 to 1 to restart the RBD timer (POLL)
 	 */
@@ -1676,7 +1680,7 @@
 	eop = tx_ring->buffer_info[i].next_to_watch;
 	eop_desc = IXGB_TX_DESC(*tx_ring, eop);
 
-	while (eop_desc->status & cpu_to_le32(IXGB_TX_DESC_STATUS_DD)) {
+	while (eop_desc->status & IXGB_TX_DESC_STATUS_DD) {
 
 		for (cleaned = FALSE; !cleaned;) {
 			tx_desc = IXGB_TX_DESC(*tx_ring, i);
diff -Nru a/drivers/net/mac8390.c b/drivers/net/mac8390.c
--- a/drivers/net/mac8390.c	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/mac8390.c	2004-10-26 01:30:56 -04:00
@@ -42,10 +42,6 @@
 
 #include "8390.h"
 
-#if (LINUX_VERSION_CODE < 0x02030e)
-#define net_device device
-#endif
-
 #define WD_START_PG			0x00	/* First page of TX buffer */
 #define CABLETRON_RX_START_PG		0x00    /* First page of RX buffer */
 #define CABLETRON_RX_STOP_PG		0x30    /* Last page +1 of RX ring */
diff -Nru a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
--- a/drivers/net/ne2k-pci.c	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/ne2k-pci.c	2004-10-26 01:30:56 -04:00
@@ -653,12 +653,43 @@
 	pci_set_drvdata(pdev, NULL);
 }
 
+#ifdef CONFIG_PM
+static int ne2k_pci_suspend (struct pci_dev *pdev, u32 state)
+{
+	struct net_device *dev = pci_get_drvdata (pdev);
+
+	netif_device_detach(dev);
+	pci_save_state(pdev);
+	pci_set_power_state(pdev, state);
+
+	return 0;
+}
+
+static int ne2k_pci_resume (struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata (pdev);
+
+	pci_set_power_state(pdev, 0);
+	pci_restore_state(pdev);
+	NS8390_init(dev, 1);
+	netif_device_attach(dev);
+
+	return 0;
+}
+
+#endif /* CONFIG_PM */
+
 
 static struct pci_driver ne2k_driver = {
 	.name		= DRV_NAME,
 	.probe		= ne2k_pci_init_one,
 	.remove		= __devexit_p(ne2k_pci_remove_one),
 	.id_table	= ne2k_pci_tbl,
+#ifdef CONFIG_PM
+	.suspend	= ne2k_pci_suspend,
+	.resume		= ne2k_pci_resume,
+#endif /* CONFIG_PM */
+
 };
 
 
diff -Nru a/drivers/net/ns83820.c b/drivers/net/ns83820.c
--- a/drivers/net/ns83820.c	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/ns83820.c	2004-10-26 01:30:56 -04:00
@@ -64,6 +64,8 @@
  *				tuning
  *			0.20 -	fix stupid RFEN thinko.  i am such a smurf.
  *
+ *	20040828	0.21 -	add hardware vlan accleration
+ *				by Neil Horman <nhorman@redhat.com>
  * Driver Overview
  * ===============
  *
@@ -92,7 +94,9 @@
 //#define dprintk		printk
 #define dprintk(x...)		do { } while (0)
 
+#include <linux/config.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
@@ -108,6 +112,7 @@
 #include <linux/prefetch.h>
 #include <linux/ethtool.h>
 #include <linux/timer.h>
+#include <linux/if_vlan.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -115,7 +120,7 @@
 
 #define DRV_NAME "ns83820"
 
-/* Global parameters.  See MODULE_PARM near the bottom. */
+/* Global parameters.  See module_param near the bottom. */
 static int ihr = 2;
 static int reset_phy = 0;
 static int lnksts = 0;		/* CFG_LNKSTS bit polarity */
@@ -138,6 +143,9 @@
 
 /* tunables */
 #define RX_BUF_SIZE	1500	/* 8192 */
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+#define NS83820_VLAN_ACCEL_SUPPORT
+#endif
 
 /* Must not exceed ~65000. */
 #define NR_RX_DESC	64
@@ -262,6 +270,8 @@
 #define EXTSTS_UDPPKT	0x00200000
 #define EXTSTS_TCPPKT	0x00080000
 #define EXTSTS_IPPKT	0x00020000
+#define EXTSTS_VPKT	0x00010000
+#define EXTSTS_VTG_MASK	0x0000ffff
 
 #define SPDSTS_POLARITY	(CFG_SPDSTS1 | CFG_SPDSTS0 | CFG_DUPSTS | (lnksts ? CFG_LNKSTS : 0))
 
@@ -403,6 +413,7 @@
 #define CMDSTS_INTR	0x20000000
 #define CMDSTS_ERR	0x10000000
 #define CMDSTS_OK	0x08000000
+#define CMDSTS_RUNT	0x00200000
 #define CMDSTS_LEN_MASK	0x0000ffff
 
 #define CMDSTS_DEST_MASK	0x01800000
@@ -432,6 +443,10 @@
 
 	struct pci_dev		*pci_dev;
 
+#ifdef NS83820_VLAN_ACCEL_SUPPORT
+	struct vlan_group	*vlgrp;
+#endif
+
 	struct rx_info		rx_info;
 	struct tasklet_struct	rx_tasklet;
 
@@ -494,6 +509,33 @@
 	(((NR_TX_DESC-2 + dev->tx_done_idx - dev->tx_free_idx) % NR_TX_DESC) > MIN_TX_DESC_FREE)
 
 
+#ifdef NS83820_VLAN_ACCEL_SUPPORT 
+static void ns83820_vlan_rx_register(struct net_device *ndev, struct vlan_group *grp)
+{
+	struct ns83820 *dev = PRIV(ndev);
+
+	spin_lock_irq(&dev->misc_lock);
+	spin_lock(&dev->tx_lock);
+
+	dev->vlgrp = grp;
+
+	spin_unlock(&dev->tx_lock);
+	spin_unlock_irq(&dev->misc_lock);
+}
+
+static void ns83820_vlan_rx_kill_vid(struct net_device *ndev, unsigned short vid)
+{
+	struct ns83820 *dev = PRIV(ndev);
+
+	spin_lock_irq(&dev->misc_lock);
+	spin_lock(&dev->tx_lock);
+	if (dev->vlgrp)
+		dev->vlgrp->vlan_devices[vid] = NULL;
+	spin_unlock(&dev->tx_lock);
+	spin_unlock_irq(&dev->misc_lock);
+}
+#endif
+
 /* Packet Receiver
  *
  * The hardware supports linked lists of receive descriptors for
@@ -836,6 +878,7 @@
 	struct ns83820 *dev = PRIV(ndev);
 	struct rx_info *info = &dev->rx_info;
 	unsigned next_rx;
+	int rx_rc, len;
 	u32 cmdsts, *desc;
 	unsigned long flags;
 	int nr = 0;
@@ -876,8 +919,24 @@
 
 		pci_unmap_single(dev->pci_dev, bufptr,
 				 RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+		len = cmdsts & CMDSTS_LEN_MASK;
+#ifdef NS83820_VLAN_ACCEL_SUPPORT
+		/* NH: As was mentioned below, this chip is kinda
+		 * brain dead about vlan tag stripping.  Frames
+		 * that are 64 bytes with a vlan header appended
+		 * like arp frames, or pings, are flagged as Runts
+		 * when the tag is stripped and hardware.  This
+		 * also means that the OK bit in the descriptor 
+		 * is cleared when the frame comes in so we have
+		 * to do a specific length check here to make sure
+		 * the frame would have been ok, had we not stripped
+		 * the tag.
+		 */ 
+		if (likely((CMDSTS_OK & cmdsts) ||
+			((cmdsts & CMDSTS_RUNT) && len >= 56))) {   
+#else
 		if (likely(CMDSTS_OK & cmdsts)) {
-			int len = cmdsts & 0xffff;
+#endif
 			skb_put(skb, len);
 			if (unlikely(!skb))
 				goto netdev_mangle_me_harder_failed;
@@ -891,7 +950,18 @@
 				skb->ip_summed = CHECKSUM_NONE;
 			}
 			skb->protocol = eth_type_trans(skb, ndev);
-			if (NET_RX_DROP == netif_rx(skb)) {
+#ifdef NS83820_VLAN_ACCEL_SUPPORT 
+			if(extsts & EXTSTS_VPKT) {
+				unsigned short tag;
+				tag = ntohs(extsts & EXTSTS_VTG_MASK);
+				rx_rc = vlan_hwaccel_rx(skb,dev->vlgrp,tag);
+			} else {
+				rx_rc = netif_rx(skb);
+			}
+#else
+			rx_rc = netif_rx(skb);
+#endif
+			if (NET_RX_DROP == rx_rc) {
 netdev_mangle_me_harder_failed:
 				dev->stats.rx_dropped ++;
 			}
@@ -1099,6 +1169,17 @@
 			extsts |= EXTSTS_UDPPKT;
 	}
 
+#ifdef NS83820_VLAN_ACCEL_SUPPORT
+	if(vlan_tx_tag_present(skb)) {
+		/* fetch the vlan tag info out of the
+		 * ancilliary data if the vlan code
+		 * is using hw vlan acceleration
+		 */
+		short tag = vlan_tx_tag_get(skb);
+		extsts |= (EXTSTS_VPKT | htons(tag));
+	}
+#endif
+
 	len = skb->len;
 	if (nr_frags)
 		len -= skb->data_len;
@@ -1854,7 +1935,6 @@
 	SET_ETHTOOL_OPS(ndev, &ops);
 	ndev->tx_timeout = ns83820_tx_timeout;
 	ndev->watchdog_timeo = 5 * HZ;
-
 	pci_set_drvdata(pci_dev, ndev);
 
 	ns83820_do_reset(dev, CR_RST);
@@ -1980,11 +2060,25 @@
 	 * a ping with a VLAN header) then the card, strips the 4 byte VLAN
 	 * tag and then checks the packet size, so if RXCFG_ARP is not enabled,
 	 * it discrards it!.  These guys......
+	 * also turn on tag stripping if hardware acceleration is enabled
 	 */
-	writel(VRCR_IPEN | VRCR_VTDEN, dev->base + VRCR);
+#ifdef NS83820_VLAN_ACCEL_SUPPORT
+#define VRCR_INIT_VALUE (VRCR_IPEN|VRCR_VTDEN|VRCR_VTREN) 
+#else
+#define VRCR_INIT_VALUE (VRCR_IPEN|VRCR_VTDEN)
+#endif
+	writel(VRCR_INIT_VALUE, dev->base + VRCR);
 
-	/* Enable per-packet TCP/UDP/IP checksumming */
-	writel(VTCR_PPCHK, dev->base + VTCR);
+	/* Enable per-packet TCP/UDP/IP checksumming
+	 * and per packet vlan tag insertion if
+	 * vlan hardware acceleration is enabled
+	 */
+#ifdef NS83820_VLAN_ACCEL_SUPPORT
+#define VTCR_INIT_VALUE (VTCR_PPCHK|VTCR_VPPTI)
+#else
+#define VTCR_INIT_VALUE VTCR_PPCHK
+#endif
+	writel(VTCR_INIT_VALUE, dev->base + VTCR);
 
 	/* Ramit : Enable async and sync pause frames */
 	/* writel(0, dev->base + PCR); */
@@ -2001,6 +2095,13 @@
 	ndev->features |= NETIF_F_SG;
 	ndev->features |= NETIF_F_IP_CSUM;
 
+#ifdef NS83820_VLAN_ACCEL_SUPPORT
+	/* We also support hardware vlan acceleration */
+	ndev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+	ndev->vlan_rx_register = ns83820_vlan_rx_register;
+	ndev->vlan_rx_kill_vid = ns83820_vlan_rx_kill_vid;
+#endif
+
 	if (using_dac) {
 		printk(KERN_INFO "%s: using 64 bit addressing.\n",
 			ndev->name);
@@ -2109,13 +2210,13 @@
 
 MODULE_DEVICE_TABLE(pci, ns83820_pci_tbl);
 
-MODULE_PARM(lnksts, "i");
+module_param(lnksts, int, 0);
 MODULE_PARM_DESC(lnksts, "Polarity of LNKSTS bit");
 
-MODULE_PARM(ihr, "i");
+module_param(ihr, int, 0);
 MODULE_PARM_DESC(ihr, "Time in 100 us increments to delay interrupts (range 0-127)");
 
-MODULE_PARM(reset_phy, "i");
+module_param(reset_phy, int, 0);
 MODULE_PARM_DESC(reset_phy, "Set to 1 to reset the PHY on startup");
 
 module_init(ns83820_init);
diff -Nru a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
--- a/drivers/net/pcnet32.c	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/pcnet32.c	2004-10-26 01:30:56 -04:00
@@ -359,9 +359,9 @@
     struct net_device_stats stats;
     char		tx_full;
     int			options;
-    int	shared_irq:1,			/* shared irq possible */
-	dxsuflo:1,			/* disable transmit stop on uflo */
-	mii:1;				/* mii port available */
+    unsigned int	shared_irq:1,	/* shared irq possible */
+			dxsuflo:1,	/* disable transmit stop on uflo */
+			mii:1;		/* mii port available */
     struct net_device	*next;
     struct mii_if_info	mii_if;
     struct timer_list	watchdog_timer;
diff -Nru a/drivers/net/sis900.c b/drivers/net/sis900.c
--- a/drivers/net/sis900.c	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/sis900.c	2004-10-26 01:30:56 -04:00
@@ -262,13 +262,12 @@
 	u8 reg;
 	int i;
 
-	isa_bridge = pci_find_device(PCI_VENDOR_ID_SI, 0x0008, isa_bridge);
+	isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, 0x0008, isa_bridge);
+	if (!isa_bridge)
+		isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, 0x0018, isa_bridge);
 	if (!isa_bridge) {
-		isa_bridge = pci_find_device(PCI_VENDOR_ID_SI, 0x0018, isa_bridge);
-		if (!isa_bridge) {
-			printk("%s: Can not find ISA bridge\n", net_dev->name);
-			return 0;
-		}
+		printk("%s: Can not find ISA bridge\n", net_dev->name);
+		return 0;
 	}
 	pci_read_config_byte(isa_bridge, 0x48, &reg);
 	pci_write_config_byte(isa_bridge, 0x48, reg | 0x40);
@@ -278,6 +277,7 @@
 		((u8 *)(net_dev->dev_addr))[i] = inb(0x71); 
 	}
 	pci_write_config_byte(isa_bridge, 0x48, reg & ~0x40);
+	pci_dev_put(isa_bridge);
 
 	return 1;
 }
@@ -488,9 +488,11 @@
 	}
 
 	/* save our host bridge revision */
-	dev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630, NULL);
-	if (dev)
+	dev = pci_get_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630, NULL);
+	if (dev) {
 		pci_read_config_byte(dev, PCI_CLASS_REVISION, &sis_priv->host_bridge_rev);
+		pci_dev_put(dev);
+	}
 
 	/* print some information about our NIC */
 	printk(KERN_INFO "%s: %s at %#lx, IRQ %d, ", net_dev->name,
diff -Nru a/drivers/net/skfp/hwmtm.c b/drivers/net/skfp/hwmtm.c
--- a/drivers/net/skfp/hwmtm.c	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/skfp/hwmtm.c	2004-10-26 01:30:56 -04:00
@@ -1901,7 +1901,8 @@
 	}
 
 	if (!smc->hw.mac_ring_is_up || frag_count > queue->tx_free) {
-		if (frame_status &= ~LAN_TX) {
+		frame_status &= ~LAN_TX;
+		if (frame_status) {
 			DB_TX("Ring is down: terminate LAN_TX",0,0,2) ;
 		}
 		else {
diff -Nru a/drivers/net/slip.c b/drivers/net/slip.c
--- a/drivers/net/slip.c	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/slip.c	2004-10-26 01:30:56 -04:00
@@ -57,6 +57,7 @@
 #define SL_CHECK_TRANSMIT
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -85,8 +86,8 @@
 
 static struct net_device **slip_devs;
 
-int slip_maxdev = SL_NRUNIT;		/* Can be overridden with insmod! */
-MODULE_PARM(slip_maxdev, "i");
+static int slip_maxdev = SL_NRUNIT;
+module_param(slip_maxdev, int, 0);
 MODULE_PARM_DESC(slip_maxdev, "Maximum number of slip devices");
 
 static int slip_esc(unsigned char *p, unsigned char *d, int len);
@@ -458,13 +459,11 @@
 
 static void sl_tx_timeout(struct net_device *dev)
 {
-	struct slip *sl = (struct slip*)(dev->priv);
+	struct slip *sl = netdev_priv(dev);
 
 	spin_lock(&sl->lock);
 
 	if (netif_queue_stopped(dev)) {
-		struct slip *sl = (struct slip*)(dev->priv);
-
 		if (!netif_running(dev))
 			goto out;
 
@@ -494,7 +493,7 @@
 static int
 sl_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct slip *sl = (struct slip*)(dev->priv);
+	struct slip *sl = netdev_priv(dev);
 
 	spin_lock(&sl->lock);
 	if (!netif_running(dev))  {
@@ -528,7 +527,7 @@
 static int
 sl_close(struct net_device *dev)
 {
-	struct slip *sl = (struct slip*)(dev->priv);
+	struct slip *sl = netdev_priv(dev);
 
 	spin_lock_bh(&sl->lock);
 	if (sl->tty) {
@@ -547,7 +546,7 @@
 
 static int sl_open(struct net_device *dev)
 {
-	struct slip *sl = (struct slip*)(dev->priv);
+	struct slip *sl = netdev_priv(dev);
 
 	if (sl->tty==NULL)
 		return -ENODEV;
@@ -561,7 +560,7 @@
 
 static int sl_change_mtu(struct net_device *dev, int new_mtu)
 {
-	struct slip *sl = (struct slip*)(dev->priv);
+	struct slip *sl = netdev_priv(dev);
 
 	if (new_mtu < 68 || new_mtu > 65534)
 		return -EINVAL;
@@ -577,7 +576,7 @@
 sl_get_stats(struct net_device *dev)
 {
 	static struct net_device_stats stats;
-	struct slip *sl = (struct slip*)(dev->priv);
+	struct slip *sl = netdev_priv(dev);
 #ifdef SL_INCLUDE_CSLIP
 	struct slcompress *comp;
 #endif
@@ -612,7 +611,7 @@
 
 static int sl_init(struct net_device *dev)
 {
-	struct slip *sl = (struct slip*)(dev->priv);
+	struct slip *sl = netdev_priv(dev);
 
 	/*
 	 *	Finish setting up the DEVICE info. 
@@ -630,7 +629,7 @@
 
 static void sl_uninit(struct net_device *dev)
 {
-	struct slip *sl = (struct slip*)(dev->priv);
+	struct slip *sl = netdev_priv(dev);
 
 	sl_free_bufs(sl);
 }
@@ -719,7 +718,7 @@
 		if ((dev = slip_devs[i]) == NULL)
 			break;
 
-		sl = dev->priv;
+		sl = netdev_priv(dev);
 		if (sl->tty || sl->leased)
 			continue;
 		if (dev->flags&IFF_UP)
@@ -746,7 +745,7 @@
 		if (dev == NULL)
 			break;
 
-		sl = dev->priv;
+		sl = netdev_priv(dev);
 		if (sl->leased) {
 			if (sl->line != line)
 				continue;
@@ -788,7 +787,7 @@
 		i = sel;
 		dev = slip_devs[i];
 		if (score > 1) {
-			sl = dev->priv;
+			sl = netdev_priv(dev);
 			sl->flags &= (1 << SLF_INUSE);
 			return sl;
 		}
@@ -799,7 +798,7 @@
 		return NULL;
 
 	if (dev) {
-		sl = dev->priv;
+		sl = netdev_priv(dev);
 		if (test_bit(SLF_INUSE, &sl->flags)) {
 			unregister_netdevice(dev);
 			dev = NULL;
@@ -817,7 +816,7 @@
 		dev->base_addr  = i;
 	}
 
-	sl = dev->priv;
+	sl = netdev_priv(dev);
 
 	/* Initialize channel control data */
 	sl->magic       = SLIP_MAGIC;
@@ -1260,7 +1259,7 @@
 
 static int sl_ioctl(struct net_device *dev,struct ifreq *rq,int cmd)
 {
-	struct slip *sl = (struct slip*)(dev->priv);
+	struct slip *sl = netdev_priv(dev);
 	unsigned long *p = (unsigned long *)&rq->ifr_ifru;
 
 	if (sl == NULL)		/* Allocation failed ?? */
@@ -1406,7 +1405,7 @@
 			dev = slip_devs[i];
 			if (!dev)
 				continue;
-			sl = dev->priv;
+			sl = netdev_priv(dev);
 			spin_lock_bh(&sl->lock);
 			if (sl->tty) {
 				busy++;
@@ -1423,7 +1422,7 @@
 			continue;
 		slip_devs[i] = NULL;
 
-		sl = dev->priv;
+		sl = netdev_priv(dev);
 		if (sl->tty) {
 			printk(KERN_ERR "%s: tty discipline still running\n",
 			       dev->name);
diff -Nru a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c
--- a/drivers/net/tokenring/olympic.c	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/tokenring/olympic.c	2004-10-26 01:30:56 -04:00
@@ -1401,7 +1401,6 @@
 	u16 lan_status = 0, lan_status_diff  ; /* Initialize to stop compiler warning */
 	u8 fdx_prot_error ; 
 	u16 next_ptr;
-	int i ; 
 
 	arb_block = (olympic_priv->olympic_lap + olympic_priv->arb) ; 
 	asb_block = (olympic_priv->olympic_lap + olympic_priv->asb) ; 
diff -Nru a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
--- a/drivers/net/tulip/de2104x.c	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/tulip/de2104x.c	2004-10-26 01:30:56 -04:00
@@ -1208,8 +1208,7 @@
 		pci_write_config_dword(de->pdev, PCIPM, pmctl);
 
 		/* de4x5.c delays, so we do too */
-		current->state = TASK_UNINTERRUPTIBLE;
-		schedule_timeout(msecs_to_jiffies(10));
+		msleep(10);
 	}
 }
 
diff -Nru a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
--- a/drivers/net/tulip/de4x5.c	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/tulip/de4x5.c	2004-10-26 01:30:56 -04:00
@@ -5089,7 +5089,7 @@
     lp->useMII = TRUE;
 
     /* Search the MII address space for possible PHY devices */
-    for (n=0, lp->mii_cnt=0, i=1; !((i==1) && (n==1)); i=(++i)%DE4X5_MAX_MII) {
+    for (n=0, lp->mii_cnt=0, i=1; !((i==1) && (n==1)); i=(i+1)%DE4X5_MAX_MII) {
 	lp->phy[lp->active].addr = i;
 	if (i==0) n++;                             /* Count cycles */
 	while (de4x5_reset_phy(dev)<0) udelay(100);/* Wait for reset */
diff -Nru a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
--- a/drivers/net/tulip/tulip_core.c	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/tulip/tulip_core.c	2004-10-26 01:30:56 -04:00
@@ -1221,6 +1221,11 @@
 	struct tulip_private *tp;
 	/* See note below on the multiport cards. */
 	static unsigned char last_phys_addr[6] = {0x00, 'L', 'i', 'n', 'u', 'x'};
+	static struct pci_device_id early_486_chipsets[] = {
+		{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82424) },
+		{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496) },
+		{ },
+	};
 	static int last_irq;
 	static int multiport_cnt;	/* For four-port boards w/one EEPROM */
 	u8 chip_rev;
@@ -1274,17 +1279,15 @@
 	 *	without the workarounds being on.
 	 */
 
-	/* Intel Saturn. Switch to 8 long words burst, 8 long word cache aligned
-	   Aries might need this too. The Saturn errata are not pretty reading but
-	   thankfully it's an old 486 chipset.
+	/* 1. Intel Saturn. Switch to 8 long words burst, 8 long word cache
+	      aligned.  Aries might need this too. The Saturn errata are not 
+	      pretty reading but thankfully it's an old 486 chipset.
+
+	   2. The dreaded SiS496 486 chipset. Same workaround as Intel
+	      Saturn.
 	*/
 
-	if (pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82424, NULL)) {
-		csr0 = MRL | MRM | (8 << BurstLenShift) | (1 << CALShift);
-		force_csr0 = 1;
-	}
-	/* The dreaded SiS496 486 chipset. Same workaround as above. */
-	if (pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, NULL)) {
+	if (pci_dev_present(early_486_chipsets)) {
 		csr0 = MRL | MRM | (8 << BurstLenShift) | (1 << CALShift);
 		force_csr0 = 1;
 	}
diff -Nru a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c
--- a/drivers/net/tulip/xircom_cb.c	2004-10-26 01:30:56 -04:00
+++ b/drivers/net/tulip/xircom_cb.c	2004-10-26 01:30:56 -04:00
@@ -117,6 +117,9 @@
 static int xircom_close(struct net_device *dev);
 static void xircom_up(struct xircom_private *card);
 static struct net_device_stats *xircom_get_stats(struct net_device *dev);
+#if CONFIG_NET_POLL_CONTROLLER
+static void xircom_poll_controller(struct net_device *dev);
+#endif
 
 static void investigate_read_descriptor(struct net_device *dev,struct xircom_private *card, int descnr, unsigned int bufferoffset);
 static void investigate_write_descriptor(struct net_device *dev, struct xircom_private *card, int descnr, unsigned int bufferoffset);
@@ -269,6 +272,9 @@
 	dev->stop = &xircom_close;
 	dev->get_stats = &xircom_get_stats;
 	dev->priv = private;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	dev->poll_controller = &xircom_poll_controller;
+#endif
 	SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 	pci_set_drvdata(pdev, dev);
 
@@ -500,6 +506,14 @@
 } 
                                                  
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void xircom_poll_controller(struct net_device *dev)
+{
+	disable_irq(dev->irq);
+	xircom_interrupt(dev->irq, dev, NULL);
+	enable_irq(dev->irq);
+}
+#endif
 
 
 static void initialize_card(struct xircom_private *card)
diff -Nru a/include/linux/netdevice.h b/include/linux/netdevice.h
--- a/include/linux/netdevice.h	2004-10-26 01:30:56 -04:00
+++ b/include/linux/netdevice.h	2004-10-26 01:30:56 -04:00
@@ -930,8 +930,6 @@
 /* Load a device via the kmod */
 extern void		dev_load(const char *name);
 extern void		dev_mcast_init(void);
-extern int		netdev_register_fc(struct net_device *dev, void (*stimul)(struct net_device *dev));
-extern void		netdev_unregister_fc(int bit);
 extern int		netdev_max_backlog;
 extern int		weight_p;
 extern unsigned long	netdev_fc_xoff;
diff -Nru a/net/Kconfig b/net/Kconfig
--- a/net/Kconfig	2004-10-26 01:30:56 -04:00
+++ b/net/Kconfig	2004-10-26 01:30:56 -04:00
@@ -564,24 +564,6 @@
 
 	  If unsure, say N.
 
-config NET_HW_FLOWCONTROL
-	bool "Forwarding between high speed interfaces"
-	depends on EXPERIMENTAL
-	---help---
-	  This option enables NIC (Network Interface Card) hardware throttling
-	  during periods of extreme congestion. At the moment only a couple
-	  of device drivers support it (really only one -- tulip, a modified
-	  8390 driver can be found at
-	  <ftp://ftp.tux.org/pub/net/ip-routing/fastroute/fastroute-8390.tar.gz>).
-
-	  Really, this option is applicable to any machine attached to a fast
-	  enough network, and even a 10 Mb NIC is able to kill a not very slow
-	  box, such as a 120MHz Pentium.
-
-	  However, do not say Y here if you did not experience any serious
-	  problems.
-
-
 menu "QoS and/or fair queueing"
 
 config NET_SCHED
diff -Nru a/net/core/dev.c b/net/core/dev.c
--- a/net/core/dev.c	2004-10-26 01:30:56 -04:00
+++ b/net/core/dev.c	2004-10-26 01:30:56 -04:00
@@ -1390,66 +1390,6 @@
 DEFINE_PER_CPU(struct netif_rx_stats, netdev_rx_stat) = { 0, };
 
 
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-atomic_t netdev_dropping = ATOMIC_INIT(0);
-static unsigned long netdev_fc_mask = 1;
-unsigned long netdev_fc_xoff;
-spinlock_t netdev_fc_lock = SPIN_LOCK_UNLOCKED;
-
-static struct
-{
-	void (*stimul)(struct net_device *);
-	struct net_device *dev;
-} netdev_fc_slots[BITS_PER_LONG];
-
-int netdev_register_fc(struct net_device *dev,
-		       void (*stimul)(struct net_device *dev))
-{
-	int bit = 0;
-	unsigned long flags;
-
-	spin_lock_irqsave(&netdev_fc_lock, flags);
-	if (netdev_fc_mask != ~0UL) {
-		bit = ffz(netdev_fc_mask);
-		netdev_fc_slots[bit].stimul = stimul;
-		netdev_fc_slots[bit].dev = dev;
-		set_bit(bit, &netdev_fc_mask);
-		clear_bit(bit, &netdev_fc_xoff);
-	}
-	spin_unlock_irqrestore(&netdev_fc_lock, flags);
-	return bit;
-}
-
-void netdev_unregister_fc(int bit)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&netdev_fc_lock, flags);
-	if (bit > 0) {
-		netdev_fc_slots[bit].stimul = NULL;
-		netdev_fc_slots[bit].dev = NULL;
-		clear_bit(bit, &netdev_fc_mask);
-		clear_bit(bit, &netdev_fc_xoff);
-	}
-	spin_unlock_irqrestore(&netdev_fc_lock, flags);
-}
-
-static void netdev_wakeup(void)
-{
-	unsigned long xoff;
-
-	spin_lock(&netdev_fc_lock);
-	xoff = netdev_fc_xoff;
-	netdev_fc_xoff = 0;
-	while (xoff) {
-		int i = ffz(~xoff);
-		xoff &= ~(1 << i);
-		netdev_fc_slots[i].stimul(netdev_fc_slots[i].dev);
-	}
-	spin_unlock(&netdev_fc_lock);
-}
-#endif
-
 static void get_sample_stats(int cpu)
 {
 #ifdef RAND_LIE
@@ -1559,13 +1499,8 @@
 			return queue->cng_level;
 		}
 
-		if (queue->throttle) {
+		if (queue->throttle)
 			queue->throttle = 0;
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-			if (atomic_dec_and_test(&netdev_dropping))
-				netdev_wakeup();
-#endif
-		}
 
 		netif_rx_schedule(&queue->backlog_dev);
 		goto enqueue;
@@ -1574,9 +1509,6 @@
 	if (!queue->throttle) {
 		queue->throttle = 1;
 		__get_cpu_var(netdev_rx_stat).throttled++;
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-		atomic_inc(&netdev_dropping);
-#endif
 	}
 
 drop:
@@ -1848,16 +1780,6 @@
 		if (work >= quota || jiffies - start_time > 1)
 			break;
 
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-		if (queue->throttle &&
-		    queue->input_pkt_queue.qlen < no_cong_thresh ) {
-			queue->throttle = 0;
-			if (atomic_dec_and_test(&netdev_dropping)) {
-				netdev_wakeup();
-				break;
-			}
-		}
-#endif
 	}
 
 	backlog_dev->quota -= work;
@@ -1872,13 +1794,8 @@
 	smp_mb__before_clear_bit();
 	netif_poll_enable(backlog_dev);
 
-	if (queue->throttle) {
+	if (queue->throttle)
 		queue->throttle = 0;
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-		if (atomic_dec_and_test(&netdev_dropping))
-			netdev_wakeup();
-#endif
-	}
 	local_irq_enable();
 	return 0;
 }
@@ -3364,12 +3281,6 @@
 
 #ifdef CONFIG_KMOD
 EXPORT_SYMBOL(dev_load);
-#endif
-#ifdef CONFIG_NET_HW_FLOWCONTROL
-EXPORT_SYMBOL(netdev_dropping);
-EXPORT_SYMBOL(netdev_fc_xoff);
-EXPORT_SYMBOL(netdev_register_fc);
-EXPORT_SYMBOL(netdev_unregister_fc);
 #endif
 
 #ifdef CONFIG_NET_CLS_ACT
diff -Nru a/net/irda/irlan/irlan_client.c b/net/irda/irlan/irlan_client.c
--- a/net/irda/irlan/irlan_client.c	2004-10-26 01:30:56 -04:00
+++ b/net/irda/irlan/irlan_client.c	2004-10-26 01:30:56 -04:00
@@ -234,7 +234,7 @@
 	ASSERT(tsap == self->client.tsap_ctrl, return;);
 
        	/* Remove frames queued on the control channel */
-	while ((skb = skb_dequeue(&self->client.txq))) {
+	while ((skb = skb_dequeue(&self->client.txq)) != NULL) {
 		dev_kfree_skb(skb);
 	}
 	self->client.tx_busy = FALSE;

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [BK PATCHES] 2.6.x net driver updates
@ 2004-10-25  8:24 Jeff Garzik
  0 siblings, 0 replies; 28+ messages in thread
From: Jeff Garzik @ 2004-10-25  8:24 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev


Continuing the merge...  e100, defxx, set-config no-op removal, acenic

Please do a

	bk pull bk://gkernel.bkbits.net/net-drivers-2.6

This will update the following files:

 drivers/media/dvb/dvb-core/dvb_net.c |    9 -
 drivers/net/acenic.c                 |  171 +++++++++++++++--------------------
 drivers/net/acenic.h                 |   23 +---
 drivers/net/acenic_firmware.h        |    2 
 drivers/net/defxx.c                  |  144 ++++++++++++++---------------
 drivers/net/defxx.h                  |    2 
 drivers/net/e100.c                   |   51 ++++++----
 drivers/net/ibmlana.c                |    9 -
 drivers/net/meth.c                   |   26 -----
 drivers/net/sk_mca.c                 |    9 -
 drivers/net/wan/lmc/lmc_main.c       |    9 -
 drivers/net/wireless/netwave_cs.c    |   12 --
 12 files changed, 185 insertions(+), 282 deletions(-)

through these ChangeSets:

Anton Blanchard:
  o fix acenic hotplug

Ganesh Venkatesan:
  o e100: Driver version number update
  o e100: Fix set ringparam for ethtool returning error code on bad input
  o e100: Fix loss of connectivity to BMC when interface is brought down.
  o e100 driver version number update
  o e100 - use NET_IP_ALIGN to set rx data buffer alignment
  o e100 - Use pci_device_name for syslog messages till registering netdevice

Jeff Garzik:
  o [netdev] Remove no-op in-driver implementations of ->set_config()

Jesse Brandeburg:
  o e100: whitespace and DPRINTKS
  o e100: fix NAPI race with watchdog

Maciej W. Rozycki:
  o defxx device name fixes
  o defxx trivial updates

Stephen Hemminger:
  o (4/4) acenic - don't spin forever in hard_start_xmit
  o (3/4) acenic - __iomem warnings cleanup
  o (2/4) acenic - eliminate MAX_SKB_FRAGS #if
  o (1/4) acenic - use netdev_priv

diff -Nru a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
--- a/drivers/media/dvb/dvb-core/dvb_net.c	2004-10-25 03:39:21 -04:00
+++ b/drivers/media/dvb/dvb-core/dvb_net.c	2004-10-25 03:39:21 -04:00
@@ -917,14 +917,6 @@
 }
 
 
-static int dvb_net_set_config(struct net_device *dev, struct ifmap *map)
-{
-	if (netif_running(dev))
-		return -EBUSY;
-	return 0;
-}
-
-
 static void wq_restart_net_feed (void *data)
 {
 	struct net_device *dev = data;
@@ -983,7 +975,6 @@
 	dev->hard_start_xmit	= dvb_net_tx;
 	dev->get_stats		= dvb_net_get_stats;
 	dev->set_multicast_list = dvb_net_set_multicast_list;
-	dev->set_config         = dvb_net_set_config;
 	dev->set_mac_address    = dvb_net_set_mac;
 	dev->mtu		= 4096;
 	dev->mc_count           = 0;
diff -Nru a/drivers/net/acenic.c b/drivers/net/acenic.c
--- a/drivers/net/acenic.c	2004-10-25 03:39:21 -04:00
+++ b/drivers/net/acenic.c	2004-10-25 03:39:21 -04:00
@@ -443,7 +443,7 @@
 MODULE_PARM_DESC(tx_ratio, "AceNIC/3C985/GA620 ratio of NIC memory used for TX/RX descriptors (range 0-63)");
 
 
-static char version[] __initdata = 
+static char version[] __devinitdata = 
   "acenic.c: v0.92 08/05/2002  Jes Sorensen, linux-acenic@SunSITE.dk\n"
   "                            http://home.cern.ch/~jes/gige/acenic.html\n";
 
@@ -538,7 +538,7 @@
 	 * addresses but who gives a damn.
 	 */
 	dev->base_addr = pci_resource_start(pdev, 0);
-	ap->regs = (struct ace_regs *)ioremap(dev->base_addr, 0x4000);
+	ap->regs = ioremap(dev->base_addr, 0x4000);
 	if (!ap->regs) {
 		printk(KERN_ERR "%s:  Unable to map I/O register, "
 		       "AceNIC %i will be disabled.\n",
@@ -631,7 +631,7 @@
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct ace_private *ap = netdev_priv(dev);
-	struct ace_regs *regs = ap->regs;
+	struct ace_regs __iomem *regs = ap->regs;
 	short i;
 
 	unregister_netdev(dev);
@@ -884,7 +884,7 @@
 /*
  * Commands are considered to be slow.
  */
-static inline void ace_issue_cmd(struct ace_regs *regs, struct cmd *cmd)
+static inline void ace_issue_cmd(struct ace_regs __iomem *regs, struct cmd *cmd)
 {
 	u32 idx;
 
@@ -897,10 +897,10 @@
 }
 
 
-static int __init ace_init(struct net_device *dev)
+static int __devinit ace_init(struct net_device *dev)
 {
 	struct ace_private *ap;
-	struct ace_regs *regs;
+	struct ace_regs __iomem *regs;
 	struct ace_info *info = NULL;
 	struct pci_dev *pdev;
 	unsigned long myjif;
@@ -1318,11 +1318,10 @@
 	writel(TX_RING_BASE, &regs->WinBase);
 
 	if (ACE_IS_TIGON_I(ap)) {
-		ap->tx_ring = (struct tx_desc *)regs->Window;
-		for (i = 0; i < (TIGON_I_TX_RING_ENTRIES * 
-				 sizeof(struct tx_desc) / 4); i++) {
-			writel(0, (unsigned long)ap->tx_ring + i * 4);
-		}
+		ap->tx_ring = (struct tx_desc *) regs->Window;
+		for (i = 0; i < (TIGON_I_TX_RING_ENTRIES 
+				 * sizeof(struct tx_desc)) / sizeof(u32); i++)
+			writel(0, (void __iomem *)ap->tx_ring  + i * 4);
 
 		set_aceaddr(&info->tx_ctrl.rngptr, TX_RING_BASE);
 	} else {
@@ -1549,14 +1548,9 @@
 
 static void ace_set_rxtx_parms(struct net_device *dev, int jumbo)
 {
-	struct ace_private *ap;
-	struct ace_regs *regs;
-	int board_idx;
-
-	ap = netdev_priv(dev);
-	regs = ap->regs;
-
-	board_idx = ap->board_idx;
+	struct ace_private *ap = netdev_priv(dev);
+	struct ace_regs __iomem *regs = ap->regs;
+	int board_idx = ap->board_idx;
 
 	if (board_idx >= 0) {
 		if (!jumbo) {
@@ -1594,7 +1588,7 @@
 {
 	struct net_device *dev = data;
 	struct ace_private *ap = netdev_priv(dev);
-	struct ace_regs *regs = ap->regs;
+	struct ace_regs __iomem *regs = ap->regs;
 
 	/*
 	 * We haven't received a stats update event for more than 2.5
@@ -1617,7 +1611,7 @@
 
 static void ace_tasklet(unsigned long dev)
 {
-	struct ace_private *ap = ((struct net_device *)dev)->priv;
+	struct ace_private *ap = netdev_priv((struct net_device *)dev);
 	int cur_size;
 
 	cur_size = atomic_read(&ap->cur_rx_bufs);
@@ -1675,10 +1669,9 @@
  */
 static void ace_load_std_rx_ring(struct ace_private *ap, int nr_bufs)
 {
-	struct ace_regs *regs;
+	struct ace_regs __iomem *regs = ap->regs;
 	short i, idx;
-
-	regs = ap->regs;
+	
 
 	prefetchw(&ap->cur_rx_bufs);
 
@@ -1739,11 +1732,9 @@
 
 static void ace_load_mini_rx_ring(struct ace_private *ap, int nr_bufs)
 {
-	struct ace_regs *regs;
+	struct ace_regs __iomem *regs = ap->regs;
 	short i, idx;
 
-	regs = ap->regs;
-
 	prefetchw(&ap->cur_mini_bufs);
 
 	idx = ap->rx_mini_skbprd;
@@ -1798,11 +1789,9 @@
  */
 static void ace_load_jumbo_rx_ring(struct ace_private *ap, int nr_bufs)
 {
-	struct ace_regs *regs;
+	struct ace_regs __iomem *regs = ap->regs;
 	short i, idx;
 
-	regs = ap->regs;
-
 	idx = ap->rx_jumbo_skbprd;
 
 	for (i = 0; i < nr_bufs; i++) {
@@ -2082,8 +2071,7 @@
 	 * the 12.3.x Firmware - my Tigon I NICs seem to disagree!
 	 */
 	if (ACE_IS_TIGON_I(ap)) {
-		struct ace_regs *regs = ap->regs;
-		writel(idx, &regs->RxRetCsm);
+		writel(idx, &ap->regs->RxRetCsm);
 	}
 	ap->cur_rx = idx;
 
@@ -2163,16 +2151,13 @@
 
 static irqreturn_t ace_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
 {
-	struct ace_private *ap;
-	struct ace_regs *regs;
 	struct net_device *dev = (struct net_device *)dev_id;
+	struct ace_private *ap = netdev_priv(dev);
+	struct ace_regs __iomem *regs = ap->regs;
 	u32 idx;
 	u32 txcsm, rxretcsm, rxretprd;
 	u32 evtcsm, evtprd;
 
-	ap = netdev_priv(dev);
-	regs = ap->regs;
-
 	/*
 	 * In case of PCI shared interrupts or spurious interrupts,
 	 * we want to make sure it is actually our interrupt before
@@ -2325,13 +2310,10 @@
 
 static int ace_open(struct net_device *dev)
 {
-	struct ace_private *ap;
-	struct ace_regs *regs;
+	struct ace_private *ap = netdev_priv(dev);
+	struct ace_regs __iomem *regs = ap->regs;
 	struct cmd cmd;
 
-	ap = netdev_priv(dev);
-	regs = ap->regs;
-
 	if (!(ap->fw_running)) {
 		printk(KERN_WARNING "%s: Firmware not running!\n", dev->name);
 		return -EBUSY;
@@ -2383,8 +2365,8 @@
 
 static int ace_close(struct net_device *dev)
 {
-	struct ace_private *ap;
-	struct ace_regs *regs;
+	struct ace_private *ap = netdev_priv(dev);
+	struct ace_regs __iomem *regs = ap->regs;
 	struct cmd cmd;
 	unsigned long flags;
 	short i;
@@ -2396,9 +2378,7 @@
 	 */
 	netif_stop_queue(dev);
 
-	ap = netdev_priv(dev);
-	regs = ap->regs;
-
+	
 	if (ap->promisc) {
 		cmd.evt = C_SET_PROMISC_MODE;
 		cmd.code = C_C_PROMISC_DISABLE;
@@ -2433,9 +2413,11 @@
 
 		if (mapping) {
 			if (ACE_IS_TIGON_I(ap)) {
-				writel(0, &ap->tx_ring[i].addr.addrhi);
-				writel(0, &ap->tx_ring[i].addr.addrlo);
-				writel(0, &ap->tx_ring[i].flagsize);
+				struct tx_desc __iomem *tx 
+					= (struct tx_desc __iomem *) &ap->tx_ring[i];
+				writel(0, &tx->addr.addrhi);
+				writel(0, &tx->addr.addrlo);
+				writel(0, &tx->flagsize);
 			} else
 				memset(ap->tx_ring + i, 0,
 				       sizeof(struct tx_desc));
@@ -2492,11 +2474,12 @@
 #endif
 
 	if (ACE_IS_TIGON_I(ap)) {
-		writel(addr >> 32, &desc->addr.addrhi);
-		writel(addr & 0xffffffff, &desc->addr.addrlo);
-		writel(flagsize, &desc->flagsize);
+		struct tx_desc __iomem *io = (struct tx_desc __iomem *) desc;
+		writel(addr >> 32, &io->addr.addrhi);
+		writel(addr & 0xffffffff, &io->addr.addrlo);
+		writel(flagsize, &io->flagsize);
 #if ACENIC_DO_VLAN
-		writel(vlan_tag, &desc->vlanres);
+		writel(vlan_tag, &io->vlanres);
 #endif
 	} else {
 		desc->addr.addrhi = addr >> 32;
@@ -2512,9 +2495,10 @@
 static int ace_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct ace_private *ap = netdev_priv(dev);
-	struct ace_regs *regs = ap->regs;
+	struct ace_regs __iomem *regs = ap->regs;
 	struct tx_desc *desc;
 	u32 idx, flagsize;
+	unsigned long maxjiff = jiffies + 3*HZ;
 
 restart:
 	idx = ap->tx_prd;
@@ -2522,10 +2506,7 @@
 	if (tx_ring_full(ap, ap->tx_ret_csm, idx))
 		goto overflow;
 
-#if MAX_SKB_FRAGS
-	if (!skb_shinfo(skb)->nr_frags)
-#endif
-	{
+	if (!skb_shinfo(skb)->nr_frags)	{
 		dma_addr_t mapping;
 		u32 vlan_tag = 0;
 
@@ -2547,9 +2528,7 @@
 			flagsize |= BD_FLG_COAL_NOW;
 
 		ace_load_tx_bd(ap, desc, mapping, flagsize, vlan_tag);
-	}
-#if MAX_SKB_FRAGS
-	else {
+	} else {
 		dma_addr_t mapping;
 		u32 vlan_tag = 0;
 		int i, len = 0;
@@ -2604,7 +2583,6 @@
 			ace_load_tx_bd(ap, desc, mapping, flagsize, vlan_tag);
 		}
 	}
-#endif
 
  	wmb();
  	ap->tx_prd = idx;
@@ -2624,7 +2602,7 @@
 	}
 
 	dev->trans_start = jiffies;
-	return 0;
+	return NETDEV_TX_OK;
 
 overflow:
 	/*
@@ -2643,15 +2621,22 @@
 	 * Alternative is to return with 1 not throttling queue. In this
 	 * case loop becomes longer, no more useful effects.
 	 */
-	barrier();
-	goto restart;
+	if (time_before(jiffies, maxjiff)) {
+		barrier();
+		cpu_relax();
+		goto restart;
+	}
+	
+	/* The ring is stuck full. */
+	printk(KERN_WARNING "%s: Transmit ring stuck full\n", dev->name);
+	return NETDEV_TX_BUSY;
 }
 
 
 static int ace_change_mtu(struct net_device *dev, int new_mtu)
 {
 	struct ace_private *ap = netdev_priv(dev);
-	struct ace_regs *regs = ap->regs;
+	struct ace_regs __iomem *regs = ap->regs;
 
 	if (new_mtu > ACE_JUMBO_MTU)
 		return -EINVAL;
@@ -2688,7 +2673,7 @@
 static int ace_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
 	struct ace_private *ap = netdev_priv(dev);
-	struct ace_regs *regs = ap->regs;
+	struct ace_regs __iomem *regs = ap->regs;
 	u32 link;
 
 	memset(ecmd, 0, sizeof(struct ethtool_cmd));
@@ -2741,7 +2726,7 @@
 static int ace_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
 	struct ace_private *ap = netdev_priv(dev);
-	struct ace_regs *regs = ap->regs;
+	struct ace_regs __iomem *regs = ap->regs;
 	u32 link, speed;
 
 	link = readl(&regs->GigLnkState);
@@ -2821,8 +2806,9 @@
  */
 static int ace_set_mac_addr(struct net_device *dev, void *p)
 {
+	struct ace_private *ap = netdev_priv(dev);
+	struct ace_regs __iomem *regs = ap->regs;
 	struct sockaddr *addr=p;
-	struct ace_regs *regs;
 	u8 *da;
 	struct cmd cmd;
 
@@ -2833,7 +2819,6 @@
 
 	da = (u8 *)dev->dev_addr;
 
-	regs = ((struct ace_private *)netdev_priv(dev))->regs;
 	writel(da[0] << 8 | da[1], &regs->MacAddrHi);
 	writel((da[2] << 24) | (da[3] << 16) | (da[4] << 8) | da[5],
 	       &regs->MacAddrLo);
@@ -2850,7 +2835,7 @@
 static void ace_set_multicast_list(struct net_device *dev)
 {
 	struct ace_private *ap = netdev_priv(dev);
-	struct ace_regs *regs = ap->regs;
+	struct ace_regs __iomem *regs = ap->regs;
 	struct cmd cmd;
 
 	if ((dev->flags & IFF_ALLMULTI) && !(ap->mcast_all)) {
@@ -2904,8 +2889,8 @@
 static struct net_device_stats *ace_get_stats(struct net_device *dev)
 {
 	struct ace_private *ap = netdev_priv(dev);
-	struct ace_mac_stats *mac_stats =
-		(struct ace_mac_stats *)ap->regs->Stats;
+	struct ace_mac_stats __iomem *mac_stats =
+		(struct ace_mac_stats __iomem *)ap->regs->Stats;
 
 	ap->stats.rx_missed_errors = readl(&mac_stats->drop_space);
 	ap->stats.multicast = readl(&mac_stats->kept_mc);
@@ -2915,10 +2900,10 @@
 }
 
 
-static void __init ace_copy(struct ace_regs *regs, void *src,
+static void __devinit ace_copy(struct ace_regs __iomem *regs, void *src,
 			    u32 dest, int size)
 {
-	unsigned long tdest;
+	void __iomem *tdest;
 	u32 *wsrc;
 	short tsize, i;
 
@@ -2928,7 +2913,7 @@
 	while (size > 0) {
 		tsize = min_t(u32, ((~dest & (ACE_WINDOW_SIZE - 1)) + 1),
 			    min_t(u32, size, ACE_WINDOW_SIZE));
-		tdest = (unsigned long)&regs->Window +
+		tdest = (void __iomem *) &regs->Window + 
 			(dest & (ACE_WINDOW_SIZE - 1));
 		writel(dest & ~(ACE_WINDOW_SIZE - 1), &regs->WinBase);
 		/*
@@ -2948,9 +2933,9 @@
 }
 
 
-static void __init ace_clear(struct ace_regs *regs, u32 dest, int size)
+static void __devinit ace_clear(struct ace_regs __iomem *regs, u32 dest, int size)
 {
-	unsigned long tdest;
+	void __iomem *tdest;
 	short tsize = 0, i;
 
 	if (size <= 0)
@@ -2959,7 +2944,7 @@
 	while (size > 0) {
 		tsize = min_t(u32, ((~dest & (ACE_WINDOW_SIZE - 1)) + 1),
 				min_t(u32, size, ACE_WINDOW_SIZE));
-		tdest = (unsigned long)&regs->Window +
+		tdest = (void __iomem *) &regs->Window + 
 			(dest & (ACE_WINDOW_SIZE - 1));
 		writel(dest & ~(ACE_WINDOW_SIZE - 1), &regs->WinBase);
 
@@ -2981,13 +2966,10 @@
  * This operation requires the NIC to be halted and is performed with
  * interrupts disabled and with the spinlock hold.
  */
-int __init ace_load_firmware(struct net_device *dev)
+int __devinit ace_load_firmware(struct net_device *dev)
 {
-	struct ace_private *ap;
-	struct ace_regs *regs;
-
-	ap = netdev_priv(dev);
-	regs = ap->regs;
+	struct ace_private *ap = netdev_priv(dev);
+	struct ace_regs __iomem *regs = ap->regs;
 
 	if (!(readl(&regs->CpuCtrl) & CPU_HALTED)) {
 		printk(KERN_ERR "%s: trying to download firmware while the "
@@ -3035,7 +3017,7 @@
  * Thanks to Stevarino Webinski for helping tracking down the bugs in the
  * code i2c readout code by beta testing all my hacks.
  */
-static void __init eeprom_start(struct ace_regs *regs)
+static void __devinit eeprom_start(struct ace_regs __iomem *regs)
 {
 	u32 local;
 
@@ -3064,7 +3046,7 @@
 }
 
 
-static void __init eeprom_prep(struct ace_regs *regs, u8 magic)
+static void __devinit eeprom_prep(struct ace_regs __iomem *regs, u8 magic)
 {
 	short i;
 	u32 local;
@@ -3101,7 +3083,7 @@
 }
 
 
-static int __init eeprom_check_ack(struct ace_regs *regs)
+static int __devinit eeprom_check_ack(struct ace_regs __iomem *regs)
 {
 	int state;
 	u32 local;
@@ -3129,7 +3111,7 @@
 }
 
 
-static void __init eeprom_stop(struct ace_regs *regs)
+static void __devinit eeprom_stop(struct ace_regs __iomem *regs)
 {
 	u32 local;
 
@@ -3164,11 +3146,11 @@
 /*
  * Read a whole byte from the EEPROM.
  */
-static int __init read_eeprom_byte(struct net_device *dev,
+static int __devinit read_eeprom_byte(struct net_device *dev,
 				   unsigned long offset)
 {
-	struct ace_private *ap;
-	struct ace_regs *regs;
+	struct ace_private *ap = netdev_priv(dev);
+	struct ace_regs __iomem *regs = ap->regs;
 	unsigned long flags;
 	u32 local;
 	int result = 0;
@@ -3179,9 +3161,6 @@
 		result = -ENODEV;
 		goto out;
 	}
-
-	ap = netdev_priv(dev);
-	regs = ap->regs;
 
 	/*
 	 * Don't take interrupts on this CPU will bit banging
diff -Nru a/drivers/net/acenic.h b/drivers/net/acenic.h
--- a/drivers/net/acenic.h	2004-10-25 03:39:21 -04:00
+++ b/drivers/net/acenic.h	2004-10-25 03:39:21 -04:00
@@ -10,11 +10,6 @@
  */
 #define USE_TX_COAL_NOW	 0
 
-#ifndef MAX_SKB_FRAGS
-#define MAX_SKB_FRAGS 0
-#endif
-
-
 /*
  * Addressing:
  *
@@ -638,7 +633,7 @@
 struct ace_private
 {
 	struct ace_info		*info;
-	struct ace_regs		*regs;		/* register base */
+	struct ace_regs	__iomem	*regs;		/* register base */
 	struct ace_skb		*skb;
 	dma_addr_t		info_dma;	/* 32/64 bit */
 
@@ -712,13 +707,7 @@
 }
 
 #define tx_free(ap) 		tx_space((ap)->tx_ret_csm, (ap)->tx_prd, ap)
-
-#if MAX_SKB_FRAGS
 #define tx_ring_full(ap, csm, prd)	(tx_space(ap, csm, prd) <= TX_RESERVED)
-#else
-#define tx_ring_full			0
-#endif
-
 
 static inline void set_aceaddr(aceaddr *aa, dma_addr_t addr)
 {
@@ -729,7 +718,7 @@
 }
 
 
-static inline void ace_set_txprd(struct ace_regs *regs,
+static inline void ace_set_txprd(struct ace_regs __iomem *regs,
 				 struct ace_private *ap, u32 value)
 {
 #ifdef INDEX_DEBUG
@@ -750,8 +739,8 @@
 
 static inline void ace_mask_irq(struct net_device *dev)
 {
-	struct ace_private *ap = dev->priv;
-	struct ace_regs *regs = ap->regs;
+	struct ace_private *ap = netdev_priv(dev);
+	struct ace_regs __iomem *regs = ap->regs;
 
 	if (ACE_IS_TIGON_I(ap))
 		writel(1, &regs->MaskInt);
@@ -764,8 +753,8 @@
 
 static inline void ace_unmask_irq(struct net_device *dev)
 {
-	struct ace_private *ap = dev->priv;
-	struct ace_regs *regs = ap->regs;
+	struct ace_private *ap = netdev_priv(dev);
+	struct ace_regs __iomem *regs = ap->regs;
  
 	if (ACE_IS_TIGON_I(ap))
 		writel(0, &regs->MaskInt);
diff -Nru a/drivers/net/acenic_firmware.h b/drivers/net/acenic_firmware.h
--- a/drivers/net/acenic_firmware.h	2004-10-25 03:39:21 -04:00
+++ b/drivers/net/acenic_firmware.h	2004-10-25 03:39:21 -04:00
@@ -23,7 +23,7 @@
 #define tigonFwRodata NULL
 #else
 /* Generated by genfw.c */
-static u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
+static u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __devinitdata = {
 0x10000003, 
 0x0, 0xd, 0xd, 0x3c1d0001, 
 0x8fbd5c54, 0x3a0f021, 0x3c100000, 0x26104000, 
diff -Nru a/drivers/net/defxx.c b/drivers/net/defxx.c
--- a/drivers/net/defxx.c	2004-10-25 03:39:21 -04:00
+++ b/drivers/net/defxx.c	2004-10-25 03:39:21 -04:00
@@ -19,7 +19,7 @@
  *   LVS	Lawrence V. Stefani <lstefani@yahoo.com>
  *
  * Maintainers:
- *   macro	Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+ *   macro	Maciej W. Rozycki <macro@linux-mips.org>
  *
  * Credits:
  *   I'd like to thank Patricia Cross for helping me get started with
@@ -190,6 +190,7 @@
  *		Feb 2001			Skb allocation fixes
  *		Feb 2001	davej		PCI enable cleanups.
  *		04 Aug 2003	macro		Converted to the DMA API.
+ *		14 Aug 2004	macro		Fix device names reported.
  */
 
 /* Include files */
@@ -214,12 +215,14 @@
 
 #include "defxx.h"
 
-/* Version information string - should be updated prior to each new release!!! */
+/* Version information string should be updated prior to each new release!  */
+#define DRV_NAME "defxx"
+#define DRV_VERSION "v1.07"
+#define DRV_RELDATE "2004/08/14"
 
 static char version[] __devinitdata =
-	"defxx.c:v1.06 2003/08/04  Lawrence V. Stefani and others\n";
-
-#define DRV_NAME "defxx"
+	DRV_NAME ": " DRV_VERSION " " DRV_RELDATE
+	"  Lawrence V. Stefani and others\n";
 
 #define DYNAMIC_BUFFERS 1
 
@@ -235,7 +238,7 @@
 static void		dfx_bus_init(struct net_device *dev);
 static void		dfx_bus_config_check(DFX_board_t *bp);
 
-static int		dfx_driver_init(struct net_device *dev);
+static int		dfx_driver_init(struct net_device *dev, const char *print_name);
 static int		dfx_adap_init(DFX_board_t *bp, int get_buffers);
 
 static int		dfx_open(struct net_device *dev);
@@ -404,24 +407,25 @@
  */
 static int __devinit dfx_init_one_pci_or_eisa(struct pci_dev *pdev, long ioaddr)
 {
+	static int version_disp;
+	char *print_name = DRV_NAME;
 	struct net_device *dev;
 	DFX_board_t	  *bp;			/* board pointer */
 	int alloc_size;				/* total buffer size used */
 	int err;
 
-#ifndef MODULE
-	static int version_disp;
-
-	if (!version_disp)	/* display version info if adapter is found */
-	{
+	if (!version_disp) {	/* display version info if adapter is found */
 		version_disp = 1;	/* set display flag to TRUE so that */
 		printk(version);	/* we only display this string ONCE */
 	}
-#endif
+
+	if (pdev != NULL)
+		print_name = pdev->slot_name;
 
 	dev = alloc_fddidev(sizeof(*bp));
 	if (!dev) {
-		printk (KERN_ERR "defxx: unable to allocate fddidev, aborting\n");
+		printk(KERN_ERR "%s: unable to allocate fddidev, aborting\n",
+		       print_name);
 		return -ENOMEM;
 	}
 
@@ -437,9 +441,12 @@
 
 	bp = dev->priv;
 
-	if (!request_region (ioaddr, pdev ? PFI_K_CSR_IO_LEN : PI_ESIC_K_CSR_IO_LEN, DRV_NAME)) {
-		printk (KERN_ERR "%s: Cannot reserve I/O resource 0x%x @ 0x%lx, aborting\n",
-			DRV_NAME, PFI_K_CSR_IO_LEN, ioaddr);
+	if (!request_region(ioaddr,
+			    pdev ? PFI_K_CSR_IO_LEN : PI_ESIC_K_CSR_IO_LEN,
+			    print_name)) {
+		printk(KERN_ERR "%s: Cannot reserve I/O resource "
+		       "0x%x @ 0x%lx, aborting\n", print_name,
+		       pdev ? PFI_K_CSR_IO_LEN : PI_ESIC_K_CSR_IO_LEN, ioaddr);
 		err = -EBUSY;
 		goto err_out;
 	}
@@ -468,7 +475,7 @@
 		pci_set_master (pdev);
 	}
 
-	if (dfx_driver_init(dev) != DFX_K_SUCCESS) {
+	if (dfx_driver_init(dev, print_name) != DFX_K_SUCCESS) {
 		err = -ENODEV;
 		goto err_out_region;
 	}
@@ -477,6 +484,7 @@
 	if (err)
 		goto err_out_kfree;
 
+	printk("%s: registered as %s\n", print_name, dev->name);
 	return 0;
 
 err_out_kfree:
@@ -770,6 +778,7 @@
  *       
  * Arguments:
  *   dev - pointer to device information
+ *   print_name - printable device name
  *
  * Functional Description:
  *   This function allocates additional resources such as the host memory
@@ -792,7 +801,8 @@
  *   returning from this routine.
  */
 
-static int __devinit dfx_driver_init(struct net_device *dev)
+static int __devinit dfx_driver_init(struct net_device *dev,
+				     const char *print_name)
 {
 	DFX_board_t *bp = dev->priv;
 	int			alloc_size;			/* total buffer size needed */
@@ -841,26 +851,20 @@
 
 	/*  Read the factory MAC address from the adapter then save it */
 
-	if (dfx_hw_port_ctrl_req(bp,
-							PI_PCTRL_M_MLA,
-							PI_PDATA_A_MLA_K_LO,
-							0,
-							&data) != DFX_K_SUCCESS)
-		{
-		printk("%s: Could not read adapter factory MAC address!\n", dev->name);
+	if (dfx_hw_port_ctrl_req(bp, PI_PCTRL_M_MLA, PI_PDATA_A_MLA_K_LO, 0,
+				 &data) != DFX_K_SUCCESS) {
+		printk("%s: Could not read adapter factory MAC address!\n",
+		       print_name);
 		return(DFX_K_FAILURE);
-		}
+	}
 	memcpy(&bp->factory_mac_addr[0], &data, sizeof(u32));
 
-	if (dfx_hw_port_ctrl_req(bp,
-							PI_PCTRL_M_MLA,
-							PI_PDATA_A_MLA_K_HI,
-							0,
-							&data) != DFX_K_SUCCESS)
-		{
-		printk("%s: Could not read adapter factory MAC address!\n", dev->name);
+	if (dfx_hw_port_ctrl_req(bp, PI_PCTRL_M_MLA, PI_PDATA_A_MLA_K_HI, 0,
+				 &data) != DFX_K_SUCCESS) {
+		printk("%s: Could not read adapter factory MAC address!\n",
+		       print_name);
 		return(DFX_K_FAILURE);
-		}
+	}
 	memcpy(&bp->factory_mac_addr[4], &data, sizeof(u16));
 
 	/*
@@ -872,27 +876,19 @@
 
 	memcpy(dev->dev_addr, bp->factory_mac_addr, FDDI_K_ALEN);
 	if (bp->bus_type == DFX_BUS_TYPE_EISA)
-		printk("%s: DEFEA at I/O addr = 0x%lX, IRQ = %d, Hardware addr = %02X-%02X-%02X-%02X-%02X-%02X\n",
-				dev->name,
-				dev->base_addr,
-				dev->irq,
-				dev->dev_addr[0],
-				dev->dev_addr[1],
-				dev->dev_addr[2],
-				dev->dev_addr[3],
-				dev->dev_addr[4],
-				dev->dev_addr[5]);
+		printk("%s: DEFEA at I/O addr = 0x%lX, IRQ = %d, "
+		       "Hardware addr = %02X-%02X-%02X-%02X-%02X-%02X\n",
+		       print_name, dev->base_addr, dev->irq,
+		       dev->dev_addr[0], dev->dev_addr[1],
+		       dev->dev_addr[2], dev->dev_addr[3],
+		       dev->dev_addr[4], dev->dev_addr[5]);
 	else
-		printk("%s: DEFPA at I/O addr = 0x%lX, IRQ = %d, Hardware addr = %02X-%02X-%02X-%02X-%02X-%02X\n",
-				dev->name,
-				dev->base_addr,
-				dev->irq,
-				dev->dev_addr[0],
-				dev->dev_addr[1],
-				dev->dev_addr[2],
-				dev->dev_addr[3],
-				dev->dev_addr[4],
-				dev->dev_addr[5]);
+		printk("%s: DEFPA at I/O addr = 0x%lX, IRQ = %d, "
+		       "Hardware addr = %02X-%02X-%02X-%02X-%02X-%02X\n",
+		       print_name, dev->base_addr, dev->irq,
+		       dev->dev_addr[0], dev->dev_addr[1],
+		       dev->dev_addr[2], dev->dev_addr[3],
+		       dev->dev_addr[4], dev->dev_addr[5]);
 
 	/*
 	 * Get memory for descriptor block, consumer block, and other buffers
@@ -909,11 +905,11 @@
 					(PI_ALIGN_K_DESC_BLK - 1);
 	bp->kmalloced = top_v = pci_alloc_consistent(bp->pci_dev, alloc_size,
 						     &bp->kmalloced_dma);
-	if (top_v == NULL)
-		{
-		printk("%s: Could not allocate memory for host buffers and structures!\n", dev->name);
+	if (top_v == NULL) {
+		printk("%s: Could not allocate memory for host buffers "
+		       "and structures!\n", print_name);
 		return(DFX_K_FAILURE);
-		}
+	}
 	memset(top_v, 0, alloc_size);	/* zero out memory before continuing */
 	top_p = bp->kmalloced_dma;	/* get physical address of buffer */
 
@@ -970,14 +966,20 @@
 
 	/* Display virtual and physical addresses if debug driver */
 
-	DBG_printk("%s: Descriptor block virt = %0lX, phys = %0X\n",				dev->name, (long)bp->descr_block_virt,	bp->descr_block_phys);
-	DBG_printk("%s: Command Request buffer virt = %0lX, phys = %0X\n",			dev->name, (long)bp->cmd_req_virt,		bp->cmd_req_phys);
-	DBG_printk("%s: Command Response buffer virt = %0lX, phys = %0X\n",			dev->name, (long)bp->cmd_rsp_virt,		bp->cmd_rsp_phys);
-	DBG_printk("%s: Receive buffer block virt = %0lX, phys = %0X\n",			dev->name, (long)bp->rcv_block_virt,	bp->rcv_block_phys);
-	DBG_printk("%s: Consumer block virt = %0lX, phys = %0X\n",				dev->name, (long)bp->cons_block_virt,	bp->cons_block_phys);
+	DBG_printk("%s: Descriptor block virt = %0lX, phys = %0X\n",
+		   print_name,
+		   (long)bp->descr_block_virt, bp->descr_block_phys);
+	DBG_printk("%s: Command Request buffer virt = %0lX, phys = %0X\n",
+		   print_name, (long)bp->cmd_req_virt, bp->cmd_req_phys);
+	DBG_printk("%s: Command Response buffer virt = %0lX, phys = %0X\n",
+		   print_name, (long)bp->cmd_rsp_virt, bp->cmd_rsp_phys);
+	DBG_printk("%s: Receive buffer block virt = %0lX, phys = %0X\n",
+		   print_name, (long)bp->rcv_block_virt, bp->rcv_block_phys);
+	DBG_printk("%s: Consumer block virt = %0lX, phys = %0X\n",
+		   print_name, (long)bp->cons_block_virt, bp->cons_block_phys);
 
 	return(DFX_K_SUCCESS);
-	}
+}
 
 \f
 /*
@@ -2668,12 +2670,12 @@
  
 static void my_skb_align(struct sk_buff *skb, int n)
 {
-	unsigned long x=(unsigned long)skb->data;	
+	unsigned long x = (unsigned long)skb->data;
 	unsigned long v;
 	
-	v=(x+n-1)&~(n-1);	/* Where we want to be */
+	v = ALIGN(x, n);	/* Where we want to be */
 	
-	skb_reserve(skb, v-x);
+	skb_reserve(skb, v - x);
 }
 
 \f
@@ -3428,11 +3430,6 @@
 {
 	int rc_pci, rc_eisa;
 
-/* when a module, this is printed whether or not devices are found in probe */
-#ifdef MODULE
-	printk(version);
-#endif
-
 	rc_pci = pci_module_init(&dfx_driver);
 	if (rc_pci >= 0) dfx_have_pci = 1;
 	
@@ -3453,6 +3450,9 @@
 
 module_init(dfx_init);
 module_exit(dfx_cleanup);
+MODULE_AUTHOR("Lawrence V. Stefani");
+MODULE_DESCRIPTION("DEC FDDIcontroller EISA/PCI (DEFEA/DEFPA) driver "
+		   DRV_VERSION " " DRV_RELDATE);
 MODULE_LICENSE("GPL");
 
 \f
diff -Nru a/drivers/net/defxx.h b/drivers/net/defxx.h
--- a/drivers/net/defxx.h	2004-10-25 03:39:21 -04:00
+++ b/drivers/net/defxx.h	2004-10-25 03:39:21 -04:00
@@ -16,7 +16,7 @@
  *   LVS	Lawrence V. Stefani <lstefani@yahoo.com>
  *
  * Maintainers:
- *   macro	Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+ *   macro	Maciej W. Rozycki <macro@linux-mips.org>
  *
  * Modification History:
  *		Date		Name	Description
diff -Nru a/drivers/net/e100.c b/drivers/net/e100.c
--- a/drivers/net/e100.c	2004-10-25 03:39:21 -04:00
+++ b/drivers/net/e100.c	2004-10-25 03:39:21 -04:00
@@ -154,8 +154,8 @@
 
 
 #define DRV_NAME		"e100"
-#define DRV_EXT			"-NAPI"
-#define DRV_VERSION		"3.0.27-k2"DRV_EXT
+#define DRV_EXT		"-NAPI"
+#define DRV_VERSION		"3.2.3-k2"DRV_EXT
 #define DRV_DESCRIPTION		"Intel(R) PRO/100 Network Driver"
 #define DRV_COPYRIGHT		"Copyright(c) 1999-2004 Intel Corporation"
 #define PFX			DRV_NAME ": "
@@ -574,13 +574,21 @@
 
 static inline void e100_enable_irq(struct nic *nic)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&nic->cmd_lock, flags);
 	writeb(irq_mask_none, &nic->csr->scb.cmd_hi);
+	spin_unlock_irqrestore(&nic->cmd_lock, flags);
 	e100_write_flush(nic);
 }
 
 static inline void e100_disable_irq(struct nic *nic)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&nic->cmd_lock, flags);
 	writeb(irq_mask_all, &nic->csr->scb.cmd_hi);
+	spin_unlock_irqrestore(&nic->cmd_lock, flags);
 	e100_write_flush(nic);
 }
 
@@ -595,16 +603,6 @@
 	writel(software_reset, &nic->csr->port);
 	e100_write_flush(nic); udelay(20);
 
-	/* TCO workaround - 82559 and greater */
-	if(nic->mac >= mac_82559_D101M) {
-		/* Issue a redundant CU load base without setting
-		 * general pointer, and without waiting for scb to
-		 * clear.  This gets us into post-driver.  Finally,
-		 * wait 20 msec for reset to take effect. */
-		writeb(cuc_load_base, &nic->csr->scb.cmd_lo);
-		mdelay(20);
-	}
-
 	/* Mask off our interrupt line - it's unmasked after reset */
 	e100_disable_irq(nic);
 }
@@ -1253,8 +1251,13 @@
 	mii_check_link(&nic->mii);
 
 	/* Software generated interrupt to recover from (rare) Rx
-	 * allocation failure */
-	writeb(irq_sw_gen, &nic->csr->scb.cmd_hi);
+	* allocation failure.
+	* Unfortunately have to use a spinlock to not re-enable interrupts
+	* accidentally, due to hardware that shares a register between the
+	* interrupt mask bit and the SW Interrupt generation bit */
+	spin_lock_irq(&nic->cmd_lock);
+	writeb(readb(&nic->csr->scb.cmd_hi) | irq_sw_gen,&nic->csr->scb.cmd_hi);
+	spin_unlock_irq(&nic->cmd_lock);
 	e100_write_flush(nic);
 
 	e100_update_stats(nic);
@@ -1304,6 +1307,7 @@
 	switch(err) {
 	case -ENOSPC:
 		/* We queued the skb, but now we're out of space. */
+		DPRINTK(TX_ERR, DEBUG, "No space for CB\n");
 		netif_stop_queue(netdev);
 		break;
 	case -ENOMEM:
@@ -1424,14 +1428,12 @@
 #define RFD_BUF_LEN (sizeof(struct rfd) + VLAN_ETH_FRAME_LEN)
 static inline int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
 {
-	unsigned int rx_offset = 2; /* u32 align protocol headers */
-
-	if(!(rx->skb = dev_alloc_skb(RFD_BUF_LEN + rx_offset)))
+	if(!(rx->skb = dev_alloc_skb(RFD_BUF_LEN + NET_IP_ALIGN)))
 		return -ENOMEM;
 
 	/* Align, init, and map the RFD. */
 	rx->skb->dev = nic->netdev;
-	skb_reserve(rx->skb, rx_offset);
+	skb_reserve(rx->skb, NET_IP_ALIGN);
 	memcpy(rx->skb->data, &nic->blank_rfd, sizeof(struct rfd));
 	rx->dma_addr = pci_map_single(nic->pdev, rx->skb->data,
 		RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL);
@@ -1470,7 +1472,7 @@
 
 	/* If data isn't ready, nothing to indicate */
 	if(unlikely(!(rfd_status & cb_complete)))
-       		return -EAGAIN;
+		return -EAGAIN;
 
 	/* Get actual data size */
 	actual_size = le16_to_cpu(rfd->actual_size) & 0x3FFF;
@@ -1762,7 +1764,7 @@
 
 	if(memcmp(nic->rx_to_clean->skb->data + sizeof(struct rfd),
 	   skb->data, ETH_DATA_LEN))
-       		err = -EAGAIN;
+		err = -EAGAIN;
 
 err_loopback_none:
 	mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR, 0);
@@ -1955,12 +1957,17 @@
 	struct param_range *rfds = &nic->params.rfds;
 	struct param_range *cbs = &nic->params.cbs;
 
+	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) 
+		return -EINVAL;
+
 	if(netif_running(netdev))
 		e100_down(nic);
 	rfds->count = max(ring->rx_pending, rfds->min);
 	rfds->count = min(rfds->count, rfds->max);
 	cbs->count = max(ring->tx_pending, cbs->min);
 	cbs->count = min(cbs->count, cbs->max);
+	DPRINTK(DRV, INFO, "Ring Param settings: rx: %d, tx %d\n",
+	        rfds->count, cbs->count);
 	if(netif_running(netdev))
 		e100_up(nic);
 
@@ -2172,6 +2179,7 @@
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	netdev->poll_controller = e100_netpoll;
 #endif
+	strcpy(netdev->name, pci_name(pdev));
 
 	nic = netdev_priv(netdev);
 	nic->netdev = netdev;
@@ -2255,6 +2263,7 @@
 
 	pci_enable_wake(pdev, 0, nic->flags & (wol_magic | e100_asf(nic)));
 
+	strcpy(netdev->name, "eth%d");
 	if((err = register_netdev(netdev))) {
 		DPRINTK(PROBE, ERR, "Cannot register net device, aborting.\n");
 		goto err_out_free;
@@ -2351,7 +2360,7 @@
 		printk(KERN_INFO PFX "%s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
 		printk(KERN_INFO PFX "%s\n", DRV_COPYRIGHT);
 	}
-        return pci_module_init(&e100_driver);
+	return pci_module_init(&e100_driver);
 }
 
 static void __exit e100_cleanup_module(void)
diff -Nru a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c
--- a/drivers/net/ibmlana.c	2004-10-25 03:39:21 -04:00
+++ b/drivers/net/ibmlana.c	2004-10-25 03:39:21 -04:00
@@ -885,14 +885,6 @@
 	return &priv->stat;
 }
 
-/* we don't support runtime reconfiguration, since am MCA card can
-   be unambigously identified by its POS registers. */
-
-static int ibmlana_config(struct net_device *dev, struct ifmap *map)
-{
-	return 0;
-}
-
 /* switch receiver mode. */
 
 static void ibmlana_set_multicast_list(struct net_device *dev)
@@ -984,7 +976,6 @@
 
 	dev->open = ibmlana_open;
 	dev->stop = ibmlana_close;
-	dev->set_config = ibmlana_config;
 	dev->hard_start_xmit = ibmlana_tx;
 	dev->do_ioctl = NULL;
 	dev->get_stats = ibmlana_stats;
diff -Nru a/drivers/net/meth.c b/drivers/net/meth.c
--- a/drivers/net/meth.c	2004-10-25 03:39:21 -04:00
+++ b/drivers/net/meth.c	2004-10-25 03:39:21 -04:00
@@ -368,31 +368,6 @@
 }
 
 /*
- * Configuration changes (passed on by ifconfig)
- */
-static int meth_config(struct net_device *dev, struct ifmap *map)
-{
-	if (dev->flags & IFF_UP) /* can't act on a running interface */
-		return -EBUSY;
-
-	/* Don't allow changing the I/O address */
-	if (map->base_addr != dev->base_addr) {
-		printk(KERN_WARNING "meth: Can't change I/O address\n");
-		return -EOPNOTSUPP;
-	}
-
-	/* Don't allow changing the IRQ */
-	if (map->irq != dev->irq) {
-		printk(KERN_WARNING "meth: Can't change IRQ\n");
-		return -EOPNOTSUPP;
-	}
-	DPRINTK("Configured\n");
-
-	/* ignore other fields */
-	return 0;
-}
-
-/*
  * Receive a packet: retrieve, encapsulate and pass over to upper levels
  */
 static void meth_rx(struct net_device* dev, unsigned long int_status)
@@ -813,7 +788,6 @@
 
 	dev->open            = meth_open;
 	dev->stop            = meth_release;
-	dev->set_config      = meth_config;
 	dev->hard_start_xmit = meth_tx;
 	dev->do_ioctl        = meth_ioctl;
 	dev->get_stats       = meth_stats;
diff -Nru a/drivers/net/sk_mca.c b/drivers/net/sk_mca.c
--- a/drivers/net/sk_mca.c	2004-10-25 03:39:21 -04:00
+++ b/drivers/net/sk_mca.c	2004-10-25 03:39:21 -04:00
@@ -972,14 +972,6 @@
 	return &(priv->stat);
 }
 
-/* we don't support runtime reconfiguration, since an MCA card can
-   be unambigously identified by its POS registers. */
-
-static int skmca_config(struct net_device *dev, struct ifmap *map)
-{
-	return 0;
-}
-
 /* switch receiver mode.  We use the LANCE's multicast filter to prefilter
    multicast addresses. */
 
@@ -1147,7 +1139,6 @@
 	/* set methods */
 	dev->open = skmca_open;
 	dev->stop = skmca_close;
-	dev->set_config = skmca_config;
 	dev->hard_start_xmit = skmca_tx;
 	dev->do_ioctl = NULL;
 	dev->get_stats = skmca_stats;
diff -Nru a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
--- a/drivers/net/wan/lmc/lmc_main.c	2004-10-25 03:39:21 -04:00
+++ b/drivers/net/wan/lmc/lmc_main.c	2004-10-25 03:39:21 -04:00
@@ -101,7 +101,6 @@
 static int lmc_close(struct net_device *dev);
 static struct net_device_stats *lmc_get_stats(struct net_device *dev);
 static irqreturn_t lmc_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
-static int lmc_set_config(struct net_device *dev, struct ifmap *map);
 static void lmc_initcsrs(lmc_softc_t * const sc, lmc_csrptr_t csr_base, size_t csr_size);
 static void lmc_softreset(lmc_softc_t * const);
 static void lmc_running_reset(struct net_device *dev);
@@ -814,7 +813,6 @@
     dev->stop = lmc_close;
     dev->get_stats = lmc_get_stats;
     dev->do_ioctl = lmc_ioctl;
-    dev->set_config = lmc_set_config;
     dev->tx_timeout = lmc_driver_timeout;
     dev->watchdog_timeo = (HZ); /* 1 second */
     
@@ -1973,13 +1971,6 @@
     LMC_CSR_WRITE (sc, csr_txlist, virt_to_bus (sc->lmc_txring));
 
     lmc_trace(sc->lmc_device, "lmc_softreset out");
-}
-
-static int lmc_set_config(struct net_device *dev, struct ifmap *map) /*fold00*/
-{
-    lmc_trace(dev, "lmc_set_config in");
-    lmc_trace(dev, "lmc_set_config out");
-    return -EOPNOTSUPP;
 }
 
 void lmc_gpio_mkinput(lmc_softc_t * const sc, u_int32_t bits) /*fold00*/
diff -Nru a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
--- a/drivers/net/wireless/netwave_cs.c	2004-10-25 03:39:21 -04:00
+++ b/drivers/net/wireless/netwave_cs.c	2004-10-25 03:39:21 -04:00
@@ -219,7 +219,6 @@
 /* Misc device stuff */
 static int netwave_open(struct net_device *dev);  /* Open the device */
 static int netwave_close(struct net_device *dev); /* Close the device */
-static int netwave_config(struct net_device *dev, struct ifmap *map);
 
 /* Packet transmission and Packet reception */
 static int netwave_start_xmit( struct sk_buff *skb, struct net_device *dev);
@@ -482,7 +481,6 @@
     /* Netwave specific entries in the device structure */
     SET_MODULE_OWNER(dev);
     dev->hard_start_xmit = &netwave_start_xmit;
-    dev->set_config = &netwave_config;
     dev->get_stats  = &netwave_get_stats;
     dev->set_multicast_list = &set_multicast_list;
     /* wireless extensions */
@@ -1286,16 +1284,6 @@
     /* Set the IENA bit in COR */
     wait_WOC(iobase);
     outb(corConfIENA + corConfLVLREQ, iobase + NETWAVE_REG_COR);
-}
-
-/*
- * Function netwave_config (dev, map)
- *
- *    Configure device, this work is done by netwave_pcmcia_config when a
- *    card is inserted
- */
-static int netwave_config(struct net_device *dev, struct ifmap *map) {
-    return 0; 
 }
 
 /*

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [BK PATCHES] 2.6.x net driver updates
@ 2004-10-22  2:11 Jeff Garzik
  0 siblings, 0 replies; 28+ messages in thread
From: Jeff Garzik @ 2004-10-22  2:11 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev


The day's net driver merges.

Please do a

	bk pull bk://gkernel.bkbits.net/net-drivers-2.6

This will update the following files:

 drivers/net/8139cp.c                          |    1 
 drivers/net/b44.c                             |  131 +++--
 drivers/net/b44.h                             |  113 ----
 drivers/net/depca.c                           |    8 
 drivers/net/forcedeth.c                       |   31 +
 drivers/net/sis900.c                          |  258 +++++-----
 drivers/net/smc91x.c                          |  484 ++++++++++---------
 drivers/net/smc91x.h                          |   33 -
 drivers/net/tokenring/lanstreamer.c           |    2 
 drivers/net/tulip/dmfe.c                      |    1 
 drivers/net/via-rhine.c                       |    4 
 drivers/net/wireless/prism54/isl_38xx.c       |   15 
 drivers/net/wireless/prism54/isl_38xx.h       |    4 
 drivers/net/wireless/prism54/isl_ioctl.c      |  639 ++++++++++++++++++++++----
 drivers/net/wireless/prism54/isl_ioctl.h      |    2 
 drivers/net/wireless/prism54/isl_oid.h        |    9 
 drivers/net/wireless/prism54/islpci_dev.c     |   49 +
 drivers/net/wireless/prism54/islpci_dev.h     |    4 
 drivers/net/wireless/prism54/islpci_eth.c     |    5 
 drivers/net/wireless/prism54/islpci_hotplug.c |    3 
 drivers/net/wireless/prism54/islpci_mgt.c     |    1 
 drivers/net/wireless/prism54/islpci_mgt.h     |    2 
 drivers/net/wireless/prism54/oid_mgt.c        |  126 ++++-
 drivers/net/wireless/prism54/oid_mgt.h        |    5 
 24 files changed, 1273 insertions(+), 657 deletions(-)

through these ChangeSets:

<jolt:tuxbox.org>:
  o [netdrvr b44] clean up SiliconBackplane definitions/functions
  o [netdrvr b44] ignore carrier lost errors

Alexander Viro:
  o depca removal of bogus virt_to_bus() uses
  o missing includes of asm/irq.h
  o lanstreamer fix

Andrew Morton:
  o typhoon build fix

Con Kolivas:
  o b44poll - whitespace
  o netconsole support for b44

Daniele Venzano:
  o [netdrvr sis900] whitespace and codingstyle updates

Hirokazu Takata:
  o m32r: trivial fix of smc91x.h

Jeff Garzik:
  o [netdrvr b44] update MODULE_AUTHORS

Manfred Spraul:
  o rx checksum support for gige nForce ethernet

Margit Schubert-While:
  o prism54 bug initialization/mgt_commit
  o prism54 print firmware version
  o prism54 Bug in timeout scheduling
  o prism54 remove TRACE
  o prism54 fix wpa_supplicant frequency parsing
  o prism54 initial WPA support
  o prism54 add WE17 support
  o prism54 remove module params
  o prism54 Code cleanup

Nicolas Pitre:
  o smc91x: release on-chip RX packet memory ASAP
  o smc91x: receives two bytes too many
  o smc91x: fix compilation with DMA on PXA2xx
  o smc91x: more SMP locking fixes
  o smc91x: fix SMP lock usage
  o smc91x: cosmetics
  o smc91x: straighten SMP locking
  o smc91x: display pertinent register values from the  timeout function
  o smc91x: fix possible leak of the skb waiting for mem  allocation
  o smc91x: use a work queue to reconfigure the phy from  smc_timeout()
  o smc91x: move TX processing out of IRQ context entirely
  o smc91x: simplify register bank usage
  o smc91x: fold smc_setmulticast() into smc_set_multicast_list()
  o smc91x: set the MAC addr from the smc_enable function
  o smc91x: Assorted minor cleanups
  o smc91x: Revert 1.1923.3.58: "m32r: modify drivers/net/smc91x.c for m32r"

Pavel Machek:
  o Fix suspend/resume support in via-rhine2

Pekka Pietikäinen:
  o b44: use bounce buffers to workaround chip DMA bug/limitations

Stephen Hemminger:
  o b44: use netdev_priv
  o b44: replace MODULE_PARM

diff -Nru a/drivers/net/8139cp.c b/drivers/net/8139cp.c
--- a/drivers/net/8139cp.c	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/8139cp.c	2004-10-21 22:09:44 -04:00
@@ -71,6 +71,7 @@
 #include <linux/udp.h>
 #include <linux/cache.h>
 #include <asm/io.h>
+#include <asm/irq.h>
 #include <asm/uaccess.h>
 
 /* VLAN tagging feature enable/disable */
diff -Nru a/drivers/net/b44.c b/drivers/net/b44.c
--- a/drivers/net/b44.c	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/b44.c	2004-10-21 22:09:44 -04:00
@@ -8,6 +8,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/types.h>
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
@@ -27,8 +28,8 @@
 
 #define DRV_MODULE_NAME		"b44"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"0.94"
-#define DRV_MODULE_RELDATE	"May 4, 2004"
+#define DRV_MODULE_VERSION	"0.95"
+#define DRV_MODULE_RELDATE	"Aug 3, 2004"
 
 #define B44_DEF_MSG_ENABLE	  \
 	(NETIF_MSG_DRV		| \
@@ -57,6 +58,7 @@
 #define B44_DEF_TX_RING_PENDING		(B44_TX_RING_SIZE - 1)
 #define B44_TX_RING_BYTES	(sizeof(struct dma_desc) * \
 				 B44_TX_RING_SIZE)
+#define B44_DMA_MASK 0x3fffffff
 
 #define TX_RING_GAP(BP)	\
 	(B44_TX_RING_SIZE - (BP)->tx_pending)
@@ -67,6 +69,7 @@
 #define NEXT_TX(N)		(((N) + 1) & (B44_TX_RING_SIZE - 1))
 
 #define RX_PKT_BUF_SZ		(1536 + bp->rx_offset + 64)
+#define TX_PKT_BUF_SZ		(B44_MAX_MTU + ETH_HLEN + 8)
 
 /* minimum number of free TX descriptors required to wake up TX process */
 #define B44_TX_WAKEUP_THRESH		(B44_TX_RING_SIZE / 4)
@@ -74,13 +77,13 @@
 static char version[] __devinitdata =
 	DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
 
-MODULE_AUTHOR("David S. Miller (davem@redhat.com)");
+MODULE_AUTHOR("Florian Schirmer, Pekka Pietikainen, David S. Miller");
 MODULE_DESCRIPTION("Broadcom 4400 10/100 PCI ethernet driver");
 MODULE_LICENSE("GPL");
-MODULE_PARM(b44_debug, "i");
-MODULE_PARM_DESC(b44_debug, "B44 bitmapped debugging message enable value");
 
 static int b44_debug = -1;	/* -1 == use B44_DEF_MSG_ENABLE as value */
+module_param(b44_debug, int, 0);
+MODULE_PARM_DESC(b44_debug, "B44 bitmapped debugging message enable value");
 
 static struct pci_device_id b44_pci_tbl[] = {
 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401,
@@ -97,6 +100,10 @@
 static void b44_halt(struct b44 *);
 static void b44_init_rings(struct b44 *);
 static void b44_init_hw(struct b44 *);
+static int b44_poll(struct net_device *dev, int *budget);
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void b44_poll_controller(struct net_device *dev);
+#endif
 
 static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
 {
@@ -141,41 +148,8 @@
  * interrupts disabled.
  */
 
-#define SBID_SDRAM		0
-#define SBID_PCI_MEM		1
-#define SBID_PCI_CFG		2
-#define SBID_PCI_DMA		3
-#define	SBID_SDRAM_SWAPPED	4
-#define SBID_ENUM		5
-#define SBID_REG_SDRAM		6
-#define SBID_REG_ILINE20	7
-#define SBID_REG_EMAC		8
-#define SBID_REG_CODEC		9
-#define SBID_REG_USB		10
-#define SBID_REG_PCI		11
-#define SBID_REG_MIPS		12
-#define SBID_REG_EXTIF		13
-#define	SBID_EXTIF		14
-#define	SBID_EJTAG		15
-#define	SBID_MAX		16
-
-static u32 ssb_get_addr(struct b44 *bp, u32 id, u32 instance)
-{
-	switch (id) {
-	case SBID_PCI_DMA:
-		return 0x40000000;
-	case SBID_ENUM:
-		return 0x18000000;
-	case SBID_REG_EMAC:
-		return 0x18000000;
-	case SBID_REG_CODEC:
-		return 0x18001000;
-	case SBID_REG_PCI:
-		return 0x18002000;
-	default:
-		return 0;
-	};
-}
+#define SB_PCI_DMA             0x40000000      /* Client Mode PCI memory access space (1 GB) */
+#define BCM4400_PCI_CORE_ADDR  0x18002000      /* Address of PCI core on BCM4400 cards */
 
 static u32 ssb_get_core_rev(struct b44 *bp)
 {
@@ -187,8 +161,7 @@
 	u32 bar_orig, pci_rev, val;
 
 	pci_read_config_dword(bp->pdev, SSB_BAR0_WIN, &bar_orig);
-	pci_write_config_dword(bp->pdev, SSB_BAR0_WIN,
-			       ssb_get_addr(bp, SBID_REG_PCI, 0));
+	pci_write_config_dword(bp->pdev, SSB_BAR0_WIN, BCM4400_PCI_CORE_ADDR);
 	pci_rev = ssb_get_core_rev(bp);
 
 	val = br32(bp, B44_SBINTVEC);
@@ -649,10 +622,30 @@
 	if (skb == NULL)
 		return -ENOMEM;
 
-	skb->dev = bp->dev;
 	mapping = pci_map_single(bp->pdev, skb->data,
 				 RX_PKT_BUF_SZ,
 				 PCI_DMA_FROMDEVICE);
+
+	/* Hardware bug work-around, the chip is unable to do PCI DMA
+	   to/from anything above 1GB :-( */
+	if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) {
+		/* Sigh... */
+		pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
+		dev_kfree_skb_any(skb);
+		skb = __dev_alloc_skb(RX_PKT_BUF_SZ,GFP_DMA);
+		if (skb == NULL)
+			return -ENOMEM;
+		mapping = pci_map_single(bp->pdev, skb->data,
+					 RX_PKT_BUF_SZ,
+					 PCI_DMA_FROMDEVICE);
+		if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) {
+			pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
+			dev_kfree_skb_any(skb);
+			return -ENOMEM;
+		}
+	}
+
+	skb->dev = bp->dev;
 	skb_reserve(skb, bp->rx_offset);
 
 	rh = (struct rx_header *)
@@ -930,6 +923,12 @@
 
 	entry = bp->tx_prod;
 	mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
+	if(mapping+len > B44_DMA_MASK) {
+		/* Chip can't handle DMA to/from >1GB, use bounce buffer */
+		pci_unmap_single(bp->pdev, mapping, len,PCI_DMA_TODEVICE);
+		memcpy(bp->tx_bufs+entry*TX_PKT_BUF_SZ,skb->data,skb->len);
+		mapping = pci_map_single(bp->pdev, bp->tx_bufs+entry*TX_PKT_BUF_SZ, len, PCI_DMA_TODEVICE);
+	}
 
 	bp->tx_buffers[entry].skb = skb;
 	pci_unmap_addr_set(&bp->tx_buffers[entry], mapping, mapping);
@@ -1077,6 +1076,11 @@
 				    bp->tx_ring, bp->tx_ring_dma);
 		bp->tx_ring = NULL;
 	}
+	if (bp->tx_bufs) {
+		pci_free_consistent(bp->pdev, B44_TX_RING_SIZE * TX_PKT_BUF_SZ,
+				    bp->tx_bufs, bp->tx_bufs_dma);
+		bp->tx_bufs = NULL;
+	}
 }
 
 /*
@@ -1099,6 +1103,12 @@
 		goto out_err;
 	memset(bp->tx_buffers, 0, size);
 
+	size = B44_TX_RING_SIZE * TX_PKT_BUF_SZ;
+	bp->tx_bufs = pci_alloc_consistent(bp->pdev, size, &bp->tx_bufs_dma);
+	if (!bp->tx_bufs)
+		goto out_err;
+	memset(bp->tx_bufs, 0, size);
+
 	size = DMA_TABLE_BYTES;
 	bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma);
 	if (!bp->rx_ring)
@@ -1297,6 +1307,19 @@
 }
 #endif
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling receive - used by netconsole and other diagnostic tools
+ * to allow network i/o with interrupts disabled.
+ */
+static void b44_poll_controller(struct net_device *dev)
+{
+	disable_irq(dev->irq);
+	b44_interrupt(dev->irq, dev, NULL);
+	enable_irq(dev->irq);
+}
+#endif
+
 static int b44_close(struct net_device *dev)
 {
 	struct b44 *bp = netdev_priv(dev);
@@ -1358,7 +1381,10 @@
 				   hwstat->rx_symbol_errs);
 
 	nstat->tx_aborted_errors = hwstat->tx_underruns;
+#if 0
+	/* Carrier lost counter seems to be broken for some devices */
 	nstat->tx_carrier_errors = hwstat->tx_carrier_lost;
+#endif
 
 	return nstat;
 }
@@ -1684,7 +1710,6 @@
 	bp->dev->dev_addr[5] = eeprom[82];
 
 	bp->phy_addr = eeprom[90] & 0x1f;
-	bp->mdc_port = (eeprom[90] >> 14) & 0x1;
 
 	/* With this, plus the rx_header prepended to the data by the
 	 * hardware, we'll land the ethernet header on a 2-byte boundary.
@@ -1694,7 +1719,7 @@
 	bp->imask = IMASK_DEF;
 
 	bp->core_unit = ssb_core_unit(bp);
-	bp->dma_offset = ssb_get_addr(bp, SBID_PCI_DMA, 0);
+	bp->dma_offset = SB_PCI_DMA;
 
 	/* XXX - really required? 
 	   bp->flags |= B44_FLAG_BUGGY_TXPTR;
@@ -1738,12 +1763,19 @@
 
 	pci_set_master(pdev);
 
-	err = pci_set_dma_mask(pdev, (u64) 0xffffffff);
+	err = pci_set_dma_mask(pdev, (u64) B44_DMA_MASK);
 	if (err) {
 		printk(KERN_ERR PFX "No usable DMA configuration, "
 		       "aborting.\n");
 		goto err_out_free_res;
 	}
+	
+	err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK);
+	if (err) {
+	  printk(KERN_ERR PFX "No usable DMA configuration, "
+		 "aborting.\n");
+	  goto err_out_free_res;
+	}
 
 	b44reg_base = pci_resource_start(pdev, 0);
 	b44reg_len = pci_resource_len(pdev, 0);
@@ -1793,6 +1825,9 @@
 	dev->poll = b44_poll;
 	dev->weight = 64;
 	dev->watchdog_timeo = B44_TX_TIMEOUT;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	dev->poll_controller = b44_poll_controller;
+#endif
 	dev->change_mtu = b44_change_mtu;
 	dev->irq = pdev->irq;
 	SET_ETHTOOL_OPS(dev, &b44_ethtool_ops);
@@ -1870,7 +1905,7 @@
 static int b44_suspend(struct pci_dev *pdev, u32 state)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
-	struct b44 *bp = dev->priv;
+	struct b44 *bp = netdev_priv(dev);
 
         if (!netif_running(dev))
                  return 0;
@@ -1891,7 +1926,7 @@
 static int b44_resume(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
-	struct b44 *bp = dev->priv;
+	struct b44 *bp = netdev_priv(dev);
 
 	pci_restore_state(pdev);
 
diff -Nru a/drivers/net/b44.h b/drivers/net/b44.h
--- a/drivers/net/b44.h	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/b44.h	2004-10-21 22:09:44 -04:00
@@ -223,21 +223,8 @@
 #define B44_RX_SYM	0x05D0UL /* MIB RX Symbol Errors */
 #define B44_RX_PAUSE	0x05D4UL /* MIB RX Pause Packets */
 #define B44_RX_NPAUSE	0x05D8UL /* MIB RX Non-Pause Packets */
-#define B44_SBIPSFLAG	0x0F08UL /* SB Initiator Port OCP Slave Flag */
-#define  SBIPSFLAG_IMASK1	0x0000003f /* Which sbflags --> mips interrupt 1 */
-#define  SBIPSFLAG_ISHIFT1	0
-#define  SBIPSFLAG_IMASK2	0x00003f00 /* Which sbflags --> mips interrupt 2 */
-#define  SBIPSFLAG_ISHIFT2	8
-#define  SBIPSFLAG_IMASK3	0x003f0000 /* Which sbflags --> mips interrupt 3 */
-#define  SBIPSFLAG_ISHIFT3	16
-#define  SBIPSFLAG_IMASK4	0x3f000000 /* Which sbflags --> mips interrupt 4 */
-#define  SBIPSFLAG_ISHIFT4	24
-#define B44_SBTPSFLAG	0x0F18UL /* SB Target Port OCP Slave Flag */
-#define  SBTPS_NUM0_MASK	0x0000003f
-#define  SBTPS_F0EN0		0x00000040
-#define B44_SBADMATCH3	0x0F60UL /* SB Address Match 3 */
-#define B44_SBADMATCH2	0x0F68UL /* SB Address Match 2 */
-#define B44_SBADMATCH1	0x0F70UL /* SB Address Match 1 */
+
+/* Silicon backplane register definitions */
 #define B44_SBIMSTATE	0x0F90UL /* SB Initiator Agent State */
 #define  SBIMSTATE_PC		0x0000000f /* Pipe Count */
 #define  SBIMSTATE_AP_MASK	0x00000030 /* Arbitration Priority */
@@ -269,86 +256,6 @@
 #define  SBTMSHIGH_GCR		0x20000000 /* Gated Clock Request */
 #define  SBTMSHIGH_BISTF	0x40000000 /* BIST Failed */
 #define  SBTMSHIGH_BISTD	0x80000000 /* BIST Done */
-#define B44_SBBWA0	0x0FA0UL /* SB Bandwidth Allocation Table 0 */
-#define  SBBWA0_TAB0_MASK	0x0000ffff /* Lookup Table 0 */
-#define  SBBWA0_TAB0_SHIFT	0
-#define  SBBWA0_TAB1_MASK	0xffff0000 /* Lookup Table 0 */
-#define  SBBWA0_TAB1_SHIFT	16
-#define B44_SBIMCFGLOW	0x0FA8UL /* SB Initiator Configuration Low */
-#define  SBIMCFGLOW_STO_MASK	0x00000003 /* Service Timeout */
-#define  SBIMCFGLOW_RTO_MASK	0x00000030 /* Request Timeout */
-#define  SBIMCFGLOW_RTO_SHIFT	4
-#define  SBIMCFGLOW_CID_MASK	0x00ff0000 /* Connection ID */
-#define  SBIMCFGLOW_CID_SHIFT	16
-#define B44_SBIMCFGHIGH	0x0FACUL /* SB Initiator Configuration High */
-#define  SBIMCFGHIGH_IEM_MASK	0x0000000c /* Inband Error Mode */
-#define  SBIMCFGHIGH_TEM_MASK	0x00000030 /* Timeout Error Mode */
-#define  SBIMCFGHIGH_TEM_SHIFT	4
-#define  SBIMCFGHIGH_BEM_MASK	0x000000c0 /* Bus Error Mode */
-#define  SBIMCFGHIGH_BEM_SHIFT	6
-#define B44_SBADMATCH0	0x0FB0UL /* SB Address Match 0 */
-#define  SBADMATCH0_TYPE_MASK	0x00000003 /* Address Type */
-#define  SBADMATCH0_AD64	0x00000004 /* Reserved */
-#define  SBADMATCH0_AI0_MASK	0x000000f8 /* Type0 Size */
-#define  SBADMATCH0_AI0_SHIFT	3
-#define  SBADMATCH0_AI1_MASK	0x000001f8 /* Type1 Size */
-#define  SBADMATCH0_AI1_SHIFT	3
-#define  SBADMATCH0_AI2_MASK	0x000001f8 /* Type2 Size */
-#define  SBADMATCH0_AI2_SHIFT	3
-#define  SBADMATCH0_ADEN	0x00000400 /* Enable */
-#define  SBADMATCH0_ADNEG	0x00000800 /* Negative Decode */
-#define  SBADMATCH0_BS0_MASK	0xffffff00 /* Type0 Base Address */
-#define  SBADMATCH0_BS0_SHIFT	8
-#define  SBADMATCH0_BS1_MASK	0xfffff000 /* Type1 Base Address */
-#define  SBADMATCH0_BS1_SHIFT	12
-#define  SBADMATCH0_BS2_MASK	0xffff0000 /* Type2 Base Address */
-#define  SBADMATCH0_BS2_SHIFT	16
-#define B44_SBTMCFGLOW	0x0FB8UL /* SB Target Configuration Low */
-#define  SBTMCFGLOW_CD_MASK	0x000000ff /* Clock Divide Mask */
-#define  SBTMCFGLOW_CO_MASK	0x0000f800 /* Clock Offset Mask */
-#define  SBTMCFGLOW_CO_SHIFT	11
-#define  SBTMCFGLOW_IF_MASK	0x00fc0000 /* Interrupt Flags Mask */
-#define  SBTMCFGLOW_IF_SHIFT	18
-#define  SBTMCFGLOW_IM_MASK	0x03000000 /* Interrupt Mode Mask */
-#define  SBTMCFGLOW_IM_SHIFT	24
-#define B44_SBTMCFGHIGH	0x0FBCUL /* SB Target Configuration High */
-#define  SBTMCFGHIGH_BM_MASK	0x00000003 /* Busy Mode */
-#define  SBTMCFGHIGH_RM_MASK	0x0000000C /* Retry Mode */
-#define  SBTMCFGHIGH_RM_SHIFT	2
-#define  SBTMCFGHIGH_SM_MASK	0x00000030 /* Stop Mode */
-#define  SBTMCFGHIGH_SM_SHIFT	4
-#define  SBTMCFGHIGH_EM_MASK	0x00000300 /* Error Mode */
-#define  SBTMCFGHIGH_EM_SHIFT	8
-#define  SBTMCFGHIGH_IM_MASK	0x00000c00 /* Interrupt Mode */
-#define  SBTMCFGHIGH_IM_SHIFT	10
-#define B44_SBBCFG	0x0FC0UL /* SB Broadcast Configuration */
-#define  SBBCFG_LAT_MASK	0x00000003 /* SB Latency */
-#define  SBBCFG_MAX0_MASK	0x000f0000 /* MAX Counter 0 */
-#define  SBBCFG_MAX0_SHIFT	16
-#define  SBBCFG_MAX1_MASK	0x00f00000 /* MAX Counter 1 */
-#define  SBBCFG_MAX1_SHIFT	20
-#define B44_SBBSTATE	0x0FC8UL /* SB Broadcast State */
-#define  SBBSTATE_SRD		0x00000001 /* ST Reg Disable */
-#define  SBBSTATE_HRD		0x00000002 /* Hold Reg Disable */
-#define B44_SBACTCNFG	0x0FD8UL /* SB Activate Configuration */
-#define B44_SBFLAGST	0x0FE8UL /* SB Current SBFLAGS */
-#define B44_SBIDLOW	0x0FF8UL /* SB Identification Low */
-#define  SBIDLOW_CS_MASK	0x00000003 /* Config Space Mask */
-#define  SBIDLOW_AR_MASK	0x00000038 /* Num Address Ranges Supported */
-#define  SBIDLOW_AR_SHIFT	3
-#define  SBIDLOW_SYNCH		0x00000040 /* Sync */
-#define  SBIDLOW_INIT		0x00000080 /* Initiator */
-#define  SBIDLOW_MINLAT_MASK	0x00000f00 /* Minimum Backplane Latency */
-#define  SBIDLOW_MINLAT_SHIFT	8
-#define  SBIDLOW_MAXLAT_MASK	0x0000f000 /* Maximum Backplane Latency */
-#define  SBIDLOW_MAXLAT_SHIFT	12
-#define  SBIDLOW_FIRST		0x00010000 /* This Initiator is First */
-#define  SBIDLOW_CW_MASK	0x000c0000 /* Cycle Counter Width */
-#define  SBIDLOW_CW_SHIFT	18
-#define  SBIDLOW_TP_MASK	0x00f00000 /* Target Ports */
-#define  SBIDLOW_TP_SHIFT	20
-#define  SBIDLOW_IP_MASK	0x0f000000 /* Initiator Ports */
-#define  SBIDLOW_IP_SHIFT	24
 #define B44_SBIDHIGH	0x0FFCUL /* SB Identification High */
 #define  SBIDHIGH_RC_MASK	0x0000000f /* Revision Code */
 #define  SBIDHIGH_CC_MASK	0x0000fff0 /* Core Code */
@@ -356,23 +263,13 @@
 #define  SBIDHIGH_VC_MASK	0xffff0000 /* Vendor Code */
 #define  SBIDHIGH_VC_SHIFT	16
 
-#define  CORE_CODE_ILINE20	0x801
-#define  CORE_CODE_SDRAM	0x803
-#define  CORE_CODE_PCI		0x804
-#define  CORE_CODE_MIPS		0x805
-#define  CORE_CODE_ENET		0x806
-#define  CORE_CODE_CODEC	0x807
-#define  CORE_CODE_USB		0x808
-#define  CORE_CODE_ILINE100	0x80a
-#define  CORE_CODE_EXTIF	0x811
-
 /* SSB PCI config space registers.  */
 #define	SSB_BAR0_WIN		0x80
 #define	SSB_BAR1_WIN		0x84
 #define	SSB_SPROM_CONTROL	0x88
 #define	SSB_BAR1_CONTROL	0x8c
 
-/* SSB core and hsot control registers.  */
+/* SSB core and host control registers.  */
 #define SSB_CONTROL		0x0000UL
 #define SSB_ARBCONTROL		0x0010UL
 #define SSB_ISTAT		0x0020UL
@@ -500,6 +397,7 @@
 
 	struct ring_info	*rx_buffers;
 	struct ring_info	*tx_buffers;
+	unsigned char		*tx_bufs; 
 
 	u32			dma_offset;
 	u32			flags;
@@ -531,12 +429,11 @@
 	struct pci_dev		*pdev;
 	struct net_device	*dev;
 
-	dma_addr_t		rx_ring_dma, tx_ring_dma;
+	dma_addr_t		rx_ring_dma, tx_ring_dma,tx_bufs_dma;
 
 	u32			rx_pending;
 	u32			tx_pending;
 	u8			phy_addr;
-	u8			mdc_port;
 	u8			core_unit;
 
 	struct mii_if_info	mii_if;
diff -Nru a/drivers/net/depca.c b/drivers/net/depca.c
--- a/drivers/net/depca.c	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/depca.c	2004-10-21 22:09:44 -04:00
@@ -1222,10 +1222,10 @@
 		/* clear IDON by writing a "1", enable interrupts and start lance */
 		outw(IDON | INEA | STRT, DEPCA_DATA);
 		if (depca_debug > 2) {
-			printk("%s: DEPCA open after %d ticks, init block 0x%08lx csr0 %4.4x.\n", dev->name, i, virt_to_phys(lp->sh_mem), inw(DEPCA_DATA));
+			printk("%s: DEPCA open after %d ticks, init block 0x%08lx csr0 %4.4x.\n", dev->name, i, lp->mem_start, inw(DEPCA_DATA));
 		}
 	} else {
-		printk("%s: DEPCA unopen after %d ticks, init block 0x%08lx csr0 %4.4x.\n", dev->name, i, virt_to_phys(lp->sh_mem), inw(DEPCA_DATA));
+		printk("%s: DEPCA unopen after %d ticks, init block 0x%08lx csr0 %4.4x.\n", dev->name, i, lp->mem_start, inw(DEPCA_DATA));
 		status = -1;
 	}
 
@@ -1901,7 +1901,7 @@
 			}
 		}
 		printk("...0x%8.8x\n", readl(&lp->tx_ring[i].base));
-		printk("Initialisation block at 0x%8.8lx(Phys)\n", virt_to_phys(lp->sh_mem));
+		printk("Initialisation block at 0x%8.8lx(Phys)\n", lp->mem_start);
 		printk("        mode: 0x%4.4x\n", p->mode);
 		printk("        physical address: ");
 		for (i = 0; i < ETH_ALEN - 1; i++) {
@@ -1915,7 +1915,7 @@
 		printk("%2.2x\n", p->mcast_table[i]);
 		printk("        rx_ring at: 0x%8.8x\n", p->rx_ring);
 		printk("        tx_ring at: 0x%8.8x\n", p->tx_ring);
-		printk("buffers (Phys): 0x%8.8lx\n", virt_to_phys(lp->sh_mem) + lp->buffs_offset);
+		printk("buffers (Phys): 0x%8.8lx\n", lp->mem_start + lp->buffs_offset);
 		printk("Ring size:\nRX: %d  Log2(rxRingMask): 0x%8.8x\n", (int) lp->rxRingMask + 1, lp->rx_rlen);
 		printk("TX: %d  Log2(txRingMask): 0x%8.8x\n", (int) lp->txRingMask + 1, lp->tx_rlen);
 		outw(CSR2, DEPCA_ADDR);
diff -Nru a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
--- a/drivers/net/forcedeth.c	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/forcedeth.c	2004-10-21 22:09:44 -04:00
@@ -76,6 +76,9 @@
  *			   for registers, link status and other minor fixes.
  *	0.28: 21 Jun 2004: Big cleanup, making driver mostly endian safe
  *	0.29: 31 Aug 2004: Add backup timer for link change notification.
+ *	0.30: 25 Sep 2004: rx checksum support for nf 250 Gb. Add rx reset
+ *			   into nv_close, otherwise reenabling for wol can
+ *			   cause DMA to kfree'd memory.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -87,7 +90,7 @@
  * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
  * superfluous timer interrupts from the nic.
  */
-#define FORCEDETH_VERSION		"0.29"
+#define FORCEDETH_VERSION		"0.30"
 #define DRV_NAME			"forcedeth"
 
 #include <linux/module.h>
@@ -217,6 +220,7 @@
 #define NVREG_TXRXCTL_BIT2	0x0004
 #define NVREG_TXRXCTL_IDLE	0x0008
 #define NVREG_TXRXCTL_RESET	0x0010
+#define NVREG_TXRXCTL_RXCHECK	0x0400
 	NvRegMIIStatus = 0x180,
 #define NVREG_MIISTAT_ERROR		0x0001
 #define NVREG_MIISTAT_LINKCHANGE	0x0008
@@ -313,6 +317,10 @@
 #define NV_RX_ERROR		(1<<30)
 #define NV_RX_AVAIL		(1<<31)
 
+#define NV_RX2_CHECKSUMMASK	(0x1C000000)
+#define NV_RX2_CHECKSUMOK1	(0x10000000)
+#define NV_RX2_CHECKSUMOK2	(0x14000000)
+#define NV_RX2_CHECKSUMOK3	(0x18000000)
 #define NV_RX2_DESCRIPTORVALID	(1<<29)
 #define NV_RX2_SUBSTRACT1	(1<<25)
 #define NV_RX2_ERROR1		(1<<18)
@@ -371,8 +379,15 @@
 #define POLL_WAIT	(1+HZ/100)
 #define LINK_TIMEOUT	(3*HZ)
 
+/* 
+ * desc_ver values:
+ * This field has two purposes:
+ * - Newer nics uses a different ring layout. The layout is selected by
+ *   comparing np->desc_ver with DESC_VER_xy.
+ * - It contains bits that are forced on when writing to NvRegTxRxControl.
+ */
 #define DESC_VER_1	0x0
-#define DESC_VER_2	0x02100
+#define DESC_VER_2	(0x02100|NVREG_TXRXCTL_RXCHECK)
 
 /* PHY defines */
 #define PHY_OUI_MARVELL	0x5043
@@ -1142,6 +1157,15 @@
 					goto next_pkt;
 				}
 			}
+			Flags &= NV_RX2_CHECKSUMMASK;
+			if (Flags == NV_RX2_CHECKSUMOK1 ||
+					Flags == NV_RX2_CHECKSUMOK2 ||
+					Flags == NV_RX2_CHECKSUMOK3) {
+				dprintk(KERN_DEBUG "%s: hw checksum hit!.\n", dev->name);
+				np->rx_skbuff[i]->ip_summed = CHECKSUM_UNNECESSARY;
+			} else {
+				dprintk(KERN_DEBUG "%s: hwchecksum miss!.\n", dev->name);
+			}
 		}
 		/* got a valid packet - forward it to the network core */
 		skb = np->rx_skbuff[i];
@@ -1634,9 +1658,10 @@
 	spin_lock_irq(&np->lock);
 	nv_stop_tx(dev);
 	nv_stop_rx(dev);
-	base = get_hwbase(dev);
+	nv_txrx_reset(dev);
 
 	/* disable interrupts on the nic or we will lock up */
+	base = get_hwbase(dev);
 	writel(0, base + NvRegIrqMask);
 	pci_push(base);
 	dprintk(KERN_INFO "%s: Irqmask is zero again\n", dev->name);
diff -Nru a/drivers/net/sis900.c b/drivers/net/sis900.c
--- a/drivers/net/sis900.c	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/sis900.c	2004-10-21 22:09:44 -04:00
@@ -140,9 +140,9 @@
 };
 
 typedef struct _BufferDesc {
-	u32	link;
-	u32	cmdsts;
-	u32	bufptr;
+	u32 link;
+	u32 cmdsts;
+	u32 bufptr;
 } BufferDesc;
 
 struct sis900_private {
@@ -156,7 +156,7 @@
 	unsigned int cur_phy;
 
 	struct timer_list timer; /* Link status detection timer. */
-	u8     autong_complete; /* 1: auto-negotiate complete  */
+	u8 autong_complete; /* 1: auto-negotiate complete  */
 
 	unsigned int cur_rx, dirty_rx; /* producer/comsumer pointers for Tx/Rx ring */
 	unsigned int cur_tx, dirty_tx;
@@ -170,7 +170,7 @@
 	dma_addr_t tx_ring_dma;
 	dma_addr_t rx_ring_dma;
 
-	unsigned int tx_full;			/* The Tx queue is full.    */
+	unsigned int tx_full; /* The Tx queue is full. */
 	u8 host_bridge_rev;
 };
 
@@ -255,7 +255,8 @@
  *	MAC address is read into @net_dev->dev_addr.
  */
 
-static int __devinit sis630e_get_mac_addr(struct pci_dev * pci_dev, struct net_device *net_dev)
+static int __devinit sis630e_get_mac_addr(struct pci_dev * pci_dev,
+					struct net_device *net_dev)
 {
 	struct pci_dev *isa_bridge = NULL;
 	u8 reg;
@@ -292,7 +293,8 @@
  *	@net_dev->dev_addr.
  */
 
-static int __devinit sis635_get_mac_addr(struct pci_dev * pci_dev, struct net_device *net_dev)
+static int __devinit sis635_get_mac_addr(struct pci_dev * pci_dev,
+					struct net_device *net_dev)
 {
 	long ioaddr = net_dev->base_addr;
 	u32 rfcrSave;
@@ -334,7 +336,8 @@
  *	MAC address is read into @net_dev->dev_addr.
  */
 
-static int __devinit sis96x_get_mac_addr(struct pci_dev * pci_dev, struct net_device *net_dev)
+static int __devinit sis96x_get_mac_addr(struct pci_dev * pci_dev,
+					struct net_device *net_dev)
 {
 	long ioaddr = net_dev->base_addr;
 	long ee_addr = ioaddr + mear;
@@ -371,7 +374,8 @@
  *	ie: sis900_open(), sis900_start_xmit(), sis900_close(), etc.
  */
 
-static int __devinit sis900_probe (struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
+static int __devinit sis900_probe(struct pci_dev *pci_dev,
+				const struct pci_device_id *pci_id)
 {
 	struct sis900_private *sis_priv;
 	struct net_device *net_dev;
@@ -522,7 +526,7 @@
  *	return error if it failed to found.
  */
 
-static int __init sis900_mii_probe (struct net_device * net_dev)
+static int __init sis900_mii_probe(struct net_device * net_dev)
 {
 	struct sis900_private * sis_priv = net_dev->priv;
 	u16 poll_bit = MII_STAT_LINK, status = 0;
@@ -572,9 +576,10 @@
 				mii_phy->phy_types = mii_chip_table[i].phy_types;
 				if (mii_chip_table[i].phy_types == MIX)
 					mii_phy->phy_types =
-						(mii_status & (MII_STAT_CAN_TX_FDX | MII_STAT_CAN_TX)) ? LAN : HOME;
+					    (mii_status & (MII_STAT_CAN_TX_FDX | MII_STAT_CAN_TX)) ? LAN : HOME;
 				printk(KERN_INFO "%s: %s transceiver found at address %d.\n",
-				       net_dev->name, mii_chip_table[i].name, phy_addr);
+				       net_dev->name, mii_chip_table[i].name,
+				       phy_addr);
 				break;
 			}
 			
@@ -587,7 +592,7 @@
 	
 	if (sis_priv->mii == NULL) {
 		printk(KERN_INFO "%s: No MII transceivers found!\n",
-		       net_dev->name);
+			net_dev->name);
 		return 0;
 	}
 
@@ -611,7 +616,8 @@
 
 			poll_bit ^= (mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS) & poll_bit);
 			if (time_after_eq(jiffies, timeout)) {
-				printk(KERN_WARNING "%s: reset phy and link down now\n", net_dev->name);
+				printk(KERN_WARNING "%s: reset phy and link down now\n",
+					net_dev->name);
 				return -ETIME;
 			}
 		}
@@ -647,38 +653,41 @@
 static u16 sis900_default_phy(struct net_device * net_dev)
 {
 	struct sis900_private * sis_priv = net_dev->priv;
- 	struct mii_phy *phy = NULL, *phy_home = NULL, *default_phy = NULL, *phy_lan = NULL;
+ 	struct mii_phy *phy = NULL, *phy_home = NULL, 
+		*default_phy = NULL, *phy_lan = NULL;
 	u16 status;
 
-        for( phy=sis_priv->first_mii; phy; phy=phy->next ){
+        for (phy=sis_priv->first_mii; phy; phy=phy->next) {
 		status = mdio_read(net_dev, phy->phy_addr, MII_STATUS);
 		status = mdio_read(net_dev, phy->phy_addr, MII_STATUS);
 
 		/* Link ON & Not select default PHY & not ghost PHY */
-		 if ( (status & MII_STAT_LINK) && !default_phy && (phy->phy_types != UNKNOWN) )
+		 if ((status & MII_STAT_LINK) && !default_phy &&
+					(phy->phy_types != UNKNOWN))
 		 	default_phy = phy;
-		 else{
+		 else {
 			status = mdio_read(net_dev, phy->phy_addr, MII_CONTROL);
 			mdio_write(net_dev, phy->phy_addr, MII_CONTROL,
 				status | MII_CNTL_AUTO | MII_CNTL_ISOLATE);
-			if( phy->phy_types == HOME )
+			if (phy->phy_types == HOME)
 				phy_home = phy;
-			else if (phy->phy_types == LAN)
+			else if(phy->phy_types == LAN)
 				phy_lan = phy;
 		 }
 	}
 
-	if( !default_phy && phy_home )
+	if (!default_phy && phy_home)
 		default_phy = phy_home;
-	else if( !default_phy && phy_lan )
+	else if (!default_phy && phy_lan)
 		default_phy = phy_lan;
-	else if ( !default_phy )
+	else if (!default_phy)
 		default_phy = sis_priv->first_mii;
 
-	if( sis_priv->mii != default_phy ){
+	if (sis_priv->mii != default_phy) {
 		sis_priv->mii = default_phy;
 		sis_priv->cur_phy = default_phy->phy_addr;
-		printk(KERN_INFO "%s: Using transceiver found at address %d as default\n", net_dev->name,sis_priv->cur_phy);
+		printk(KERN_INFO "%s: Using transceiver found at address %d as default\n",
+					net_dev->name,sis_priv->cur_phy);
 	}
 	
 	status = mdio_read(net_dev, sis_priv->cur_phy, MII_CONTROL);
@@ -701,7 +710,7 @@
  *	mii status register. It's necessary before auto-negotiate.
  */
  
-static void sis900_set_capability( struct net_device *net_dev , struct mii_phy *phy )
+static void sis900_set_capability(struct net_device *net_dev, struct mii_phy *phy)
 {
 	u16 cap;
 	u16 status;
@@ -851,7 +860,8 @@
  *	please see SiS7014 or ICS spec
  */
 
-static void mdio_write(struct net_device *net_dev, int phy_id, int location, int value)
+static void mdio_write(struct net_device *net_dev, int phy_id, int location,
+			int value)
 {
 	long mdio_addr = net_dev->base_addr + mear;
 	int mii_cmd = MIIwrite|(phy_id<<MIIpmdShift)|(location<<MIIregShift);
@@ -939,7 +949,8 @@
 	pci_read_config_byte(sis_priv->pci_dev, PCI_CLASS_REVISION, &revision);
 	sis630_set_eq(net_dev, revision);
 
-	ret = request_irq(net_dev->irq, &sis900_interrupt, SA_SHIRQ, net_dev->name, net_dev);
+	ret = request_irq(net_dev->irq, &sis900_interrupt, SA_SHIRQ,
+						net_dev->name, net_dev);
 	if (ret)
 		return ret;
 
@@ -1136,48 +1147,55 @@
 		return;
 
 	if (netif_carrier_ok(net_dev)) {
-		reg14h=mdio_read(net_dev, sis_priv->cur_phy, MII_RESV);
-		mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, (0x2200 | reg14h) & 0xBFFF);
+		reg14h = mdio_read(net_dev, sis_priv->cur_phy, MII_RESV);
+		mdio_write(net_dev, sis_priv->cur_phy, MII_RESV,
+					(0x2200 | reg14h) & 0xBFFF);
 		for (i=0; i < maxcount; i++) {
-			eq_value=(0x00F8 & mdio_read(net_dev, sis_priv->cur_phy, MII_RESV)) >> 3;
+			eq_value = (0x00F8 & mdio_read(net_dev,
+					sis_priv->cur_phy, MII_RESV)) >> 3;
 			if (i == 0)
 				max_value=min_value=eq_value;
-			max_value=(eq_value > max_value) ? eq_value : max_value;
-			min_value=(eq_value < min_value) ? eq_value : min_value;
+			max_value = (eq_value > max_value) ?
+						eq_value : max_value;
+			min_value = (eq_value < min_value) ?
+						eq_value : min_value;
 		}
 		/* 630E rule to determine the equalizer value */
 		if (revision == SIS630E_900_REV || revision == SIS630EA1_900_REV ||
 		    revision == SIS630ET_900_REV) {
 			if (max_value < 5)
-				eq_value=max_value;
+				eq_value = max_value;
 			else if (max_value >= 5 && max_value < 15)
-				eq_value=(max_value == min_value) ? max_value+2 : max_value+1;
+				eq_value = (max_value == min_value) ?
+						max_value+2 : max_value+1;
 			else if (max_value >= 15)
-				eq_value=(max_value == min_value) ? max_value+6 : max_value+5;
+				eq_value=(max_value == min_value) ?
+						max_value+6 : max_value+5;
 		}
 		/* 630B0&B1 rule to determine the equalizer value */
 		if (revision == SIS630A_900_REV && 
 		    (sis_priv->host_bridge_rev == SIS630B0 || 
 		     sis_priv->host_bridge_rev == SIS630B1)) {
 			if (max_value == 0)
-				eq_value=3;
+				eq_value = 3;
 			else
-				eq_value=(max_value+min_value+1)/2;
+				eq_value = (max_value + min_value + 1)/2;
 		}
 		/* write equalizer value and setting */
-		reg14h=mdio_read(net_dev, sis_priv->cur_phy, MII_RESV);
-		reg14h=(reg14h & 0xFF07) | ((eq_value << 3) & 0x00F8);
-		reg14h=(reg14h | 0x6000) & 0xFDFF;
+		reg14h = mdio_read(net_dev, sis_priv->cur_phy, MII_RESV);
+		reg14h = (reg14h & 0xFF07) | ((eq_value << 3) & 0x00F8);
+		reg14h = (reg14h | 0x6000) & 0xFDFF;
 		mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, reg14h);
-	}
-	else {
-		reg14h=mdio_read(net_dev, sis_priv->cur_phy, MII_RESV);
+	} else {
+		reg14h = mdio_read(net_dev, sis_priv->cur_phy, MII_RESV);
 		if (revision == SIS630A_900_REV && 
 		    (sis_priv->host_bridge_rev == SIS630B0 || 
 		     sis_priv->host_bridge_rev == SIS630B1)) 
-			mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, (reg14h | 0x2200) & 0xBFFF);
+			mdio_write(net_dev, sis_priv->cur_phy, MII_RESV,
+						(reg14h | 0x2200) & 0xBFFF);
 		else
-			mdio_write(net_dev, sis_priv->cur_phy, MII_RESV, (reg14h | 0x2000) & 0xBFFF);
+			mdio_write(net_dev, sis_priv->cur_phy, MII_RESV,
+						(reg14h | 0x2000) & 0xBFFF);
 	}
 	return;
 }
@@ -1205,7 +1223,8 @@
 		sis900_read_mode(net_dev, &speed, &duplex);
 		if (duplex){
 			sis900_set_mode(net_dev->base_addr, speed, duplex);
-			pci_read_config_byte(sis_priv->pci_dev, PCI_CLASS_REVISION, &revision);
+			pci_read_config_byte(sis_priv->pci_dev,
+						PCI_CLASS_REVISION, &revision);
 			sis630_set_eq(net_dev, revision);
 			netif_start_queue(net_dev);
 		}
@@ -1229,9 +1248,8 @@
 			sis900_check_mode(net_dev, mii_phy);
 			netif_carrier_on(net_dev);
 		}
-	}
+	} else {
 	/* Link ON -> OFF */
-	else {
                 if (!(status & MII_STAT_LINK)){
                 	netif_carrier_off(net_dev);
                 	printk(KERN_INFO "%s: Media Link Off\n", net_dev->name);
@@ -1241,7 +1259,8 @@
 			    ((mii_phy->phy_id1 & 0xFFF0) == 0x8000))
                			sis900_reset_phy(net_dev,  sis_priv->cur_phy);
   
-                	pci_read_config_byte(sis_priv->pci_dev, PCI_CLASS_REVISION, &revision);
+                	pci_read_config_byte(sis_priv->pci_dev,
+					PCI_CLASS_REVISION, &revision);
 			sis630_set_eq(net_dev, revision);
   
                 	goto LookForLink;
@@ -1264,18 +1283,18 @@
  *	and autong_complete should be set to 1.
  */
 
-static void sis900_check_mode (struct net_device *net_dev, struct mii_phy *mii_phy)
+static void sis900_check_mode(struct net_device *net_dev, struct mii_phy *mii_phy)
 {
 	struct sis900_private *sis_priv = net_dev->priv;
 	long ioaddr = net_dev->base_addr;
 	int speed, duplex;
 
-	if( mii_phy->phy_types == LAN  ){
-		outl( ~EXD & inl( ioaddr + cfg ), ioaddr + cfg);
+	if (mii_phy->phy_types == LAN) {
+		outl(~EXD & inl(ioaddr + cfg), ioaddr + cfg);
 		sis900_set_capability(net_dev , mii_phy);
 		sis900_auto_negotiate(net_dev, sis_priv->cur_phy);
-	}else{
-		outl(EXD | inl( ioaddr + cfg ), ioaddr + cfg);
+	} else {
+		outl(EXD | inl(ioaddr + cfg), ioaddr + cfg);
 		speed = HW_SPEED_HOME;
 		duplex = FDX_CAPABLE_HALF_SELECTED;
 		sis900_set_mode(ioaddr, speed, duplex);
@@ -1300,20 +1319,20 @@
 {
 	u32 tx_flags = 0, rx_flags = 0;
 
-	if( inl(ioaddr + cfg) & EDB_MASTER_EN ){
-		tx_flags = TxATP | (DMA_BURST_64 << TxMXDMA_shift) | (TX_FILL_THRESH << TxFILLT_shift);
+	if (inl(ioaddr + cfg) & EDB_MASTER_EN) {
+		tx_flags = TxATP | (DMA_BURST_64 << TxMXDMA_shift) |
+					(TX_FILL_THRESH << TxFILLT_shift);
 		rx_flags = DMA_BURST_64 << RxMXDMA_shift;
-	}
-	else{
-		tx_flags = TxATP | (DMA_BURST_512 << TxMXDMA_shift) | (TX_FILL_THRESH << TxFILLT_shift);
+	} else {
+		tx_flags = TxATP | (DMA_BURST_512 << TxMXDMA_shift) |
+					(TX_FILL_THRESH << TxFILLT_shift);
 		rx_flags = DMA_BURST_512 << RxMXDMA_shift;
 	}
 
-	if (speed == HW_SPEED_HOME || speed == HW_SPEED_10_MBPS ) {
+	if (speed == HW_SPEED_HOME || speed == HW_SPEED_10_MBPS) {
 		rx_flags |= (RxDRNT_10 << RxDRNT_shift);
 		tx_flags |= (TxDRNT_10 << TxDRNT_shift);
-	}
-	else {
+	} else {
 		rx_flags |= (RxDRNT_100 << RxDRNT_shift);
 		tx_flags |= (TxDRNT_100 << TxDRNT_shift);
 	}
@@ -1403,19 +1422,19 @@
 	sis_priv->autong_complete = 1;
 
 	/* Workaround for Realtek RTL8201 PHY issue */
-	if((phy->phy_id0 == 0x0000) && ((phy->phy_id1 & 0xFFF0) == 0x8200)){
-		if(mdio_read(net_dev, phy_addr, MII_CONTROL) & MII_CNTL_FDX)
+	if ((phy->phy_id0 == 0x0000) && ((phy->phy_id1 & 0xFFF0) == 0x8200)) {
+		if (mdio_read(net_dev, phy_addr, MII_CONTROL) & MII_CNTL_FDX)
 			*duplex = FDX_CAPABLE_FULL_SELECTED;
-		if(mdio_read(net_dev, phy_addr, 0x0019) & 0x01)
+		if (mdio_read(net_dev, phy_addr, 0x0019) & 0x01)
 			*speed = HW_SPEED_100_MBPS;
 	}
 
 	printk(KERN_INFO "%s: Media Link On %s %s-duplex \n",
-	       net_dev->name,
-	       *speed == HW_SPEED_100_MBPS ?
-	       "100mbps" : "10mbps",
-	       *duplex == FDX_CAPABLE_FULL_SELECTED ?
-	       "full" : "half");
+	       				net_dev->name,
+	       				*speed == HW_SPEED_100_MBPS ?
+	       					"100mbps" : "10mbps",
+	       				*duplex == FDX_CAPABLE_FULL_SELECTED ?
+	       					"full" : "half");
 }
 
 /**
@@ -1677,13 +1696,13 @@
 			sis_priv->stats.rx_bytes += rx_size;
 			sis_priv->stats.rx_packets++;
 
-			/* refill the Rx buffer, what if there is not enought memory for
-			   new socket buffer ?? */
+			/* refill the Rx buffer, what if there is not enought
+			 * memory for new socket buffer ?? */
 			if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) {
-				/* not enough memory for skbuff, this makes a "hole"
-				   on the buffer ring, it is not clear how the
-				   hardware will react to this kind of degenerated
-				   buffer */
+				/* not enough memory for skbuff, this makes a
+				 * "hole" on the buffer ring, it is not clear
+				 * how the hardware will react to this kind
+				 * of degenerated buffer */
 				printk(KERN_INFO "%s: Memory squeeze,"
 				       "deferring packet.\n",
 				       net_dev->name);
@@ -1707,8 +1726,8 @@
 		rx_status = sis_priv->rx_ring[entry].cmdsts;
 	} // while
 
-	/* refill the Rx buffer, what if the rate of refilling is slower than 
-	   consuming ?? */
+	/* refill the Rx buffer, what if the rate of refilling is slower
+	 * than consuming ?? */
 	for (;sis_priv->cur_rx - sis_priv->dirty_rx > 0; sis_priv->dirty_rx++) {
 		struct sk_buff *skb;
 
@@ -1716,10 +1735,10 @@
 
 		if (sis_priv->rx_skbuff[entry] == NULL) {
 			if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) {
-				/* not enough memory for skbuff, this makes a "hole"
-				   on the buffer ring, it is not clear how the 
-				   hardware will react to this kind of degenerated 
-				   buffer */
+				/* not enough memory for skbuff, this makes a
+				 * "hole" on the buffer ring, it is not clear
+				 * how the hardware will react to this kind
+				 * of degenerated buffer */
 				printk(KERN_INFO "%s: Memory squeeze,"
 				       "deferring packet.\n",
 				       net_dev->name);
@@ -1764,8 +1783,8 @@
 
 		if (tx_status & OWN) {
 			/* The packet is not transmitted yet (owned by hardware) !
-			   Note: the interrupt is generated only when Tx Machine
-			   is idle, so this is an almost impossible case */
+			 * Note: the interrupt is generated only when Tx Machine
+			 * is idle, so this is an almost impossible case */
 			break;
 		}
 
@@ -1803,8 +1822,8 @@
 
 	if (sis_priv->tx_full && netif_queue_stopped(net_dev) &&
 	    sis_priv->cur_tx - sis_priv->dirty_tx < NUM_TX_DESC - 4) {
-		/* The ring is no longer full, clear tx_full and schedule more transmission
-		   by netif_wake_queue(net_dev) */
+		/* The ring is no longer full, clear tx_full and schedule
+		 * more transmission by netif_wake_queue(net_dev) */
 		sis_priv->tx_full = 0;
 		netif_wake_queue (net_dev);
 	}
@@ -1818,8 +1837,7 @@
  *	free Tx and RX socket buffer
  */
 
-static int
-sis900_close(struct net_device *net_dev)
+static int sis900_close(struct net_device *net_dev)
 {
 	long ioaddr = net_dev->base_addr;
 	struct sis900_private *sis_priv = net_dev->priv;
@@ -1955,27 +1973,28 @@
 
 	if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) {
 		/* we switch on the ifmap->port field. I couldn't find anything
-		   like a definition or standard for the values of that field.
-		   I think the meaning of those values is device specific. But
-		   since I would like to change the media type via the ifconfig
-		   command I use the definition from linux/netdevice.h 
-		   (which seems to be different from the ifport(pcmcia) definition) 
-		*/
+		 * like a definition or standard for the values of that field.
+		 * I think the meaning of those values is device specific. But
+		 * since I would like to change the media type via the ifconfig
+		 * command I use the definition from linux/netdevice.h 
+		 * (which seems to be different from the ifport(pcmcia) definition) */
 		switch(map->port){
 		case IF_PORT_UNKNOWN: /* use auto here */   
 			dev->if_port = map->port;
-			/* we are going to change the media type, so the Link will
-			   be temporary down and we need to reflect that here. When
-			   the Link comes up again, it will be sensed by the sis_timer
-			   procedure, which also does all the rest for us */
+			/* we are going to change the media type, so the Link
+			 * will be temporary down and we need to reflect that
+			 * here. When the Link comes up again, it will be
+			 * sensed by the sis_timer procedure, which also does
+			 * all the rest for us */
 			netif_carrier_off(dev);
                 
 			/* read current state */
 			status = mdio_read(dev, mii_phy->phy_addr, MII_CONTROL);
                 
 			/* enable auto negotiation and reset the negotioation
-			   (I don't really know what the auto negatiotiation reset
-			   really means, but it sounds for me right to do one here)*/
+			 * (I don't really know what the auto negatiotiation
+			 * reset really means, but it sounds for me right to
+			 * do one here) */
 			mdio_write(dev, mii_phy->phy_addr,
 				   MII_CONTROL, status | MII_CNTL_AUTO | MII_CNTL_RST_AUTO);
 
@@ -1984,10 +2003,11 @@
 		case IF_PORT_10BASET: /* 10BaseT */         
 			dev->if_port = map->port;
                 
-			/* we are going to change the media type, so the Link will
-			   be temporary down and we need to reflect that here. When
-			   the Link comes up again, it will be sensed by the sis_timer
-			   procedure, which also does all the rest for us */
+			/* we are going to change the media type, so the Link
+			 * will be temporary down and we need to reflect that
+			 * here. When the Link comes up again, it will be
+			 * sensed by the sis_timer procedure, which also does
+			 * all the rest for us */
 			netif_carrier_off(dev);
         
 			/* set Speed to 10Mbps */
@@ -1996,24 +2016,27 @@
                 
 			/* disable auto negotiation and force 10MBit mode*/
 			mdio_write(dev, mii_phy->phy_addr,
-				   MII_CONTROL, status & ~(MII_CNTL_SPEED | MII_CNTL_AUTO));
+				   MII_CONTROL, status & ~(MII_CNTL_SPEED |
+					MII_CNTL_AUTO));
 			break;
             
 		case IF_PORT_100BASET: /* 100BaseT */
 		case IF_PORT_100BASETX: /* 100BaseTx */ 
 			dev->if_port = map->port;
                 
-			/* we are going to change the media type, so the Link will
-			   be temporary down and we need to reflect that here. When
-			   the Link comes up again, it will be sensed by the sis_timer
-			   procedure, which also does all the rest for us */
+			/* we are going to change the media type, so the Link
+			 * will be temporary down and we need to reflect that
+			 * here. When the Link comes up again, it will be
+			 * sensed by the sis_timer procedure, which also does
+			 * all the rest for us */
 			netif_carrier_off(dev);
                 
 			/* set Speed to 100Mbps */
 			/* disable auto negotiation and enable 100MBit Mode */
 			status = mdio_read(dev, mii_phy->phy_addr, MII_CONTROL);
 			mdio_write(dev, mii_phy->phy_addr,
-				   MII_CONTROL, (status & ~MII_CNTL_SPEED) | MII_CNTL_SPEED);
+				   MII_CONTROL, (status & ~MII_CNTL_SPEED) |
+				   MII_CNTL_SPEED);
                 
 			break;
             
@@ -2093,12 +2116,14 @@
 		for (i = 0; i < table_entries; i++)
 			mc_filter[i] = 0xffff;
 	} else {
-		/* Accept Broadcast packet, destination address matchs our MAC address,
-		   use Receive Filter to reject unwanted MCAST packet */
+		/* Accept Broadcast packet, destination address matchs our
+		 * MAC address, use Receive Filter to reject unwanted MCAST
+		 * packets */
 		struct dev_mc_list *mclist;
 		rx_mode = RFAAB;
-		for (i = 0, mclist = net_dev->mc_list; mclist && i < net_dev->mc_count;
-		     i++, mclist = mclist->next) {
+		for (i = 0, mclist = net_dev->mc_list;
+			mclist && i < net_dev->mc_count;
+			i++, mclist = mclist->next) {
 			unsigned int bit_nr =
 				sis900_mcast_bitnr(mclist->dmi_addr, revision);
 			mc_filter[bit_nr >> 4] |= (1 << (bit_nr & 0xf));
@@ -2114,7 +2139,8 @@
 
 	outl(RFEN | rx_mode, ioaddr + rfcr);
 
-	/* sis900 is capatable of looping back packet at MAC level for debugging purpose */
+	/* sis900 is capable of looping back packets at MAC level for
+	 * debugging purpose */
 	if (net_dev->flags & IFF_LOOPBACK) {
 		u32 cr_saved;
 		/* We must disable Tx/Rx before setting loopback mode */
diff -Nru a/drivers/net/smc91x.c b/drivers/net/smc91x.c
--- a/drivers/net/smc91x.c	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/smc91x.c	2004-10-21 22:09:44 -04:00
@@ -55,12 +55,10 @@
  *                                  smc_phy_configure
  *                                - clean up (and fix stack overrun) in PHY
  *                                  MII read/write functions
- *   09/15/04  Hayato Fujiwara    - Add m32r support.
- *                                - Modify for SMP kernel; Change spin-locked
- *                                  regions.
+ *   22/09/04  Nicolas Pitre      big update (see commit log for details)
  */
 static const char version[] =
-	"smc91x.c: v1.0, mar 07 2003 by Nicolas Pitre <nico@cam.org>\n";
+	"smc91x.c: v1.1, sep 22 2004 by Nicolas Pitre <nico@cam.org>\n";
 
 /* Debugging level */
 #ifndef SMC_DEBUG
@@ -75,7 +73,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
-#include <linux/timer.h>
+#include <linux/interrupt.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/crc32.h>
@@ -83,6 +81,7 @@
 #include <linux/spinlock.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
+#include <linux/workqueue.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -177,7 +176,8 @@
 	 * packet, I will store the skbuff here, until I get the
 	 * desired memory.  Then, I'll send it out and free it.
 	 */
-	struct sk_buff *saved_skb;
+	struct sk_buff *pending_tx_skb;
+	struct tasklet_struct tx_task;
 
  	/*
 	 * these are things that the kernel wants me to keep, so users
@@ -203,6 +203,8 @@
 	u32	msg_enable;
 	u32	phy_type;
 	struct mii_if_info mii;
+	struct work_struct phy_configure;
+
 	spinlock_t lock;
 
 #ifdef SMC_USE_PXA_DMA
@@ -215,7 +217,7 @@
 #define DBG(n, args...)					\
 	do {						\
 		if (SMC_DEBUG >= (n))			\
-			printk(KERN_DEBUG args);	\
+			printk(args);	\
 	} while (0)
 
 #define PRINTK(args...)   printk(args)
@@ -260,17 +262,21 @@
 /* this enables an interrupt in the interrupt mask register */
 #define SMC_ENABLE_INT(x) do {						\
 	unsigned char mask;						\
+	spin_lock_irq(&lp->lock);					\
 	mask = SMC_GET_INT_MASK();					\
 	mask |= (x);							\
 	SMC_SET_INT_MASK(mask);						\
+	spin_unlock_irq(&lp->lock);					\
 } while (0)
 
 /* this disables an interrupt from the interrupt mask register */
 #define SMC_DISABLE_INT(x) do {						\
 	unsigned char mask;						\
+	spin_lock_irq(&lp->lock);					\
 	mask = SMC_GET_INT_MASK();					\
 	mask &= ~(x);							\
 	SMC_SET_INT_MASK(mask);						\
+	spin_unlock_irq(&lp->lock);					\
 } while (0)
 
 /*
@@ -299,10 +305,17 @@
 static void smc_reset(struct net_device *dev)
 {
 	unsigned long ioaddr = dev->base_addr;
+	struct smc_local *lp = netdev_priv(dev);
 	unsigned int ctl, cfg;
 
 	DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
 
+	/* Disable all interrupts */
+	spin_lock(&lp->lock);
+	SMC_SELECT_BANK(2);
+	SMC_SET_INT_MASK(0);
+	spin_unlock(&lp->lock);
+
 	/*
 	 * This resets the registers mostly to defaults, but doesn't
 	 * affect EEPROM.  That seems unnecessary
@@ -358,20 +371,24 @@
 	 * transmitted packets, to make the best use out of our limited
 	 * memory
 	 */
-#if ! THROTTLE_TX_PKTS
-	ctl |= CTL_AUTO_RELEASE;
-#else
-	ctl &= ~CTL_AUTO_RELEASE;
-#endif
+	if(!THROTTLE_TX_PKTS)
+		ctl |= CTL_AUTO_RELEASE;
+	else
+		ctl &= ~CTL_AUTO_RELEASE;
 	SMC_SET_CTL(ctl);
 
-	/* Disable all interrupts */
-	SMC_SELECT_BANK(2);
-	SMC_SET_INT_MASK(0);
-
 	/* Reset the MMU */
+	SMC_SELECT_BANK(2);
 	SMC_SET_MMU_CMD(MC_RESET);
 	SMC_WAIT_MMU_BUSY();
+
+	/* clear anything saved */
+	if (lp->pending_tx_skb != NULL) {
+		dev_kfree_skb (lp->pending_tx_skb);
+		lp->pending_tx_skb = NULL;
+		lp->stats.tx_errors++;
+		lp->stats.tx_aborted_errors++;
+	}
 }
 
 /*
@@ -390,24 +407,39 @@
 	SMC_SET_TCR(lp->tcr_cur_mode);
 	SMC_SET_RCR(lp->rcr_cur_mode);
 
+	SMC_SELECT_BANK(1);
+	SMC_SET_MAC_ADDR(dev->dev_addr);
+
 	/* now, enable interrupts */
 	mask = IM_EPH_INT|IM_RX_OVRN_INT|IM_RCV_INT;
 	if (lp->version >= (CHIP_91100 << 4))
 		mask |= IM_MDINT;
 	SMC_SELECT_BANK(2);
 	SMC_SET_INT_MASK(mask);
+
+	/*
+	 * From this point the register bank must _NOT_ be switched away
+	 * to something else than bank 2 without proper locking against
+	 * races with any tasklet or interrupt handlers until smc_shutdown()
+	 * or smc_reset() is called.
+	 */
 }
 
 /*
  * this puts the device in an inactive state
  */
-static void smc_shutdown(unsigned long ioaddr)
+static void smc_shutdown(struct net_device *dev)
 {
+	unsigned long ioaddr = dev->base_addr;
+	struct smc_local *lp = netdev_priv(dev);
+
 	DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
 
 	/* no more interrupts for me */
+	spin_lock(&lp->lock);
 	SMC_SELECT_BANK(2);
 	SMC_SET_INT_MASK(0);
+	spin_unlock(&lp->lock);
 
 	/* and tell the card to stay away from that nasty outside world */
 	SMC_SELECT_BANK(0);
@@ -449,6 +481,8 @@
 		packet_len, packet_len);
 
 	if (unlikely(status & RS_ERRORS)) {
+		SMC_WAIT_MMU_BUSY();
+		SMC_SET_MMU_CMD(MC_RELEASE);
 		lp->stats.rx_errors++;
 		if (status & RS_ALGNERR)
 			lp->stats.rx_frame_errors++;
@@ -466,17 +500,21 @@
 			lp->stats.multicast++;
 
 		/*
-		 * Actual payload is packet_len - 4 (or 3 if odd byte).
+		 * Actual payload is packet_len - 6 (or 5 if odd byte).
 		 * We want skb_reserve(2) and the final ctrl word
 		 * (2 bytes, possibly containing the payload odd byte).
-		 * Ence packet_len - 4 + 2 + 2.
+		 * Furthermore, we add 2 bytes to allow rounding up to
+		 * multiple of 4 bytes on 32 bit buses.
+		 * Ence packet_len - 6 + 2 + 2 + 2.
 		 */
 		skb = dev_alloc_skb(packet_len);
 		if (unlikely(skb == NULL)) {
 			printk(KERN_NOTICE "%s: Low memory, packet dropped.\n",
 				dev->name);
+			SMC_WAIT_MMU_BUSY();
+			SMC_SET_MMU_CMD(MC_RELEASE);
 			lp->stats.rx_dropped++;
-			goto done;
+			return;
 		}
 
 		/* Align IP header to 32 bits */
@@ -487,14 +525,18 @@
 			status |= RS_ODDFRAME;
 
 		/*
-		 * If odd length: packet_len - 3,
-		 * otherwise packet_len - 4.
+		 * If odd length: packet_len - 5,
+		 * otherwise packet_len - 6.
+		 * With the trailing ctrl byte it's packet_len - 4.
 		 */
-		data_len = packet_len - ((status & RS_ODDFRAME) ? 3 : 4);
+		data_len = packet_len - ((status & RS_ODDFRAME) ? 5 : 6);
 		data = skb_put(skb, data_len);
-		SMC_PULL_DATA(data, packet_len - 2);
+		SMC_PULL_DATA(data, packet_len - 4);
 
-		PRINT_PKT(data, packet_len - 2);
+		SMC_WAIT_MMU_BUSY();
+		SMC_SET_MMU_CMD(MC_RELEASE);
+
+		PRINT_PKT(data, packet_len - 4);
 
 		dev->last_rx = jiffies;
 		skb->dev = dev;
@@ -503,34 +545,76 @@
 		lp->stats.rx_packets++;
 		lp->stats.rx_bytes += data_len;
 	}
-
-done:
-	SMC_WAIT_MMU_BUSY();
-	SMC_SET_MMU_CMD(MC_RELEASE);
 }
 
+#ifdef CONFIG_SMP
+/*
+ * On SMP we have the following problem:
+ *
+ * 	A = smc_hardware_send_pkt()
+ * 	B = smc_hard_start_xmit()
+ * 	C = smc_interrupt()
+ *
+ * A and B can never be executed simultaneously.  However, at least on UP,
+ * it is possible (and even desirable) for C to interrupt execution of
+ * A or B in order to have better RX reliability and avoid overruns.
+ * C, just like A and B, must have exclusive access to the chip and
+ * each of them must lock against any other concurrent access.
+ * Unfortunately this is not possible to have C suspend execution of A or
+ * B taking place on another CPU. On UP this is no an issue since A and B
+ * are run from softirq context and C from hard IRQ context, and there is
+ * no other CPU where concurrent access can happen.
+ * If ever there is a way to force at least B and C to always be executed
+ * on the same CPU then we could use read/write locks to protect against
+ * any other concurrent access and C would always interrupt B. But life
+ * isn't that easy in a SMP world...
+ */
+#define smc_special_trylock(lock)					\
+({									\
+	int __ret;							\
+	local_irq_disable();						\
+	__ret = spin_trylock(lock);					\
+	if (!__ret)							\
+		local_irq_enable();					\
+	__ret;								\
+})
+#define smc_special_lock(lock)		spin_lock_irq(lock)
+#define smc_special_unlock(lock)	spin_unlock_irq(lock)
+#else
+#define smc_special_trylock(lock)	(1)
+#define smc_special_lock(lock)		do { } while (0)
+#define smc_special_unlock(lock)	do { } while (0)
+#endif
+
 /*
  * This is called to actually send a packet to the chip.
- * Returns non-zero when successful.
  */
-static void smc_hardware_send_packet(struct net_device *dev)
+static void smc_hardware_send_pkt(unsigned long data)
 {
+	struct net_device *dev = (struct net_device *)data;
 	struct smc_local *lp = netdev_priv(dev);
 	unsigned long ioaddr = dev->base_addr;
-	struct sk_buff *skb = lp->saved_skb;
+	struct sk_buff *skb;
 	unsigned int packet_no, len;
 	unsigned char *buf;
 
 	DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
 
+	if (!smc_special_trylock(&lp->lock)) {
+		netif_stop_queue(dev);
+		tasklet_schedule(&lp->tx_task);
+		return;
+	}
+
+	skb = lp->pending_tx_skb;
+	lp->pending_tx_skb = NULL;
 	packet_no = SMC_GET_AR();
 	if (unlikely(packet_no & AR_FAILED)) {
 		printk("%s: Memory allocation failed.\n", dev->name);
-		lp->saved_skb = NULL;
 		lp->stats.tx_errors++;
 		lp->stats.tx_fifo_errors++;
-		dev_kfree_skb_any(skb);
-		return;
+		smc_special_unlock(&lp->lock);
+		goto done;
 	}
 
 	/* point to the beginning of the packet */
@@ -555,15 +639,33 @@
 	/* Send final ctl word with the last byte if there is one */
 	SMC_outw(((len & 1) ? (0x2000 | buf[len-1]) : 0), ioaddr, DATA_REG);
 
-	/* and let the chipset deal with it */
+	/*
+	 * If THROTTLE_TX_PKTS is set, we look at the TX_EMPTY flag
+	 * before queueing this packet for TX, and if it's clear then
+	 * we stop the queue here.  This will have the effect of
+	 * having at most 2 packets queued for TX in the chip's memory
+	 * at all time. If THROTTLE_TX_PKTS is not set then the queue
+	 * is stopped only when memory allocation (MC_ALLOC) does not
+	 * succeed right away.
+	 */
+	if (THROTTLE_TX_PKTS && !(SMC_GET_INT() & IM_TX_EMPTY_INT))
+		netif_stop_queue(dev);
+
+	/* queue the packet for TX */
 	SMC_SET_MMU_CMD(MC_ENQUEUE);
 	SMC_ACK_INT(IM_TX_EMPTY_INT);
+	smc_special_unlock(&lp->lock);
 
 	dev->trans_start = jiffies;
-	dev_kfree_skb_any(skb);
-	lp->saved_skb = NULL;
 	lp->stats.tx_packets++;
 	lp->stats.tx_bytes += len;
+
+	SMC_ENABLE_INT(IM_TX_INT | IM_TX_EMPTY_INT);
+
+done:	if (!THROTTLE_TX_PKTS)
+		netif_wake_queue(dev);
+
+	dev_kfree_skb(skb);
 }
 
 /*
@@ -576,15 +678,12 @@
 {
 	struct smc_local *lp = netdev_priv(dev);
 	unsigned long ioaddr = dev->base_addr;
-	unsigned int numPages, poll_count, status, saved_bank;
-	unsigned long flags;
+	unsigned int numPages, poll_count, status;
 
 	DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
 
-	spin_lock_irqsave(&lp->lock, flags);
-
-	BUG_ON(lp->saved_skb != NULL);
-	lp->saved_skb = skb;
+	BUG_ON(lp->pending_tx_skb != NULL);
+	lp->pending_tx_skb = skb;
 
 	/*
 	 * The MMU wants the number of pages to be the number of 256 bytes
@@ -600,17 +699,16 @@
 	numPages = ((skb->len & ~1) + (6 - 1)) >> 8;
 	if (unlikely(numPages > 7)) {
 		printk("%s: Far too big packet error.\n", dev->name);
-		lp->saved_skb = NULL;
+		lp->pending_tx_skb = NULL;
 		lp->stats.tx_errors++;
 		lp->stats.tx_dropped++;
 		dev_kfree_skb(skb);
-		spin_unlock_irqrestore(&lp->lock, flags);
 		return 0;
 	}
 
+	smc_special_lock(&lp->lock);
+
 	/* now, try to allocate the memory */
-	saved_bank = SMC_CURRENT_BANK();
-	SMC_SELECT_BANK(2);
 	SMC_SET_MMU_CMD(MC_ALLOC | numPages);
 
 	/*
@@ -626,6 +724,8 @@
 		}
    	} while (--poll_count);
 
+	smc_special_unlock(&lp->lock);
+
    	if (!poll_count) {
 		/* oh well, wait until the chip finds memory later */
 		netif_stop_queue(dev);
@@ -635,25 +735,10 @@
 		/*
 		 * Allocation succeeded: push packet to the chip's own memory
 		 * immediately.
-		 *
-		 * If THROTTLE_TX_PKTS is selected that means we don't want
-		 * more than a single TX packet taking up space in the chip's
-		 * internal memory at all time, in which case we stop the
-		 * queue right here until we're notified of TX completion.
-		 *
-		 * Otherwise we're quite happy to feed more TX packets right
-		 * away for better TX throughput, in which case the queue is
-		 * left active.
 		 */  
-#if THROTTLE_TX_PKTS
-		netif_stop_queue(dev);
-#endif
-		smc_hardware_send_packet(dev);
-		SMC_ENABLE_INT(IM_TX_INT | IM_TX_EMPTY_INT);
+		smc_hardware_send_pkt((unsigned long)dev);
 	}
 
-	SMC_SELECT_BANK(saved_bank);
-	spin_unlock_irqrestore(&lp->lock, flags);
 	return 0;
 }
 
@@ -767,10 +852,8 @@
 static int smc_phy_read(struct net_device *dev, int phyaddr, int phyreg)
 {
 	unsigned long ioaddr = dev->base_addr;
-	unsigned int phydata, old_bank;
+	unsigned int phydata;
 
-	/* Save the current bank, and select bank 3 */
-	old_bank = SMC_CURRENT_BANK();
 	SMC_SELECT_BANK(3);
 
 	/* Idle - 32 ones */
@@ -785,12 +868,10 @@
 	/* Return to idle state */
 	SMC_SET_MII(SMC_GET_MII() & ~(MII_MCLK|MII_MDOE|MII_MDO));
 
-	/* And select original bank */
-	SMC_SELECT_BANK(old_bank);
-
 	DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
 		__FUNCTION__, phyaddr, phyreg, phydata);
 
+	SMC_SELECT_BANK(2);
 	return phydata;
 }
 
@@ -801,10 +882,7 @@
 			  int phydata)
 {
 	unsigned long ioaddr = dev->base_addr;
-	unsigned int old_bank;
 
-	/* Save the current bank, and select bank 3 */
-	old_bank = SMC_CURRENT_BANK();
 	SMC_SELECT_BANK(3);
 
 	/* Idle - 32 ones */
@@ -816,11 +894,10 @@
 	/* Return to idle state */
 	SMC_SET_MII(SMC_GET_MII() & ~(MII_MCLK|MII_MDOE|MII_MDO));
 
-	/* And select original bank */
-	SMC_SELECT_BANK(old_bank);
-
 	DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
 		__FUNCTION__, phyaddr, phyreg, phydata);
+
+	SMC_SELECT_BANK(2);
 }
 
 /*
@@ -893,7 +970,9 @@
 	smc_phy_write(dev, phyaddr, MII_BMCR, bmcr);
 
 	/* Re-Configure the Receive/Phy Control register */
+	SMC_SELECT_BANK(0);
 	SMC_SET_RPC(lp->rpc_cur_mode);
+	SMC_SELECT_BANK(2);
 
 	return 1;
 }
@@ -941,13 +1020,10 @@
  */
 static void smc_phy_powerdown(struct net_device *dev, int phy)
 {
-	struct smc_local *lp = netdev_priv(dev);
 	unsigned int bmcr;
 
-	spin_lock_irq(&lp->lock);
 	bmcr = smc_phy_read(dev, phy, MII_BMCR);
 	smc_phy_write(dev, phy, MII_BMCR, bmcr | BMCR_PDOWN);
-	spin_unlock_irq(&lp->lock);
 }
 
 /*
@@ -964,8 +1040,6 @@
 	unsigned long ioaddr = dev->base_addr;
 
 	if (mii_check_media(&lp->mii, netif_msg_link(lp), init)) {
-		unsigned int old_bank;
-
 		/* duplex state has changed */
 		if (lp->mii.full_duplex) {
 			lp->tcr_cur_mode |= TCR_SWFDUP;
@@ -973,10 +1047,8 @@
 			lp->tcr_cur_mode &= ~TCR_SWFDUP;
 		}
 
-		old_bank = SMC_CURRENT_BANK();
 		SMC_SELECT_BANK(0);
 		SMC_SET_TCR(lp->tcr_cur_mode);
-		SMC_SELECT_BANK(old_bank);
 	}
 }
 
@@ -989,8 +1061,9 @@
  * of autonegotiation.)  If the RPC ANEG bit is cleared, the selection
  * is controlled by the RPC SPEED and RPC DPLX bits.
  */
-static void smc_phy_configure(struct net_device *dev)
+static void smc_phy_configure(void *data)
 {
+	struct net_device *dev = data;
 	struct smc_local *lp = netdev_priv(dev);
 	unsigned long ioaddr = dev->base_addr;
 	int phyaddr = lp->mii.phy_id;
@@ -1117,12 +1190,13 @@
 {
 	struct smc_local *lp = netdev_priv(dev);
 	unsigned long ioaddr = dev->base_addr;
-	unsigned int old_carrier, new_carrier, old_bank;
+	unsigned int old_carrier, new_carrier;
 
-	old_bank = SMC_CURRENT_BANK();
-	SMC_SELECT_BANK(0);
 	old_carrier = netif_carrier_ok(dev) ? 1 : 0;
+
+	SMC_SELECT_BANK(0);
 	new_carrier = SMC_inw(ioaddr, EPH_STATUS_REG) & ES_LINK_OK ? 1 : 0;
+	SMC_SELECT_BANK(2);
 
 	if (init || (old_carrier != new_carrier)) {
 		if (!new_carrier) {
@@ -1134,24 +1208,20 @@
 			printk(KERN_INFO "%s: link %s\n", dev->name,
 			       new_carrier ? "up" : "down");
 	}
-	SMC_SELECT_BANK(old_bank);
 }
 
 static void smc_eph_interrupt(struct net_device *dev)
 {
 	unsigned long ioaddr = dev->base_addr;
-	unsigned int old_bank, ctl;
+	unsigned int ctl;
 
 	smc_10bt_check_media(dev, 0);
 
-	old_bank = SMC_CURRENT_BANK();
 	SMC_SELECT_BANK(1);
-
 	ctl = SMC_GET_CTL();
 	SMC_SET_CTL(ctl & ~CTL_LE_ENABLE);
 	SMC_SET_CTL(ctl);
-
-	SMC_SELECT_BANK(old_bank);
+	SMC_SELECT_BANK(2);
 }
 
 /*
@@ -1164,14 +1234,12 @@
 	unsigned long ioaddr = dev->base_addr;
 	struct smc_local *lp = netdev_priv(dev);
 	int status, mask, timeout, card_stats;
-	int saved_bank, saved_pointer;
+	int saved_pointer;
 
 	DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
 
 	spin_lock(&lp->lock);
 
-	saved_bank = SMC_CURRENT_BANK();
-	SMC_SELECT_BANK(2);
 	saved_pointer = SMC_GET_PTR();
 	mask = SMC_GET_INT_MASK();
 	SMC_SET_INT_MASK(0);
@@ -1182,7 +1250,7 @@
 	do {
 		status = SMC_GET_INT();
 
-		DBG(2, "%s: IRQ 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n",
+		DBG(2, "%s: INT 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n",
 			dev->name, status, mask,
 			({ int meminfo; SMC_SELECT_BANK(0);
 			   meminfo = SMC_GET_MIR();
@@ -1200,17 +1268,12 @@
 			DBG(3, "%s: TX int\n", dev->name);
 			smc_tx(dev);
 			SMC_ACK_INT(IM_TX_INT);
-#if THROTTLE_TX_PKTS
-			netif_wake_queue(dev);
-#endif
+			if (THROTTLE_TX_PKTS)
+				netif_wake_queue(dev);
 		} else if (status & IM_ALLOC_INT) {
 			DBG(3, "%s: Allocation irq\n", dev->name);
-			smc_hardware_send_packet(dev);
-			mask |= (IM_TX_INT | IM_TX_EMPTY_INT);
+			tasklet_hi_schedule(&lp->tx_task);
 			mask &= ~IM_ALLOC_INT;
-#if ! THROTTLE_TX_PKTS
-			netif_wake_queue(dev);
-#endif
 		} else if (status & IM_TX_EMPTY_INT) {
 			DBG(3, "%s: TX empty\n", dev->name);
 			mask &= ~IM_TX_EMPTY_INT;
@@ -1240,17 +1303,16 @@
 			SMC_ACK_INT(IM_ERCV_INT);
 			PRINTK("%s: UNSUPPORTED: ERCV INTERRUPT \n", dev->name);
 		}
-
 	} while (--timeout);
 
 	/* restore register states */
-	SMC_SET_INT_MASK(mask);
 	SMC_SET_PTR(saved_pointer);
-	SMC_SELECT_BANK(saved_bank);
+	SMC_SET_INT_MASK(mask);
+
+	spin_unlock(&lp->lock);
 
 	DBG(3, "%s: Interrupt done (%d loops)\n", dev->name, 8-timeout);
 
-	spin_unlock(&lp->lock);
 	/*
 	 * We return IRQ_HANDLED unconditionally here even if there was
 	 * nothing to do.  There is a possibility that a packet might
@@ -1266,101 +1328,39 @@
 static void smc_timeout(struct net_device *dev)
 {
 	struct smc_local *lp = netdev_priv(dev);
-	unsigned long flags;
+	unsigned long ioaddr = dev->base_addr;
+	int status, mask, meminfo, fifo;
 
-	spin_lock_irqsave(&lp->lock, flags);
 	DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
 
+	spin_lock_irq(&lp->lock);
+	status = SMC_GET_INT();
+	mask = SMC_GET_INT_MASK();
+	fifo = SMC_GET_FIFO();
+	SMC_SELECT_BANK(0);
+	meminfo = SMC_GET_MIR();
+	SMC_SELECT_BANK(2);
+	spin_unlock_irq(&lp->lock);
+	PRINTK( "%s: INT 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n",
+		dev->name, status, mask, meminfo, fifo );
+
 	smc_reset(dev);
 	smc_enable(dev);
 
-#if 0
 	/*
 	 * Reconfiguring the PHY doesn't seem like a bad idea here, but
-	 * it introduced a problem.  Now that this is a timeout routine,
-	 * we are getting called from within an interrupt context.
-	 * smc_phy_configure() calls msleep() which calls
-	 * schedule_timeout() which calls schedule().  When schedule()
-	 * is called from an interrupt context, it prints out
-	 * "Scheduling in interrupt" and then calls BUG().  This is
-	 * obviously not desirable.  This was worked around by removing
-	 * the call to smc_phy_configure() here because it didn't seem
-	 * absolutely necessary.  Ultimately, if msleep() is
-	 * supposed to be usable from an interrupt context (which it
-	 * looks like it thinks it should handle), it should be fixed.
+	 * smc_phy_configure() calls msleep() which calls schedule_timeout()
+	 * which calls schedule().  Ence we use a work queue.
 	 */
 	if (lp->phy_type != 0)
-		smc_phy_configure(dev);
-#endif
+		schedule_work(&lp->phy_configure);
 
-	/* clear anything saved */
-	if (lp->saved_skb != NULL) {
-		dev_kfree_skb (lp->saved_skb);
-		lp->saved_skb = NULL;
-		lp->stats.tx_errors++;
-		lp->stats.tx_aborted_errors++;
-	}
 	/* We can accept TX packets again */
 	dev->trans_start = jiffies;
-
-	spin_unlock_irqrestore(&lp->lock, flags);
-
 	netif_wake_queue(dev);
 }
 
 /*
- *    This sets the internal hardware table to filter out unwanted multicast
- *    packets before they take up memory.
- *
- *    The SMC chip uses a hash table where the high 6 bits of the CRC of
- *    address are the offset into the table.  If that bit is 1, then the
- *    multicast packet is accepted.  Otherwise, it's dropped silently.
- *
- *    To use the 6 bits as an offset into the table, the high 3 bits are the
- *    number of the 8 bit register, while the low 3 bits are the bit within
- *    that register.
- *
- *    This routine is based very heavily on the one provided by Peter Cammaert.
- */
-static void
-smc_setmulticast(unsigned long ioaddr, int count, struct dev_mc_list *addrs)
-{
-	int i;
-	unsigned char multicast_table[8];
-	struct dev_mc_list *cur_addr;
-
-	/* table for flipping the order of 3 bits */
-	static unsigned char invert3[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
-
-	/* start with a table of all zeros: reject all */
-	memset(multicast_table, 0, sizeof(multicast_table));
-
-	cur_addr = addrs;
-	for (i = 0; i < count; i++, cur_addr = cur_addr->next) {
-		int position;
-
-		/* do we have a pointer here? */
-		if (!cur_addr)
-			break;
-		/* make sure this is a multicast address - shouldn't this
-		   be a given if we have it here ? */
-		if (!(*cur_addr->dmi_addr & 1))
-			continue;
-
-		/* only use the low order bits */
-		position = crc32_le(~0, cur_addr->dmi_addr, 6) & 0x3f;
-
-		/* do some messy swapping to put the bit in the right spot */
-		multicast_table[invert3[position&7]] |=
-					(1<<invert3[(position>>3)&7]);
-
-	}
-	/* now, the table can be loaded into the chipset */
-	SMC_SELECT_BANK(3);
-	SMC_SET_MCAST(multicast_table);
-}
-
-/*
  * This routine will, depending on the values passed to it,
  * either make it accept multicast packets, go into
  * promiscuous mode (for TCPDUMP and cousins) or accept
@@ -1370,14 +1370,14 @@
 {
 	struct smc_local *lp = netdev_priv(dev);
 	unsigned long ioaddr = dev->base_addr;
+	unsigned char multicast_table[8];
+	int update_multicast = 0;
 
 	DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
 
-	SMC_SELECT_BANK(0);
 	if (dev->flags & IFF_PROMISC) {
 		DBG(2, "%s: RCR_PRMS\n", dev->name);
 		lp->rcr_cur_mode |= RCR_PRMS;
-		SMC_SET_RCR(lp->rcr_cur_mode);
 	}
 
 /* BUG?  I never disable promiscuous mode if multicasting was turned on.
@@ -1391,38 +1391,78 @@
 	 * checked before the table is
 	 */
 	else if (dev->flags & IFF_ALLMULTI || dev->mc_count > 16) {
-		lp->rcr_cur_mode |= RCR_ALMUL;
-		SMC_SET_RCR(lp->rcr_cur_mode);
 		DBG(2, "%s: RCR_ALMUL\n", dev->name);
+		lp->rcr_cur_mode |= RCR_ALMUL;
 	}
 
 	/*
-	 * We just get all multicast packets even if we only want them
-	 * from one source.  This will be changed at some future point.
+	 * This sets the internal hardware table to filter out unwanted
+	 * multicast packets before they take up memory.
+	 *
+	 * The SMC chip uses a hash table where the high 6 bits of the CRC of
+	 * address are the offset into the table.  If that bit is 1, then the
+	 * multicast packet is accepted.  Otherwise, it's dropped silently.
+	 *
+	 * To use the 6 bits as an offset into the table, the high 3 bits are
+	 * the number of the 8 bit register, while the low 3 bits are the bit
+	 * within that register.
 	 */
 	else if (dev->mc_count)  {
-		/* support hardware multicasting */
+		int i;
+		struct dev_mc_list *cur_addr;
+
+		/* table for flipping the order of 3 bits */
+		static const unsigned char invert3[] = {0, 4, 2, 6, 1, 5, 3, 7};
+
+		/* start with a table of all zeros: reject all */
+		memset(multicast_table, 0, sizeof(multicast_table));
+
+		cur_addr = dev->mc_list;
+		for (i = 0; i < dev->mc_count; i++, cur_addr = cur_addr->next) {
+			int position;
+
+			/* do we have a pointer here? */
+			if (!cur_addr)
+				break;
+			/* make sure this is a multicast address -
+		   	   shouldn't this be a given if we have it here ? */
+			if (!(*cur_addr->dmi_addr & 1))
+				continue;
+
+			/* only use the low order bits */
+			position = crc32_le(~0, cur_addr->dmi_addr, 6) & 0x3f;
+
+			/* do some messy swapping to put the bit in the right spot */
+			multicast_table[invert3[position&7]] |=
+				(1<<invert3[(position>>3)&7]);
+		}
 
 		/* be sure I get rid of flags I might have set */
 		lp->rcr_cur_mode &= ~(RCR_PRMS | RCR_ALMUL);
-		SMC_SET_RCR(lp->rcr_cur_mode);
-		/*
-		 * NOTE: this has to set the bank, so make sure it is the
-		 * last thing called.  The bank is set to zero at the top
-		 */
-		smc_setmulticast(ioaddr, dev->mc_count, dev->mc_list);
+
+		/* now, the table can be loaded into the chipset */
+		update_multicast = 1;
 	} else  {
 		DBG(2, "%s: ~(RCR_PRMS|RCR_ALMUL)\n", dev->name);
 		lp->rcr_cur_mode &= ~(RCR_PRMS | RCR_ALMUL);
-		SMC_SET_RCR(lp->rcr_cur_mode);
 
 		/*
 		 * since I'm disabling all multicast entirely, I need to
 		 * clear the multicast list
 		 */
+		memset(multicast_table, 0, sizeof(multicast_table));
+		update_multicast = 1;
+	}
+
+	spin_lock_irq(&lp->lock);
+	SMC_SELECT_BANK(0);
+	SMC_SET_RCR(lp->rcr_cur_mode);
+	if (update_multicast) {
 		SMC_SELECT_BANK(3);
-		SMC_CLEAR_MCAST();
+		SMC_SET_MCAST(multicast_table);
 	}
+	SMC_SELECT_BANK(2);
+	spin_unlock_irq(&lp->lock);
 }
 
 
@@ -1435,7 +1475,6 @@
 smc_open(struct net_device *dev)
 {
 	struct smc_local *lp = netdev_priv(dev);
-	unsigned long ioaddr = dev->base_addr;
 
 	DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
 
@@ -1445,13 +1484,10 @@
 	 * address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx
 	 */
 	if (!is_valid_ether_addr(dev->dev_addr)) {
-		DBG(2, "smc_open: no valid ethernet hw addr\n");
+		PRINTK("%s: no valid ethernet hw addr\n", __FUNCTION__);
 		return -EINVAL;
 	}
 
-	/* clear out all the junk that was put here before... */
-	lp->saved_skb = NULL;
-
 	/* Setup the default Register Modes */
 	lp->tcr_cur_mode = TCR_DEFAULT;
 	lp->rcr_cur_mode = RCR_DEFAULT;
@@ -1468,10 +1504,7 @@
 	smc_reset(dev);
 	smc_enable(dev);
 
-	SMC_SELECT_BANK(1);
-	SMC_SET_MAC_ADDR(dev->dev_addr);
-
-	/* Configure the PHY */
+	/* Configure the PHY, initialize the link state */
 	if (lp->phy_type != 0)
 		smc_phy_configure(dev);
 	else {
@@ -1480,12 +1513,6 @@
 		spin_unlock_irq(&lp->lock);
 	}
 
-	/*
-	 * make sure to initialize the link state with netif_carrier_off()
-	 * somewhere, too --jgarzik
-	 *
-	 * smc_phy_configure() and smc_10bt_check_media() does that. --rmk
-	 */
 	netif_start_queue(dev);
 	return 0;
 }
@@ -1507,10 +1534,17 @@
 	netif_carrier_off(dev);
 
 	/* clear everything */
-	smc_shutdown(dev->base_addr);
+	smc_shutdown(dev);
 
-	if (lp->phy_type != 0)
+	if (lp->phy_type != 0) {
+		flush_scheduled_work();
 		smc_phy_powerdown(dev, lp->mii.phy_id);
+	}
+
+	if (lp->pending_tx_skb) {
+		dev_kfree_skb(lp->pending_tx_skb);
+		lp->pending_tx_skb = NULL;
+	}
 
 	return 0;
 }
@@ -1800,6 +1834,7 @@
 	/* fill in some of the fields */
 	dev->base_addr = ioaddr;
 	lp->version = revision_register & 0xff;
+	spin_lock_init(&lp->lock);
 
 	/* Get the MAC address */
 	SMC_SELECT_BANK(1);
@@ -1855,7 +1890,8 @@
 	dev->set_multicast_list = smc_set_multicast_list;
 	dev->ethtool_ops = &smc_ethtool_ops;
 
-	spin_lock_init(&lp->lock);
+	tasklet_init(&lp->tx_task, smc_hardware_send_pkt, (unsigned long)dev);
+	INIT_WORK(&lp->phy_configure, smc_phy_configure, dev);
 	lp->mii.phy_id_mask = 0x1f;
 	lp->mii.reg_num_mask = 0x1f;
 	lp->mii.force_media = 0;
@@ -1885,9 +1921,8 @@
       	if (retval)
       		goto err_out;
 
-#if !defined(__m32r__)
 	set_irq_type(dev->irq, IRQT_RISING);
-#endif
+
 #ifdef SMC_USE_PXA_DMA
 	{
 		int dma = pxa_request_dma(dev->name, DMA_PRIO_LOW,
@@ -2121,7 +2156,7 @@
 	if (ndev && level == SUSPEND_DISABLE) {
 		if (netif_running(ndev)) {
 			netif_device_detach(ndev);
-			smc_shutdown(ndev->base_addr);
+			smc_shutdown(ndev);
 		}
 	}
 	return 0;
@@ -2134,15 +2169,12 @@
 
 	if (ndev && level == RESUME_ENABLE) {
 		struct smc_local *lp = netdev_priv(ndev);
-		unsigned long ioaddr = ndev->base_addr;
 
 		if (pdev->num_resources == 3)
 			smc_enable_device(pdev->resource[2].start);
 		if (netif_running(ndev)) {
 			smc_reset(ndev);
 			smc_enable(ndev);
-			SMC_SELECT_BANK(1);
-			SMC_SET_MAC_ADDR(ndev->dev_addr);
 			if (lp->phy_type != 0)
 				smc_phy_configure(ndev);
 			netif_device_attach(ndev);
diff -Nru a/drivers/net/smc91x.h b/drivers/net/smc91x.h
--- a/drivers/net/smc91x.h	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/smc91x.h	2004-10-21 22:09:44 -04:00
@@ -173,6 +173,11 @@
 #define SMC_insw(a, r, p, l)	insw((a) + (r) - 0xa0000000, p, l)
 #define SMC_outsw(a, r, p, l)	outsw((a) + (r) - 0xa0000000, p, l)
 
+#define set_irq_type(irq, type)	do {} while(0)
+
+#define RPC_LSA_DEFAULT		RPC_LED_TX_RX
+#define RPC_LSB_DEFAULT		RPC_LED_100_10
+
 #else
 
 #define SMC_CAN_USE_8BIT	1
@@ -202,8 +207,9 @@
  * different and probably not worth it for that reason, and not as critical
  * as RX which can overrun memory and lose packets.
  */
-#include <linux/pci.h>
+#include <linux/dma-mapping.h>
 #include <asm/dma.h>
+#include <asm/arch/pxa-regs.h>
 
 #ifdef SMC_insl
 #undef SMC_insl
@@ -223,19 +229,21 @@
 
 	/* 64 bit alignment is required for memory to memory DMA */
 	if ((long)buf & 4) {
-		*((u32 *)buf)++ = SMC_inl(ioaddr, reg);
+		*((u32 *)buf) = SMC_inl(ioaddr, reg);
+		buf += 4;
 		len--;
 	}
 
 	len *= 4;
-	dmabuf = dma_map_single(NULL, buf, len, PCI_DMA_FROMDEVICE);
+	dmabuf = dma_map_single(NULL, buf, len, DMA_FROM_DEVICE);
 	DCSR(dma) = DCSR_NODESC;
 	DTADR(dma) = dmabuf;
 	DSADR(dma) = physaddr + reg;
 	DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 |
 		     DCMD_WIDTH4 | (DCMD_LENGTH & len));
 	DCSR(dma) = DCSR_NODESC | DCSR_RUN;
-	while (!(DCSR(dma) & DCSR_STOPSTATE));
+	while (!(DCSR(dma) & DCSR_STOPSTATE))
+		cpu_relax();
 	DCSR(dma) = 0;
 	dma_unmap_single(NULL, dmabuf, len, PCI_DMA_FROMDEVICE);
 }
@@ -259,7 +267,8 @@
 
 	/* 64 bit alignment is required for memory to memory DMA */
 	while ((long)buf & 6) {
-		*((u16 *)buf)++ = SMC_inw(ioaddr, reg);
+		*((u16 *)buf) = SMC_inw(ioaddr, reg);
+		buf += 2;
 		len--;
 	}
 
@@ -271,9 +280,10 @@
 	DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 |
 		     DCMD_WIDTH2 | (DCMD_LENGTH & len));
 	DCSR(dma) = DCSR_NODESC | DCSR_RUN;
-	while (!(DCSR(dma) & DCSR_STOPSTATE));
+	while (!(DCSR(dma) & DCSR_STOPSTATE))
+		cpu_relax();
 	DCSR(dma) = 0;
-	dma_unmap_single(NULL, dmabuf, len, PCI_DMA_FROMDEVICE);
+	dma_unmap_single(NULL, dmabuf, len, DMA_FROM_DEVICE);
 }
 #endif
 
@@ -762,16 +772,9 @@
 		SMC_outw( addr[4]|(addr[5] << 8), ioaddr, ADDR2_REG );	\
 	} while (0)
 
-#define SMC_CLEAR_MCAST()						\
-	do {								\
-		SMC_outw( 0, ioaddr, MCAST_REG1 );			\
-		SMC_outw( 0, ioaddr, MCAST_REG2 );			\
-		SMC_outw( 0, ioaddr, MCAST_REG3 );			\
-		SMC_outw( 0, ioaddr, MCAST_REG4 );			\
-	} while (0)
 #define SMC_SET_MCAST(x)						\
 	do {								\
-		unsigned char *mt = (x);				\
+		const unsigned char *mt = (x);				\
 		SMC_outw( mt[0] | (mt[1] << 8), ioaddr, MCAST_REG1 );	\
 		SMC_outw( mt[2] | (mt[3] << 8), ioaddr, MCAST_REG2 );	\
 		SMC_outw( mt[4] | (mt[5] << 8), ioaddr, MCAST_REG3 );	\
diff -Nru a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c
--- a/drivers/net/tokenring/lanstreamer.c	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/tokenring/lanstreamer.c	2004-10-21 22:09:44 -04:00
@@ -1606,7 +1606,7 @@
 				i += 2;
 			}
 
-			memcpy_fromio(skb_put(mac_frame, buffer_len),
+			memcpy(skb_put(mac_frame, buffer_len),
 				      frame_data, buffer_len);
 		} while (next_ptr && (buff_off = next_ptr));
 
diff -Nru a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
--- a/drivers/net/tulip/dmfe.c	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/tulip/dmfe.c	2004-10-21 22:09:44 -04:00
@@ -92,6 +92,7 @@
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/uaccess.h>
+#include <asm/irq.h>
 
 
 /* Board/System/Debug information/definition ---------------- */
diff -Nru a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
--- a/drivers/net/via-rhine.c	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/via-rhine.c	2004-10-21 22:09:44 -04:00
@@ -1957,6 +1957,7 @@
 	rhine_shutdown(&pdev->dev);
 	spin_unlock_irqrestore(&rp->lock, flags);
 
+	free_irq(dev->irq, dev);
 	return 0;
 }
 
@@ -1969,6 +1970,9 @@
 
 	if (!netif_running(dev))
 		return 0;
+
+        if (request_irq(dev->irq, rhine_interrupt, SA_SHIRQ, dev->name, dev))
+		printk(KERN_ERR "via-rhine %s: request_irq failed\n", dev->name);
 
 	ret = pci_set_power_state(pdev, 0);
 	if (debug > 1)
diff -Nru a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c
--- a/drivers/net/wireless/prism54/isl_38xx.c	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/wireless/prism54/isl_38xx.c	2004-10-21 22:09:44 -04:00
@@ -133,8 +133,8 @@
 		      readl(device_base + ISL38XX_CTRL_STAT_REG));
 		udelay(ISL38XX_WRITEIO_DELAY);
 
-		if (reg = readl(device_base + ISL38XX_INT_IDENT_REG),
-		    reg == 0xabadface) {
+		reg = readl(device_base + ISL38XX_INT_IDENT_REG);
+		if (reg == 0xabadface) {
 #if VERBOSE > SHOW_ERROR_MESSAGES
 			do_gettimeofday(&current_time);
 			DEBUG(SHOW_TRACING,
@@ -192,10 +192,8 @@
 void
 isl38xx_interface_reset(void __iomem *device_base, dma_addr_t host_address)
 {
-	u32 reg;
-
 #if VERBOSE > SHOW_ERROR_MESSAGES
-	DEBUG(SHOW_FUNCTION_CALLS, "isl38xx_interface_reset \n");
+	DEBUG(SHOW_FUNCTION_CALLS, "isl38xx_interface_reset\n");
 #endif
 
 	/* load the address of the control block in the device */
@@ -203,8 +201,7 @@
 	udelay(ISL38XX_WRITEIO_DELAY);
 
 	/* set the reset bit in the Device Interrupt Register */
-	isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_RESET,
-			  ISL38XX_DEV_INT_REG);
+	isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_RESET, ISL38XX_DEV_INT_REG);
 	udelay(ISL38XX_WRITEIO_DELAY);
 
 	/* enable the interrupt for detecting initialization */
@@ -212,9 +209,7 @@
 	/* Note: Do not enable other interrupts here. We want the
 	 * device to have come up first 100% before allowing any other 
 	 * interrupts. */
-	reg = ISL38XX_INT_IDENT_INIT;
-
-	isl38xx_w32_flush(device_base, reg, ISL38XX_INT_EN_REG);
+	isl38xx_w32_flush(device_base, ISL38XX_INT_IDENT_INIT, ISL38XX_INT_EN_REG);
 	udelay(ISL38XX_WRITEIO_DELAY);  /* allow complete full reset */
 }
 
diff -Nru a/drivers/net/wireless/prism54/isl_38xx.h b/drivers/net/wireless/prism54/isl_38xx.h
--- a/drivers/net/wireless/prism54/isl_38xx.h	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/wireless/prism54/isl_38xx.h	2004-10-21 22:09:44 -04:00
@@ -95,6 +95,10 @@
 #define ISL38XX_INT_SOURCES                     0x001E
 
 /* Control/Status register bits */
+/* Looks like there are other meaningful bits
+    0x20004400 seen in normal operation,
+    0x200044db at 'timeout waiting for mgmt response'
+*/
 #define ISL38XX_CTRL_STAT_SLEEPMODE             0x00000200
 #define	ISL38XX_CTRL_STAT_CLKRUN		0x00800000
 #define ISL38XX_CTRL_STAT_RESET                 0x10000000
diff -Nru a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
--- a/drivers/net/wireless/prism54/isl_ioctl.c	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/wireless/prism54/isl_ioctl.c	2004-10-21 22:09:44 -04:00
@@ -36,38 +36,6 @@
 
 #include <net/iw_handler.h>	/* New driver API */
 
-static int init_mode = CARD_DEFAULT_IW_MODE;
-static int init_channel = CARD_DEFAULT_CHANNEL;
-static int init_wep = CARD_DEFAULT_WEP;
-static int init_filter = CARD_DEFAULT_FILTER;
-static int init_authen = CARD_DEFAULT_AUTHEN;
-static int init_dot1x = CARD_DEFAULT_DOT1X;
-static int init_conformance = CARD_DEFAULT_CONFORMANCE;
-static int init_mlme = CARD_DEFAULT_MLME_MODE;
-
-module_param(init_mode, int, 0);
-MODULE_PARM_DESC(init_mode,
-		 "Set card mode:\n0: Auto\n1: Ad-Hoc\n2: Managed Client (Default)\n3: Master / Access Point\n4: Repeater (Not supported yet)\n5: Secondary (Not supported yet)\n6: Monitor");
-
-module_param(init_channel, int, 0);
-MODULE_PARM_DESC(init_channel,
-		 "Check `iwpriv ethx channel` for available channels");
-
-module_param(init_wep, int, 0);
-module_param(init_filter, int, 0);
-
-module_param(init_authen, int, 0);
-MODULE_PARM_DESC(init_authen,
-		 "Authentication method. Can be of seven types:\n0 0x0000: None\n1 0x0001: DOT11_AUTH_OS (Default)\n2 0x0002: DOT11_AUTH_SK\n3 0x0003: DOT11_AUTH_BOTH");
-
-module_param(init_dot1x, int, 0);
-MODULE_PARM_DESC(init_dot1x,
-		 "\n0: None/not set	(Default)\n1: DOT11_DOT1X_AUTHENABLED\n2: DOT11_DOT1X_KEYTXENABLED");
-
-module_param(init_mlme, int, 0);
-MODULE_PARM_DESC(init_mlme,
-		 "Sets the MAC layer management entity (MLME) mode of operation,\n0: DOT11_MLME_AUTO (Default)\n1: DOT11_MLME_INTERMEDIATE\n2: DOT11_MLME_EXTENDED");
-
 /**
  * prism54_mib_mode_helper - MIB change mode helper function
  * @mib: the &struct islpci_mib object to modify
@@ -141,36 +109,34 @@
 void
 prism54_mib_init(islpci_private *priv)
 {
-	u32 t;
+	u32 channel, authen, wep, filter, dot1x, mlme, conformance, power, mode;
 	struct obj_buffer psm_buffer = {
 		.size = PSM_BUFFER_SIZE,
 		.addr = priv->device_psm_buffer
 	};
 
-	mgt_set(priv, DOT11_OID_CHANNEL, &init_channel);
-	mgt_set(priv, DOT11_OID_AUTHENABLE, &init_authen);
-	mgt_set(priv, DOT11_OID_PRIVACYINVOKED, &init_wep);
-
+	channel = CARD_DEFAULT_CHANNEL;
+	authen = CARD_DEFAULT_AUTHEN;
+	wep = CARD_DEFAULT_WEP;
+	filter = CARD_DEFAULT_FILTER; /* (0) Do not filter un-encrypted data */
+	dot1x = CARD_DEFAULT_DOT1X; 
+	mlme = CARD_DEFAULT_MLME_MODE;
+	conformance = CARD_DEFAULT_CONFORMANCE;
+	power = 127;
+	mode = CARD_DEFAULT_IW_MODE;
+
+	mgt_set(priv, DOT11_OID_CHANNEL, &channel);
+	mgt_set(priv, DOT11_OID_AUTHENABLE, &authen);
+	mgt_set(priv, DOT11_OID_PRIVACYINVOKED, &wep);
 	mgt_set(priv, DOT11_OID_PSMBUFFER, &psm_buffer);
-	mgt_set(priv, DOT11_OID_EXUNENCRYPTED, &init_filter);
-	mgt_set(priv, DOT11_OID_DOT1XENABLE, &init_dot1x);
-	mgt_set(priv, DOT11_OID_MLMEAUTOLEVEL, &init_mlme);
-	mgt_set(priv, OID_INL_DOT11D_CONFORMANCE, &init_conformance);
-
-	t = 127;
-	mgt_set(priv, OID_INL_OUTPUTPOWER, &t);
-
-	/* Important: we are setting a default wireless mode and we are 
-	 * forcing a valid one, so prism54_mib_mode_helper should just set
-	 * mib values depending on what the wireless mode given is. No need
-	 * for it save old values */
-	if (init_mode > IW_MODE_MONITOR || init_mode < IW_MODE_AUTO) {
-		printk(KERN_DEBUG "%s(): You passed a non-valid init_mode. "
-		       "Using default mode\n", __FUNCTION__);
-		init_mode = CARD_DEFAULT_IW_MODE;
-	}
+	mgt_set(priv, DOT11_OID_EXUNENCRYPTED, &filter);
+	mgt_set(priv, DOT11_OID_DOT1XENABLE, &dot1x);
+	mgt_set(priv, DOT11_OID_MLMEAUTOLEVEL, &mlme);
+	mgt_set(priv, OID_INL_DOT11D_CONFORMANCE, &conformance);
+	mgt_set(priv, OID_INL_OUTPUTPOWER, &power);
+
 	/* This sets all of the mode-dependent values */
-	prism54_mib_mode_helper(priv, init_mode);
+	prism54_mib_mode_helper(priv, mode);
 }
 
 /* this will be executed outside of atomic context thanks to
@@ -374,7 +340,10 @@
 
 	mgt_set(priv, DOT11_OID_MLMEAUTOLEVEL, &mlmeautolevel);
 
-	mgt_commit(priv);
+	if (mgt_commit(priv)) {
+		up_write(&priv->mib_sem);
+		return -EIO;
+	}
 	priv->ndev->type = (priv->iw_mode == IW_MODE_MONITOR)
 	    ? priv->monitor_type : ARPHRD_ETHER;
 	up_write(&priv->mib_sem);
@@ -485,6 +454,15 @@
 	/* txpower is supported in dBm's */
 	range->txpower_capa = IW_TXPOW_DBM;
 
+#if WIRELESS_EXT > 16
+	/* Event capability (kernel + driver) */
+	range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
+	IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
+	IW_EVENT_CAPA_MASK(SIOCGIWAP));
+	range->event_capa[1] = IW_EVENT_CAPA_K_1;
+	range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVCUSTOM);
+#endif /* WIRELESS_EXT > 16 */
+
 	if (islpci_get_state(priv) < PRV_STATE_INIT)
 		return 0;
 
@@ -629,8 +607,8 @@
 	current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, NULL);
 
 	/* Add frequency. (short) bss->channel is the frequency in MHz */
-	iwe.u.freq.m = channel_of_freq(bss->channel);
-	iwe.u.freq.e = 0;
+	iwe.u.freq.m = bss->channel;
+	iwe.u.freq.e = 6;
 	iwe.cmd = SIOCGIWFREQ;
 	current_ev =
 	    iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
@@ -690,19 +668,33 @@
 	rvalue = mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r);
 	noise = r.u;
 
-	/* Ask the device for a list of known bss. We can report at most
-	 * IW_MAX_AP=64 to the range struct. But the device won't repport anything
-	 * if you change the value of IWMAX_BSS=24.
-	 */
+	/* Ask the device for a list of known bss.
+	* The old API, using SIOCGIWAPLIST, had a hard limit of IW_MAX_AP=64.
+	* The new API, using SIOCGIWSCAN, is only limited by the buffer size.
+	* WE-14->WE-16, the buffer is limited to IW_SCAN_MAX_DATA bytes.
+	* Starting with WE-17, the buffer can be as big as needed.
+	* But the device won't repport anything if you change the value
+	* of IWMAX_BSS=24. */
+	
 	rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r);
 	bsslist = r.ptr;
 
 	/* ok now, scan the list and translate its info */
-	for (i = 0; i < min(IW_MAX_AP, (int) bsslist->nr); i++)
+	for (i = 0; i < (int) bsslist->nr; i++) {
 		current_ev = prism54_translate_bss(ndev, current_ev,
-						   extra + IW_SCAN_MAX_DATA,
+						   extra + dwrq->length,
 						   &(bsslist->bsslist[i]),
 						   noise);
+#if WIRELESS_EXT > 16
+		/* Check if there is space for one more entry */
+		if((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) {
+			/* Ask user space to try again with a bigger buffer */
+			rvalue = -E2BIG;
+			break;
+		}
+#endif /* WIRELESS_EXT > 16 */
+	}
+
 	kfree(bsslist);
 	dwrq->length = (current_ev - extra);
 	dwrq->flags = 0;	/* todo */
@@ -1412,7 +1404,10 @@
 		mlmeautolevel = DOT11_MLME_EXTENDED;
 	mgt_set(priv, DOT11_OID_MLMEAUTOLEVEL, &mlmeautolevel);
 	/* restart the card with our new policy */
-	mgt_commit(priv);
+	if (mgt_commit(priv)) {
+		up_write(&priv->mib_sem);
+		return -EIO;
+	}
 	up_write(&priv->mib_sem);
 
 	return 0;
@@ -1746,11 +1741,13 @@
 			    char *data)
 {
 	struct obj_mlme *mlme = (struct obj_mlme *) data;
-	size_t len;
-	u8 *payload, *pos = (u8 *) (mlme + 1);
-
-	len = pos[0] | (pos[1] << 8);	/* little endian data length */
-	payload = pos + 2;
+	struct obj_mlmeex *mlmeex = (struct obj_mlmeex *) data;
+	struct obj_mlmeex *confirm;
+	u8 wpa_ie[MAX_WPA_IE_LEN];
+	int wpa_ie_len;
+	size_t len = 0; /* u16, better? */
+	u8 *payload = 0, *pos = 0;
+	int ret;
 
 	/* I think all trapable objects are listed here.
 	 * Some oids have a EX version. The difference is that they are emitted
@@ -1760,9 +1757,14 @@
 	 * suited. We use the more flexible custom event facility.
 	 */
 
+	if (oid >= DOT11_OID_BEACON) {
+		len = mlmeex->size;
+		payload = pos = mlmeex->data;
+	}
+
 	/* I fear prism54_process_bss_data won't work with big endian data */
 	if ((oid == DOT11_OID_BEACON) || (oid == DOT11_OID_PROBE))
-		prism54_process_bss_data(priv, oid, mlme->address,
+		prism54_process_bss_data(priv, oid, mlmeex->address,
 					 payload, len);
 
 	mgt_le_to_cpu(isl_oid[oid].flags & OID_FLAG_TYPE, (void *) mlme);
@@ -1822,21 +1824,134 @@
 
 	case DOT11_OID_AUTHENTICATEEX:
 		handle_request(priv, mlme, oid);
-		send_formatted_event(priv, "Authenticate request", mlme, 1);
+		send_formatted_event(priv, "Authenticate request (ex)", mlme, 1);
+
+		if (priv->iw_mode != IW_MODE_MASTER 
+				&& mlmeex->state != DOT11_STATE_AUTHING)
+			break;
+
+		confirm = kmalloc(sizeof(struct obj_mlmeex) + 6, GFP_ATOMIC);
+
+		if (!confirm) 
+			break;
+
+		memcpy(&confirm->address, mlmeex->address, ETH_ALEN);
+		printk(KERN_DEBUG "Authenticate from: address:\t%02x:%02x:%02x:%02x:%02x:%02x\n", 
+				mlmeex->address[0],
+				mlmeex->address[1],
+				mlmeex->address[2],
+				mlmeex->address[3],
+				mlmeex->address[4],
+				mlmeex->address[5]
+				);
+		confirm->id = -1; /* or mlmeex->id ? */
+		confirm->state = 0; /* not used */
+		confirm->code = 0;
+		confirm->size = 6;
+		confirm->data[0] = 0x00;
+		confirm->data[1] = 0x00;
+		confirm->data[2] = 0x02;
+		confirm->data[3] = 0x00;
+		confirm->data[4] = 0x00;
+		confirm->data[5] = 0x00;
+
+		ret = mgt_set_varlen(priv, DOT11_OID_ASSOCIATEEX, confirm, 6);
+
+		kfree(confirm);
+		if (ret)
+			return ret;
 		break;
 
 	case DOT11_OID_DISASSOCIATEEX:
-		send_formatted_event(priv, "Disassociate request", mlme, 0);
+		send_formatted_event(priv, "Disassociate request (ex)", mlme, 0);
 		break;
 
 	case DOT11_OID_ASSOCIATEEX:
 		handle_request(priv, mlme, oid);
-		send_formatted_event(priv, "Associate request", mlme, 1);
+		send_formatted_event(priv, "Associate request (ex)", mlme, 1);
+
+		if (priv->iw_mode != IW_MODE_MASTER 
+				&& mlmeex->state != DOT11_STATE_AUTHING)
+			break;
+		
+		confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);
+
+		if (!confirm)
+			break;
+
+		memcpy(&confirm->address, mlmeex->address, ETH_ALEN);
+
+		confirm->id = ((struct obj_mlmeex *)mlme)->id;
+		confirm->state = 0; /* not used */
+		confirm->code = 0;
+
+		wpa_ie_len = prism54_wpa_ie_get(priv, mlmeex->address, wpa_ie);
+
+		if (!wpa_ie_len) {
+			printk(KERN_DEBUG "No WPA IE found from "
+					"address:\t%02x:%02x:%02x:%02x:%02x:%02x\n", 
+				mlmeex->address[0],
+				mlmeex->address[1],
+				mlmeex->address[2],
+				mlmeex->address[3],
+				mlmeex->address[4],
+				mlmeex->address[5]
+				);
+			kfree(confirm);
+			break;
+		}
+
+		confirm->size = wpa_ie_len;
+		memcpy(&confirm->data, wpa_ie, wpa_ie_len);
+
+		mgt_set_varlen(priv, oid, confirm, wpa_ie_len);
+
+		kfree(confirm);
+		
 		break;
 
 	case DOT11_OID_REASSOCIATEEX:
 		handle_request(priv, mlme, oid);
-		send_formatted_event(priv, "Reassociate request", mlme, 1);
+		send_formatted_event(priv, "Reassociate request (ex)", mlme, 1);
+
+		if (priv->iw_mode != IW_MODE_MASTER 
+				&& mlmeex->state != DOT11_STATE_ASSOCING)
+			break;
+
+		confirm = kmalloc(sizeof(struct obj_mlmeex), GFP_ATOMIC);
+
+		if (!confirm)
+			break;
+
+		memcpy(&confirm->address, mlmeex->address, ETH_ALEN);
+
+		confirm->id = mlmeex->id;
+		confirm->state = 0; /* not used */
+		confirm->code = 0;
+
+		wpa_ie_len = prism54_wpa_ie_get(priv, mlmeex->address, wpa_ie);
+
+		if (!wpa_ie_len) {
+			printk(KERN_DEBUG "No WPA IE found from "
+					"address:\t%02x:%02x:%02x:%02x:%02x:%02x\n", 
+				mlmeex->address[0],
+				mlmeex->address[1],
+				mlmeex->address[2],
+				mlmeex->address[3],
+				mlmeex->address[4],
+				mlmeex->address[5]
+				);
+			kfree(confirm);
+			break;
+		}
+
+		confirm->size = wpa_ie_len; 
+		memcpy(&confirm->data, wpa_ie, wpa_ie_len);
+
+		mgt_set_varlen(priv, oid, confirm, wpa_ie_len);
+
+		kfree(confirm);
+		
 		break;
 
 	default:
@@ -1879,23 +1994,367 @@
 	return ret;
 }
 
+/* Note: currently, use hostapd ioctl from the Host AP driver for WPA
+ * support. This is to be replaced with Linux wireless extensions once they
+ * get WPA support. */
+
+/* Note II: please leave all this together as it will be easier to remove later,
+ * once wireless extensions add WPA support -mcgrof */
+
+/* PRISM54_HOSTAPD ioctl() cmd: */
+enum {
+	PRISM2_SET_ENCRYPTION = 6,
+	PRISM2_HOSTAPD_SET_GENERIC_ELEMENT = 12,
+	PRISM2_HOSTAPD_MLME = 13,
+	PRISM2_HOSTAPD_SCAN_REQ = 14,
+};
+
+#define PRISM54_SET_WPA			SIOCIWFIRSTPRIV+12
+#define PRISM54_HOSTAPD			SIOCIWFIRSTPRIV+25
+#define PRISM54_DROP_UNENCRYPTED	SIOCIWFIRSTPRIV+26
+
+#define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024
+#define PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \
+((int) (&((struct prism2_hostapd_param *) 0)->u.generic_elem.data))
+
+/* Maximum length for algorithm names (-1 for nul termination) 
+ * used in ioctl() */
+#define HOSTAP_CRYPT_ALG_NAME_LEN 16
+	
+struct prism2_hostapd_param {
+	u32 cmd;
+	u8 sta_addr[ETH_ALEN];
+	union {
+	       struct {
+		       u8 alg[HOSTAP_CRYPT_ALG_NAME_LEN];
+		       u32 flags;
+		       u32 err;
+		       u8 idx;
+		       u8 seq[8]; /* sequence counter (set: RX, get: TX) */
+		       u16 key_len;
+		       u8 key[0];
+		       } crypt;
+               struct {
+                       u8 len;
+                       u8 data[0];
+               } generic_elem;
+               struct {
+#define MLME_STA_DEAUTH 0
+#define MLME_STA_DISASSOC 1
+                       u16 cmd;
+                       u16 reason_code;
+               } mlme;
+               struct {
+                       u8 ssid_len;
+                       u8 ssid[32];
+               } scan_req;
+       } u;
+};
+
+
+static int
+prism2_ioctl_set_encryption(struct net_device *dev,
+	struct prism2_hostapd_param *param,
+	int param_len)
+{
+	islpci_private *priv = netdev_priv(dev);
+	int rvalue = 0, force = 0;
+	int authen = DOT11_AUTH_OS, invoke = 0, exunencrypt = 0;
+	union oid_res_t r;
+
+	/* with the new API, it's impossible to get a NULL pointer.
+	 * New version of iwconfig set the IW_ENCODE_NOKEY flag
+	 * when no key is given, but older versions don't. */
+
+	if (param->u.crypt.key_len > 0) {
+		/* we have a key to set */
+		int index = param->u.crypt.idx;
+		int current_index;
+		struct obj_key key = { DOT11_PRIV_TKIP, 0, "" };
+
+		/* get the current key index */
+		rvalue = mgt_get_request(priv, DOT11_OID_DEFKEYID, 0, NULL, &r);
+		current_index = r.u;
+		/* Verify that the key is not marked as invalid */
+		if (!(param->u.crypt.flags & IW_ENCODE_NOKEY)) {
+			key.length = param->u.crypt.key_len > sizeof (param->u.crypt.key) ?
+			    sizeof (param->u.crypt.key) : param->u.crypt.key_len;
+			memcpy(key.key, param->u.crypt.key, key.length);
+			if (key.length == 32)
+				/* we want WPA-PSK */
+				key.type = DOT11_PRIV_TKIP;
+			if ((index < 0) || (index > 3))
+				/* no index provided use the current one */
+				index = current_index;
+
+			/* now send the key to the card  */
+			rvalue |=
+			    mgt_set_request(priv, DOT11_OID_DEFKEYX, index,
+					    &key);
+		}
+		/*
+		 * If a valid key is set, encryption should be enabled 
+		 * (user may turn it off later).
+		 * This is also how "iwconfig ethX key on" works
+		 */
+		if ((index == current_index) && (key.length > 0))
+			force = 1;
+	} else {
+		int index = (param->u.crypt.flags & IW_ENCODE_INDEX) - 1;
+		if ((index >= 0) && (index <= 3)) {
+			/* we want to set the key index */
+			rvalue |=
+			    mgt_set_request(priv, DOT11_OID_DEFKEYID, 0,
+					    &index);
+		} else {
+			if (!param->u.crypt.flags & IW_ENCODE_MODE) {
+				/* we cannot do anything. Complain. */
+				return -EINVAL;
+			}
+		}
+	}
+	/* now read the flags */
+	if (param->u.crypt.flags & IW_ENCODE_DISABLED) {
+		/* Encoding disabled, 
+		 * authen = DOT11_AUTH_OS;
+		 * invoke = 0;
+		 * exunencrypt = 0; */
+	}
+	if (param->u.crypt.flags & IW_ENCODE_OPEN)
+		/* Encode but accept non-encoded packets. No auth */
+		invoke = 1;
+	if ((param->u.crypt.flags & IW_ENCODE_RESTRICTED) || force) {
+		/* Refuse non-encoded packets. Auth */
+		authen = DOT11_AUTH_BOTH;
+		invoke = 1;
+		exunencrypt = 1;
+	}
+	/* do the change if requested  */
+	if ((param->u.crypt.flags & IW_ENCODE_MODE) || force) {
+		rvalue |=
+		    mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
+		rvalue |=
+		    mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &invoke);
+		rvalue |=
+		    mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0,
+				    &exunencrypt);
+	}
+	return rvalue;
+}
+
+static int
+prism2_ioctl_set_generic_element(struct net_device *ndev,
+	struct prism2_hostapd_param *param,
+	int param_len)
+{
+       islpci_private *priv = netdev_priv(ndev);
+       int max_len, len, alen, ret=0;
+       struct obj_attachment *attach;
+
+       len = param->u.generic_elem.len;
+       max_len = param_len - PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN;
+       if (max_len < 0 || max_len < len)
+               return -EINVAL;
+
+       alen = sizeof(*attach) + len;
+       attach = kmalloc(alen, GFP_KERNEL);
+       if (attach == NULL)
+               return -ENOMEM;
+
+       memset(attach, 0, alen);
+#define WLAN_FC_TYPE_MGMT 0
+#define WLAN_FC_STYPE_ASSOC_REQ 0
+#define WLAN_FC_STYPE_REASSOC_REQ 2
+
+       /* Note: endianness is covered by mgt_set_varlen */
+
+       attach->type = (WLAN_FC_TYPE_MGMT << 2) |
+               (WLAN_FC_STYPE_ASSOC_REQ << 4);
+       attach->id = -1;
+       attach->size = len;
+       memcpy(attach->data, param->u.generic_elem.data, len);
+
+       ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, len);
+
+       if (ret == 0) {
+               attach->type = (WLAN_FC_TYPE_MGMT << 2) |
+                       (WLAN_FC_STYPE_REASSOC_REQ << 4);
+
+	       ret = mgt_set_varlen(priv, DOT11_OID_ATTACHMENT, attach, len);
+
+	       if (ret == 0) 
+		       printk(KERN_DEBUG "%s: WPA IE Attachment was set\n",
+				       ndev->name);
+       }
+
+       kfree(attach);
+       return ret;
+
+}
+
+static int
+prism2_ioctl_mlme(struct net_device *dev, struct prism2_hostapd_param *param)
+{
+	return -EOPNOTSUPP;
+}
+
+static int
+prism2_ioctl_scan_req(struct net_device *ndev,
+                     struct prism2_hostapd_param *param)
+{
+	islpci_private *priv = netdev_priv(ndev);
+	int i, rvalue;
+	struct obj_bsslist *bsslist;
+	u32 noise = 0;
+	char *extra = "";
+	char *current_ev = "foo";
+	union oid_res_t r;
+
+	if (islpci_get_state(priv) < PRV_STATE_INIT) {
+		/* device is not ready, fail gently */
+		return 0;
+	}
+
+	/* first get the noise value. We will use it to report the link quality */
+	rvalue = mgt_get_request(priv, DOT11_OID_NOISEFLOOR, 0, NULL, &r);
+	noise = r.u;
+
+	/* Ask the device for a list of known bss. We can report at most
+	 * IW_MAX_AP=64 to the range struct. But the device won't repport anything
+	 * if you change the value of IWMAX_BSS=24.
+	 */
+	rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r);
+	bsslist = r.ptr;
+
+	/* ok now, scan the list and translate its info */
+	for (i = 0; i < min(IW_MAX_AP, (int) bsslist->nr); i++)
+		current_ev = prism54_translate_bss(ndev, current_ev,
+						   extra + IW_SCAN_MAX_DATA,
+						   &(bsslist->bsslist[i]),
+						   noise);
+	kfree(bsslist);
+
+	return rvalue;
+}
+
+static int
+prism54_hostapd(struct net_device *ndev, struct iw_point *p)
+{
+       struct prism2_hostapd_param *param;
+       int ret = 0;
+       u32 uwrq;
+
+       printk(KERN_DEBUG "prism54_hostapd - len=%d\n", p->length);
+       if (p->length < sizeof(struct prism2_hostapd_param) ||
+           p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer)
+               return -EINVAL;
+
+       param = (struct prism2_hostapd_param *) kmalloc(p->length, GFP_KERNEL);
+       if (param == NULL)
+               return -ENOMEM;
+
+       if (copy_from_user(param, p->pointer, p->length)) {
+               kfree(param);
+               return -EFAULT;
+       }
+
+       switch (param->cmd) {
+       case PRISM2_SET_ENCRYPTION:
+	       printk(KERN_DEBUG "%s: Caught WPA supplicant set encryption request\n",
+			       ndev->name);
+               ret = prism2_ioctl_set_encryption(ndev, param, p->length);
+               break;
+       case PRISM2_HOSTAPD_SET_GENERIC_ELEMENT:
+	       printk(KERN_DEBUG "%s: Caught WPA supplicant set WPA IE request\n",
+			       ndev->name);
+               ret = prism2_ioctl_set_generic_element(ndev, param,
+                                                      p->length);
+               break;
+       case PRISM2_HOSTAPD_MLME:
+	       printk(KERN_DEBUG "%s: Caught WPA supplicant MLME request\n",
+			       ndev->name);
+               ret = prism2_ioctl_mlme(ndev, param);
+               break;
+       case PRISM2_HOSTAPD_SCAN_REQ:
+	       printk(KERN_DEBUG "%s: Caught WPA supplicant scan request\n",
+			       ndev->name);
+               ret = prism2_ioctl_scan_req(ndev, param);
+               break;
+	case PRISM54_SET_WPA:
+	       printk(KERN_DEBUG "%s: Caught WPA supplicant wpa init request\n",
+			       ndev->name);
+	       uwrq = 1;
+	       ret = prism54_set_wpa(ndev, NULL, &uwrq, NULL);
+	       break;
+	case PRISM54_DROP_UNENCRYPTED:
+	       printk(KERN_DEBUG "%s: Caught WPA drop unencrypted request\n",
+			       ndev->name);
+#if 0
+	       uwrq = 0x01;
+	       mgt_set(priv, DOT11_OID_EXUNENCRYPTED, &uwrq);
+	       down_write(&priv->mib_sem);
+	       mgt_commit(priv);
+	       up_write(&priv->mib_sem);
+#endif
+	       /* Not necessary, as set_wpa does it, should we just do it here though? */
+	       ret = 0;
+	       break;
+       default:
+	       printk(KERN_DEBUG "%s: Caught a WPA supplicant request that is not supported\n",
+			       ndev->name);
+               ret = -EOPNOTSUPP;
+               break;
+       }
+
+       if (ret == 0 && copy_to_user(p->pointer, param, p->length))
+               ret = -EFAULT;
+
+       kfree(param);
+
+       return ret;
+}
+
 int
 prism54_set_wpa(struct net_device *ndev, struct iw_request_info *info,
 		__u32 * uwrq, char *extra)
 {
 	islpci_private *priv = netdev_priv(ndev);
+	u32 mlme, authen, dot1x, filter, wep;
 
-	down_write(&priv->mib_sem);
+	if (islpci_get_state(priv) < PRV_STATE_INIT)
+		return 0;
+
+	wep = 1; /* For privacy invoked */
+	filter = 1; /* Filter out all unencrypted frames */
+	dot1x = 0x01; /* To enable eap filter */
+	mlme = DOT11_MLME_EXTENDED;
+	authen = DOT11_AUTH_OS; /* Only WEP uses _SK and _BOTH */
 
+	down_write(&priv->mib_sem);
 	priv->wpa = *uwrq;
-	if (priv->wpa) {
-		u32 l = DOT11_MLME_EXTENDED;
-		mgt_set(priv, DOT11_OID_MLMEAUTOLEVEL, &l);
+
+	switch (priv->wpa) {
+		default:
+		case 0: /* Clears/disables WPA and friends */
+			wep = 0;
+			filter = 0; /* Do not filter un-encrypted data */
+			dot1x = 0;
+			mlme = DOT11_MLME_AUTO;
+			printk("%s: Disabling WPA\n", ndev->name);
+			break;
+		case 2: 
+		case 1: /* WPA */
+			printk("%s: Enabling WPA\n", ndev->name);
+			break;
 	}
-	/* restart the card with new level. Needed ? */
-	mgt_commit(priv);
 	up_write(&priv->mib_sem);
 
+	mgt_set_request(priv, DOT11_OID_AUTHENABLE, 0, &authen);
+	mgt_set_request(priv, DOT11_OID_PRIVACYINVOKED, 0, &wep);
+	mgt_set_request(priv, DOT11_OID_EXUNENCRYPTED, 0, &filter);
+	mgt_set_request(priv, DOT11_OID_DOT1XENABLE, 0, &dot1x);
+	mgt_set_request(priv, DOT11_OID_MLMEAUTOLEVEL, 0, &mlme);
+
 	return 0;
 }
 
@@ -1947,7 +2406,7 @@
 		      struct iw_point *data, char *extra)
 {
 	islpci_private *priv = netdev_priv(ndev);
-	struct islpci_mgmtframe *response = NULL;
+	struct islpci_mgmtframe *response;
 	int ret = -EIO;
 
 	printk("%s: get_oid 0x%08X\n", ndev->name, priv->priv_oid);
@@ -1983,7 +2442,7 @@
 		      struct iw_point *data, char *extra)
 {
 	islpci_private *priv = netdev_priv(ndev);
-	struct islpci_mgmtframe *response = NULL;
+	struct islpci_mgmtframe *response;
 	int ret = 0, response_op = PIMFOR_OP_ERROR;
 
 	printk("%s: set_oid 0x%08X\tlen: %d\n", ndev->name, priv->priv_oid,
@@ -2256,14 +2715,24 @@
 	.standard = (iw_handler *) prism54_handler,
 	.private = (iw_handler *) prism54_private_handler,
 	.private_args = (struct iw_priv_args *) prism54_private_args,
+#if WIRELESS_EXT == 16
 	.spy_offset = offsetof(islpci_private, spy_data),
+#endif /* WIRELESS_EXT == 16 */
 };
 
-/* For ioctls that don't work with the new API */
+/* For wpa_supplicant */
 
 int
 prism54_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
 {
-
+	struct iwreq *wrq = (struct iwreq *) rq;
+	int ret = -1;
+	switch (cmd) {
+		case PRISM54_HOSTAPD:
+		if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+		ret = prism54_hostapd(ndev, &wrq->u.data);
+		return ret;
+	}
 	return -EOPNOTSUPP;
 }
diff -Nru a/drivers/net/wireless/prism54/isl_ioctl.h b/drivers/net/wireless/prism54/isl_ioctl.h
--- a/drivers/net/wireless/prism54/isl_ioctl.h	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/wireless/prism54/isl_ioctl.h	2004-10-21 22:09:44 -04:00
@@ -48,6 +48,8 @@
 int prism54_set_mac_address(struct net_device *, void *);
 
 int prism54_ioctl(struct net_device *, struct ifreq *, int);
+int prism54_set_wpa(struct net_device *, struct iw_request_info *, 
+			__u32 *, char *);
 
 extern const struct iw_handler_def prism54_handler_def;
 
diff -Nru a/drivers/net/wireless/prism54/isl_oid.h b/drivers/net/wireless/prism54/isl_oid.h
--- a/drivers/net/wireless/prism54/isl_oid.h	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/wireless/prism54/isl_oid.h	2004-10-21 22:09:44 -04:00
@@ -91,6 +91,14 @@
 	u16 mhz[0];
 } __attribute__ ((packed));
 
+struct obj_attachment {
+	char type;
+	char reserved;
+	short id;
+	short size;
+	char data[0];
+} __attribute__((packed));
+
 /* 
  * in case everything's ok, the inlined function below will be
  * optimized away by the compiler...
@@ -472,6 +480,7 @@
 #define OID_TYPE_MLMEEX		0x09
 #define OID_TYPE_ADDR		0x0A
 #define OID_TYPE_RAW		0x0B
+#define OID_TYPE_ATTACH		0x0C
 
 /* OID_TYPE_MLMEEX is special because of a variable size field when sending.
  * Not yet implemented (not used in driver anyway).
diff -Nru a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
--- a/drivers/net/wireless/prism54/islpci_dev.c	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/wireless/prism54/islpci_dev.c	2004-10-21 22:09:44 -04:00
@@ -105,7 +105,7 @@
 			       "%s: firmware '%s' size is not multiple of 32bit, aborting!\n",
 			       "prism54", priv->firmware);
 			release_firmware(fw_entry);
-			return EILSEQ; /* Illegal byte sequence  */;
+			return -EILSEQ; /* Illegal byte sequence  */;
 		}
 
 		while (fw_len > 0) {
@@ -142,6 +142,10 @@
 
 		BUG_ON(fw_len != 0);
 
+		/* Firmware version is at offset 40 (also for "newmac") */
+		printk(KERN_DEBUG "%s: firmware version: %.8s\n",
+		       priv->ndev->name, fw_entry->data + 40);
+
 		release_firmware(fw_entry);
 	}
 
@@ -375,8 +379,6 @@
 	u32 rc;
 	islpci_private *priv = netdev_priv(ndev);
 
-	printk(KERN_DEBUG "%s: islpci_open()\n", ndev->name);
-
 	/* reset data structures, upload firmware and reset device */
 	rc = islpci_reset(priv,1);
 	if (rc) {
@@ -462,8 +464,7 @@
 		return rc;
 	}
 
-	printk(KERN_DEBUG
-	       "%s: firmware uploaded done, now triggering reset...\n",
+	printk(KERN_DEBUG "%s: firmware upload complete\n",
 	       priv->ndev->name);
 
 	islpci_set_state(priv, PRV_STATE_POSTBOOT);
@@ -489,6 +490,7 @@
 		/* The software reset acknowledge needs about 220 msec here.
 		 * Be conservative and wait for up to one second. */
 	
+		set_current_state(TASK_UNINTERRUPTIBLE);
 		remaining = schedule_timeout(HZ);
 
 		if(remaining > 0) {
@@ -499,15 +501,16 @@
 		/* If we're here it's because our IRQ hasn't yet gone through. 
 		 * Retry a bit more...
 		 */
-		 printk(KERN_ERR "%s: device soft reset timed out\n",
-		       priv->ndev->name);
-
+		printk(KERN_ERR "%s: no 'reset complete' IRQ seen - retrying\n",
+			priv->ndev->name);
 	}
 
 	finish_wait(&priv->reset_done, &wait);
 
-	if(result)
+	if (result) {
+		printk(KERN_ERR "%s: interface reset failure\n", priv->ndev->name);
 		return result;
+	}
 
 	islpci_set_state(priv, PRV_STATE_INIT);
 
@@ -519,11 +522,17 @@
 	isl38xx_enable_common_interrupts(priv->device_base);
 
 	down_write(&priv->mib_sem);
-	mgt_commit(priv);
+	result = mgt_commit(priv);
+	if (result) {
+		printk(KERN_ERR "%s: interface reset failure\n", priv->ndev->name);
+		up_write(&priv->mib_sem);
+		return result;
+	}
 	up_write(&priv->mib_sem);
 
 	islpci_set_state(priv, PRV_STATE_READY);
 
+	printk(KERN_DEBUG "%s: interface reset complete\n", priv->ndev->name);
 	return 0;
 }
 
@@ -584,18 +593,18 @@
 	/* now that the data structures are cleaned up, upload
 	 * firmware and reset interface */
 		rc = islpci_upload_fw(priv);
-		if (rc) 
+		if (rc) {
+			printk(KERN_ERR "%s: islpci_reset: failure\n",
+				priv->ndev->name);
 			return rc;
+		}
 	}
 
 	/* finally reset interface */
 	rc = islpci_reset_if(priv);
-	if (!rc) /* If successful */
-		return rc;
-	
-	printk(KERN_DEBUG  "prism54: Your card/socket may be faulty, or IRQ line too busy :(\n");
+	if (rc)
+		printk(KERN_ERR "prism54: Your card/socket may be faulty, or IRQ line too busy :(\n");
 	return rc;
-
 }
 
 struct net_device_stats *
@@ -604,7 +613,7 @@
 	islpci_private *priv = netdev_priv(ndev);
 
 #if VERBOSE > SHOW_ERROR_MESSAGES
-	DEBUG(SHOW_FUNCTION_CALLS, "islpci_statistics \n");
+	DEBUG(SHOW_FUNCTION_CALLS, "islpci_statistics\n");
 #endif
 
 	return &priv->statistics;
@@ -829,6 +838,12 @@
 	priv->monitor_type = ARPHRD_IEEE80211;
 	priv->ndev->type = (priv->iw_mode == IW_MODE_MONITOR) ?
 		priv->monitor_type : ARPHRD_ETHER;
+
+#if WIRELESS_EXT > 16
+	/* Add pointers to enable iwspy support. */
+	priv->wireless_data.spy_data = &priv->spy_data;
+	ndev->wireless_data = &priv->wireless_data;
+#endif /* WIRELESS_EXT > 16 */
 
 	/* save the start and end address of the PCI memory area */
 	ndev->mem_start = (unsigned long) priv->device_base;
diff -Nru a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h
--- a/drivers/net/wireless/prism54/islpci_dev.h	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/wireless/prism54/islpci_dev.h	2004-10-21 22:09:44 -04:00
@@ -100,6 +100,10 @@
 
 	struct iw_spy_data spy_data; /* iwspy support */
 
+#if WIRELESS_EXT > 16
+	struct iw_public_data wireless_data;
+#endif /* WIRELESS_EXT > 16 */
+
 	int monitor_type; /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_PRISM */
 
 	struct islpci_acl acl;
diff -Nru a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
--- a/drivers/net/wireless/prism54/islpci_eth.c	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/wireless/prism54/islpci_eth.c	2004-10-21 22:09:44 -04:00
@@ -508,11 +508,12 @@
 	/* increment the transmit error counter */
 	statistics->tx_errors++;
 
+	printk(KERN_WARNING "%s: tx_timeout", ndev->name);
 	if (!priv->reset_task_pending) {
 		priv->reset_task_pending = 1;
+		printk(", scheduling a reset");
 		netif_stop_queue(ndev);
 		schedule_work(&priv->reset_task);
 	}
-
-	return;
+	printk("\n");
 }
diff -Nru a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c
--- a/drivers/net/wireless/prism54/islpci_hotplug.c	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/wireless/prism54/islpci_hotplug.c	2004-10-21 22:09:44 -04:00
@@ -107,9 +107,6 @@
 	islpci_private *priv;
 	int rvalue;
 
-	/* TRACE(DRV_NAME); */
-	
-	
 	/* Enable the pci device */
 	if (pci_enable_device(pdev)) {
 		printk(KERN_ERR "%s: pci_enable_device() failed.\n", DRV_NAME);
diff -Nru a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c
--- a/drivers/net/wireless/prism54/islpci_mgt.c	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/wireless/prism54/islpci_mgt.c	2004-10-21 22:09:44 -04:00
@@ -473,6 +473,7 @@
 		int timeleft;
 		struct islpci_mgmtframe *frame;
 
+		set_current_state(TASK_UNINTERRUPTIBLE);
 		timeleft = schedule_timeout(wait_cycle_jiffies);
 		frame = xchg(&priv->mgmt_received, NULL);
 		if (frame) {
diff -Nru a/drivers/net/wireless/prism54/islpci_mgt.h b/drivers/net/wireless/prism54/islpci_mgt.h
--- a/drivers/net/wireless/prism54/islpci_mgt.h	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/wireless/prism54/islpci_mgt.h	2004-10-21 22:09:44 -04:00
@@ -31,8 +31,6 @@
 #define K_DEBUG(f, m, args...) do { if(f & m) printk(KERN_DEBUG args); } while(0)
 #define DEBUG(f, args...) K_DEBUG(f, pc_debug, args)
 
-#define TRACE(devname)   K_DEBUG(SHOW_TRACING, VERBOSE, "%s:  -> " __FUNCTION__ "()\n", devname)
-
 extern int pc_debug;
 #define init_wds 0	/* help compiler optimize away dead code */
 
diff -Nru a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
--- a/drivers/net/wireless/prism54/oid_mgt.c	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/wireless/prism54/oid_mgt.c	2004-10-21 22:09:44 -04:00
@@ -201,7 +201,8 @@
 	OID_U32(DOT11_OID_STATIMEOUT, 0x19000000),
 	OID_U32_C(DOT11_OID_MLMEAUTOLEVEL, 0x19000001),
 	OID_U32(DOT11_OID_BSSTIMEOUT, 0x19000002),
-	OID_UNKNOWN(DOT11_OID_ATTACHMENT, 0x19000003),
+	[DOT11_OID_ATTACHMENT] = {0x19000003, 0,
+		sizeof(struct obj_attachment), OID_TYPE_ATTACH},
 	OID_STRUCT_C(DOT11_OID_PSMBUFFER, 0x19000004, struct obj_buffer,
 		     OID_TYPE_BUFFER),
 
@@ -329,6 +330,12 @@
 			mlme->size = le16_to_cpu(mlme->size);
 			break;
 		}
+	case OID_TYPE_ATTACH:{
+			struct obj_attachment *attach = data;
+			attach->id = le16_to_cpu(attach->id);
+			attach->size = le16_to_cpu(attach->size);; 
+			break;
+	}
 	case OID_TYPE_SSID:
 	case OID_TYPE_KEY:
 	case OID_TYPE_ADDR:
@@ -392,6 +399,12 @@
 			mlme->size = cpu_to_le16(mlme->size);
 			break;
 		}
+	case OID_TYPE_ATTACH:{
+			struct obj_attachment *attach = data;
+			attach->id = cpu_to_le16(attach->id);
+			attach->size = cpu_to_le16(attach->size);; 
+			break;
+	}
 	case OID_TYPE_SSID:
 	case OID_TYPE_KEY:
 	case OID_TYPE_ADDR:
@@ -465,6 +478,42 @@
 	return ret;
 }
 
+/* None of these are cached */
+int
+mgt_set_varlen(islpci_private *priv, enum oid_num_t n, void *data, int extra_len)
+{
+	int ret = 0;
+	struct islpci_mgmtframe *response;
+	int response_op = PIMFOR_OP_ERROR;
+	int dlen;
+	u32 oid;
+
+	BUG_ON(OID_NUM_LAST <= n);
+
+	dlen = isl_oid[n].size;
+	oid = isl_oid[n].oid;
+
+	mgt_cpu_to_le(isl_oid[n].flags & OID_FLAG_TYPE, data);
+
+	if (islpci_get_state(priv) >= PRV_STATE_READY) {
+		ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET, oid,
+					     data, dlen + extra_len, &response);
+		if (!ret) {
+			response_op = response->header->operation;
+			islpci_mgt_release(response);
+		}
+		if (ret || response_op == PIMFOR_OP_ERROR)
+			ret = -EIO;
+	} else 
+		ret = -EIO;
+
+	/* re-set given data to what it was */
+	if (data)
+		mgt_le_to_cpu(isl_oid[n].flags & OID_FLAG_TYPE, data);
+
+	return ret;
+}
+
 int
 mgt_get_request(islpci_private *priv, enum oid_num_t n, int extra, void *data,
 		union oid_res_t *res)
@@ -555,15 +604,18 @@
 		u32 oid = t->oid;
 		BUG_ON(data == NULL);
 		while (j <= t->range) {
-			response = NULL;
-			ret |= islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET,
+			int r = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_SET,
 						      oid, data, t->size,
 						      &response);
 			if (response) {
-				ret |= (response->header->operation ==
-					PIMFOR_OP_ERROR);
+				r |= (response->header->operation == PIMFOR_OP_ERROR);
 				islpci_mgt_release(response);
 			}
+			if (r)
+				printk(KERN_ERR "%s: mgt_commit_list: failure. "
+					"oid=%08x err=%d\n",
+					priv->ndev->name, oid, r);
+			ret |= r;
 			j++;
 			oid++;
 			data += t->size;
@@ -624,7 +676,7 @@
 static int
 mgt_update_addr(islpci_private *priv)
 {
-	struct islpci_mgmtframe *res = NULL;
+	struct islpci_mgmtframe *res;
 	int ret;
 
 	ret = islpci_mgt_transaction(priv->ndev, PIMFOR_OP_GET,
@@ -638,26 +690,26 @@
 	if (res)
 		islpci_mgt_release(res);
 
+	if (ret)
+		printk(KERN_ERR "%s: mgt_update_addr: failure\n", priv->ndev->name);
 	return ret;
 }
 
-void
+#define VEC_SIZE(a) (sizeof(a)/sizeof(a[0]))
+
+int
 mgt_commit(islpci_private *priv)
 {
 	int rvalue;
 	u32 u;
 
 	if (islpci_get_state(priv) < PRV_STATE_INIT)
-		return;
+		return 0;
 
-	rvalue = mgt_commit_list(priv, commit_part1,
-				 sizeof (commit_part1) /
-				 sizeof (commit_part1[0]));
+	rvalue = mgt_commit_list(priv, commit_part1, VEC_SIZE(commit_part1));
 
 	if (priv->iw_mode != IW_MODE_MONITOR)
-		rvalue |= mgt_commit_list(priv, commit_part2,
-					  sizeof (commit_part2) /
-					  sizeof (commit_part2[0]));
+		rvalue |= mgt_commit_list(priv, commit_part2, VEC_SIZE(commit_part2));
 
 	u = OID_INL_MODE;
 	rvalue |= mgt_commit_list(priv, &u, 1);
@@ -666,9 +718,43 @@
 	if (rvalue) {
 		/* some request have failed. The device might be in an
 		   incoherent state. We should reset it ! */
-		printk(KERN_DEBUG "%s: mgt_commit has failed. Restart the "
-		       "device \n", priv->ndev->name);
+		printk(KERN_DEBUG "%s: mgt_commit: failure\n", priv->ndev->name);
 	}
+	return rvalue;
+}
+
+/* The following OIDs need to be "unlatched":
+ *
+ * MEDIUMLIMIT,BEACONPERIOD,DTIMPERIOD,ATIMWINDOW,LISTENINTERVAL
+ * FREQUENCY,EXTENDEDRATES.
+ *
+ * The way to do this is to set ESSID. Note though that they may get 
+ * unlatch before though by setting another OID. */
+void
+mgt_unlatch_all(islpci_private *priv)
+{
+	u32 u;
+	int rvalue = 0;
+
+	if (islpci_get_state(priv) < PRV_STATE_INIT)
+		return;
+
+	u = DOT11_OID_SSID;
+	rvalue = mgt_commit_list(priv, &u, 1);
+	/* Necessary if in MANUAL RUN mode? */
+#if 0
+	u = OID_INL_MODE;
+	rvalue |= mgt_commit_list(priv, &u, 1);
+
+	u = DOT11_OID_MLMEAUTOLEVEL;
+	rvalue |= mgt_commit_list(priv, &u, 1);
+
+	u = OID_INL_MODE;
+	rvalue |= mgt_commit_list(priv, &u, 1);
+#endif
+
+	if (rvalue)
+		printk(KERN_DEBUG "%s: Unlatching OIDs failed\n", priv->ndev->name);
 }
 
 /* This will tell you if you are allowed to answer a mlme(ex) request .*/
@@ -769,6 +855,14 @@
 					"id=0x%X\nstate=0x%X\n"
 					"code=0x%X\nsize=0x%X\n", mlme->id,
 					mlme->state, mlme->code, mlme->size);
+		}
+		break;
+	case OID_TYPE_ATTACH:{
+			struct obj_attachment *attach = r->ptr;
+			return snprintf(str, PRIV_STR_SIZE,
+					"id=%d\nsize=%d\n",
+					attach->id,
+					attach->size);
 		}
 		break;
 	case OID_TYPE_SSID:{
diff -Nru a/drivers/net/wireless/prism54/oid_mgt.h b/drivers/net/wireless/prism54/oid_mgt.h
--- a/drivers/net/wireless/prism54/oid_mgt.h	2004-10-21 22:09:44 -04:00
+++ b/drivers/net/wireless/prism54/oid_mgt.h	2004-10-21 22:09:44 -04:00
@@ -36,6 +36,8 @@
 void mgt_le_to_cpu(int, void *);
 
 int mgt_set_request(islpci_private *, enum oid_num_t, int, void *);
+int mgt_set_varlen(islpci_private *, enum oid_num_t, void *, int);
+
 
 int mgt_get_request(islpci_private *, enum oid_num_t, int, void *,
 		    union oid_res_t *);
@@ -46,7 +48,8 @@
 
 void mgt_get(islpci_private *, enum oid_num_t, void *);
 
-void mgt_commit(islpci_private *);
+int mgt_commit(islpci_private *);
+void mgt_unlatch_all(islpci_private *);
 
 int mgt_mlme_answer(islpci_private *);
 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [BK PATCHES] 2.6.x net driver updates
@ 2004-07-09 20:14 Jeff Garzik
  0 siblings, 0 replies; 28+ messages in thread
From: Jeff Garzik @ 2004-07-09 20:14 UTC (permalink / raw)
  To: netdev


Just emailed this to Andrew and Linus...




Please do a

	bk pull bk://gkernel.bkbits.net/net-drivers-2.6

This will update the following files:

 drivers/net/epic100.c                  |  426 ++++++++-----
 drivers/net/forcedeth.c                |  848 +++++++++++++++++++-------
 drivers/net/natsemi.c                  | 1064 +++++++++++++++++++++++++--------
 drivers/net/pci-skeleton.c             |   27 
 drivers/net/sis900.c                   |   21 
 drivers/net/sk98lin/h/skdrv1st.h       |    1 
 drivers/net/wireless/prism54/oid_mgt.c |   10 
 include/linux/pci_ids.h                |   13 
 8 files changed, 1761 insertions(+), 649 deletions(-)

through these ChangeSets:

Daniele Venzano:
  o sis900-fix-phy-transceiver-detection.patch

François Romieu:
  o epic100: code removal in irq handler
  o epic100: spin_unlock_irqrestore avoidance
  o [netdrvr epic100] napi fixes
  o [netdrvr epic100] napi 3/3 - transmit path
  o [netdrvr epic100] napi 2/3 - receive path
  o [netdrvr epic100] napi 1/3 - just shuffle some code around
  o [netdrvr epic100] minor cleanups

Manfred Spraul:
  o Gigabit Ethernet support for forcedeth
  o natsemi 2: support packets > 1518 bytes
  o natsemi 1: switch to netdev_priv()
  o natsemi updates

Margit Schubert-While:
  o prism54 freq to channel incorrect for 5GHz

Pavel Roskin:
  o [netdrvr pci-skeleton] refresh

Rusty Russell:
  o [TRIVIAL 2.6] sk98lin: kill dup include

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [BK PATCHES] 2.6.x net driver updates
@ 2004-07-02 17:14 Jeff Garzik
  0 siblings, 0 replies; 28+ messages in thread
From: Jeff Garzik @ 2004-07-02 17:14 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev


Please do a

	bk pull bk://gkernel.bkbits.net/net-drivers-2.6

This will update the following files:

 drivers/net/8139too.c               |    2 +-
 drivers/net/arcnet/arcnet.c         |    4 ++--
 drivers/net/irda/Kconfig            |    2 +-
 drivers/net/irda/donauboe.c         |    4 ++++
 drivers/net/rrunner.c               |    8 ++++----
 drivers/net/sk98lin/skge.c          |    1 +
 drivers/net/tokenring/Kconfig       |    2 +-
 drivers/net/tokenring/lanstreamer.c |    5 +++++
 drivers/net/wireless/atmel_cs.c     |   20 +++++++++++++++-----
 9 files changed, 34 insertions(+), 14 deletions(-)

through these ChangeSets:

<simon@thekelleys.org.uk> (04/07/02 1.1787)
   [PATCH] [Bug 2948] New: Atmel wireless driver Oopses

<akpm@osdl.org> (04/07/02 1.1786)
   [PATCH] err2-14: skge locking fix
   
   It can return with the lock held.
   
   Found by the Stanford locking checker.
   
   Signed-off-by: Andrew Morton <akpm@osdl.org>

<jgarzik@pobox.com> (04/07/01 1.1778.4.25)
   [netdrvr] fix warnings found on 64-bit platforms
   
   Updated:  8139too, arcnet/arcnet, rrunner

<jgarzik@pobox.com> (04/07/01 1.1778.4.24)
   [netdrvr] disable certain drivers that are broken on 64-bit
   
   Disable Toshiba FIR IRDA driver (donauboe) and IBM Lanstreamer
   token ring driver on all 64-bit platforms.  Add #error to each driver
   explaining the problem, causing build of driver to fail when
   BITS_PER_LONG == 64.

diff -Nru a/drivers/net/8139too.c b/drivers/net/8139too.c
--- a/drivers/net/8139too.c	2004-07-02 13:13:12 -04:00
+++ b/drivers/net/8139too.c	2004-07-02 13:13:12 -04:00
@@ -777,7 +777,7 @@
 	u8 tmp8;
 	int rc;
 	unsigned int i;
-	u32 pio_start, pio_end, pio_flags, pio_len;
+	unsigned long pio_start, pio_end, pio_flags, pio_len;
 	unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
 	u32 version;
 
diff -Nru a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
--- a/drivers/net/arcnet/arcnet.c	2004-07-02 13:13:12 -04:00
+++ b/drivers/net/arcnet/arcnet.c	2004-07-02 13:13:12 -04:00
@@ -479,7 +479,7 @@
 		*(uint16_t *) skb_push(skb, 2) = type;
 		if (skb->nh.raw - skb->mac.raw != 2)
 			BUGMSG(D_NORMAL, "arcnet_header: Yikes!  diff (%d) is not 2!\n",
-			       skb->nh.raw - skb->mac.raw);
+			       (int)(skb->nh.raw - skb->mac.raw));
 		return -2;	/* return error -- can't transmit yet! */
 	}
 	/* otherwise, we can just add the header as usual. */
@@ -514,7 +514,7 @@
 	if (skb->nh.raw - skb->mac.raw != 2) {
 		BUGMSG(D_NORMAL,
 		     "rebuild_header: shouldn't be here! (hdrsize=%d)\n",
-		       skb->nh.raw - skb->mac.raw);
+		     (int)(skb->nh.raw - skb->mac.raw));
 		return 0;
 	}
 	type = *(uint16_t *) skb_pull(skb, 2);
diff -Nru a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig
--- a/drivers/net/irda/Kconfig	2004-07-02 13:13:12 -04:00
+++ b/drivers/net/irda/Kconfig	2004-07-02 13:13:12 -04:00
@@ -333,7 +333,7 @@
 
 config TOSHIBA_FIR
 	tristate "Toshiba Type-O IR Port"
-	depends on IRDA
+	depends on IRDA && !64BIT
 	help
 	  Say Y here if you want to build support for the Toshiba Type-O IR
 	  and Donau oboe chipsets. These chipsets are used by the Toshiba
diff -Nru a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
--- a/drivers/net/irda/donauboe.c	2004-07-02 13:13:12 -04:00
+++ b/drivers/net/irda/donauboe.c	2004-07-02 13:13:12 -04:00
@@ -1622,6 +1622,10 @@
       goto freeregion;
     }
 
+#if (BITS_PER_LONG == 64)
+#error broken on 64-bit:  casts pointer to 32-bit, and then back to pointer.
+#endif
+
   /*We need to align the taskfile on a taskfile size boundary */
   {
     unsigned long addr;
diff -Nru a/drivers/net/rrunner.c b/drivers/net/rrunner.c
--- a/drivers/net/rrunner.c	2004-07-02 13:13:12 -04:00
+++ b/drivers/net/rrunner.c	2004-07-02 13:13:12 -04:00
@@ -1335,10 +1335,10 @@
 	if (rrpriv->tx_skbuff[cons]){
 		len = min_t(int, 0x80, rrpriv->tx_skbuff[cons]->len);
 		printk("skbuff for cons %i is valid - dumping data (0x%x bytes - skbuff len 0x%x)\n", cons, len, rrpriv->tx_skbuff[cons]->len);
-		printk("mode 0x%x, size 0x%x,\n phys %08x, skbuff-addr %08lx, truesize 0x%x\n",
+		printk("mode 0x%x, size 0x%x,\n phys %08Lx, skbuff-addr %08lx, truesize 0x%x\n",
 		       rrpriv->tx_ring[cons].mode,
 		       rrpriv->tx_ring[cons].size,
-		       rrpriv->tx_ring[cons].addr.addrlo,
+		       (unsigned long long) rrpriv->tx_ring[cons].addr.addrlo,
 		       (unsigned long)rrpriv->tx_skbuff[cons]->data,
 		       (unsigned int)rrpriv->tx_skbuff[cons]->truesize);
 		for (i = 0; i < len; i++){
@@ -1351,10 +1351,10 @@
 
 	printk("dumping TX ring info:\n");
 	for (i = 0; i < TX_RING_ENTRIES; i++)
-		printk("mode 0x%x, size 0x%x, phys-addr %08x\n",
+		printk("mode 0x%x, size 0x%x, phys-addr %08Lx\n",
 		       rrpriv->tx_ring[i].mode,
 		       rrpriv->tx_ring[i].size,
-		       rrpriv->tx_ring[i].addr.addrlo);
+		       (unsigned long long) rrpriv->tx_ring[i].addr.addrlo);
 
 }
 
diff -Nru a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
--- a/drivers/net/sk98lin/skge.c	2004-07-02 13:13:12 -04:00
+++ b/drivers/net/sk98lin/skge.c	2004-07-02 13:13:12 -04:00
@@ -1927,6 +1927,7 @@
 	*/
 	if (BytesSend < C_LEN_ETHERNET_MINSIZE) {
 		if ((pMessage = skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) == NULL) {
+			spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags);
 			return 0;
 		}
 		pMessage->len = C_LEN_ETHERNET_MINSIZE;
diff -Nru a/drivers/net/tokenring/Kconfig b/drivers/net/tokenring/Kconfig
--- a/drivers/net/tokenring/Kconfig	2004-07-02 13:13:12 -04:00
+++ b/drivers/net/tokenring/Kconfig	2004-07-02 13:13:12 -04:00
@@ -54,7 +54,7 @@
 
 config IBMLS
 	tristate "IBM Lanstreamer chipset PCI adapter support"
-	depends on TR && PCI
+	depends on TR && PCI && !64BIT
 	help
 	  This is support for IBM Lanstreamer PCI Token Ring Cards.
 
diff -Nru a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c
--- a/drivers/net/tokenring/lanstreamer.c	2004-07-02 13:13:12 -04:00
+++ b/drivers/net/tokenring/lanstreamer.c	2004-07-02 13:13:12 -04:00
@@ -129,6 +129,11 @@
 
 #include "lanstreamer.h"
 
+#if (BITS_PER_LONG == 64)
+#error broken on 64-bit: stores pointer to rx_ring->buffer in 32-bit int
+#endif
+
+
 /* I've got to put some intelligence into the version number so that Peter and I know
  * which version of the code somebody has got. 
  * Version Number = a.b.c.d  where a.b.c is the level of code and d is the latest author.
diff -Nru a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
--- a/drivers/net/wireless/atmel_cs.c	2004-07-02 13:13:12 -04:00
+++ b/drivers/net/wireless/atmel_cs.c	2004-07-02 13:13:12 -04:00
@@ -348,9 +348,19 @@
 };
 
 /* This is strictly temporary, until PCMCIA devices get integrated into the device model. */
-static struct device atmel_device = {
-        .bus_id    = "pcmcia",
-};
+static struct device *atmel_device(void)
+{
+	static char *kobj_name = "atmel_cs";
+
+	static struct device dev = {
+		.bus_id    = "pcmcia",
+	};
+	dev.kobj.k_name = kmalloc(strlen(kobj_name)+1, GFP_KERNEL);
+	strcpy(dev.kobj.k_name, kobj_name);
+	kobject_init(&dev.kobj);
+	
+	return &dev;
+}
 
 static void atmel_config(dev_link_t *link)
 {
@@ -537,12 +547,12 @@
 		       "atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config.");
 		goto cs_failed;
 	}
-	
+       
 	((local_info_t*)link->priv)->eth_dev = 
 		init_atmel_card(link->irq.AssignedIRQ,
 				link->io.BasePort1,
 				card_index == -1 ? NULL :  card_table[card_index].firmware,
-				&atmel_device,
+				atmel_device(),
 				card_present, 
 				link);
 	if (!((local_info_t*)link->priv)->eth_dev) 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [BK PATCHES] 2.6.x net driver updates
@ 2004-07-01  3:54 Jeff Garzik
  0 siblings, 0 replies; 28+ messages in thread
From: Jeff Garzik @ 2004-07-01  3:54 UTC (permalink / raw)
  To: netdev



This is what I just sent to Andrew and Linus.

BK users may do a

	bk pull bk://gkernel.bkbits.net/net-drivers-2.6

This will update the following files:

 drivers/net/arm/smc91x.c                      | 2171 -------------------------
 drivers/net/arm/smc91x.h                      |  829 ---------
 drivers/net/3c59x.c                           |    6 
 drivers/net/Kconfig                           |   25 
 drivers/net/Makefile                          |    2 
 drivers/net/acenic.c                          |   12 
 drivers/net/arm/Kconfig                       |   18 
 drivers/net/arm/Makefile                      |    1 
 drivers/net/eepro100.c                        |    6 
 drivers/net/epic100.c                         |    6 
 drivers/net/fec_8xx/Kconfig                   |   14 
 drivers/net/fec_8xx/Makefile                  |   12 
 drivers/net/fec_8xx/fec_8xx-netta.c           |  153 +
 drivers/net/fec_8xx/fec_8xx.h                 |  218 ++
 drivers/net/fec_8xx/fec_main.c                | 1275 +++++++++++++++
 drivers/net/fec_8xx/fec_mii.c                 |  380 ++++
 drivers/net/ixgb/ixgb.h                       |    2 
 drivers/net/natsemi.c                         |    6 
 drivers/net/pcmcia/3c574_cs.c                 |   11 
 drivers/net/pcmcia/3c589_cs.c                 |    9 
 drivers/net/pcmcia/axnet_cs.c                 |    9 
 drivers/net/pcmcia/com20020_cs.c              |   32 
 drivers/net/pcmcia/fmvj18x_cs.c               |    9 
 drivers/net/pcmcia/ibmtr_cs.c                 |    1 
 drivers/net/pcmcia/nmclan_cs.c                |    9 
 drivers/net/pcmcia/pcnet_cs.c                 |    9 
 drivers/net/pcmcia/smc91c92_cs.c              |    9 
 drivers/net/pcmcia/xirc2ps_cs.c               |    9 
 drivers/net/pcnet32.c                         |   61 
 drivers/net/sb1250-mac.c                      |    6 
 drivers/net/sk98lin/h/skdrv1st.h              |    6 
 drivers/net/skfp/fplustm.c                    |   28 
 drivers/net/skfp/h/cmtdef.h                   |    4 
 drivers/net/skfp/h/targetos.h                 |    2 
 drivers/net/skfp/skfddi.c                     |    5 
 drivers/net/skfp/smt.c                        |   86 -
 drivers/net/smc91x.c                          | 2173 ++++++++++++++++++++++++++
 drivers/net/smc91x.h                          |  866 ++++++++++
 drivers/net/sundance.c                        |    9 
 drivers/net/tulip/winbond-840.c               |    9 
 drivers/net/typhoon.c                         |    6 
 drivers/net/via-rhine.c                       |    6 
 drivers/net/wan/sbni.h                        |    2 
 drivers/net/wireless/prism54/isl_ioctl.c      |    4 
 drivers/net/wireless/prism54/islpci_dev.c     |    7 
 drivers/net/wireless/prism54/islpci_dev.h     |    2 
 drivers/net/wireless/prism54/islpci_eth.c     |    8 
 drivers/net/wireless/prism54/islpci_hotplug.c |  124 +
 drivers/net/wireless/prism54/islpci_mgt.h     |    3 
 drivers/net/wireless/prism54/oid_mgt.c        |    4 
 drivers/net/yellowfin.c                       |    8 
 51 files changed, 5374 insertions(+), 3298 deletions(-)

through these ChangeSets:

<jgarzik@pobox.com> (04/06/30 1.1805)
   [netdrvr] add fec_8xx to Makefile

<shemminger@osdl.org> (04/06/30 1.1804)
   [PATCH] skfddi - cleanup local and dead functions
   
   Cleanup the SK Fddi driver a little more.  Mark some functions as static,
   and eliminate (or comment out) some that are defined but never used.
   
   Signed-off-by: Stephen Hemminger <shemminger@osdl.org>

<shemminger@osdl.org> (04/06/30 1.1803)
   [PATCH] skfddi - fix warning
   
   The conversion to ANSI, caused a warning because the mulitcast code needs
   a cast.  dmi->dmi_addr is a u8 array, and fddi_addr is just a wrapper around a u8 array.
   
   Signed-off-by: Stephen Hemminger <shemminger@osdl.org>

<panto@intracom.gr> (04/06/30 1.1802)
   [PATCH] add new fec_8xx network driver

<dale@farnsworth.org> (04/06/30 1.1801)
   [PATCH] Patch 2/2 enable smc91x enet driver for use by PPC
   
   Hi,
   
   Patch 2 of 2 to enable the smc91x driver to be used by the IBM Redwood5
   and Redwood6 boards.
   
   Enable smc91x driver to support IBM Redwood5 and Redwood6 boards
   
   Signed-off-by: Dale Farnsworth <dale@farnsworth.org>

<dale@farnsworth.org> (04/06/30 1.1800)
   [PATCH] Patch 1/2 enable smc91x enet driver for use by PPC
   
   Hi,
   
   Patch 1 of 2 to enable the smc91x driver to be used by the IBM Redwood5
   and Redwood6 boards.
   
   Move drivers/net/arm/smc91x.[ch] to drivers/net
   
   Signed-off-by: Dale Farnsworth <dale@farnsworth.org>

<rmk+lkml@arm.linux.org.uk> (04/06/30 1.1799)
   [PATCH] PCMCIA net device unplugging ordering fix
   
   This is a rather old patch which re-orders the teardown of PCMCIA
   network devices.  Current device drivers remove the IO mappings,
   interrupts, and free any PCMCIA windows before they unregister
   themselves from the network layer.
   
   This patch ensures that we first unregister from the network layer
   before performing any teardown of resources or windows.
   
   Note: the only card which has been tested in this patch is pcnet_cs.

<shemminger@osdl.org> (04/06/30 1.1798)
   [PATCH] get rid of __OPTIMIZE__ requirement in net drivers
   
   Several network drivers have checks that they are only built with -O.
   This breaks checking with sparse and other tools, and seems like a holdover from
   when drivers were built out of tree and the kernel build system was less stable.
   This patch gets rid of these.
   
   Signed-off-by: Stephen Hemminger <shemminger@osdl.org>

<shemminger@osdl.org> (04/06/30 1.1797)
   [PATCH] [sparse] get rid of warnings about #if DEBUG
   
   Several drivers use '#if DEBUG' which is a warning under the sparse checker.
   
   Signed-off-by: Stephen Hemminger <shemminger@osdl.org>

<shemminger@osdl.org> (04/06/30 1.1796)
   [PATCH] (2/3) skfp -- sparse __user annotation
   
   Add __user annotation to the device specific ioctl.

<shemminger@osdl.org> (04/06/30 1.1795)
   [PATCH] (1/3) skfp - cleanup is_XXX functions
   
   This started out from sparse warnings about calling with fddi_broadcast
   that is declared const.  This fixes that and gets rid of some of the namespace
   pollution of this driver by moving the predicate function is_individual, is_broadcast, ...
   as inline's in the one file that uses them.
   
   Signed-off-by: Stephen Hemminger <shemminger@osdl.org>

<akpm@osdl.org> (04/06/30 1.1794)
   [PATCH] net/ne2.c needs MCA_LEGACY
   
   From: "Luiz Fernando N. Capitulino" <lcapitulino@prefeitura.sp.gov.br>
   
   drivers/net/ne2.c does not compile without CONFIG_MCA_LEGACY set.
   
   As CONFIG_MCA_LEGACY depends on CONFIG_MCA, we can use only
   CONFIG_MCA_LEGACY, insteed of "MCA && MCA_LEGACY".
   
   Signed-off-by: Luiz Capitulino <lcapitulino@prefeitura.sp.gov.br>
   Signed-off-by: Andrew Morton <akpm@osdl.org>

<akpm@osdl.org> (04/06/30 1.1793)
   [PATCH] net/at1700.c depends on MCA_LEGACY
   
   From: "Luiz Fernando N. Capitulino" <lcapitulino@prefeitura.sp.gov.br>
   
   drivers/net/at1700.c does not compile without CONFIG_MCA_LEGACY set.
   
   As CONFIG_MCA_LEGACY depends on CONFIG_MCA, we can use only
   CONFIG_MCA_LEGACY, insteed of "MCA && MCA_LEGACY".
   
   Signed-off-by: Luiz Capitulino <lcapitulino@prefeitura.sp.gov.br>
   Signed-off-by: Andrew Morton <akpm@osdl.org>

<brazilnut@us.ibm.com> (04/06/30 1.1792)
   [PATCH] pcnet32: change to use module_param
   
   Change the pcnet32 driver to use module_param and module_param_array.

<brazilnut@us.ibm.com> (04/06/30 1.1791)
   [PATCH] pcnet32:  correctly program bcr32.
   
   The pcnet32 driver was not correctly enabling MII autonegotiation after
   booting when ppc firmware forced the speed/duplex mode of the chip.
   After several conversations with AMD this patch corrects the problem.
   
   I have tested this on hardware I have available (ia32 and ppc64) but I
   would like wider audience testing of this patch.
   
   Signed-off-by: Don Fry <brazilnut@us.ibm.com>

<brazilnut@us.ibm.com> (04/06/30 1.1790)
   [PATCH] pcnet32: Add HomePNA parameter for 79C978.
   
   This patch adds a module parameter to select HomePNA mode of operation for
   the 79C978 version of the pcnet32.  Tested ia32 and ppc64.
   
   signed-off-by: Patrick Simmons <psimmons@flash.net>
   signed-off-by: Don Fry <brazilnut@us.ibm.com>

<brazilnut@us.ibm.com> (04/06/30 1.1789)
   [PATCH] pcnet32: acknowledge all interrupts early.
   
   A recent change I made broke pcnet32 in a way that allowed real hardware
   to work, but broke VMWare.  This patch acknowledges all interrupts early
   in the pcnet32_interrupt while loop.  Without this patch on real hardware
   the first transmit operation would clear the 'init' interrupt, but in
   VMWare it would rain interrupts.  Keith Moore did more testing for me
   on VMWare and I did a better job testing on hardware.  Petr Vandrovec
   correctly pointed out the source of the problem on lkml.
   
   This patch is not needed for 2.4.27-rc1 unless my patch labeled
   "pcnet32: recover after rx hang" is applied (which it has not).
   
   signed-off-by: Don Fry <brazilnut@us.ibm.com>

<margitsw@t-online.de> (04/06/30 1.1788)
   [PATCH] prism54 use set_pci_mwi()
   
   2004-06-28 Margit Schubert-While <margitsw@t-online.de>
   
   * Use set_pci_mwi()

<margitsw@t-online.de> (04/06/30 1.1787)
   [PATCH] prism54 remove prog reg poke
   
   2004-06-28 Margit Schubert-While <margitsw@t-online.de>
   
   * Don't poke around in the timeout registers

<margitsw@t-online.de> (04/06/30 1.1786)
   [PATCH] prism54 device list cleanup
   
   2004-06-28 Margit Schubert-While <margitsw@t-online.de>
   
   * Clean up the device table

<margitsw@t-online.de> (04/06/30 1.1785)
   [PATCH] prism54 fix unlikely
   
   2004-06-28 Margit Schubert-While <margitsw@t-online.de>
   
   * Fix a thinko by me

<margitsw@t-online.de> (04/06/30 1.1784)
   [PATCH] prism54 missing error check
   
   2004-06-28 Margit Schubert-While <margitsw@t-online.de>
   
   * Missing error check after dev_alloc_skb

<margitsw@t-online.de> (04/06/30 1.1783)
   [PATCH] prism54 cleanup functions
   
   2004-06-28 Margit Schubert-While <margitsw@t-online.de>
   
   * Clean up function definitions (missing static, extraneous inline)

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [BK PATCHES] 2.6.x net driver updates
@ 2004-06-17  1:01 Jeff Garzik
  0 siblings, 0 replies; 28+ messages in thread
From: Jeff Garzik @ 2004-06-17  1:01 UTC (permalink / raw)
  To: NetDev list


(just sent to andrew/linus)

BK users may do a

	bk pull bk://gkernel.bkbits.net/net-drivers-2.6

This will update the following files:

 Documentation/networking/00-INDEX             |    2 
 drivers/net/3c501.c                           |    2 
 drivers/net/3c503.c                           |    6 
 drivers/net/3c505.c                           |    3 
 drivers/net/3c507.c                           |    4 
 drivers/net/3c523.c                           |    4 
 drivers/net/3c527.c                           |    4 
 drivers/net/8139too.c                         |    2 
 drivers/net/82596.c                           |    4 
 drivers/net/Kconfig                           |   85 
 drivers/net/Makefile                          |    1 
 drivers/net/ac3200.c                          |    8 
 drivers/net/acenic.c                          |  248 -
 drivers/net/acenic.h                          |    1 
 drivers/net/apne.c                            |    6 
 drivers/net/arm/Kconfig                       |   17 
 drivers/net/arm/Makefile                      |    1 
 drivers/net/arm/smc91x.c                      | 2171 +++++++++++++++++
 drivers/net/arm/smc91x.h                      |  829 ++++++
 drivers/net/at1700.c                          |    8 
 drivers/net/cs89x0.c                          |    8 
 drivers/net/defxx.c                           |    6 
 drivers/net/e2100.c                           |    6 
 drivers/net/eepro.c                           |    6 
 drivers/net/eexpress.c                        |    2 
 drivers/net/epic100.c                         |    5 
 drivers/net/es3210.c                          |    2 
 drivers/net/eth16i.c                          |   10 
 drivers/net/ewrk3.c                           |    6 
 drivers/net/fealnx.c                          |    5 
 drivers/net/fmv18x.c                          |    6 
 drivers/net/forcedeth.c                       |    3 
 drivers/net/hp-plus.c                         |    6 
 drivers/net/hp.c                              |   10 
 drivers/net/hp100.c                           |    2 
 drivers/net/ibmlana.c                         |    6 
 drivers/net/isa-skeleton.c                    |    2 
 drivers/net/jazzsonic.c                       |    4 
 drivers/net/lance.c                           |    2 
 drivers/net/lne390.c                          |   10 
 drivers/net/lp486e.c                          |    4 
 drivers/net/natsemi.c                         |    7 
 drivers/net/ne-h8300.c                        |    6 
 drivers/net/ne.c                              |    6 
 drivers/net/ne2.c                             |    8 
 drivers/net/ne2k_cbus.c                       |    6 
 drivers/net/ne3210.c                          |   10 
 drivers/net/ni52.c                            |    4 
 drivers/net/ns83820.c                         |    4 
 drivers/net/oaknet.c                          |    2 
 drivers/net/r8169.c                           |    2 
 drivers/net/smc-mca.c                         |    4 
 drivers/net/smc-ultra.c                       |    6 
 drivers/net/smc-ultra32.c                     |    4 
 drivers/net/smc9194.c                         |    8 
 drivers/net/starfire.c                        |    2 
 drivers/net/stnic.c                           |    4 
 drivers/net/sun3_82586.c                      |    4 
 drivers/net/sungem.c                          |    2 
 drivers/net/sunhme.c                          |    4 
 drivers/net/tulip/Kconfig                     |   15 
 drivers/net/tulip/winbond-840.c               |    6 
 drivers/net/via-rhine.c                       |  306 +-
 drivers/net/via-velocity.c                    | 3277 ++++++++++++++++++++++++++
 drivers/net/via-velocity.h                    | 1885 ++++++++++++++
 drivers/net/wd.c                              |    6 
 drivers/net/wireless/prism54/isl_38xx.c       |  134 -
 drivers/net/wireless/prism54/isl_38xx.h       |   10 
 drivers/net/wireless/prism54/isl_ioctl.c      |  196 -
 drivers/net/wireless/prism54/isl_ioctl.h      |    1 
 drivers/net/wireless/prism54/islpci_dev.c     |  161 +
 drivers/net/wireless/prism54/islpci_dev.h     |   22 
 drivers/net/wireless/prism54/islpci_eth.c     |   73 
 drivers/net/wireless/prism54/islpci_hotplug.c |    3 
 drivers/net/wireless/prism54/islpci_mgt.c     |  165 -
 drivers/net/wireless/prism54/islpci_mgt.h     |   11 
 drivers/net/wireless/prism54/oid_mgt.c        |   88 
 drivers/net/wireless/prism54/oid_mgt.h        |    2 
 drivers/net/wireless/prism54/prismcompat.h    |   46 
 drivers/net/yellowfin.c                       |    7 
 drivers/net/zorro8390.c                       |    6 
 81 files changed, 9142 insertions(+), 888 deletions(-)

through these ChangeSets:

 D (Alex):
  o fealnx-mac-address-and-other-issues.patch

Adrian Bunk:
  o add NAPI help texts

Alan Cox:
  o add new via-velocity gigabit ethernet driver

Andrew Morton:
  o prism94 build fix

Arthur Othieno:
  o Kill stale references to Documentation/networking/8139too.txt

Evgeniy Polyakov:
  o Typo in ethtool code in acenic driver

Herbert Xu:
  o [NETDRV #2] Use driver-specific name for resources
  o [NETDRV #1] Ifdef builtin-only probe in ISA/MCA drivers

Jeff Garzik:
  o [netdrvr acenic] remove unneeded ifdefs

Margit Schubert-While:
  o prism54: White space and indentation
  o prism54: Fix typo
  o prism54: Fix channel stats, bump version to 1.2
  o prism54: Reduce module verbosity
  o prism54: Align skb patch
  o prism54: Add likely/unlikely, KO wds completely
  o prism54: Don't allow mib reads while unconfigured
  o prism54: Fix bug 77, strengthened oid txn
  o prism54: Fix bugs 39/73
  o prism54: Fix bugs 74/75
  o prism54: Fix endian patch
  o prism54: Kernel compatibility

Roger Luethi:
  o Add rhine_power_init(): get power regs into sane state
  o Rewrite special-casing
  o Return codes for rhine_init_one
  o Nuke all pci_flags
  o Nuke default_port, references to if_port, medialock
  o Nuke HasESIPhy and related code
  o Nuke CanHaveMII and related code
  o Nuke HAS_IP_COPYSUM
  o Nuke HAS_IP_COPYSUM for net drivers

Russell King:
  o add ARM smc91x driver

Stephen Hemminger:
  o fix oops from acenic ethtool

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [bk patches] 2.6.x net driver updates
@ 2003-09-28 14:45 Jeff Garzik
  0 siblings, 0 replies; 28+ messages in thread
From: Jeff Garzik @ 2003-09-28 14:45 UTC (permalink / raw)
  To: torvalds; +Cc: netdev


Linus, please do a

	bk pull bk://kernel.bkbits.net/jgarzik/net-drivers-2.5

This will update the following files:

 drivers/net/Space.c               |    4 
 drivers/net/ne3210.c              |  293 ++++++++++++++++----------------------
 drivers/net/wireless/arlan-main.c |    2 
 include/linux/hdlcdrv.h           |   10 -
 4 files changed, 137 insertions(+), 172 deletions(-)

through these ChangeSets:

<mzyngier@freesurf.fr> (03/09/28 1.1378)
   [PATCH] ne3210 update
   
   The enclosed patch ports the ne3210 driver over the EISA probing API.
   
   It also fixes some ioremap/isa_memcopy_fromio problems (depending on
   where the card memory was mapped) by using ioremap unconditionally and
   letting memcopy_fromio do the right thing.
   
   Finally, it removes the card from Space.c (warning, potential
   interface renumbering !).
   
   The module options are currently disabled, until Rusty's
   module_param_array() patch is included. I will re-introduce them ASAP.
   
   Quite heavily tested on x86.

<shemminger@osdl.org> (03/09/28 1.1377)
   [PATCH] Fix warnings in hamradio/baycom build
   
   Sorry, overlooked the corresponding .h file in that patch, here it is.

<romieu@fr.zoreil.com> (03/09/28 1.1376)
   [PATCH] Fix debug statement after return in drivers/net/wireless/arlan-main.c
   
   This patch applies to 2.5.68 and is listed on kbugs.org. The debug statement
   is never executed because it is after a return.



diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c
--- a/drivers/net/Space.c	Sun Sep 28 10:38:07 2003
+++ b/drivers/net/Space.c	Sun Sep 28 10:38:07 2003
@@ -67,7 +67,6 @@
 extern int ac3200_probe(struct net_device *);
 extern int es_probe(struct net_device *);
 extern int lne390_probe(struct net_device *);
-extern int ne3210_probe(struct net_device *);
 extern int e2100_probe(struct net_device *);
 extern int ni5010_probe(struct net_device *);
 extern int ni52_probe(struct net_device *);
@@ -154,9 +153,6 @@
 #endif
 #ifdef CONFIG_LNE390
 	{lne390_probe, 0},
-#endif
-#ifdef CONFIG_NE3210
-	{ne3210_probe, 0},
 #endif
 	{NULL, 0},
 };
diff -Nru a/drivers/net/ne3210.c b/drivers/net/ne3210.c
--- a/drivers/net/ne3210.c	Sun Sep 28 10:38:07 2003
+++ b/drivers/net/ne3210.c	Sun Sep 28 10:38:07 2003
@@ -23,6 +23,7 @@
 	This driver WILL NOT WORK FOR THE NE3200 - it is completely different
 	and does not use an 8390 at all.
 
+	Updated to EISA probing API 5/2003 by Marc Zyngier.
 */
 
 static const char *version =
@@ -44,9 +45,6 @@
 
 #include "8390.h"
 
-int ne3210_probe(struct net_device *dev);
-static int ne3210_probe1(struct net_device *dev, int ioaddr);
-
 static int ne3210_open(struct net_device *dev);
 static int ne3210_close(struct net_device *dev);
 
@@ -59,7 +57,6 @@
 #define NE3210_START_PG		0x00    /* First page of TX buffer	*/
 #define NE3210_STOP_PG		0x80    /* Last page +1 of RX ring	*/
 
-#define NE3210_ID_PORT		0xc80	/* Same for all EISA cards 	*/
 #define NE3210_IO_EXTENT	0x20
 #define NE3210_SA_PROM		0x16	/* Start of e'net addr.		*/
 #define NE3210_RESET_PORT	0xc84
@@ -69,10 +66,9 @@
 #define NE3210_ADDR1		0x00
 #define NE3210_ADDR2		0x1b
 
-#define NE3210_ID	0x0118cc3a	/* 0x3acc = 1110 10110 01100 =  nvl */
-
 #define NE3210_CFG1		0xc84	/* NB: 0xc84 is also "reset" port. */
 #define NE3210_CFG2		0xc90
+#define NE3210_CFG_EXTENT       (NE3210_CFG2 - NE3210_CFG1 + 1)
 
 /*
  *	You can OR any of the following bits together and assign it
@@ -89,152 +85,108 @@
 
 static unsigned char irq_map[] __initdata = {15, 12, 11, 10, 9, 7, 5, 3};
 static unsigned int shmem_map[] __initdata = {0xff0, 0xfe0, 0xfff0, 0xd8, 0xffe0, 0xffc0, 0xd0, 0x0};
+static const char *ifmap[] __initdata = {"UTP", "?", "BNC", "AUI"};
+static int ifmap_val[] __initdata = {
+		IF_PORT_10BASET,
+		IF_PORT_UNKNOWN,
+		IF_PORT_10BASE2,
+		IF_PORT_AUI,
+};
 
-/*
- *	Probe for the card. The best way is to read the EISA ID if it
- *	is known. Then we can check the prefix of the station address
- *	PROM for a match against the value assigned to Novell.
- */
-
-int __init ne3210_probe(struct net_device *dev)
+static int __init ne3210_eisa_probe (struct device *device)
 {
-	unsigned short ioaddr = dev->base_addr;
-
-	SET_MODULE_OWNER(dev);
+	unsigned long ioaddr, phys_mem;
+	int i, retval, port_index;
+	struct eisa_device *edev = to_eisa_device (device);
+	struct net_device *dev;
 
-	if (ioaddr > 0x1ff)		/* Check a single specified location. */
-		return ne3210_probe1(dev, ioaddr);
-	else if (ioaddr > 0)		/* Don't probe at all. */
-		return -ENXIO;
-
-	if (!EISA_bus) {
-#if NE3210_DEBUG & NE3210_D_PROBE
-		printk("ne3210-debug: Not an EISA bus. Not probing high ports.\n");
-#endif
-		return -ENXIO;
+	/* Allocate dev->priv and fill in 8390 specific dev fields. */
+	if (!(dev = alloc_ei_netdev ())) {
+		printk ("ne3210.c: unable to allocate memory for dev!\n");
+		return -ENOMEM;
 	}
 
-	/* EISA spec allows for up to 16 slots, but 8 is typical. */
-	for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000)
-		if (ne3210_probe1(dev, ioaddr) == 0)
-			return 0;
-
-	return -ENODEV;
-}
-
-static int __init ne3210_probe1(struct net_device *dev, int ioaddr)
-{
-	int i, retval;
-	unsigned long eisa_id;
-	const char *ifmap[] = {"UTP", "?", "BNC", "AUI"};
-
-	if (!request_region(dev->base_addr, NE3210_IO_EXTENT, dev->name))
-		return -EBUSY;
+	SET_MODULE_OWNER(dev);
+	SET_NETDEV_DEV(dev, device);
+	device->driver_data = dev;
+	ioaddr = edev->base_addr;
 
-	if (inb_p(ioaddr + NE3210_ID_PORT) == 0xff) {
-		retval = -ENODEV;
+	if (ethdev_init (dev)) {
+		printk ("ne3210.c: unable to allocate memory for dev->priv!\n");
+		retval = -ENOMEM;
 		goto out;
 	}
 
-#if NE3210_DEBUG & NE3210_D_PROBE
-	printk("ne3210-debug: probe at %#x, ID %#8x\n", ioaddr, inl(ioaddr + NE3210_ID_PORT));
-	printk("ne3210-debug: config regs: %#x %#x\n",
-		inb(ioaddr + NE3210_CFG1), inb(ioaddr + NE3210_CFG2));
-#endif
-
-
-/*	Check the EISA ID of the card. */
-	eisa_id = inl(ioaddr + NE3210_ID_PORT);
-	if (eisa_id != NE3210_ID) {
-		retval = -ENODEV;
+	if (!request_region(ioaddr, NE3210_IO_EXTENT, dev->name)) {
+		retval = -EBUSY;
 		goto out;
 	}
 
-	
-#if 0
-/*	Check the vendor ID as well. Not really required. */
-	if (inb(ioaddr + NE3210_SA_PROM + 0) != NE3210_ADDR0
-		|| inb(ioaddr + NE3210_SA_PROM + 1) != NE3210_ADDR1
-		|| inb(ioaddr + NE3210_SA_PROM + 2) != NE3210_ADDR2 ) {
-		printk("ne3210.c: card not found");
-		for(i = 0; i < ETHER_ADDR_LEN; i++)
-			printk(" %02x", inb(ioaddr + NE3210_SA_PROM + i));
-		printk(" (invalid prefix).\n");
-		retval = -ENODEV;
-		goto out;
+	if (!request_region(ioaddr + NE3210_CFG1,
+			    NE3210_CFG_EXTENT, dev->name)) {
+		retval = -EBUSY;
+		goto out1;
 	}
+
+#if NE3210_DEBUG & NE3210_D_PROBE
+	printk("ne3210-debug: probe at %#x, ID %s\n", ioaddr, edev->id.sig);
+	printk("ne3210-debug: config regs: %#x %#x\n",
+		inb(ioaddr + NE3210_CFG1), inb(ioaddr + NE3210_CFG2));
 #endif
 
-	/* Allocate dev->priv and fill in 8390 specific dev fields. */
-	if (ethdev_init(dev)) {
-		printk ("ne3210.c: unable to allocate memory for dev->priv!\n");
-		retval = -ENOMEM;
-		goto out;
-	}
 
+	port_index = inb(ioaddr + NE3210_CFG2) >> 6;
 	printk("ne3210.c: NE3210 in EISA slot %d, media: %s, addr:",
-		ioaddr/0x1000, ifmap[inb(ioaddr + NE3210_CFG2) >> 6]);
+		edev->slot, ifmap[port_index]);
 	for(i = 0; i < ETHER_ADDR_LEN; i++)
 		printk(" %02x", (dev->dev_addr[i] = inb(ioaddr + NE3210_SA_PROM + i)));
-	printk(".\nne3210.c: ");
+	
 
 	/* Snarf the interrupt now. CFG file has them all listed as `edge' with share=NO */
-	if (dev->irq == 0) {
-		unsigned char irq_reg = inb(ioaddr + NE3210_CFG2) >> 3;
-		dev->irq = irq_map[irq_reg & 0x07];
-		printk("using");
-	} else {
-		/* This is useless unless we reprogram the card here too */
-		if (dev->irq == 2) dev->irq = 9;	/* Doh! */
-		printk("assigning");
-	}
-	printk(" IRQ %d,", dev->irq);
+	dev->irq = irq_map[(inb(ioaddr + NE3210_CFG2) >> 3) & 0x07];
+	printk(".\nne3210.c: using IRQ %d, ", dev->irq);
 
 	retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev);
 	if (retval) {
 		printk (" unable to get IRQ %d.\n", dev->irq);
-		goto out1;
-	}
-
-	if (dev->mem_start == 0) {
-		unsigned char mem_reg = inb(ioaddr + NE3210_CFG2) & 0x07;
-		dev->mem_start = shmem_map[mem_reg] * 0x1000;
-		printk(" using ");
-	} else {
-		/* Should check for value in shmem_map and reprogram the card to use it */
-		dev->mem_start &= 0xfff8000;
-		printk(" assigning ");
+		goto out2;
 	}
 
-	printk("%dkB memory at physical address %#lx\n",
-			NE3210_STOP_PG/4, dev->mem_start);
+	phys_mem = shmem_map[inb(ioaddr + NE3210_CFG2) & 0x07] * 0x1000;
 
 	/*
 	   BEWARE!! Some dain-bramaged EISA SCUs will allow you to put
 	   the card mem within the region covered by `normal' RAM  !!!
 	*/
-	if (dev->mem_start > 1024*1024) {	/* phys addr > 1MB */
-		if (dev->mem_start < virt_to_phys(high_memory)) {
+	if (phys_mem > 1024*1024) {	/* phys addr > 1MB */
+		if (phys_mem < virt_to_phys(high_memory)) {
 			printk(KERN_CRIT "ne3210.c: Card RAM overlaps with normal memory!!!\n");
 			printk(KERN_CRIT "ne3210.c: Use EISA SCU to set card memory below 1MB,\n");
 			printk(KERN_CRIT "ne3210.c: or to an address above 0x%lx.\n", virt_to_phys(high_memory));
 			printk(KERN_CRIT "ne3210.c: Driver NOT installed.\n");
 			retval = -EINVAL;
-			goto out2;
+			goto out3;
 		}
-		dev->mem_start = (unsigned long)ioremap(dev->mem_start, NE3210_STOP_PG*0x100);
-		if (dev->mem_start == 0) {
-			printk(KERN_ERR "ne3210.c: Unable to remap card memory above 1MB !!\n");
-			printk(KERN_ERR "ne3210.c: Try using EISA SCU to set memory below 1MB.\n");
-			printk(KERN_ERR "ne3210.c: Driver NOT installed.\n");
-			retval = -EAGAIN;
-			goto out2;
-		}
-		ei_status.reg0 = 1;	/* Use as remap flag */
-		printk("ne3210.c: remapped %dkB card memory to virtual address %#lx\n",
-				NE3210_STOP_PG/4, dev->mem_start);
 	}
+	
+	if (!request_mem_region (phys_mem, NE3210_STOP_PG*0x100, dev->name)) {
+		printk ("ne3210.c: Unable to request shared memory at physical address %#lx\n",
+			phys_mem);
+		goto out3;
+	}
+	
+	printk("%dkB memory at physical address %#lx\n",
+	       NE3210_STOP_PG/4, phys_mem);
 
+	dev->mem_start = (unsigned long)ioremap(phys_mem, NE3210_STOP_PG*0x100);
+	if (dev->mem_start == 0) {
+		printk(KERN_ERR "ne3210.c: Unable to remap card memory !!\n");
+		printk(KERN_ERR "ne3210.c: Driver NOT installed.\n");
+		retval = -EAGAIN;
+		goto out4;
+	}
+	printk("ne3210.c: remapped %dkB card memory to virtual address %#lx\n",
+	       NE3210_STOP_PG/4, dev->mem_start);
 	dev->mem_end = ei_status.rmem_end = dev->mem_start
 		+ (NE3210_STOP_PG - NE3210_START_PG)*256;
 	ei_status.rmem_start = dev->mem_start + TX_PAGES*256;
@@ -247,6 +199,7 @@
 	ei_status.rx_start_page = NE3210_START_PG + TX_PAGES;
 	ei_status.stop_page = NE3210_STOP_PG;
 	ei_status.word16 = 1;
+	ei_status.priv = phys_mem;
 
 	if (ei_debug > 0)
 		printk(version);
@@ -258,18 +211,46 @@
 
 	dev->open = &ne3210_open;
 	dev->stop = &ne3210_close;
+	dev->if_port = ifmap_val[port_index];
+
+	if ((retval = register_netdev (dev)))
+		goto out5;
+		
 	NS8390_init(dev, 0);
 	return 0;
-out2:
-	free_irq(dev->irq, dev);	
-out1:
-	kfree(dev->priv);
-	dev->priv = NULL;
-out:
-	release_region(ioaddr, NE3210_IO_EXTENT);
+
+ out5:
+	iounmap((void *)dev->mem_start);
+ out4:
+	release_mem_region (phys_mem, NE3210_STOP_PG*0x100);
+ out3:
+	free_irq (dev->irq, dev);
+ out2:
+	release_region (ioaddr + NE3210_CFG1, NE3210_CFG_EXTENT);
+ out1:
+	release_region (ioaddr, NE3210_IO_EXTENT);
+ out:
+	free_netdev (dev);
+	
 	return retval;
 }
 
+static int __devexit ne3210_eisa_remove (struct device *device)
+{
+	struct net_device  *dev    = device->driver_data;
+	unsigned long       ioaddr = to_eisa_device (device)->base_addr;
+
+	unregister_netdev (dev);
+	iounmap((void *)dev->mem_start);
+	release_mem_region (ei_status.priv, NE3210_STOP_PG*0x100);
+	free_irq (dev->irq, dev);
+	release_region (ioaddr + NE3210_CFG1, NE3210_CFG_EXTENT);
+	release_region (ioaddr, NE3210_IO_EXTENT);
+	free_netdev (dev);
+
+	return 0;
+}
+
 /*
  *	Reset by toggling the "Board Enable" bits (bit 2 and 0).
  */
@@ -309,7 +290,7 @@
 ne3210_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
 {
 	unsigned long hdr_start = dev->mem_start + ((ring_page - NE3210_START_PG)<<8);
-	isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
+	memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
 	hdr->count = (hdr->count + 3) & ~3;     /* Round up allocation. */
 }
 
@@ -327,12 +308,12 @@
 	if (xfer_start + count > ei_status.rmem_end) {
 		/* Packet wraps over end of ring buffer. */
 		int semi_count = ei_status.rmem_end - xfer_start;
-		isa_memcpy_fromio(skb->data, xfer_start, semi_count);
+		memcpy_fromio(skb->data, xfer_start, semi_count);
 		count -= semi_count;
-		isa_memcpy_fromio(skb->data + semi_count, ei_status.rmem_start, count);
+		memcpy_fromio(skb->data + semi_count, ei_status.rmem_start, count);
 	} else {
 		/* Packet is in one chunk. */
-		isa_memcpy_fromio(skb->data, xfer_start, count);
+		memcpy_fromio(skb->data, xfer_start, count);
 	}
 }
 
@@ -342,7 +323,7 @@
 	unsigned long shmem = dev->mem_start + ((start_page - NE3210_START_PG)<<8);
 
 	count = (count + 3) & ~3;     /* Round up to doubleword */
-	isa_memcpy_toio(shmem, buf, count);
+	memcpy_toio(shmem, buf, count);
 }
 
 static int ne3210_open(struct net_device *dev)
@@ -361,7 +342,23 @@
 	return 0;
 }
 
+static struct eisa_device_id ne3210_ids[] = {
+	{ "EGL0101" },
+	{ "NVL1801" },
+	{ "" },
+};
+
+static struct eisa_driver ne3210_eisa_driver = {
+	.id_table = ne3210_ids,
+	.driver   = {
+		.name   = "ne3210",
+		.probe  = ne3210_eisa_probe,
+		.remove = __devexit_p (ne3210_eisa_remove),
+	},
+};
+
 #ifdef MODULE
+#if 0
 #define MAX_NE3210_CARDS	4	/* Max number of NE3210 cards per module */
 static struct net_device dev_ne3210[MAX_NE3210_CARDS];
 static int io[MAX_NE3210_CARDS];
@@ -374,50 +371,22 @@
 MODULE_PARM_DESC(io, "I/O base address(es)");
 MODULE_PARM_DESC(irq, "IRQ number(s)");
 MODULE_PARM_DESC(mem, "memory base address(es)");
+#endif
+#endif /* MODULE */
+
+
 MODULE_DESCRIPTION("NE3210 EISA Ethernet driver");
 MODULE_LICENSE("GPL");
 
-int init_module(void)
+int ne3210_init(void)
 {
-	int this_dev, found = 0;
-
-	for (this_dev = 0; this_dev < MAX_NE3210_CARDS; this_dev++) {
-		struct net_device *dev = &dev_ne3210[this_dev];
-		dev->irq = irq[this_dev];
-		dev->base_addr = io[this_dev];
-		dev->mem_start = mem[this_dev];
-		dev->init = ne3210_probe;
-		/* Default is to only install one card. */
-		if (io[this_dev] == 0 && this_dev != 0) break;
-		if (register_netdev(dev) != 0) {
-			printk(KERN_WARNING "ne3210.c: No NE3210 card found (i/o = 0x%x).\n", io[this_dev]);
-			if (found != 0) {	/* Got at least one. */
-				return 0;
-			}
-			return -ENXIO;
-		}
-		found++;
-	}
-	return 0;
+	return eisa_driver_register (&ne3210_eisa_driver);
 }
 
-void cleanup_module(void)
+void ne3210_cleanup(void)
 {
-	int this_dev;
-
-	for (this_dev = 0; this_dev < MAX_NE3210_CARDS; this_dev++) {
-		struct net_device *dev = &dev_ne3210[this_dev];
-		if (dev->priv != NULL) {
-			free_irq(dev->irq, dev);
-			release_region(dev->base_addr, NE3210_IO_EXTENT);
-			if (ei_status.reg0)
-				iounmap((void *)dev->mem_start);
-			unregister_netdev(dev);
-			kfree(dev->priv);
-			dev->priv = NULL;
-		}
-	}
+	eisa_driver_unregister (&ne3210_eisa_driver);
 }
 
-#endif /* MODULE */
-
+module_init (ne3210_init);
+module_exit (ne3210_cleanup);
diff -Nru a/drivers/net/wireless/arlan-main.c b/drivers/net/wireless/arlan-main.c
--- a/drivers/net/wireless/arlan-main.c	Sun Sep 28 10:38:07 2003
+++ b/drivers/net/wireless/arlan-main.c	Sun Sep 28 10:38:07 2003
@@ -721,9 +721,9 @@
 	else
 	{
 		netif_stop_queue (dev);
-		return -1;
 		IFDEBUG(ARLAN_DEBUG_TX_CHAIN)
 			printk(KERN_ERR "TX TAIL & HEAD full, return, tailStart %d headEnd %d\n", tailStarts, headEnds);
+		return -1;
 	}
 	priv->out_bytes += length;
 	priv->out_bytes10 += length;
diff -Nru a/include/linux/hdlcdrv.h b/include/linux/hdlcdrv.h
--- a/include/linux/hdlcdrv.h	Sun Sep 28 10:38:07 2003
+++ b/include/linux/hdlcdrv.h	Sun Sep 28 10:38:07 2003
@@ -359,11 +359,11 @@
 void hdlcdrv_receiver(struct net_device *, struct hdlcdrv_state *);
 void hdlcdrv_transmitter(struct net_device *, struct hdlcdrv_state *);
 void hdlcdrv_arbitrate(struct net_device *, struct hdlcdrv_state *);
-int hdlcdrv_register_hdlcdrv(struct net_device *dev, const struct hdlcdrv_ops *ops,
-			     unsigned int privsize, char *ifname,
-			     unsigned int baseaddr, unsigned int irq, 
-			     unsigned int dma);
-int hdlcdrv_unregister_hdlcdrv(struct net_device *dev);
+struct net_device *hdlcdrv_register(const struct hdlcdrv_ops *ops,
+				    unsigned int privsize, const char *ifname,
+				    unsigned int baseaddr, unsigned int irq, 
+				    unsigned int dma);
+void hdlcdrv_unregister(struct net_device *dev);
 
 /* -------------------------------------------------------------------- */
 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [BK PATCHES] 2.6.x net driver updates
@ 2003-09-27 11:55 Jeff Garzik
  0 siblings, 0 replies; 28+ messages in thread
From: Jeff Garzik @ 2003-09-27 11:55 UTC (permalink / raw)
  To: torvalds; +Cc: netdev, linux-kernel

This should fix the build.  Only thing left not building is g_ncr5380...



Linus, please do a

	bk pull bk://kernel.bkbits.net/jgarzik/net-drivers-2.5

This will update the following files:

 drivers/usb/net/Makefile.mii      |    6 
 drivers/net/Kconfig               |   11 
 drivers/net/Makefile              |   28 --
 drivers/net/e100/e100.h           |    1 
 drivers/net/e100/e100_config.c    |    2 
 drivers/net/e100/e100_config.h    |    1 
 drivers/net/e100/e100_main.c      |   49 +---
 drivers/net/e1000/e1000.h         |    8 
 drivers/net/e1000/e1000_ethtool.c |   14 -
 drivers/net/e1000/e1000_hw.c      |   39 +--
 drivers/net/e1000/e1000_hw.h      |    2 
 drivers/net/e1000/e1000_main.c    |   90 ++++---
 drivers/net/e1000/e1000_osdep.h   |    2 
 drivers/net/hamradio/baycom_epp.c |    4 
 drivers/net/pcmcia/Kconfig        |    1 
 drivers/net/pcmcia/smc91c92_cs.c  |    8 
 drivers/net/sk98lin/skdim.c       |    5 
 drivers/net/sk98lin/skge.c        |  103 +++-----
 drivers/net/sk98lin/skproc.c      |  463 ++++++++++++++++----------------------
 drivers/net/tulip/Kconfig         |    1 
 drivers/net/wan/sealevel.c        |   36 +-
 drivers/net/wan/z85230.c          |   58 ++--
 drivers/net/wireless/orinoco.c    |    4 
 drivers/usb/net/Kconfig           |    2 
 24 files changed, 447 insertions(+), 491 deletions(-)

through these ChangeSets:

<bunk@fs.tum.de> (03/09/27 1.1371)
   [PATCH] select MII
   
   The patch below switches MII to be select'ed instead of including it in
   the Makefile.
   
   Note that this patch requires a recent Linus' tree with the select CRC32
   patch included.
   
   diffstat output:
   
    drivers/net/Kconfig          |   11 +++++++++++
    drivers/net/Makefile         |   28 +++++++++++-----------------
    drivers/net/pcmcia/Kconfig   |    1 +
    drivers/net/tulip/Kconfig    |    1 +
    drivers/usb/net/Kconfig      |    2 ++
    drivers/usb/net/Makefile.mii |    6 ------
    6 files changed, 26 insertions(+), 23 deletions(-)
   
   
   Tangential to the patch I observed a small problem (not fixed in the patch):
   MII depends on NET_ETHERNET, but USB_PEGASUS and USB_USBNET depend
   only on NET.
   
   cu
   Adrian

<shemminger@osdl.org> (03/09/27 1.1370)
   [PATCH] wan/z8530 deadlocks
   
   Existing code for drivers/net/wan/z8530 is riddled with self-deadlocks
   and irq flag confusion.  For example:
   	z8530_init -> do_z8530_init -> write_zsreg
   self deadlocks on the channel lock.
   
   Several places acquire both the channel and dma lock and then
   reuse the same irq flags variable - ouch.
   
   This code at least, correctly probes (for no device case) on SMP.
   Other paths verified by inspection.

<shemminger@osdl.org> (03/09/27 1.1369)
   [PATCH] sealevel -- syncppp startup fix
   
   The sealevel driver called sppp_attach before checking that board existed
   and never called detach in the error path.
   
   My change is to call sppp_attach from the netdev->init hook which happens
   later in the process, and call detach from the uninit hook.
   
   Also, changed the structure element 'netdev' to 'pppdev' to avoid confusion.
   
   Here is the fix against 2.6.0-test5 latest

<komujun@nifty.com> (03/09/27 1.1368)
   [netdrvr smc91c92_cs] select proper bank for MII registers

<komujun@nifty.com> (03/09/27 1.1367)
   [netdrvr] build fixes
   
   For e1000 and baycom_epp.
   
   Contributed by Jeff Garzik.

<rddunlap@osdl.org> (03/09/27 1.1366)
   [PATCH] janitor: e100: cleanup #includes
   
   Hi,
   Please apply to 2.6.0-test5-current.
   
   Thanks,
   --
   ~Randy
   
   
   From: Randy Hron <rwhron@earthlink.net>
   
   
   Remove unneeded include of version.h.
   Test compiled against 2.6.0-test5-bk9.
   
   
    linux-260-t5bk12-kj-rddunlap/drivers/net/e100/e100.h |    1 -
    1 files changed, 1 deletion(-)

<rddunlap@osdl.org> (03/09/27 1.1365)
   [PATCH] janitor: hermes: delete verify_area call
   
   Hi,
   Please apply to 2.6.0-test5-current.
   
   Thanks,
   --
   ~Randy
   
   
   From: Domen Puncer <domen@coderock.org>
   
   IMO, that verify_area wasn't needed.
   
   
   
    linux-260-t5bk12-kj-rddunlap/drivers/net/wireless/orinoco.c |    4 ----
    1 files changed, 4 deletions(-)

<scott.feldman@intel.com> (03/09/27 1.1364)
   [e100] trying to pci_alloc before pci_enable
   
   * Some archs don't like calling pci_alloc_consistent before calling
   pci_enable_device.  (Imagine that).  This corrects that.

<scott.feldman@intel.com> (03/09/27 1.1363)
   [e100] h/w can't do IPv6 checksum offloading
   
   * Driver was advertising HW_CSUM, but hardware is only capable of IP_CSUM.

<scott.feldman@intel.com> (03/09/27 1.1362)
   [e100] PRO/10+ not configured properly
   
   * PRO/10+ (10 Mbps-only card) was not configured properly so it didn't
   pass traffic.

<scott.feldman@intel.com> (03/09/27 1.1361)
   [e1000] misc
   
   * removed unused var, ASSERT macro
   * missed a free_netdev() in probe cleanup undo.

<scott.feldman@intel.com> (03/09/27 1.1360)
   [e1000] better propagation of error codes
   
   * Better propagation of error codes during probe/open paths.
     {Janice Girouard (janiceg@us.ibm.com)]

<scott.feldman@intel.com> (03/09/27 1.1359)
   [e1000] force 1000/full on SERDES connected to back-plane
   
   * Bug fix: SERDES devices might be connected to back-plan switch that
     doesn't support auto-neg, so add the capability to force 1000/full.

<scott.feldman@intel.com> (03/09/27 1.1358)
   [e1000] flow control updates
   
   * handle ethtool force flow control
   * correctly set flow control hi/low watermarks based on size of Rx FIFO
     area.  The size can change if doing Jumbo Frames or, in the case of
     82547, is smaller to start with.
   * was not properly forcing flow control settings to fc_none if using
     strict IEEE flow control override.

<shemminger@osdl.org> (03/09/27 1.1357)
   [netdrvr sk98lin] use seq_file for /proc
   
   Replace proc_read with seq_file interface which is much cleaner.
   
   Also, instead of searching the list of devices looking for the
   name which is slow and would break if interface name changes;
   store a pointer to device in the proc entry, and retrieve
   it from the information saved by single_open.
   
   Formatting and other behaviours are retained.

<shemminger@osdl.org> (03/09/27 1.1356)
   [netdrvr skge] handle proc_fs errors.
   
   Existing code does not
   	- check if proc_fs functions return error.
   	- use proc_mkdir to make the directory.
   
   Note pSkRootDir defined twice.

<shemminger@osdl.org> (03/09/27 1.1355)
   [netdrvr sk98lin] build on smp fix
   
   There is no exported variable called smp_num_cpus! so this driver
   won't build on SMP.  Since the local variable is never used anyway
   just get rid of it.
   
   This applies against 2.6.0-test5-bk13 which has the last vendor
   driver update.


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [bk patches] 2.6.x net driver updates
  2003-09-26  1:02 [bk patches] " Jeff Garzik
@ 2003-09-27  5:20 ` Linus Torvalds
  0 siblings, 0 replies; 28+ messages in thread
From: Linus Torvalds @ 2003-09-27  5:20 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev



Hmm.. "make allyesconfig" is broken again:

	drivers/net/hamradio/baycom_epp.c:1447: conflicting types for `baycom_epp_setup'
	drivers/net/hamradio/baycom_epp.c:1359: previous declaration of `baycom_epp_setup'

and

	drivers/net/sk98lin/skdim.c: In function `GetCurrentSystemLoad':
	drivers/net/sk98lin/skdim.c:322: `smp_num_cpus' undeclared (first use in this function)
	drivers/net/sk98lin/skdim.c:322: (Each undeclared identifier is reported only once
	drivers/net/sk98lin/skdim.c:322: for each function it appears in.)
	drivers/net/sk98lin/skdim.c:322: warning: unused variable `SKNumCpus'

Pls fix,

		Linus

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [bk patches] 2.6.x net driver updates
@ 2003-09-26  1:02 Jeff Garzik
  2003-09-27  5:20 ` Linus Torvalds
  0 siblings, 1 reply; 28+ messages in thread
From: Jeff Garzik @ 2003-09-26  1:02 UTC (permalink / raw)
  To: torvalds; +Cc: netdev, linux-kernel


Linus, please do a

	bk pull bk://kernel.bkbits.net/jgarzik/net-drivers-2.5

This will update the following files:

 drivers/net/wireless/arlan.c          | 2078 ------------------------------
 Documentation/networking/sk98lin.txt  |  140 --
 drivers/net/3c503.c                   |    9 
 drivers/net/3c509.c                   |    9 
 drivers/net/8390.c                    |   11 
 drivers/net/Kconfig                   |  170 --
 drivers/net/ac3200.c                  |   10 
 drivers/net/appletalk/Kconfig         |    6 
 drivers/net/arcnet/Kconfig            |   40 
 drivers/net/e2100.c                   |   10 
 drivers/net/hamradio/Kconfig          |   41 
 drivers/net/hamradio/baycom_epp.c     |   79 -
 drivers/net/hamradio/baycom_par.c     |   57 
 drivers/net/hamradio/baycom_ser_fdx.c |   60 
 drivers/net/hamradio/baycom_ser_hdx.c |   57 
 drivers/net/hamradio/hdlcdrv.c        |   90 -
 drivers/net/hp-plus.c                 |   11 
 drivers/net/hp.c                      |   11 
 drivers/net/ne.c                      |    9 
 drivers/net/ne2.c                     |    8 
 drivers/net/ne2k-pci.c                |   49 
 drivers/net/ne2k_cbus.c               |   55 
 drivers/net/pcmcia/Kconfig            |   69 -
 drivers/net/saa9730.c                 |  201 ++
 drivers/net/saa9730.h                 |    1 
 drivers/net/sk98lin/h/skdrv1st.h      |    7 
 drivers/net/sk98lin/h/skdrv2nd.h      |   24 
 drivers/net/sk98lin/h/skgeinit.h      |   19 
 drivers/net/sk98lin/h/sktypes.h       |    7 
 drivers/net/sk98lin/h/skversion.h     |   31 
 drivers/net/sk98lin/skdim.c           |   18 
 drivers/net/sk98lin/skge.c            |  350 +++--
 drivers/net/sk98lin/skproc.c          |  325 +---
 drivers/net/smc-ultra.c               |   13 
 drivers/net/tlan.c                    |    7 
 drivers/net/tokenring/Kconfig         |   66 
 drivers/net/tulip/Kconfig             |   48 
 drivers/net/wan/Kconfig               |  111 -
 drivers/net/wd.c                      |   10 
 drivers/net/wireless/Kconfig          |   32 
 drivers/net/wireless/Makefile         |    4 
 drivers/net/wireless/arlan-main.c     | 2329 +++++++++++++++++++++++++++++++---
 drivers/net/wireless/arlan-proc.c     |   25 
 drivers/net/wireless/arlan.h          |  106 -
 drivers/net/wireless/atmel.c          |    2 
 drivers/net/wireless/atmel_cs.c       |    4 
 include/linux/hdlcdrv.h               |    1 
 47 files changed, 3157 insertions(+), 3663 deletions(-)

through these ChangeSets:

<trivial@rustcorp.com.au> (03/09/25 1.1357)
   [PATCH] [PATCH 2.6.0-test1] remove check_region from drivers_net_3c509.c
   
   From:  Domen Puncer <root@coderock.org>

<buffer@antifork.org> (03/09/25 1.1356)
   [PATCH] saa9730 (minor revision)
   
   Don't know if the patch I released few days ago was still
   applied. This is a minor revision of that patch which converts
   saa9730 to spinlocks thus removing save_and_cli() and
   restore_flags() calls.
   
   Regards,
   Angelo Dell'Aera

<simon@thekelleys.org.uk> (03/09/25 1.1355)
   [PATCH] - atmel wireless driver
   
   This does two things:
   
   1) Fix alignment problem on PARISC64 (and maybe other 64bit archs.)
   2) Add another couple of cards to the table.
   
   Cheers,
   
   Simon.

<p_gortmaker@yahoo.com> (03/09/25 1.1354)
   [PATCH] Remove emacs cruft from 8390 drivers

<p_gortmaker@yahoo.com> (03/09/25 1.1353)
   [PATCH] ne2k_cbus tidy up

<p_gortmaker@yahoo.com> (03/09/25 1.1352)
   [PATCH] ne2k-pci full duplex with RealTek

<shemminger@osdl.org> (03/09/25 1.1351)
   [PATCH] (3/4) baycom/hdlcdrv unregister
   
   If baycom driver has never been opened, it will attempt to free
   an IRQ that it never registered when removed.  The problem is that hdlcdrv
   does not keep track of open/close state.

<shemminger@osdl.org> (03/09/25 1.1350)
   [PATCH] (2/4) baycom c99 initializers

<shemminger@osdl.org> (03/09/25 1.1349)
   [PATCH] (1/4) Update baycom drivers for 2.6
   
   Update baycom drivers for 2.6.0-test5
   	- get rid of MOD_INC/DEC
   	    (looked into hdlcdrv_ops and don't need to have owner field because
   	     baycom drivers unregister on  unload).
   	- use alloc_netdev instead of static device structures.
   	- hdlcdrv_register returns device instead of getting passed one.
   	- put private data in space allocated at dev->priv in alloc_netdev
   	- shorten name of hdlcdrv_register_hdlcdrv to hdlcdrv_register
   
   I don't have actual baycom hardware, but driver builds and loads/unloads.
   Real hardware initialization doesn't happen until open.
   
   The first one is the important patch, the other three are just code review
   type cleanups.

<trivial@rustcorp.com.au> (03/09/25 1.1325.8.23)
   [PATCH] Remove modules.txt drivers_net_pcmcia_Kconfig
   
   From:  Nicolas Kaiser <nikai@nikai.net>

<trivial@rustcorp.com.au> (03/09/25 1.1325.8.22)
   [PATCH] Remove modules.txt drivers_net_wan_Kconfig
   
   From:  Nicolas Kaiser <nikai@nikai.net>

<trivial@rustcorp.com.au> (03/09/25 1.1325.8.21)
   [PATCH] Remove modules.txt drivers_net_tokenring_Kconfig
   
   From:  Nicolas Kaiser <nikai@nikai.net>

<trivial@rustcorp.com.au> (03/09/25 1.1325.8.20)
   [PATCH] Remove modules.txt drivers_net_hamradio_Kconfig
   
   From:  Nicolas Kaiser <nikai@nikai.net>
   
     Cheers, n.

<trivial@rustcorp.com.au> (03/09/25 1.1325.8.19)
   [PATCH] Remove modules.txt drivers_net_arcnet_Kconfig
   
   From:  Nicolas Kaiser <nikai@nikai.net>

<trivial@rustcorp.com.au> (03/09/25 1.1325.8.18)
   [PATCH] Remove modules.txt drivers_net_wireless_Kconfig
   
   From:  Nicolas Kaiser <nikai@nikai.net>

<trivial@rustcorp.com.au> (03/09/25 1.1325.8.17)
   [PATCH] Remove modules.txt drivers_net_tulip_Kconfig
   
   From:  Nicolas Kaiser <nikai@nikai.net>

<trivial@rustcorp.com.au> (03/09/25 1.1325.8.16)
   [PATCH] Remove modules.txt drivers_net_appletalk_Kconfig
   
   From:  Nicolas Kaiser <nikai@nikai.net>

<mlindner@syskonnect.de> (03/09/25 1.1325.8.15)
   [netdrvr sk98lin] fix leaks on error, and related cleanups

<mlindner@syskonnect.de> (03/09/25 1.1325.8.14)
   [netdrvr sk98lin] bump version number

<mlindner@syskonnect.de> (03/09/25 1.1325.8.13)
   [netdrvr sk98lin] small fixes
   
   Patch 3/5 (Update to version 6.17)
   * Add: Removed SkNumber and SkDoDiv
   * Add: Counter output as (unsigned long long)

<mlindner@syskonnect.de> (03/09/25 1.1325.8.12)
   [netdrvr sk98lin] update readme, remove old changelog

<mlindner@syskonnect.de> (03/09/25 1.1325.8.11)
   [netdrvr sk98lin] small updates
   
   
   Patch 1/5 (Update to version 6.17)
   * Add: Better parameter check
   * Add: UDP and TCP HW Csum changes
   * Add: Interrupt Moderation infos

<shemminger@osdl.org> (03/09/25 1.1325.8.10)
   [PATCH] (8/8) arlan -- proper jiffies usage
   
   Add proper management of jiffies and time values, rather than punting
   and doing long long arithmetic on usecs.

<shemminger@osdl.org> (03/09/25 1.1325.8.9)
   [PATCH] (7/8) arlan -- more dead wood removal
   
   Still more driver data which was updated but never used.

<shemminger@osdl.org> (03/09/25 1.1325.8.8)
   [PATCH] (6/8) arlan -- add spinlock
   
   Convert bogus test_and_set local wait, to a real spin_lock so it
   has a chance of working on an SMP.  This also does the right thing
   and locks out interrupts while giving commands on UP;  maybe the
   comment in Kconfig was because there was never a proper mutex...
   
   Don't have real hardware to try this, but it can't be worse than
   the previous code.

<shemminger@osdl.org> (03/09/25 1.1325.8.7)
   [PATCH] (5/8) arlan -- more set never used elements
   
   Still more places state is saved and never used.

<shemminger@osdl.org> (03/09/25 1.1325.8.6)
   [PATCH] (4/8) arlan -- trailing semicolons.
   
   Get rid of extra trailing semicolons

<shemminger@osdl.org> (03/09/25 1.1325.8.5)
   [PATCH] (3/8) arlan -- get rid of unnecessary casts.
   
   Get rid of unneeded casts to cleanup readability.

<shemminger@osdl.org> (03/09/25 1.1325.8.4)
   [PATCH] (2/8) arlan -- get rid of some dead wood
   
   This code is littered with unused structure elements and globals.
   Eliminate some of the fields set and never used.
   
   More in later patches.

<shemminger@osdl.org> (03/09/25 1.1325.8.3)
   [PATCH] (1/8) arlan -- merge arlan-proc with main code
   
   The arlan driver tries to build it's /proc interface into a separate module,
   which leads to circular dependencies and other ugliness.  This patch
   moves arlan.c to arlan-main.c and changes initialization builds one module arlan.o
   
   Patch is for 2.6.0-test5

<mpm@selenic.com> (03/09/24 1.1325.8.2)
   [netdrvr tlan] netif_carrier_* support

<mlindner@syskonnect.de> (03/09/24 1.1325.8.1)
   [netdrvr sk98lin] Remove useless configure options
   
   here is a new version of the sk98lin driver (v6.18) with some changes
   for kernel 2.6.0-test4. This is a diff between the latest patched kernel
   version with sk98lin driver v6.17.
   
   Patch 1/3
   * Remove bogus config stuff


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [bk patches] 2.6.x net driver updates
@ 2003-09-20 19:27 Jeff Garzik
  0 siblings, 0 replies; 28+ messages in thread
From: Jeff Garzik @ 2003-09-20 19:27 UTC (permalink / raw)
  To: torvalds; +Cc: netdev, linux-kernel

First queue push after return from Silly Valley.


Linus, please do a

	bk pull bk://kernel.bkbits.net/jgarzik/net-drivers-2.5

Patch is also available at:

ftp://ftp.kernel.org/pub/linux/kernel/people/jgarzik/patchkits/2.6/2.6.0-test5-bk7-netdrvr1.patch.bz2

This will update the following files:

 drivers/net/irda/smc-ircc.c           | 1258 ----------------------------------
 drivers/net/irda/toshoboe.c           |  957 -------------------------
 Documentation/networking/bonding.txt  |    4 
 drivers/net/3c501.c                   |    6 
 drivers/net/3c505.c                   |   12 
 drivers/net/3c515.c                   |    1 
 drivers/net/Space.c                   |    4 
 drivers/net/acenic.c                  |    3 
 drivers/net/bonding/bond_alb.c        |  150 +++-
 drivers/net/bonding/bond_alb.h        |    8 
 drivers/net/bonding/bond_main.c       | 1202 ++++++++++++++++++++------------
 drivers/net/bonding/bonding.h         |    4 
 drivers/net/cs89x0.c                  |    1 
 drivers/net/depca.c                   |  944 ++++++++++++-------------
 drivers/net/e1000/e1000_main.c        |   13 
 drivers/net/eepro.c                   |    6 
 drivers/net/ewrk3.c                   |    5 
 drivers/net/hamradio/baycom_par.c     |    1 
 drivers/net/hamradio/baycom_ser_fdx.c |    1 
 drivers/net/hamradio/baycom_ser_hdx.c |    1 
 drivers/net/hamradio/hdlcdrv.c        |    1 
 drivers/net/hamradio/scc.c            |  208 +++--
 drivers/net/hamradio/yam.c            |    1 
 drivers/net/ibmlana.c                 |    1 
 drivers/net/irda/Kconfig              |   24 
 drivers/net/irda/Makefile             |    2 
 drivers/net/irda/ali-ircc.c           |   84 --
 drivers/net/irda/donauboe.c           |   50 -
 drivers/net/irda/irda-usb.c           |   44 -
 drivers/net/irda/nsc-ircc.c           |   78 --
 drivers/net/irda/sir_kthread.c        |    4 
 drivers/net/irda/via-ircc.c           |   92 --
 drivers/net/irda/w83977af_ir.c        |   54 -
 drivers/net/lance.c                   |   10 
 drivers/net/mace.c                    |    1 
 drivers/net/ne2.c                     |    1 
 drivers/net/ni5010.c                  |    5 
 drivers/net/ni52.c                    |    5 
 drivers/net/ni65.c                    |    1 
 drivers/net/ns83820.c                 |   10 
 drivers/net/pcmcia/com20020_cs.c      |   41 -
 drivers/net/rcpci45.c                 |    4 
 drivers/net/rrunner.c                 |   17 
 drivers/net/rrunner.h                 |    1 
 drivers/net/sb1000.c                  |    1 
 drivers/net/sis900.c                  |    1 
 drivers/net/sk98lin/h/skdrv1st.h      |    4 
 drivers/net/sk98lin/skge.c            |    1 
 drivers/net/sk_mca.h                  |    2 
 drivers/net/skfp/h/targetos.h         |    1 
 drivers/net/smc9194.c                 |    1 
 drivers/net/tokenring/lanstreamer.h   |    2 
 drivers/net/tokenring/proteon.c       |    2 
 drivers/net/tokenring/skisa.c         |    2 
 drivers/net/tokenring/smctr.c         |    1 
 drivers/net/tokenring/tms380tr.c      |    1 
 drivers/net/wan/comx-hw-comx.c        |    1 
 drivers/net/wan/comx-hw-locomx.c      |    1 
 drivers/net/wan/comx-hw-mixcom.c      |    1 
 drivers/net/wan/comx-hw-munich.c      |    1 
 drivers/net/wan/comx-proto-fr.c       |    1 
 drivers/net/wan/comx-proto-lapb.c     |    1 
 drivers/net/wan/comx-proto-ppp.c      |    1 
 drivers/net/wan/comx.c                |    1 
 drivers/net/wan/cycx_x25.c            |    1 
 drivers/net/wan/dlci.c                |    1 
 drivers/net/wan/dscc4.c               |    1 
 drivers/net/wan/lmc/lmc_ver.h         |    2 
 drivers/net/wan/pc300_drv.c           |    1 
 drivers/net/wan/pc300_tty.c           |    1 
 drivers/net/wan/sbni.c                |   20 
 drivers/net/wan/sdla_chdlc.c          |    1 
 drivers/net/wan/sdla_fr.c             |    1 
 drivers/net/wan/sdla_ft1.c            |    1 
 drivers/net/wan/sdla_ppp.c            |    1 
 drivers/net/wan/sdla_x25.c            |    1 
 drivers/net/wan/sdladrv.c             |    1 
 drivers/net/wan/sdlamain.c            |    1 
 drivers/net/wan/sealevel.c            |  157 ++--
 drivers/net/wan/wanpipe_multppp.c     |    1 
 drivers/net/wd.c                      |    5 
 drivers/net/wireless/airo.c           |   11 
 drivers/net/wireless/arlan-proc.c     |    3 
 drivers/net/wireless/arlan.c          |    1 
 drivers/net/wireless/arlan.h          |    1 
 drivers/net/wireless/strip.c          |    1 
 include/net/syncppp.h                 |    7 
 87 files changed, 1799 insertions(+), 3769 deletions(-)

through these ChangeSets:

<shemminger@osdl.org> (03/09/20 1.1386)
   [PATCH] Road Runner HIPPI driver (rrunner)
   
   Small clean up, to use current APIs.

<achirica@telefonica.net> (03/09/20 1.1385)
   [wireless airo] Fix MIC support with CryptoAPI

<achirica@telefonica.net> (03/09/20 1.1384)
   [wireless airo] fix PCI probe

<jochen@scram.de> (03/09/20 1.1383)
   [tokenring] fix breakage in proteon, skisa
   
   this one fixes both drivers. They have been broken since the
   reorganization in June. Unfortunately, my major build platform (alpha) had
   some issues with later 2.5.X kernels (cache problems causing all kind of
   funny behaviour), so i waited until these problems had been resolved by
   the alpha gurus :-/...
   
   In the mean time i also upgraded pine. I hope the patch corruption issue
   is resolved by now.
   

<shemminger@osdl.org> (03/09/20 1.1382)
   [PATCH] hamradio/scc -
   
   Update hamradio/scc for 2.6.0-test5
   	- use seq_file for /proc
   	- get rid of dev_get()
   	- use alloc_netdev
   
   Don't have hardware, but can load/unload the module fine.

<amir.noam@intel.com> (03/09/20 1.1381)
   [PATCH] [bonding] Convert /proc to seq_file
   
   This patch converts /proc/net/bondX/info into /proc/net/bonding/bondX
   using the seq_file interface.
   
   This is based on Stephen's recent patch, but slightly modified to work
   with the propagation patch set and with some locking changes to make it
   simpler.
   
   The patch applies both on 2.4 (after the sync set from earlier today)
   and on 2.6 (after the propagation set from 2003/11/9).
   
   Amir

<bunk@fs.tum.de> (03/09/20 1.1380)
   [PATCH] fix sbni.c compile with gcc 3.3
   
   sbni.c in 2.6.0-test5 fails to compile with gcc 3.3 with the following
   error:
   
   <--  snip  -->
   
   ...
     CC      drivers/net/wan/sbni.o
   ...
   drivers/net/wan/sbni.c: In function `calc_crc32':
   drivers/net/wan/sbni.c:1568: error: asm-specifier for variable `_crc'
   conflicts with asm clobber list
   make[3]: *** [drivers/net/wan/sbni.o] Error 1
   
   <--  snip  -->
   
   Below is the patch by Margit Schubert-White to fix this issue (it is
   already in 2.4).
   
   cu
   Adrian

<akpm@osdl.org> (03/09/20 1.1379)
   [PATCH] e1000 bug
   
   Rick Lindsley <ricklind@us.ibm.com> wrote:
   >
   > since it's been out for a while you probably already know, but the patch
   > for e1000_main.c has a bug in it.  Looks like it will fail at line 1550 if
   > compiled with NETIF_F_TSO defined.
   >
   
   So it will.  I blame the gcc developers.
   
    25-akpm/drivers/net/e1000/e1000_main.c |   13 +++++++++----
    1 files changed, 9 insertions(+), 4 deletions(-)

<amir.noam@intel.com> (03/09/20 1.1378)
   [PATCH] [bonding 2.6] Fix ipx_hdr compile error

<amir.noam@intel.com> (03/09/20 1.1377)
   [PATCH] [bonding 2.6] Add missing free_netdev()

<amir.noam@intel.com> (03/09/20 1.1376)
   [PATCH] [bonding 2.6] Enhance netdev notification handling

<amir.noam@intel.com> (03/09/20 1.1375)
   [PATCH] [bonding 2.6] Consolidate /proc code, add CHANGENAME handler

<amir.noam@intel.com> (03/09/20 1.1374)
   [PATCH] [bonding 2.6] Add support for changing HW address in ALB/TLB modes

<amir.noam@intel.com> (03/09/20 1.1373)
   [PATCH] [bonding 2.6] Add support for changing HW address and MTU

<amir.noam@intel.com> (03/09/20 1.1372)
   [PATCH] [bonding 2.6] Decouple promiscuous handling from multicast mode setting

<amir.noam@intel.com> (03/09/20 1.1371)
   [PATCH] [bonding 2.6] fix assign_current_slave

<amir.noam@intel.com> (03/09/20 1.1370)
   [PATCH] [bonding 2.6] consolidate change_active operations

<shemminger@osdl.org> (03/09/20 1.1369)
   [PATCH] update arcnet/pcmcia driver
   
   Redo of earlier patch to get rid of MOD_INC/DEC and use alloc_netdev.
   This is against 2.6.0-test5 bk latest.

<shemminger@osdl.org> (03/09/20 1.1368)
   [PATCH] sealevel wan driver
   
   Update sealevel driver to match current net_device interface:
   	- dynamically allocate netdevice and private data.
   	- get rid of MOD_INC/DEC
   	- if_ptr not used
   	- bugfix: not all of board structure was being zeroed.
   
   Note: this driver still doesn't probe() correctly since it just assumes that
   if loaded the hardware is there!
   
   Since I don't have one of these boards...
   tested it by #ifdef'ing out all the bits that touch actual hardware.

<shemminger@osdl.org> (03/09/20 1.1367)
   [IrDA] ali-ircc -- dev_alloc cleanout
   
   Convert ali-ircc driver to:
   	- use alloc_net_dev not dev_alloc
   	- allocate private data at same time
   	- cleanup error unwinds
   	- call free_netdev.
   
   Builds and loads, but don't have real hardware.

<shemminger@osdl.org> (03/09/20 1.1366)
   [IrDA] via-ircc -- dev_alloc cleanout
   
   Convert via-ircc 2.6.0-test5
   	- use alloc_net_dev not dev_alloc
   	- allocate private data at same time
   	- cleanup error unwinds
   	- call free_netdev.
   
   Builds and loads, but don't have real hardware.

<shemminger@osdl.org> (03/09/20 1.1365)
   [IrDA] nsc-ircc -- dev_alloc cleanout
   
   Cleanup nsc-ircc driver for 2.6.0-test5
   	- replace dev_alloc with alloc_netdev
   	- use private data allocated with alloc_netdev
   	- error unwind cleanup

<shemminger@osdl.org> (03/09/20 1.1364)
   [IrDA] donahoboe -- dev_alloc cleanout
   
   Fixes for donauboe for 2.6.0-test5
   	- replace dev_alloc with alloc_netdev
   	- error unwind cleanup

<shemminger@osdl.org> (03/09/20 1.1363)
   [IrDA] w83977af -- dev_alloc cleanout
   
   Yet another irda driver cleanup for 2.6.0-test5
   	- replace dev_alloc with alloc_netdev
   	- use private data allocated with alloc_netdev
   	- use free_netdev

<shemminger@osdl.org> (03/09/20 1.1362)
   [IrDA] irda-usb -- dev_alloc cleanout
   
   Update irda-usb for 2.6.0-test5
   	- use alloc_netdev (but can't use dev->priv area cause that is allocated elsewhere).

<rddunlap@osdl.org> (03/09/20 1.1361)
   [PATCH] janitor: ns83820 error handling
   
   Subject: Re: [Kernel-janitors] [PATCH] insert missing free_irq and fix 	cleanup path
   From: Leann Ogasawara <ogasawara@osdl.org>
   
   On Thu, 2003-09-04 at 13:17, Benjamin LaHaise wrote:
   > The if()s before free are redundant, turf them and it's good.

<rddunlap@osdl.org> (03/09/20 1.1360)
   [PATCH] janitor: insert a missing iounmap()
   
   From: Leann Ogasawara <ogasawara@osdl.org>
   Subject: [Kernel-janitors] [PATCH] insert missing iounmap()
   
   Patch inserts a missing iounmap().

<shemminger@osdl.org> (03/09/20 1.1359)
   [PATCH] get rid of old IRDA drivers.
   
   According to Jean the toshoboe and old smc ircc drivers are no longer needed.
   This patch removes them from 2.6.0-test5

<chrisw@osdl.org> (03/09/20 1.1358)
   [netdrvr] use cpu_relax() in busy loop, or mdelay instead of busy loop
   
   Replace busy loop nop with cpu_relax(), and just use mdelay where it's better.

<rddunlap@osdl.org> (03/09/20 1.1357)
   [PATCH] janitor: remove (or add) unneeded includes (drivers/net/)
   
   From: Randy Hron <rwhron@earthlink.net>

<rddunlap@osdl.org> (03/09/20 1.1356)
   [PATCH] janitor: remove unneeded includes (hamradio)
   
   From: Randy Hron <rwhron@earthlink.net>

<rddunlap@osdl.org> (03/09/20 1.1355)
   [PATCH] janitor: remove (or add) unneeded includes (wireless)
   
   From: Randy Hron <rwhron@earthlink.net>

<rddunlap@osdl.org> (03/09/20 1.1354)
   [PATCH] janitor: remove unneeded includes (skfp)
   
   From: Randy Hron <rwhron@earthlink.net>

<rddunlap@osdl.org> (03/09/20 1.1353)
   [PATCH] janitor: remove (or add) unneeded includes
   
   From: Randy Hron <rwhron@earthlink.net>

<rddunlap@osdl.org> (03/09/20 1.1352)
   [PATCH] janitor: remove unneeded includes (sk98lin)
   
   From: Randy Hron <rwhron@earthlink.net>

<rddunlap@osdl.org> (03/09/20 1.1351)
   [PATCH] janitor: remove unneeded includes (tokenring)
   
   From: Randy Hron <rwhron@earthlink.net>

<shemminger@osdl.org> (03/09/20 1.1350)
   [PATCH] replace sppp_of macro with inline
   
   Replace macro with inline and get some type checking.

<felipewd@terra.com.br> (03/09/20 1.1349)
   [PATCH] Unneeded memory barrier in net/irda code

<mzyngier@freesurf.fr> (03/09/20 1.1348)
   [PATCH] depca update
   
   I finally found some time to hack the depca driver, in basically the
   same way I did with the de4x5 driver. The patch is quite big (shuffles
   a lot of code around, removes lots of global variables), mainly in
   order to use the driver model on every bus supported by this driver.
   
   I also removed the probing from Space.c, so the usual warning about
   device renumbering applies.
   
   Tested on alpha (DE422, EISA) and i386 (two DE201, ISA), built-in and
   modular. The MCA part is completly untested, since I lack the hardware
   (no, I do not own every single piece of junk hardware out
   there... ;-).


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [bk patches] 2.6.x net driver updates
@ 2003-09-11 19:54 Jeff Garzik
  0 siblings, 0 replies; 28+ messages in thread
From: Jeff Garzik @ 2003-09-11 19:54 UTC (permalink / raw)
  To: torvalds, netdev


Linus, please do a

	bk pull bk://kernel.bkbits.net/jgarzik/net-drivers-2.5

The patch may be found at

ftp://ftp.kernel.org/pub/linux/kernel/people/jgarzik/patchkits/2.6/2.6.0-test5-bk2-netdrvr1.patch.bz2

This will update the following files:

 Documentation/networking/ifenslave.c |    1 
 drivers/net/Space.c                  |    5 
 drivers/net/bonding/bond_3ad.c       |   12 
 drivers/net/bonding/bond_3ad.h       |    2 
 drivers/net/bonding/bond_alb.c       |   17 
 drivers/net/bonding/bond_main.c      |  450 ++++---
 drivers/net/bonding/bonding.h        |    2 
 drivers/net/e1000/e1000.h            |    9 
 drivers/net/e1000/e1000_ethtool.c    |   84 +
 drivers/net/e1000/e1000_hw.c         | 2034 +++++++++++++++++++++--------------
 drivers/net/e1000/e1000_hw.h         |  405 ++++--
 drivers/net/e1000/e1000_main.c       |  204 ++-
 drivers/net/e1000/e1000_osdep.h      |    3 
 drivers/net/e1000/e1000_param.c      |   27 
 drivers/net/slip.c                   |    3 
 drivers/net/tokenring/olympic.c      |   37 
 drivers/net/wan/cosa.c               |   50 
 drivers/net/wan/cosa.h               |   12 
 drivers/net/wan/dlci.c               |  183 +--
 drivers/net/wan/sdla.c               |   92 -
 include/linux/if_frad.h              |    3 
 21 files changed, 2201 insertions(+), 1434 deletions(-)

through these ChangeSets:

<romieu@fr.zoreil.com> (03/09/11 1.1312)
   [PATCH] (1/4) sdla - move out of Space.c
   
   Apply on top of 2.6.0-test5-bk1 + Stephen sdla patches. Compiles fine.
   
   
   free_netdev() patrol.
   
   
    drivers/net/wan/sdla.c |    2 +-
    1 files changed, 1 insertion(+), 1 deletion(-)

<shemminger@osdl.org> (03/09/11 1.1311)
   [PATCH] (5/4) dlci netdevice event handling
   
   One more patch, found this in testing
    -- need to delete device from list when unregistered
   because of callback.

<shemminger@osdl.org> (03/09/11 1.1310)
   [PATCH] (4/4) dlci netdevice event handling
   
   Since dlci device is a pseudo device built on top of sdla, change it to
   handle unregister events and delete itself.

<shemminger@osdl.org> (03/09/11 1.1309)
   [PATCH] (3/4) dlci locking and registration changes
   
   Change the locking for the dlci device list and registration.
   - use RTNL instead of a private lock (needed for net notifier in next patch).
   - reorder the checks in the dlci_add to avoid complicated unwinds
   - use dev->destructor to free
   - hold RTNL around deassoc to protect callback from races

<shemminger@osdl.org> (03/09/11 1.1308)
   [PATCH] (2/4) get rid of register_frad
   
   The sdla and dlci drivers have a callback interface which only stores a name
   in a table, but doesn't do anything useful. Looks like an interface which has
   lost it's usefulness and can be safely removed.
   
   Tested on 2.6.0-test5 by exercising the higher layer (dlci) without real hardware.

<shemminger@osdl.org> (03/09/11 1.1307)
   [PATCH] (1/4) sdla - move out of Space.c
   
   Patch against 2.60-test5 to move sdla driver out of Space.c for initialization
   in non-module case.  Since this driver doesn't come up until the device has
   been configured with an ioctl (set_config); there is no way it can have
   startup order problems.

<shemminger@osdl.org> (03/09/11 1.1306)
   [PATCH] fix build of cosa
   
   The cosa driver definition of ioctl's either conflicts or was not picked
   up in the last round of _IOR redefinition (on 2.6.0-test5).
   
   The following makes it build, have no idea if it still works
   on real hardware.

<felipewd@terra.com.br> (03/09/11 1.1305)
   [PATCH] slip.c: current state cleanup

<rddunlap@osdl.org> (03/09/11 1.1304)
   [PATCH] tr/olympic probe: remove #warning, improve error handling
   
   This patch to 2.6.0-test5 removes the #warning in tokenring/olympic.c
   and improves error handling in the probe function.

<scott.feldman@intel.com> (03/09/11 1.1303)
   [e1000] misc whitespace cleanup, changelog
   
   * misc whitespace cleanup, changelog

<scott.feldman@intel.com> (03/09/11 1.1302)
   [e1000] Add PHY master/slave #define override
   
   * Add PHY master/slave #define override to address link issues
     with 82541/7 (rev2) against some low-end switches.  Forcing
     master will improve the time-to-link against these switches.

<scott.feldman@intel.com> (03/09/11 1.1301)
   [e1000] move static to table from .h to .c
   
   * Move static table from hw.h to hw.c to avoid creating a copy
     of table everytime hw.h is included.in .c.

<scott.feldman@intel.com> (03/09/11 1.1300)
   [e1000] cleanup error return codes
   
   * clean up error return code propagation and eliminate redundant
     DEBUGOUT statements.

<scott.feldman@intel.com> (03/09/11 1.1299)
   [e1000] make function our of setting media type
   
   * Consolidate code and make function out of setting media type.

<scott.feldman@intel.com> (03/09/11 1.1298)
   [e1000] add ethtool flow control support
   
   * Add ethtool flow control support

<scott.feldman@intel.com> (03/09/11 1.1297)
   [e1000] read correct bit from EEPROM for getting WoL settings
   
   * Bug fix: read the correct bit from the EEPROM that controls the
     initial setting for WoL after a reset.

<scott.feldman@intel.com> (03/09/11 1.1296)
   [e1000] Turn off ASF support on Fiber nics
   
   * Turn off ASF support on fiber nics.  Wasn't tested and isn't
     known to work, so disable before someone hurts themselves.

<scott.feldman@intel.com> (03/09/11 1.1295)
   [e1000] 82544 PCI-X hang fix + TSO updates
   
   * Bug fix: 82544 hang with PCI-X: if outgoing Tx buffers terminate
     within evenly-aligned dwords, and the device is sharing the bus
     segment with another PCI-X device, 82544 can hang the bus on a
     split-completion transaction.  Fix is to split buffer into two
     buffers with the first one not terminating within evenly-aligned
     dword address, and the second one being 4-bytes, which goes as a
     non-split-conpletion PCI-X transaction.
   * 8254x controllers that support TSO do an internal calculation to
     make sure there is enough FIFO space to handle the overhead
     of each TSO segment before DMA'ing TSO data from host memory.  The
     internal calculation is dependent on the mss of the TSO (defines
     the number of segments), but the reserved space is a constant, so
     we need to adjust the maximum size of each buffer queued to the
     hardware to hold the equation and not overrun the FIFO.  This is
     per TSO because the mss can change from one send to the next.

<scott.feldman@intel.com> (03/09/11 1.1294)
   [e1000] new 82541/5/6/7 hardware support
   
   * Added 82545 (rev3), 82546 (rev3), and 82541/7 (rev2) support
   	- new device IDs
   	- internal SERDES support for 82545/6 (rev3)
   	- don't apply MMRBC workaround for 82545/6 (rev3)
   	- don't use IO mapping for reset for 82545/6 (rev3)

<amir.noam@intel.com> (03/09/11 1.1293)
   [bonding 2.6] misc fixes: missing include, typos, comments

<amir.noam@intel.com> (03/09/11 1.1292)
   [bonding 2.6] make each bond device use its own /proc entry

<amir.noam@intel.com> (03/09/11 1.1291)
   [bonding 2.6] fix error handling in init code

<amir.noam@intel.com> (03/09/11 1.1290)
   [bonding 2.6] embed stats struct inside bonding private struct

<amir.noam@intel.com> (03/09/11 1.1289)
   [bonding 2.6] fix OOPS in bonding driver, when removing primary

<amir.noam@intel.com> (03/09/11 1.1288)
   [bonding 2.6] fix change active command

<amir.noam@intel.com> (03/09/11 1.1287)
   [bonding 2.6] fix kernel panic when optional feature used

<amir.noam@intel.com> (03/09/11 1.1286)
   [bonding 2.6] fix ARP monitoring bug

<amir.noam@intel.com> (03/09/11 1.1285)
   [bonding 2.6] fix load balance problem with high UDP Tx stress

<amir.noam@intel.com> (03/09/11 1.1284)
   [bonding 2.6] fix 802.3ad long fail over with high UDP Tx stress

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [bk patches] 2.6.x net driver updates
  2003-08-08  2:04     ` William Enck
@ 2003-08-08  3:01       ` William Enck
  0 siblings, 0 replies; 28+ messages in thread
From: William Enck @ 2003-08-08  3:01 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-kernel, Christoph Hellwig

On Thu, Aug 07, 2003 at 10:04:16PM -0400, William Enck wrote:
> The first set i was from -test2-bk7 and the second was from your patch.
> Your patch didn't cause the problem. I replied to your email because you
> had updates to orinoco_cs.c and I thought there was a chance your patch
> was supposed to fix it. I guess a reply was not the best thing to do,
> shall I start a new thread?

This looks like it is a totaly separate problem. I tested -mm5 and it
didn't work in there either. I'm going to start a new thread for this.

Will

-- 
William Enck
wenck@wapu.org

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [bk patches] 2.6.x net driver updates
  2003-08-08  1:41   ` Jeff Garzik
@ 2003-08-08  2:04     ` William Enck
  2003-08-08  3:01       ` William Enck
  0 siblings, 1 reply; 28+ messages in thread
From: William Enck @ 2003-08-08  2:04 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-kernel, Christoph Hellwig

On Thu, Aug 07, 2003 at 09:41:01PM -0400, Jeff Garzik wrote:
> William Enck wrote:
> >On Thu, Aug 07, 2003 at 08:05:08PM -0400, Jeff Garzik wrote:
> >
> >>Linus, please do a
> >>
> >>	bk pull bk://kernel.bkbits.net/jgarzik/net-drivers-2.6
> >>
> >>Others may download the patch from
> >>
> >>ftp://ftp.??.kernel.org/pub/linux/kernel/people/jgarzik/patchkits/2.6/2.6.0-test2-bk7-netdrvr1.patch.bz2
> >>
> >>This will update the following files:
> >
> >..snip..
> >
> >>drivers/net/wireless/orinoco_cs.c   |   16 -
> >
> >
> >dmesg gave the folloing with 2.6.0-test2-bk7
> >
> >orinoco.c 0.13e (David Gibson <hermes@gibson.dropbear.id.au> and others)
> >orinoco_cs.c 0.13e (David Gibson <hermes@gibson.dropbear.id.au> and others)
> >orinoco_cs: RequestIRQ: Unsupported mode
> >
> >I thought the above patch might fix it, so I patched and recompiled. I
> >still see the following in 2.6.0-test2-bk7-netdrvr1
> >
> >orinoco_cs.c 0.13e (David Gibson <hermes@gibson.dropbear.id.au> and others)
> >orinoco_cs: RequestIRQ: Unsupported mode
> >
> >The module loaded and worked fine in -test2 and -test2-mm4. 
> 
> 
> Can you test -test2-bk7 (without my patch)?

The first set i was from -test2-bk7 and the second was from your patch.
Your patch didn't cause the problem. I replied to your email because you
had updates to orinoco_cs.c and I thought there was a chance your patch
was supposed to fix it. I guess a reply was not the best thing to do,
shall I start a new thread?

-- 
William Enck
wenck@wapu.org

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [bk patches] 2.6.x net driver updates
  2003-08-08  1:36 ` William Enck
@ 2003-08-08  1:41   ` Jeff Garzik
  2003-08-08  2:04     ` William Enck
  0 siblings, 1 reply; 28+ messages in thread
From: Jeff Garzik @ 2003-08-08  1:41 UTC (permalink / raw)
  To: William Enck; +Cc: linux-kernel, Christoph Hellwig

William Enck wrote:
> On Thu, Aug 07, 2003 at 08:05:08PM -0400, Jeff Garzik wrote:
> 
>>Linus, please do a
>>
>>	bk pull bk://kernel.bkbits.net/jgarzik/net-drivers-2.6
>>
>>Others may download the patch from
>>
>>ftp://ftp.??.kernel.org/pub/linux/kernel/people/jgarzik/patchkits/2.6/2.6.0-test2-bk7-netdrvr1.patch.bz2
>>
>>This will update the following files:
> 
> ..snip..
> 
>> drivers/net/wireless/orinoco_cs.c   |   16 -
> 
> 
> dmesg gave the folloing with 2.6.0-test2-bk7
> 
> orinoco.c 0.13e (David Gibson <hermes@gibson.dropbear.id.au> and others)
> orinoco_cs.c 0.13e (David Gibson <hermes@gibson.dropbear.id.au> and others)
> orinoco_cs: RequestIRQ: Unsupported mode
> 
> I thought the above patch might fix it, so I patched and recompiled. I
> still see the following in 2.6.0-test2-bk7-netdrvr1
> 
> orinoco_cs.c 0.13e (David Gibson <hermes@gibson.dropbear.id.au> and others)
> orinoco_cs: RequestIRQ: Unsupported mode
> 
> The module loaded and worked fine in -test2 and -test2-mm4. 


Can you test -test2-bk7 (without my patch)?

	Jeff




^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [bk patches] 2.6.x net driver updates
  2003-08-08  0:05 Jeff Garzik
@ 2003-08-08  1:36 ` William Enck
  2003-08-08  1:41   ` Jeff Garzik
  0 siblings, 1 reply; 28+ messages in thread
From: William Enck @ 2003-08-08  1:36 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1032 bytes --]

On Thu, Aug 07, 2003 at 08:05:08PM -0400, Jeff Garzik wrote:
> 
> Linus, please do a
> 
> 	bk pull bk://kernel.bkbits.net/jgarzik/net-drivers-2.6
> 
> Others may download the patch from
> 
> ftp://ftp.??.kernel.org/pub/linux/kernel/people/jgarzik/patchkits/2.6/2.6.0-test2-bk7-netdrvr1.patch.bz2
> 
> This will update the following files:
..snip..
>  drivers/net/wireless/orinoco_cs.c   |   16 -

dmesg gave the folloing with 2.6.0-test2-bk7

orinoco.c 0.13e (David Gibson <hermes@gibson.dropbear.id.au> and others)
orinoco_cs.c 0.13e (David Gibson <hermes@gibson.dropbear.id.au> and others)
orinoco_cs: RequestIRQ: Unsupported mode

I thought the above patch might fix it, so I patched and recompiled. I
still see the following in 2.6.0-test2-bk7-netdrvr1

orinoco_cs.c 0.13e (David Gibson <hermes@gibson.dropbear.id.au> and others)
orinoco_cs: RequestIRQ: Unsupported mode

The module loaded and worked fine in -test2 and -test2-mm4. 

Attached is the .config I used for -test2-bk7-netdrvr1

Will

-- 
William Enck
wenck@wapu.org

[-- Attachment #2: config-2.6.0-test2-bk7-netdrvr1 --]
[-- Type: text/plain, Size: 21322 bytes --]

#
# Automatically generated make config: don't edit
#
CONFIG_X86=y
CONFIG_MMU=y
CONFIG_UID16=y
CONFIG_GENERIC_ISA_DMA=y

#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y

#
# General setup
#
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_SYSCTL=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y

#
# Loadable module support
#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_OBSOLETE_MODPARM=y
CONFIG_MODVERSIONS=y
CONFIG_KMOD=y

#
# Processor type and features
#
CONFIG_X86_PC=y
# CONFIG_X86_VOYAGER is not set
# CONFIG_X86_NUMAQ is not set
# CONFIG_X86_SUMMIT is not set
# CONFIG_X86_BIGSMP is not set
# CONFIG_X86_VISWS is not set
# CONFIG_X86_GENERICARCH is not set
# CONFIG_X86_ES7000 is not set
# CONFIG_M386 is not set
# CONFIG_M486 is not set
# CONFIG_M586 is not set
# CONFIG_M586TSC is not set
# CONFIG_M586MMX is not set
# CONFIG_M686 is not set
# CONFIG_MPENTIUMII is not set
# CONFIG_MPENTIUMIII is not set
CONFIG_MPENTIUM4=y
# CONFIG_MK6 is not set
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
# CONFIG_MELAN is not set
# CONFIG_MCRUSOE is not set
# CONFIG_MWINCHIPC6 is not set
# CONFIG_MWINCHIP2 is not set
# CONFIG_MWINCHIP3D is not set
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
# CONFIG_X86_GENERIC is not set
CONFIG_X86_CMPXCHG=y
CONFIG_X86_XADD=y
CONFIG_X86_L1_CACHE_SHIFT=7
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_INVLPG=y
CONFIG_X86_BSWAP=y
CONFIG_X86_POPAD_OK=y
CONFIG_X86_GOOD_APIC=y
CONFIG_X86_INTEL_USERCOPY=y
CONFIG_X86_USE_PPRO_CHECKSUM=y
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_SMP is not set
CONFIG_PREEMPT=y
# CONFIG_X86_UP_APIC is not set
CONFIG_X86_TSC=y
CONFIG_X86_MCE=y
CONFIG_X86_MCE_NONFATAL=y
# CONFIG_TOSHIBA is not set
CONFIG_I8K=y
# CONFIG_MICROCODE is not set
# CONFIG_X86_MSR is not set
# CONFIG_X86_CPUID is not set
# CONFIG_EDD is not set
CONFIG_NOHIGHMEM=y
# CONFIG_HIGHMEM4G is not set
# CONFIG_HIGHMEM64G is not set
# CONFIG_MATH_EMULATION is not set
CONFIG_MTRR=y
CONFIG_HAVE_DEC_LOCK=y

#
# Power management options (ACPI, APM)
#
CONFIG_PM=y
CONFIG_SOFTWARE_SUSPEND=y

#
# ACPI Support
#
CONFIG_ACPI=y
CONFIG_ACPI_BOOT=y
CONFIG_ACPI_SLEEP=y
CONFIG_ACPI_SLEEP_PROC_FS=y
CONFIG_ACPI_AC=y
CONFIG_ACPI_BATTERY=y
CONFIG_ACPI_BUTTON=y
CONFIG_ACPI_FAN=y
CONFIG_ACPI_PROCESSOR=y
CONFIG_ACPI_THERMAL=y
# CONFIG_ACPI_ASUS is not set
# CONFIG_ACPI_TOSHIBA is not set
CONFIG_ACPI_DEBUG=y
CONFIG_ACPI_BUS=y
CONFIG_ACPI_INTERPRETER=y
CONFIG_ACPI_EC=y
CONFIG_ACPI_POWER=y
CONFIG_ACPI_PCI=y
CONFIG_ACPI_SYSTEM=y
# CONFIG_APM is not set

#
# CPU Frequency scaling
#
# CONFIG_CPU_FREQ is not set

#
# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
#
CONFIG_PCI=y
# CONFIG_PCI_GOBIOS is not set
# CONFIG_PCI_GODIRECT is not set
CONFIG_PCI_GOANY=y
CONFIG_PCI_BIOS=y
CONFIG_PCI_DIRECT=y
# CONFIG_PCI_LEGACY_PROC is not set
CONFIG_PCI_NAMES=y
# CONFIG_ISA is not set
# CONFIG_MCA is not set
# CONFIG_SCx200 is not set
CONFIG_HOTPLUG=y

#
# PCMCIA/CardBus support
#
CONFIG_PCMCIA=y
CONFIG_YENTA=y
CONFIG_CARDBUS=y
# CONFIG_I82092 is not set
# CONFIG_TCIC is not set

#
# PCI Hotplug Support
#
# CONFIG_HOTPLUG_PCI is not set

#
# Executable file formats
#
CONFIG_KCORE_ELF=y
# CONFIG_KCORE_AOUT is not set
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_MISC=y

#
# Generic Driver Options
#
# CONFIG_FW_LOADER is not set

#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set

#
# Parallel port support
#
CONFIG_PARPORT=m
# CONFIG_PARPORT_PC is not set
# CONFIG_PARPORT_OTHER is not set
# CONFIG_PARPORT_1284 is not set

#
# Plug and Play support
#
CONFIG_PNP=y
# CONFIG_PNP_DEBUG is not set

#
# Protocols
#
# CONFIG_ISAPNP is not set
CONFIG_PNPBIOS=y

#
# Block devices
#
CONFIG_BLK_DEV_FD=y
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_LBD is not set

#
# ATA/ATAPI/MFM/RLL support
#
CONFIG_IDE=y
CONFIG_BLK_DEV_IDE=y

#
# Please see Documentation/ide.txt for help/info on IDE drives
#
# CONFIG_BLK_DEV_HD_IDE is not set
CONFIG_BLK_DEV_IDEDISK=y
CONFIG_IDEDISK_MULTI_MODE=y
# CONFIG_IDEDISK_STROKE is not set
# CONFIG_BLK_DEV_IDECS is not set
CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_IDE_TASK_IOCTL is not set
# CONFIG_IDE_TASKFILE_IO is not set

#
# IDE chipset support/bugfixes
#
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_IDEPNP is not set
CONFIG_BLK_DEV_IDEPCI=y
CONFIG_IDEPCI_SHARE_IRQ=y
# CONFIG_BLK_DEV_OFFBOARD is not set
CONFIG_BLK_DEV_GENERIC=y
# CONFIG_BLK_DEV_OPTI621 is not set
# CONFIG_BLK_DEV_RZ1000 is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_IDE_TCQ is not set
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
CONFIG_IDEDMA_PCI_AUTO=y
# CONFIG_IDEDMA_ONLYDISK is not set
# CONFIG_IDEDMA_PCI_WIP is not set
CONFIG_BLK_DEV_ADMA=y
# CONFIG_BLK_DEV_AEC62XX is not set
# CONFIG_BLK_DEV_ALI15X3 is not set
# CONFIG_BLK_DEV_AMD74XX is not set
# CONFIG_BLK_DEV_CMD64X is not set
# CONFIG_BLK_DEV_TRIFLEX is not set
# CONFIG_BLK_DEV_CY82C693 is not set
# CONFIG_BLK_DEV_CS5520 is not set
# CONFIG_BLK_DEV_CS5530 is not set
# CONFIG_BLK_DEV_HPT34X is not set
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_SC1200 is not set
CONFIG_BLK_DEV_PIIX=y
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIIMAGE is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_IVB is not set
CONFIG_IDEDMA_AUTO=y
# CONFIG_DMA_NONPCI is not set
# CONFIG_BLK_DEV_HD is not set

#
# SCSI device support
#
# CONFIG_SCSI is not set

#
# Multi-device support (RAID and LVM)
#
# CONFIG_MD is not set

#
# Fusion MPT device support
#

#
# IEEE 1394 (FireWire) support (EXPERIMENTAL)
#
# CONFIG_IEEE1394 is not set

#
# I2O device support
#
# CONFIG_I2O is not set

#
# Networking support
#
CONFIG_NET=y

#
# Networking options
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_NETLINK_DEV=y
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
# CONFIG_IP_MULTICAST is not set
# CONFIG_IP_ADVANCED_ROUTER is not set
# CONFIG_IP_PNP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_ARPD is not set
# CONFIG_INET_ECN is not set
# CONFIG_SYN_COOKIES is not set
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_IPV6 is not set
# CONFIG_DECNET is not set
# CONFIG_BRIDGE is not set
# CONFIG_NETFILTER is not set
# CONFIG_XFRM_USER is not set

#
# SCTP Configuration (EXPERIMENTAL)
#
CONFIG_IPV6_SCTP__=y
# CONFIG_IP_SCTP is not set
# CONFIG_ATM is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_LLC is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set

#
# QoS and/or fair queueing
#
# CONFIG_NET_SCHED is not set

#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
CONFIG_NETDEVICES=y

#
# ARCnet devices
#
# CONFIG_ARCNET is not set
CONFIG_DUMMY=m
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_ETHERTAP is not set
# CONFIG_NET_SB1000 is not set

#
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
CONFIG_NET_VENDOR_3COM=y
CONFIG_VORTEX=y
# CONFIG_TYPHOON is not set

#
# Tulip family network device support
#
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_NET_PCI is not set

#
# Ethernet (1000 Mbit)
#
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
# CONFIG_E1000 is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set

#
# Ethernet (10000 Mbit)
#
# CONFIG_IXGB is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
# CONFIG_PLIP is not set
CONFIG_PPP=m
# CONFIG_PPP_MULTILINK is not set
# CONFIG_PPP_FILTER is not set
CONFIG_PPP_ASYNC=m
CONFIG_PPP_SYNC_TTY=m
CONFIG_PPP_DEFLATE=m
CONFIG_PPP_BSDCOMP=m
CONFIG_PPPOE=m
# CONFIG_SLIP is not set

#
# Wireless LAN (non-hamradio)
#
CONFIG_NET_RADIO=y

#
# Obsolete Wireless cards support (pre-802.11)
#
# CONFIG_STRIP is not set
# CONFIG_PCMCIA_WAVELAN is not set
# CONFIG_PCMCIA_NETWAVE is not set

#
# Wireless 802.11 Frequency Hopping cards support
#
# CONFIG_PCMCIA_RAYCS is not set

#
# Wireless 802.11b ISA/PCI cards support
#
# CONFIG_AIRO is not set
CONFIG_HERMES=m
# CONFIG_PLX_HERMES is not set
# CONFIG_TMD_HERMES is not set
# CONFIG_PCI_HERMES is not set

#
# Wireless 802.11b Pcmcia/Cardbus cards support
#
CONFIG_PCMCIA_HERMES=m
# CONFIG_AIRO_CS is not set
# CONFIG_PCMCIA_ATMEL is not set
# CONFIG_PCMCIA_WL3501 is not set
CONFIG_NET_WIRELESS=y

#
# Token Ring devices (depends on LLC=y)
#
# CONFIG_RCPCI is not set
# CONFIG_SHAPER is not set

#
# Wan interfaces
#
# CONFIG_WAN is not set

#
# PCMCIA network device support
#
CONFIG_NET_PCMCIA=y
# CONFIG_PCMCIA_3C589 is not set
# CONFIG_PCMCIA_3C574 is not set
# CONFIG_PCMCIA_FMVJ18X is not set
# CONFIG_PCMCIA_PCNET is not set
# CONFIG_PCMCIA_NMCLAN is not set
# CONFIG_PCMCIA_SMC91C92 is not set
# CONFIG_PCMCIA_XIRC2PS is not set
# CONFIG_PCMCIA_AXNET is not set

#
# Amateur Radio support
#
# CONFIG_HAMRADIO is not set

#
# IrDA (infrared) support
#
CONFIG_IRDA=m

#
# IrDA protocols
#
# CONFIG_IRLAN is not set
# CONFIG_IRNET is not set
CONFIG_IRCOMM=m
# CONFIG_IRDA_ULTRA is not set

#
# IrDA options
#
# CONFIG_IRDA_CACHE_LAST_LSAP is not set
# CONFIG_IRDA_FAST_RR is not set
# CONFIG_IRDA_DEBUG is not set

#
# Infrared-port device drivers
#

#
# SIR device drivers
#
CONFIG_IRTTY_SIR=m

#
# Dongle support
#
# CONFIG_DONGLE is not set

#
# Old SIR device drivers
#
# CONFIG_IRTTY_OLD is not set
# CONFIG_IRPORT_SIR is not set

#
# Old Serial dongle support
#

#
# FIR device drivers
#
# CONFIG_USB_IRDA is not set
# CONFIG_TOSHIBA_OLD is not set
# CONFIG_TOSHIBA_FIR is not set
# CONFIG_VLSI_FIR is not set

#
# ISDN subsystem
#
# CONFIG_ISDN_BOOL is not set

#
# Telephony Support
#
# CONFIG_PHONE is not set

#
# Input device support
#
CONFIG_INPUT=y

#
# Userland interfaces
#
CONFIG_INPUT_MOUSEDEV=y
CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_TSDEV is not set
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set

#
# Input I/O drivers
#
# CONFIG_GAMEPORT is not set
CONFIG_SOUND_GAMEPORT=y
CONFIG_SERIO=y
CONFIG_SERIO_I8042=y
CONFIG_SERIO_SERPORT=y
# CONFIG_SERIO_CT82C710 is not set
# CONFIG_SERIO_PARKBD is not set
# CONFIG_SERIO_PCIPS2 is not set

#
# Input Device Drivers
#
CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ATKBD=y
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
# CONFIG_MOUSE_SERIAL is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set

#
# Character devices
#
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
# CONFIG_SERIAL_NONSTANDARD is not set

#
# Serial drivers
#
CONFIG_SERIAL_8250=y
# CONFIG_SERIAL_8250_CONSOLE is not set
# CONFIG_SERIAL_8250_CS is not set
# CONFIG_SERIAL_8250_ACPI is not set
# CONFIG_SERIAL_8250_EXTENDED is not set

#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_UNIX98_PTYS=y
CONFIG_UNIX98_PTY_COUNT=256
CONFIG_PRINTER=m
# CONFIG_LP_CONSOLE is not set
# CONFIG_PPDEV is not set
# CONFIG_TIPAR is not set

#
# I2C support
#
# CONFIG_I2C is not set

#
# I2C Hardware Sensors Mainboard support
#

#
# I2C Hardware Sensors Chip support
#
# CONFIG_I2C_SENSOR is not set

#
# Mice
#
# CONFIG_BUSMOUSE is not set
# CONFIG_QIC02_TAPE is not set

#
# IPMI
#
# CONFIG_IPMI_HANDLER is not set

#
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
CONFIG_HW_RANDOM=y
# CONFIG_NVRAM is not set
CONFIG_RTC=m
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_SONYPI is not set

#
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
CONFIG_AGP=y
# CONFIG_AGP_ALI is not set
# CONFIG_AGP_AMD is not set
# CONFIG_AGP_AMD_8151 is not set
CONFIG_AGP_INTEL=y
# CONFIG_AGP_NVIDIA is not set
# CONFIG_AGP_SIS is not set
# CONFIG_AGP_SWORKS is not set
# CONFIG_AGP_VIA is not set
CONFIG_DRM=y
# CONFIG_DRM_TDFX is not set
# CONFIG_DRM_GAMMA is not set
# CONFIG_DRM_R128 is not set
CONFIG_DRM_RADEON=m
# CONFIG_DRM_I810 is not set
# CONFIG_DRM_I830 is not set
# CONFIG_DRM_MGA is not set

#
# PCMCIA character devices
#
# CONFIG_SYNCLINK_CS is not set
# CONFIG_MWAVE is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_HANGCHECK_TIMER is not set

#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set

#
# Digital Video Broadcasting Devices
#
# CONFIG_DVB is not set

#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
CONFIG_EXT3_FS=y
CONFIG_EXT3_FS_XATTR=y
# CONFIG_EXT3_FS_POSIX_ACL is not set
# CONFIG_EXT3_FS_SECURITY is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_FS_MBCACHE=y
CONFIG_REISERFS_FS=y
# CONFIG_REISERFS_CHECK is not set
# CONFIG_REISERFS_PROC_INFO is not set
# CONFIG_JFS_FS is not set
# CONFIG_XFS_FS is not set
CONFIG_MINIX_FS=m
# CONFIG_ROMFS_FS is not set
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
CONFIG_AUTOFS4_FS=y

#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=y
CONFIG_JOLIET=y
# CONFIG_ZISOFS is not set
# CONFIG_UDF_FS is not set

#
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=m
CONFIG_MSDOS_FS=m
CONFIG_VFAT_FS=m
CONFIG_NTFS_FS=m
# CONFIG_NTFS_DEBUG is not set
# CONFIG_NTFS_RW is not set

#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
# CONFIG_DEVFS_FS is not set
CONFIG_DEVPTS_FS=y
# CONFIG_DEVPTS_FS_XATTR is not set
CONFIG_TMPFS=y
CONFIG_RAMFS=y

#
# Miscellaneous filesystems
#
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set

#
# Network File Systems
#
# CONFIG_NFS_FS is not set
# CONFIG_NFSD is not set
# CONFIG_EXPORTFS is not set
CONFIG_SMB_FS=y
CONFIG_SMB_NLS_DEFAULT=y
CONFIG_SMB_NLS_REMOTE="cp437"
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_INTERMEZZO_FS is not set
# CONFIG_AFS_FS is not set

#
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
CONFIG_SMB_NLS=y
CONFIG_NLS=y

#
# Native Language Support
#
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
# CONFIG_NLS_CODEPAGE_850 is not set
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
# CONFIG_NLS_CODEPAGE_860 is not set
# CONFIG_NLS_CODEPAGE_861 is not set
# CONFIG_NLS_CODEPAGE_862 is not set
# CONFIG_NLS_CODEPAGE_863 is not set
# CONFIG_NLS_CODEPAGE_864 is not set
# CONFIG_NLS_CODEPAGE_865 is not set
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_936 is not set
# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_CODEPAGE_932 is not set
# CONFIG_NLS_CODEPAGE_949 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
# CONFIG_NLS_ISO8859_5 is not set
# CONFIG_NLS_ISO8859_6 is not set
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_9 is not set
# CONFIG_NLS_ISO8859_13 is not set
# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_UTF8 is not set

#
# Graphics support
#
CONFIG_FB=y
# CONFIG_FB_CIRRUS is not set
# CONFIG_FB_PM2 is not set
# CONFIG_FB_CYBER2000 is not set
# CONFIG_FB_IMSTT is not set
# CONFIG_FB_VGA16 is not set
CONFIG_FB_VESA=y
CONFIG_VIDEO_SELECT=y
# CONFIG_FB_HGA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_I810 is not set
# CONFIG_FB_MATROX is not set
# CONFIG_FB_RADEON is not set
# CONFIG_FB_ATY128 is not set
# CONFIG_FB_ATY is not set
# CONFIG_FB_SIS is not set
# CONFIG_FB_NEOMAGIC is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_PM3 is not set
# CONFIG_FB_VIRTUAL is not set

#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
# CONFIG_MDA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_PCI_CONSOLE=y
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y

#
# Logo configuration
#
CONFIG_LOGO=y
CONFIG_LOGO_LINUX_MONO=y
# CONFIG_LOGO_LINUX_VGA16 is not set
# CONFIG_LOGO_LINUX_CLUT224 is not set

#
# Sound
#
CONFIG_SOUND=y

#
# Advanced Linux Sound Architecture
#
CONFIG_SND=m
CONFIG_SND_SEQUENCER=m
# CONFIG_SND_SEQ_DUMMY is not set
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=m
CONFIG_SND_PCM_OSS=m
# CONFIG_SND_SEQUENCER_OSS is not set
CONFIG_SND_RTCTIMER=m
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set

#
# Generic devices
#
# CONFIG_SND_DUMMY is not set
# CONFIG_SND_VIRMIDI is not set
# CONFIG_SND_MTPAV is not set
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set

#
# PCI devices
#
# CONFIG_SND_ALI5451 is not set
# CONFIG_SND_AZT3328 is not set
# CONFIG_SND_CS46XX is not set
# CONFIG_SND_CS4281 is not set
# CONFIG_SND_EMU10K1 is not set
# CONFIG_SND_KORG1212 is not set
# CONFIG_SND_NM256 is not set
# CONFIG_SND_RME32 is not set
# CONFIG_SND_RME96 is not set
# CONFIG_SND_RME9652 is not set
# CONFIG_SND_HDSP is not set
# CONFIG_SND_TRIDENT is not set
# CONFIG_SND_YMFPCI is not set
# CONFIG_SND_ALS4000 is not set
# CONFIG_SND_CMIPCI is not set
# CONFIG_SND_ENS1370 is not set
# CONFIG_SND_ENS1371 is not set
# CONFIG_SND_ES1938 is not set
# CONFIG_SND_ES1968 is not set
# CONFIG_SND_MAESTRO3 is not set
# CONFIG_SND_FM801 is not set
# CONFIG_SND_ICE1712 is not set
# CONFIG_SND_ICE1724 is not set
CONFIG_SND_INTEL8X0=m
# CONFIG_SND_SONICVIBES is not set
# CONFIG_SND_VIA82XX is not set
# CONFIG_SND_VX222 is not set

#
# ALSA USB devices
#
# CONFIG_SND_USB_AUDIO is not set

#
# PCMCIA devices
#
# CONFIG_SND_VXPOCKET is not set
# CONFIG_SND_VXP440 is not set

#
# Open Sound System
#
# CONFIG_SOUND_PRIME is not set

#
# USB support
#
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set

#
# Miscellaneous USB options
#
# CONFIG_USB_DEVICEFS is not set
# CONFIG_USB_BANDWIDTH is not set
# CONFIG_USB_DYNAMIC_MINORS is not set

#
# USB Host Controller Drivers
#
# CONFIG_USB_EHCI_HCD is not set
# CONFIG_USB_OHCI_HCD is not set
CONFIG_USB_UHCI_HCD=y

#
# USB Device Class drivers
#
# CONFIG_USB_AUDIO is not set
# CONFIG_USB_BLUETOOTH_TTY is not set
# CONFIG_USB_MIDI is not set
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set

#
# SCSI support is needed for USB Storage
#

#
# USB Human Interface Devices (HID)
#
CONFIG_USB_HID=y
CONFIG_USB_HIDINPUT=y
# CONFIG_HID_FF is not set
CONFIG_USB_HIDDEV=y
# CONFIG_USB_AIPTEK is not set
# CONFIG_USB_WACOM is not set
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
# CONFIG_USB_XPAD is not set

#
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_SCANNER is not set

#
# USB Multimedia devices
#
# CONFIG_USB_DABUSB is not set

#
# Video4Linux support is needed for USB Multimedia device support
#

#
# USB Network adaptors
#
# CONFIG_USB_AX8817X is not set
# CONFIG_USB_CATC is not set
# CONFIG_USB_KAWETH is not set
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_USBNET is not set

#
# USB port drivers
#
# CONFIG_USB_USS720 is not set

#
# USB Serial Converter support
#
# CONFIG_USB_SERIAL is not set

#
# USB Miscellaneous drivers
#
# CONFIG_USB_TIGL is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_BRLVGER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_GADGET is not set

#
# Bluetooth support
#
# CONFIG_BT is not set

#
# Profiling support
#
# CONFIG_PROFILING is not set

#
# Kernel hacking
#
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_STACKOVERFLOW is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_IOVIRT is not set
CONFIG_MAGIC_SYSRQ=y
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_FRAME_POINTER is not set

#
# Security options
#
# CONFIG_SECURITY is not set

#
# Cryptographic options
#
# CONFIG_CRYPTO is not set

#
# Library routines
#
# CONFIG_CRC32 is not set
CONFIG_ZLIB_INFLATE=m
CONFIG_ZLIB_DEFLATE=m
CONFIG_X86_BIOS_REBOOT=y

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [bk patches] 2.6.x net driver updates
@ 2003-08-08  0:05 Jeff Garzik
  2003-08-08  1:36 ` William Enck
  0 siblings, 1 reply; 28+ messages in thread
From: Jeff Garzik @ 2003-08-08  0:05 UTC (permalink / raw)
  To: torvalds; +Cc: linux-kernel, netdev


Linus, please do a

	bk pull bk://kernel.bkbits.net/jgarzik/net-drivers-2.6

Others may download the patch from

ftp://ftp.??.kernel.org/pub/linux/kernel/people/jgarzik/patchkits/2.6/2.6.0-test2-bk7-netdrvr1.patch.bz2

This will update the following files:

 CREDITS                             |   15 +
 MAINTAINERS                         |    8 
 drivers/net/arm/am79c961a.c         |    7 
 drivers/net/arm/ether00.c           |   81 ++++------
 drivers/net/arm/ether1.c            |    9 -
 drivers/net/arm/ether3.c            |    7 
 drivers/net/arm/etherh.c            |   16 +
 drivers/net/pcmcia/3c574_cs.c       |   18 --
 drivers/net/pcmcia/3c589_cs.c       |   18 --
 drivers/net/pcmcia/axnet_cs.c       |   19 --
 drivers/net/pcmcia/com20020_cs.c    |   14 -
 drivers/net/pcmcia/fmvj18x_cs.c     |   18 --
 drivers/net/pcmcia/ibmtr_cs.c       |   15 -
 drivers/net/pcmcia/nmclan_cs.c      |   17 --
 drivers/net/pcmcia/pcnet_cs.c       |   17 --
 drivers/net/pcmcia/smc91c92_cs.c    |   17 --
 drivers/net/pcmcia/xirc2ps_cs.c     |   18 --
 drivers/net/wireless/airo.c         |   33 ++--
 drivers/net/wireless/airo_cs.c      |   22 --
 drivers/net/wireless/netwave_cs.c   |   20 --
 drivers/net/wireless/orinoco_cs.c   |   16 -
 drivers/net/wireless/ray_cs.c       |   22 --
 drivers/net/wireless/wavelan_cs.c   |   15 -
 drivers/net/wireless/wavelan_cs.p.h |    2 
 drivers/net/wireless/wl3501.h       |  244 ++++++++++++++++++------------
 drivers/net/wireless/wl3501_cs.c    |  290 +++++++++++++++++++++++-------------
 26 files changed, 534 insertions(+), 444 deletions(-)

through these ChangeSets:

<jgarzik@redhat.com> (03/08/07 1.1130)
   [netdrvr airo] now that it builds, re-enable wireless_ext

<achirica@telefonica.net> (03/08/07 1.1129)
   [netdrvr airo] Fix adhoc config

<achirica@telefonica.net> (03/08/07 1.1128)
   [netdrvr airo] safer unload code

<achirica@telefonica.net> (03/08/07 1.1127)
   [netdrvr airo] MIC support with newer firmware

<achirica@telefonica.net> (03/08/07 1.1126)
   [netdrvr airo] add missing lines for Wireless Extensions 16

<achirica@telefonica.net> (03/08/07 1.1125)
   [netdrvr airo] MAC type changed to unsigned

<achirica@telefonica.net> (03/08/07 1.1124)
   [netdrvr airo] Missing defines (only for documentation)

<hch@lst.de> (03/08/07 1.1123)
   [netdrvr pcmcia] remove the release timer from all pcmcia net drivers
   
   Ack'd by Russell King as well.

<rmk@arm.linux.org.uk> (03/08/05 1.1106.1.11)
   [netdrvr ARM] alloc_etherdev updates

<acme@conectiva.com.br> (03/07/20 1.1046.409.66)
   o MAINTAINERS: add acme as wl3501 maintainer
   
   Also add Niemeyer to CREDITS for his work on early stages of
   wireless extensions support for the wl3501 card.

<acme@conectiva.com.br> (03/07/20 1.1046.409.65)
   o wl3501: add a first cut, lazy scan triggering for set_scan

<acme@conectiva.com.br> (03/07/20 1.1046.409.64)
   o wl3501: implement {get,set}_scan wireless extensions
   
   set_scan still needs to trigger a scan, but for now doing something
   that resets the card, like iwconfig eth0 mode ad-hoc triggers a
   scanning, and even without that we report the last scan results,
   good enough for now 8) But it will be implemented, don't worry! :-)

<acme@conectiva.com.br> (03/07/20 1.1046.409.63)
   o wl3501: introduce iw_mgmt_data_rset and rate labels enum

<acme@conectiva.com.br> (03/07/20 1.1046.409.62)
   o wl3501: introduce struct iw_mgmt_cf_pset
   
   Just for completeness, it is included in the mgmt frames, but
   not used in this driver, i.e. it may well be that this driver
   supports contention free service, but the original driver had
   no use for it at all.

<acme@conectiva.com.br> (03/07/20 1.1046.409.61)
   o wl3501: introduce iw_mgmt_ibss_pset

<acme@conectiva.com.br> (03/07/20 1.1046.409.60)
   o wl3501: fix bug in iw_mgmt_info_element id field and more
   
   . unfortunately we can't use enum iw_mgmt_info_element_ids for the
     id field in iw_mgmt_info_element, as it has to be u8 and sizeof(enum)
     is bigger than that, but we use the enum in the relevant functions to
     help catch invalid elements being used.
   . also we can't have iw_mgmt_info_element with a fixed size data field,
     as it is variable as per the 802.11 specs, so I do a poor man's OOP
     by subclassing iw_mgmt_info_element into the standard element types. Done
     up to now with iw_mgmt_essid_pset and iw_mgmt_ds_pset, others will follow.

<acme@conectiva.com.br> (03/07/19 1.1046.409.59)
   o wl3501: fix set_essid wireless extension, using the flags for any

<acme@conectiva.com.br> (03/07/19 1.1046.409.58)
   o wl3501: use iw_mgmt_info_element for phy_pset (now ds_parameter_set)
   
   Clarifying stuff is good: with this I have fixed a bug in join, where
   the element id and size were not being set... longstanding one, since
   original driver times...

<acme@conectiva.com.br> (03/07/19 1.1046.409.57)
   o wl3501: introduce iw_mgmt_info_element & associate functions and enums
   
   Also aimed at inclusion on the core wireless extensions, with this we are
   closer to 802.11 specs with regards to frame management elements stuff.
   Next patches will deal with other elements that are done in a raw way such
   as the phys parameter set (DS in this driver).


^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2005-03-09 17:22 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-10-14 19:06 [BK PATCHES] 2.6.x net driver updates Jeff Garzik
  -- strict thread matches above, loose matches on Subject: below --
2005-03-09 17:22 Jeff Garzik
2005-03-08 19:31 Jeff Garzik
2005-03-07 17:10 Jeff Garzik
2005-03-06 23:38 Jeff Garzik
2005-03-05 18:44 Jeff Garzik
2005-01-18  8:15 Jeff Garzik
2005-01-11  5:01 Jeff Garzik
2004-11-05  8:22 Jeff Garzik
2004-10-30 13:32 Jeff Garzik
2004-10-26  5:37 Jeff Garzik
2004-10-25  8:24 Jeff Garzik
2004-10-22  2:11 Jeff Garzik
2004-07-09 20:14 Jeff Garzik
2004-07-02 17:14 Jeff Garzik
2004-07-01  3:54 Jeff Garzik
2004-06-17  1:01 Jeff Garzik
2003-09-28 14:45 [bk patches] " Jeff Garzik
2003-09-27 11:55 [BK PATCHES] " Jeff Garzik
2003-09-26  1:02 [bk patches] " Jeff Garzik
2003-09-27  5:20 ` Linus Torvalds
2003-09-20 19:27 Jeff Garzik
2003-09-11 19:54 Jeff Garzik
2003-08-08  0:05 Jeff Garzik
2003-08-08  1:36 ` William Enck
2003-08-08  1:41   ` Jeff Garzik
2003-08-08  2:04     ` William Enck
2003-08-08  3:01       ` William Enck

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.