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


Marcelo, please do a

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

This will update the following files:

 drivers/net/8139too.c             |    2 
 drivers/net/b44.c                 |   23 +----
 drivers/net/e1000/e1000_main.c    |   30 +++++-
 drivers/net/natsemi.c             |    2 
 drivers/net/pcmcia/xircom_cb.c    |  114 ++++++++++++-------------
 drivers/net/sk98lin/h/skversion.h |   13 +-
 drivers/net/sk98lin/skge.c        |  171 ++++++++++++++++++++++++++------------
 drivers/net/tulip/tulip_core.c    |    1 
 include/linux/ethtool.h           |   11 +-
 include/linux/pci_ids.h           |    1 
 net/core/ethtool.c                |   49 ++++++----
 11 files changed, 254 insertions(+), 163 deletions(-)

through these ChangeSets:

<pp@ee.oulu.fi> (03/10/14 1.1198)
   [PATCH] b44 enable interrupts after tx timeout (2.4.23-pre6)
   
   Here's the 2.4.23-pre6 version, which syncs the driver fully with 2.6.
   Seems to work (tm).

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

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

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

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

<scott.feldman@intel.com> (03/10/14 1.1193)
   [PATCH] hang on ZEROCOPY/TSO when hitting no-Tx-resources
   
   * Critical bug fix: under heavy Tx stress using ZEROCOPY or TSO, if we
     run out of Tx descriptors, we don't calculate for the context
     descriptor used as the first of the ZEROCOPY/TSO send, nor do we clean
     up the context descriptor bits in the case where the send isn't going
     to fit and 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 caused the check for no-Tx-
     resource logic to change, and this bug slipped in.

<scott.feldman@intel.com> (03/10/14 1.1192)
   [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?

<mlindner@syskonnect.de> (03/10/14 1.1191)
   [PATCH] sk98lin-2.4: Driver update to version 6.18
   
   here is a new version of the sk98lin driver (v6.18) with some changes
   for the kernel 2.4.22-bk25.
   
   Patch 1/1
    * Add: New Gigabit LOM vendors (Epox, Gigabyte, Abit, Iwill, ECS, Asus)
    * Add: Better Support for Yukon Plus chipset
    * Fix: IO-control return race condition
    * Fix: Interrupt moderation value check
    * Fix: PCI initialization (SkGeInitPCI)
    * Fix: TCP and UDP HW Checksum calculation

<jgarzik@redhat.com> (03/10/14 1.1190)
   [netdrvr xircom_cb] backport 2.6 changes
   
   * use alloc_etherdev; fixes races in stats pointer setting
     (by Stephen Hemminger)
   * kill unnecessary whitespace and #includes
   * use C99-style initializers
   * speling and irqreturn_t changes





diff -Nru a/drivers/net/8139too.c b/drivers/net/8139too.c
--- a/drivers/net/8139too.c	Tue Oct 14 14:52:41 2003
+++ b/drivers/net/8139too.c	Tue Oct 14 14:52:41 2003
@@ -247,6 +247,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/b44.c b/drivers/net/b44.c
--- a/drivers/net/b44.c	Tue Oct 14 14:52:41 2003
+++ b/drivers/net/b44.c	Tue Oct 14 14:52:41 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,16 +80,7 @@
 
 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[] __devinitdata = {
+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 },
 	{ }	/* terminate list with empty entry */
@@ -870,6 +861,8 @@
 
 	spin_unlock_irq(&bp->lock);
 
+	b44_enable_ints(bp);
+
 	netif_wake_queue(dev);
 }
 
@@ -1393,7 +1386,7 @@
 		strcpy (info.driver, DRV_MODULE_NAME);
 		strcpy (info.version, DRV_MODULE_VERSION);
 		memset(&info.fw_version, 0, sizeof(info.fw_version));
-		strcpy (info.bus_info, pci_dev->slot_name);
+		strcpy (info.bus_info, pci_name(pci_dev));
 		info.eedump_len = 0;
 		info.regdump_len = 0;
 		if (copy_to_user (useraddr, &info, sizeof (info)))
@@ -1834,7 +1827,7 @@
 	iounmap((void *) bp->regs);
 
 err_out_free_dev:
-	kfree(dev);
+	free_netdev(dev);
 
 err_out_free_res:
 	pci_release_regions(pdev);
@@ -1852,7 +1845,7 @@
 	if (dev) {
 		unregister_netdev(dev);
 		iounmap((void *) ((struct b44 *)(dev->priv))->regs);
-		kfree(dev);
+		free_netdev(dev);
 		pci_release_regions(pdev);
 		pci_disable_device(pdev);
 		pci_set_drvdata(pdev, NULL);
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 14:52:41 2003
+++ b/drivers/net/e1000/e1000_main.c	Tue Oct 14 14:52:41 2003
@@ -59,7 +59,7 @@
 
 char e1000_driver_name[] = "e1000";
 char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
-char e1000_driver_version[] = "5.2.16-k1";
+char e1000_driver_version[] = "5.2.16-k2";
 char e1000_copyright[] = "Copyright (c) 1999-2003 Intel Corporation.";
 
 /* e1000_pci_tbl - PCI Device ID Table
@@ -1532,6 +1532,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;
@@ -1622,17 +1623,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,
@@ -1640,8 +1653,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/natsemi.c b/drivers/net/natsemi.c
--- a/drivers/net/natsemi.c	Tue Oct 14 14:52:41 2003
+++ b/drivers/net/natsemi.c	Tue Oct 14 14:52:41 2003
@@ -1528,7 +1528,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/xircom_cb.c b/drivers/net/pcmcia/xircom_cb.c
--- a/drivers/net/pcmcia/xircom_cb.c	Tue Oct 14 14:52:41 2003
+++ b/drivers/net/pcmcia/xircom_cb.c	Tue Oct 14 14:52:41 2003
@@ -14,10 +14,8 @@
  * 	$Id: xircom_cb.c,v 1.33 2001/03/19 14:02:07 arjanv Exp $
  */
 
-
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
@@ -30,12 +28,11 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/ethtool.h>
+
 #include <asm/uaccess.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
 
-
-
 #ifdef DEBUG
 #define enter(x)   printk("Enter: %s, %s line %i\n",x,__FILE__,__LINE__)
 #define leave(x)   printk("Leave: %s, %s line %i\n",x,__FILE__,__LINE__)
@@ -114,7 +111,7 @@
 /* Function prototypes */
 static int xircom_probe(struct pci_dev *pdev, const struct pci_device_id *id);
 static void xircom_remove(struct pci_dev *pdev);
-static void xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
 static int xircom_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int xircom_open(struct net_device *dev);
 static int xircom_close(struct net_device *dev);
@@ -124,7 +121,7 @@
 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);
 static void read_mac_address(struct xircom_private *card);
-static void tranceiver_voodoo(struct xircom_private *card);
+static void transceiver_voodoo(struct xircom_private *card);
 static void initialize_card(struct xircom_private *card);
 static void trigger_transmit(struct xircom_private *card);
 static void trigger_receive(struct xircom_private *card);
@@ -143,17 +140,19 @@
 
 
 
-static struct pci_device_id xircom_pci_table[] __devinitdata = {
+static struct pci_device_id xircom_pci_table[] = {
 	{0x115D, 0x0003, PCI_ANY_ID, PCI_ANY_ID,},
 	{0,},
 };
 MODULE_DEVICE_TABLE(pci, xircom_pci_table);
 
 static struct pci_driver xircom_ops = {
-	name:		"xircom_cb", 
-	id_table:	xircom_pci_table, 
-	probe:		xircom_probe, 
-	remove:		__devexit_p(xircom_remove),
+	.name		= "xircom_cb", 
+	.id_table	= xircom_pci_table, 
+	.probe		= xircom_probe, 
+	.remove		= xircom_remove, 
+	.suspend =NULL,
+	.resume =NULL
 };
 
 
@@ -226,40 +225,32 @@
 		return -ENODEV;
 	}
 
-	
 	/* 
 	   Before changing the hardware, allocate the memory.
 	   This way, we can fail gracefully if not enough memory
 	   is available. 
 	 */
-	private = kmalloc(sizeof(*private),GFP_KERNEL);
-	memset(private, 0, sizeof(struct xircom_private));
+	dev = alloc_etherdev(sizeof(struct xircom_private));
+	if (!dev) {
+		printk(KERN_ERR "xircom_probe: failed to allocate etherdev\n");
+		goto device_fail;
+	}
+	private = dev->priv;
 	
 	/* Allocate the send/receive buffers */
 	private->rx_buffer = pci_alloc_consistent(pdev,8192,&private->rx_dma_handle);
-	
 	if (private->rx_buffer == NULL) {
  		printk(KERN_ERR "xircom_probe: no memory for rx buffer \n");
- 		kfree(private);
-		return -ENODEV;
+		goto rx_buf_fail;
 	}	
 	private->tx_buffer = pci_alloc_consistent(pdev,8192,&private->tx_dma_handle);
 	if (private->tx_buffer == NULL) {
 		printk(KERN_ERR "xircom_probe: no memory for tx buffer \n");
-		kfree(private->rx_buffer);
-		kfree(private);
-		return -ENODEV;
-	}
-	dev = init_etherdev(dev, 0);
-	if (dev == NULL) {
-		printk(KERN_ERR "xircom_probe: failed to allocate etherdev\n");
-		kfree(private->rx_buffer);
-		kfree(private->tx_buffer);
-		kfree(private);
-		return -ENODEV;
+		goto tx_buf_fail;
 	}
+
 	SET_MODULE_OWNER(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;
@@ -267,11 +258,11 @@
 	private->lock = SPIN_LOCK_UNLOCKED;
 	dev->irq = pdev->irq;
 	dev->base_addr = private->io_port;
-
+	
 	initialize_card(private);
 	read_mac_address(private);
 	setup_descriptors(private);
-
+	
 	dev->open = &xircom_open;
 	dev->hard_start_xmit = &xircom_start_xmit;
 	dev->stop = &xircom_close;
@@ -280,19 +271,34 @@
 	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 */
-	tranceiver_voodoo(private);
-
+	transceiver_voodoo(private);
+	
 	spin_lock_irqsave(&private->lock,flags);
-	  activate_transmitter(private);
-	  activate_receiver(private);
+	activate_transmitter(private);
+	activate_receiver(private);
 	spin_unlock_irqrestore(&private->lock,flags);
-
+	
 	trigger_receive(private);
-
+	
 	leave("xircom_probe");
 	return 0;
+
+reg_fail:
+	kfree(private->tx_buffer);
+tx_buf_fail:
+	kfree(private->rx_buffer);
+rx_buf_fail:
+	free_netdev(dev);
+device_fail:
+	return -ENODEV;
 }
 
 
@@ -305,27 +311,20 @@
 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;			
-		}
-		kfree(card);
-	}
+	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);
-	kfree(dev);
+	free_netdev(dev);
+	pci_set_drvdata(pdev, NULL);
 	leave("xircom_remove");
 } 
 
-static void xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
+static irqreturn_t xircom_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *) dev_instance;
 	struct xircom_private *card = (struct xircom_private *) dev->priv;
@@ -369,6 +368,7 @@
 	
 	spin_unlock(&card->lock);
 	leave("xircom_interrupt");
+	return IRQ_HANDLED;
 }
 
 static int xircom_start_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -1022,7 +1022,7 @@
 
 
 /* 
-link_status() checks the link's status and will return 0 for no link, 10 for 10mbit link and 100 for.. guess what.
+link_status() checks the the links status and will return 0 for no link, 10 for 10mbit link and 100 for.. guess what.
 
 Must be called in locked state with interrupts disabled
 */
@@ -1097,15 +1097,15 @@
 
 
 /*
- tranceiver_voodoo() enables the external UTP plug thingy.
+ transceiver_voodoo() enables the external UTP plug thingy.
  it's called voodoo as I stole this code and cannot cross-reference
  it with the specification.
  */
-static void tranceiver_voodoo(struct xircom_private *card)
+static void transceiver_voodoo(struct xircom_private *card)
 {
 	unsigned long flags;
 
-	enter("tranceiver_voodoo");
+	enter("transceiver_voodoo");
 
 	/* disable all powermanagement */
 	pci_write_config_dword(card->pdev, PCI_POWERMGMT, 0x0000);
@@ -1124,7 +1124,7 @@
         spin_unlock_irqrestore(&card->lock, flags);
 
 	netif_start_queue(card->dev);
-	leave("tranceiver_voodoo");
+	leave("transceiver_voodoo");
 }
 
 
diff -Nru a/drivers/net/sk98lin/h/skversion.h b/drivers/net/sk98lin/h/skversion.h
--- a/drivers/net/sk98lin/h/skversion.h	Tue Oct 14 14:52:41 2003
+++ b/drivers/net/sk98lin/h/skversion.h	Tue Oct 14 14:52:41 2003
@@ -2,8 +2,8 @@
  *
  * Name:	version.h
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.2 $
- * Date:	$Date: 2003/08/13 12:01:01 $
+ * Version:	$Revision: 1.3 $
+ * Date:	$Date: 2003/08/25 13:34:48 $
  * Purpose:	SK specific Error log support
  *
  ******************************************************************************/
@@ -25,6 +25,9 @@
  *
  * History:
  *	$Log: skversion.h,v $
+ *	Revision 1.3  2003/08/25 13:34:48  mlindner
+ *	Fix: Lint changes
+ *	
  *	Revision 1.2  2003/08/13 12:01:01  mlindner
  *	Add: Changes for Lint
  *	
@@ -51,12 +54,12 @@
 #ifdef	lint
 static const char SysKonnectFileId[] = "@(#) (C) SysKonnect GmbH.";
 static const char SysKonnectBuildNumber[] =
-	"@(#)SK-BUILD: 6.17 PL: 01"; 
+	"@(#)SK-BUILD: 6.18 PL: 01"; 
 #endif	/* !defined(lint) */
 
-#define BOOT_STRING	"sk98lin: Network Device Driver v6.17\n" \
+#define BOOT_STRING	"sk98lin: Network Device Driver v6.18\n" \
 			"(C)Copyright 1999-2003 Marvell(R)."
 
-#define VER_STRING	"6.17"
+#define VER_STRING	"6.18"
 
 
diff -Nru a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
--- a/drivers/net/sk98lin/skge.c	Tue Oct 14 14:52:41 2003
+++ b/drivers/net/sk98lin/skge.c	Tue Oct 14 14:52:41 2003
@@ -56,6 +56,18 @@
  * History:
  *
  *	$Log: skge.c,v $
+ *	Revision 1.16  2003/09/23 11:07:35  mlindner
+ *	Fix: IO-control return race condition
+ *	Fix: Interrupt moderation value check
+ *	
+ *	Revision 1.15  2003/09/22 08:40:05  mlindner
+ *	Add: Added DRIVER_FILE_NAME and DRIVER_REL_DATE
+ *	
+ *	Revision 1.14  2003/09/22 08:11:10  mlindner
+ *	Add: New function for PCI initialization (SkGeInitPCI)
+ *	Add: Yukon Plus changes (ChipID, PCI...)
+ *	Fix: TCP and UDP Checksum calculation
+ *	
  *	Revision 1.11  2003/08/26 16:05:19  mlindner
  *	Fix: Compiler warnings (void *)
  *	
@@ -551,6 +563,7 @@
 static int	SkGeChangeMtu(struct SK_NET_DEVICE *dev, int new_mtu);
 static void	PortReInitBmu(SK_AC*, int);
 static int	SkGeIocMib(DEV_NET*, unsigned int, int);
+static int	SkGeInitPCI(SK_AC *pAC);
 static void	StartDrvCleanupTimer(SK_AC *pAC);
 static void	StopDrvCleanupTimer(SK_AC *pAC);
 static int	XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*);
@@ -620,10 +633,10 @@
 	SK_AC			*pAC;
 	DEV_NET			*pNet = NULL;
 	struct pci_dev	*pdev = NULL;
-	unsigned long		base_address;
 	struct SK_NET_DEVICE *dev = NULL;
 	SK_BOOL DeviceFound = SK_FALSE;
 	SK_BOOL BootStringCount = SK_FALSE;
+	int			retval;
 #ifdef CONFIG_PROC_FS
 	int			proc_root_initialized = 0;
 	struct proc_dir_entry	*pProcFile;
@@ -668,6 +681,8 @@
 		pNet = dev->priv;
 		pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
 		if (pNet->pAC == NULL){
+			dev->get_stats = NULL;
+			unregister_netdev(dev);
 			kfree(dev->priv);
 			printk(KERN_ERR "Unable to allocate adapter "
 			       "structure!\n");
@@ -694,6 +709,14 @@
 		pNet->Mtu = 1500;
 		pNet->Up = 0;
 		dev->irq = pdev->irq;
+		retval = SkGeInitPCI(pAC);
+		if (retval) {
+			printk("SKGE: PCI setup failed: %i\n", retval);
+			dev->get_stats = NULL;
+			unregister_netdev(dev);
+			kfree(dev);
+			continue;
+		}
 
 		dev->open =		&SkGeOpen;
 		dev->stop =		&SkGeClose;
@@ -716,41 +739,6 @@
 #endif
 #endif
 
-		/*
-		 * Dummy value.
-		 */
-		dev->base_addr = 42;
-		pci_set_master(pdev);
-
-		pci_set_master(pdev);
-		base_address = pci_resource_start (pdev, 0);
-
-#ifdef SK_BIG_ENDIAN
-		/*
-		 * On big endian machines, we use the adapter's aibility of
-		 * reading the descriptors as big endian.
-		 */
-		{
-		SK_U32		our2;
-			SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2);
-			our2 |= PCI_REV_DESC;
-			SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2);
-		}
-#endif
-
-		/*
-		 * Remap the regs into kernel space.
-		 */
-		pAC->IoBase = (char*)ioremap(base_address, 0x4000);
-
-		if (!pAC->IoBase){
-			printk(KERN_ERR "%s:  Unable to map I/O register, "
-			       "SK 98xx No. %i will be disabled.\n",
-			       dev->name, boards_found);
-			kfree(dev);
-			break;
-		}
-
 		pAC->Index = boards_found;
 		if (SkGeBoardInit(dev, pAC)) {
 			FreeResources(dev);
@@ -887,6 +875,68 @@
 } /* skge_probe */
 
 
+
+/*****************************************************************************
+ *
+ * 	SkGeInitPCI - Init the PCI resources
+ *
+ * Description:
+ *	This function initialize the PCI resources and IO
+ *
+ * Returns: N/A
+ *	
+ */
+int SkGeInitPCI(SK_AC *pAC)
+{
+	struct SK_NET_DEVICE *dev = pAC->dev[0];
+	struct pci_dev *pdev = pAC->PciDev;
+	int retval;
+
+	if (pci_enable_device(pdev) != 0) {
+		return 1;
+	}
+
+	dev->mem_start = pci_resource_start (pdev, 0);
+	pci_set_master(pdev);
+
+	if (pci_request_regions(pdev, pAC->Name) != 0) {
+		retval = 2;
+		goto out_disable;
+	}
+
+#ifdef SK_BIG_ENDIAN
+	/*
+	 * On big endian machines, we use the adapter's aibility of
+	 * reading the descriptors as big endian.
+	 */
+	{
+		SK_U32		our2;
+		SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2);
+		our2 |= PCI_REV_DESC;
+		SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2);
+	}
+#endif
+
+	/*
+	 * Remap the regs into kernel space.
+	 */
+	pAC->IoBase = (char*)ioremap_nocache(dev->mem_start, 0x4000);
+
+	if (!pAC->IoBase){
+		retval = 3;
+		goto out_release;
+	}
+
+	return 0;
+
+ out_release:
+	pci_release_regions(pdev);
+ out_disable:
+	pci_disable_device(pdev);
+	return retval;
+}
+
+
 /*****************************************************************************
  *
  * 	FreeResources - release resources allocated for adapter
@@ -908,6 +958,9 @@
 		pNet = (DEV_NET*) dev->priv;
 		pAC = pNet->pAC;
 		AllocFlag = pAC->AllocFlag;
+		if (pAC->PciDev) {
+			pci_release_regions(pAC->PciDev);
+		}
 		if (AllocFlag & SK_ALLOC_IRQ) {
 			free_irq(dev->irq, dev);
 		}
@@ -2172,7 +2225,7 @@
 	*/
 	if (BytesSend < C_LEN_ETHERNET_MINSIZE) {
 	    skb_put(pMessage, (C_LEN_ETHERNET_MINSIZE-BytesSend));
-	    memset( ((int *)(pMessage->data))+BytesSend,
+	    SK_MEMSET( ((char *)(pMessage->data))+BytesSend,
 	            0, C_LEN_ETHERNET_MINSIZE-BytesSend);
 	}
 
@@ -2205,10 +2258,12 @@
 
 	if (pMessage->ip_summed == CHECKSUM_HW) {
 		Protocol = ((SK_U8)pMessage->data[C_OFFSET_IPPROTO] & 0xff);
-		if ((Protocol == C_PROTO_ID_UDP) && (pAC->GIni.GIChipRev != 0)) {
-			pTxd->TBControl = BMU_UDP_CHECK;
+		if ((Protocol == C_PROTO_ID_UDP) && 
+			(pAC->GIni.GIChipRev == 0) &&
+			(pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
+			pTxd->TBControl = BMU_TCP_CHECK;
 		} else {
-			pTxd->TBControl = BMU_TCP_CHECK ;
+			pTxd->TBControl = BMU_UDP_CHECK;
 		}
 
 		IpHeaderLength  = (SK_U8)pMessage->data[C_OFFSET_IPHEADER];
@@ -2232,7 +2287,7 @@
 #ifdef USE_TX_COMPLETE
 				   BMU_IRQ_EOF |
 #endif
-				   pMessage->len;
+			pMessage->len;
 	}
 
 	/* 
@@ -2333,10 +2388,12 @@
 		** (Revision 2.0)
 		*/
 		Protocol = ((SK_U8)pMessage->data[C_OFFSET_IPPROTO] & 0xff);
-		if ((Protocol == C_PROTO_ID_UDP) && (pAC->GIni.GIChipRev != 0)) {
-			pTxd->TBControl |= BMU_UDP_CHECK;
+		if ((Protocol == C_PROTO_ID_UDP) && 
+			(pAC->GIni.GIChipRev == 0) &&
+			(pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
+			pTxd->TBControl |= BMU_TCP_CHECK;
 		} else {
-			pTxd->TBControl |= BMU_TCP_CHECK ;
+			pTxd->TBControl |= BMU_UDP_CHECK;
 		}
 
 		IpHeaderLength  = ((SK_U8)pMessage->data[C_OFFSET_IPHEADER] & 0xf)*4;
@@ -2383,11 +2440,12 @@
 			** opcode for udp is not working in the hardware yet 
 			** (revision 2.0)
 			*/
-			if ( (Protocol == C_PROTO_ID_UDP) && 
-			     (pAC->GIni.GIChipRev != 0) ) {
-				pTxd->TBControl |= BMU_UDP_CHECK ;
+			if ((Protocol == C_PROTO_ID_UDP) && 
+				(pAC->GIni.GIChipRev == 0) &&
+				(pAC->GIni.GIChipId == CHIP_ID_YUKON)) {
+				pTxd->TBControl |= BMU_TCP_CHECK;
 			} else {
-				pTxd->TBControl |= BMU_TCP_CHECK ;
+				pTxd->TBControl |= BMU_UDP_CHECK;
 			}
 		} else {
 			pTxd->TBControl = BMU_CHECK | BMU_SW | BMU_OWN;
@@ -3616,21 +3674,26 @@
 			Length = sizeof(pAC->PnmiStruct) + HeaderLength;
 		}
 		if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) {
-			return -EFAULT;
+			return -ENOMEM;
 		}
 		if(copy_from_user(pMemBuf, Ioctl.pData, Length)) {
-			return -EFAULT;
+			Err = -EFAULT;
+			goto fault_gen;
 		}
 		if ((Ret = SkPnmiGenIoctl(pAC, pAC->IoBase, pMemBuf, &Length, 0)) < 0) {
-			return -EFAULT;
+			Err = -EFAULT;
+			goto fault_gen;
 		}
 		if(copy_to_user(Ioctl.pData, pMemBuf, Length) ) {
-			return -EFAULT;
+			Err = -EFAULT;
+			goto fault_gen;
 		}
 		Ioctl.Len = Length;
 		if(copy_to_user(rq->ifr_data, &Ioctl, sizeof(SK_GE_IOCTL))) {
-			return -EFAULT;
+			Err = -EFAULT;
+			goto fault_gen;
 		}
+fault_gen:
 		kfree(pMemBuf); /* cleanup everything */
 		break;
 	default:
@@ -4370,7 +4433,7 @@
         }
 
         if (IntsPerSec[pAC->Index] != 0) {
-           if ((IntsPerSec[pAC->Index]< 30)&&(IntsPerSec[pAC->Index]> 40000)) {
+           if ((IntsPerSec[pAC->Index]< 30) || (IntsPerSec[pAC->Index]> 40000)) {
               pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT;
            } else {
               pAC->DynIrqModInfo.MaxModIntsPerSec = IntsPerSec[pAC->Index];
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 14:52:41 2003
+++ b/drivers/net/tulip/tulip_core.c	Tue Oct 14 14:52:41 2003
@@ -229,6 +229,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 },
 	{ 0x14f1, 0x1803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CONEXANT },
 	{ 0x10b9, 0x5261, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X },	/* ALi 1563 integrated ethernet */
diff -Nru a/include/linux/ethtool.h b/include/linux/ethtool.h
--- a/include/linux/ethtool.h	Tue Oct 14 14:52:41 2003
+++ b/include/linux/ethtool.h	Tue Oct 14 14:52:41 2003
@@ -303,14 +303,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 *);
@@ -324,6 +324,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/include/linux/pci_ids.h b/include/linux/pci_ids.h
--- a/include/linux/pci_ids.h	Tue Oct 14 14:52:41 2003
+++ b/include/linux/pci_ids.h	Tue Oct 14 14:52:41 2003
@@ -1669,6 +1669,7 @@
 #define PCI_DEVICE_ID_TIGON3_5703A3	0x16c7
 #define PCI_DEVICE_ID_TIGON3_5901	0x170d
 #define PCI_DEVICE_ID_TIGON3_5901_2	0x170e
+#define PCI_DEVICE_ID_BCM4401		0x4401
 
 #define PCI_VENDOR_ID_SYBA		0x1592
 #define PCI_DEVICE_ID_SYBA_2P_EPP	0x0782
diff -Nru a/net/core/ethtool.c b/net/core/ethtool.c
--- a/net/core/ethtool.c	Tue Oct 14 14:52:41 2003
+++ b/net/core/ethtool.c	Tue Oct 14 14:52:41 2003
@@ -106,7 +106,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;
@@ -229,29 +230,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;
@@ -269,32 +275,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] 7+ messages in thread

* [BK PATCHES] 2.4.x net driver updates
@ 2005-04-27 21:17 Jeff Garzik
  0 siblings, 0 replies; 7+ messages in thread
From: Jeff Garzik @ 2005-04-27 21:17 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: netdev, linux-kernel


Ditto for net drivers... this is my last 'bk pull' request for you,
before we both (presumably) switch to git.

Please do a

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

This will update the following files:

 drivers/net/bonding/bond_main.c |   15 +++++++++++----
 drivers/net/pcnet32.c           |    3 ++-
 2 files changed, 13 insertions(+), 5 deletions(-)

through these ChangeSets:

<willy@w.ods.org> (05/03/30 1.1448.129.2)
   [PATCH] bonding fix
   
   It fixes a stack dump when unloading the bonding module in 802.3ad mode
   if spinlock debugging is turned on, and it was already merged in 2.6.
   
   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>

<brazilnut@us.ibm.com> (05/03/30 1.1448.129.1)
   [PATCH] pcnet32: 79C975 fiber fix
   
   From: "HARDY, Steven" <steven.hardy@astrium.eads.net>
   
   I have found a bug in the pcnet32 driver (drivers/net/pcnet32.c)
   affecting all ethernet cards based on the AMD79C975 chip, using the
   fiber interface.
   
   It's a one line fix, where some config registers get corrupted during
   initialisation (which stops the Fiber interface working with this chip)
   
   This bug was introduced somewhere betweeen 2.4.17 and 2.6.x (noticed
   whilst upgrading to 2.6), and it may affect other chips too.  I have
   checked all versions up to 2.6.11-bk6 and they are all broken.
   
   Signed-off-by: Andrew Morton <akpm@osdl.org>
   Signed-off-by: Don Fry <brazilnut@us.ibm.com>
   Signed-off-by: Jeff Garzik <jgarzik@pobox.com>

diff -Nru a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
--- a/drivers/net/bonding/bond_main.c	2005-04-27 17:16:28 -04:00
+++ b/drivers/net/bonding/bond_main.c	2005-04-27 17:16:28 -04:00
@@ -469,6 +469,13 @@
  *	  * Add support for VLAN hardware acceleration capable slaves.
  *	  * Add capability to tag self generated packets in ALB/TLB modes.
  *	  Set version to 2.6.0.
+ * 2004/10/29 - Mitch Williams <mitch.a.williams at intel dot com>
+ *	- Fixed bug when unloading module while using 802.3ad.  If
+ *	  spinlock debugging is turned on, this causes a stack dump.
+ *	  Solution is to move call to dev_remove_pack outside of the
+ *	  spinlock.
+ *	  Set version to 2.6.1.
+ *
  */
 
 //#define BONDING_DEBUG 1
@@ -3565,14 +3572,14 @@
 {
 	struct bonding *bond = bond_dev->priv;
 
-	write_lock_bh(&bond->lock);
-
-	bond_mc_list_destroy(bond);
-
 	if (bond->params.mode == BOND_MODE_8023AD) {
 		/* Unregister the receive of LACPDUs */
 		bond_unregister_lacpdu(bond);
 	}
+
+	write_lock_bh(&bond->lock);
+
+	bond_mc_list_destroy(bond);
 
 	/* signal timers not to re-arm */
 	bond->kill_timers = 1;
diff -Nru a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
--- a/drivers/net/pcnet32.c	2005-04-27 17:16:28 -04:00
+++ b/drivers/net/pcnet32.c	2005-04-27 17:16:28 -04:00
@@ -1348,7 +1348,8 @@
 	printk(KERN_INFO "%s: registered as %s\n", dev->name, lp->name);
     cards_found++;
 
-    a->write_bcr(ioaddr, 2, 0x1002);	/* enable LED writes */
+    /* enable LED writes */
+    a->write_bcr(ioaddr, 2, a->read_bcr(ioaddr, 2) | 0x1000);
 
     return 0;
 

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

* [BK PATCHES] 2.4.x net driver updates
@ 2005-03-04  0:33 Jeff Garzik
  0 siblings, 0 replies; 7+ messages in thread
From: Jeff Garzik @ 2005-03-04  0:33 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Netdev

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



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

Please do a

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

This will update the following files:

 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      |   12 +
 drivers/net/e1000/e1000_main.c    |  251 ++++++++++++++++++++++++++++++++++----
 drivers/net/tulip/21142.c         |    2 
 drivers/net/tulip/eeprom.c        |    1 
 drivers/net/tulip/interrupt.c     |    2 
 drivers/net/tulip/media.c         |    1 
 drivers/net/tulip/pnic.c          |    1 
 drivers/net/tulip/pnic2.c         |    2 
 drivers/net/tulip/timer.c         |    1 
 drivers/net/tulip/tulip.h         |   15 ++
 drivers/net/tulip/tulip_core.c    |    2 
 14 files changed, 312 insertions(+), 78 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: 2 use netif_poll_{enable|disable}
  o e1000: 1 Robert Olsson's fix and

John W. Linville:
  o tulip: make tulip_stop_rxtx() wait for DMA to fully stop


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

diff -Nru a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
--- a/drivers/net/e1000/e1000.h	2005-03-03 19:33:21 -05:00
+++ b/drivers/net/e1000/e1000.h	2005-03-03 19:33:21 -05:00
@@ -140,6 +140,7 @@
 #define E1000_RX_BUFFER_WRITE	16	/* Must be power of 2 */
 
 #define AUTO_ALL_MODES       0
+#define E1000_EEPROM_82544_APM 0x0004
 #define E1000_EEPROM_APME    0x0400
 
 #ifndef E1000_MASTER_SLAVE
@@ -211,6 +212,7 @@
 
 	/* TX */
 	struct e1000_desc_ring tx_ring;
+	struct e1000_buffer previous_buffer_info;
 	spinlock_t tx_lock;
 	uint32_t txd_cmd;
 	uint32_t tx_int_delay;
@@ -224,6 +226,7 @@
 	uint32_t tx_fifo_size;
 	atomic_t tx_fifo_stall;
 	boolean_t pcix_82544;
+	boolean_t detect_tx_hung;
 
 	/* RX */
 	struct e1000_desc_ring rx_ring;
diff -Nru a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
--- a/drivers/net/e1000/e1000_ethtool.c	2005-03-03 19:33:21 -05:00
+++ b/drivers/net/e1000/e1000_ethtool.c	2005-03-03 19:33:21 -05:00
@@ -1309,7 +1309,7 @@
 	struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
 	struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
 	struct pci_dev *pdev = adapter->pdev;
-	int i;
+	int i, ret_val;
 
 	E1000_WRITE_REG(&adapter->hw, RDT, rxdr->count - 1);
 
@@ -1329,11 +1329,12 @@
 					    rxdr->buffer_info[i].length,
 					    PCI_DMA_FROMDEVICE);
 
-		if (!e1000_check_lbtest_frame(rxdr->buffer_info[i++].skb, 1024))
-			return 0;
-	} while (i < 64);
+		ret_val = e1000_check_lbtest_frame(rxdr->buffer_info[i].skb,
+						   1024);
+		i++;
+	} while (ret_val != 0 && i < 64);
 
-	return 13;
+	return ret_val;
 }
 
 static int
diff -Nru a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
--- a/drivers/net/e1000/e1000_hw.c	2005-03-03 19:33:21 -05:00
+++ b/drivers/net/e1000/e1000_hw.c	2005-03-03 19:33:21 -05:00
@@ -1573,7 +1573,8 @@
             if(mii_status_reg & MII_SR_LINK_STATUS) break;
             msec_delay(100);
         }
-        if((i == 0) && (hw->phy_type == e1000_phy_m88)) {
+        if((i == 0) &&
+           (hw->phy_type == e1000_phy_m88)) {
             /* We didn't get link.  Reset the DSP and wait again for link. */
             ret_val = e1000_phy_reset_dsp(hw);
             if(ret_val) {
@@ -2504,7 +2505,7 @@
         }
     }
 
-    ret_val = e1000_read_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr,
+    ret_val = e1000_read_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
                                     phy_data);
 
     return ret_val;
@@ -2610,7 +2611,7 @@
         }
     }
 
-    ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr,
+    ret_val = e1000_write_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
                                      phy_data);
 
     return ret_val;
@@ -2956,8 +2957,7 @@
     /* Check polarity status */
     ret_val = e1000_check_polarity(hw, &polarity);
     if(ret_val)
-        return ret_val;
-
+        return ret_val; 
     phy_info->cable_polarity = polarity;
 
     ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
@@ -2967,9 +2967,9 @@
     phy_info->mdix_mode = (phy_data & M88E1000_PSSR_MDIX) >>
                           M88E1000_PSSR_MDIX_SHIFT;
 
-    if(phy_data & M88E1000_PSSR_1000MBS) {
-        /* Cable Length Estimation and Local/Remote Receiver Informatoion
-         * are only valid at 1000 Mbps
+    if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
+        /* Cable Length Estimation and Local/Remote Receiver Information
+         * are only valid at 1000 Mbps.
          */
         phy_info->cable_length = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
                                   M88E1000_PSSR_CABLE_LENGTH_SHIFT);
@@ -4641,41 +4641,44 @@
 {
     uint32_t status;
 
-    if(hw->mac_type < e1000_82543) {
+    switch (hw->mac_type) {
+    case e1000_82542_rev2_0:
+    case e1000_82542_rev2_1:
         hw->bus_type = e1000_bus_type_unknown;
         hw->bus_speed = e1000_bus_speed_unknown;
         hw->bus_width = e1000_bus_width_unknown;
-        return;
-    }
-
-    status = E1000_READ_REG(hw, STATUS);
-    hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ?
-                   e1000_bus_type_pcix : e1000_bus_type_pci;
+        break;
+    default:
+        status = E1000_READ_REG(hw, STATUS);
+        hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ?
+                       e1000_bus_type_pcix : e1000_bus_type_pci;
 
-    if(hw->device_id == E1000_DEV_ID_82546EB_QUAD_COPPER) {
-        hw->bus_speed = (hw->bus_type == e1000_bus_type_pci) ?
-                        e1000_bus_speed_66 : e1000_bus_speed_120;
-    } else if(hw->bus_type == e1000_bus_type_pci) {
-        hw->bus_speed = (status & E1000_STATUS_PCI66) ?
-                        e1000_bus_speed_66 : e1000_bus_speed_33;
-    } else {
-        switch (status & E1000_STATUS_PCIX_SPEED) {
-        case E1000_STATUS_PCIX_SPEED_66:
-            hw->bus_speed = e1000_bus_speed_66;
-            break;
-        case E1000_STATUS_PCIX_SPEED_100:
-            hw->bus_speed = e1000_bus_speed_100;
-            break;
-        case E1000_STATUS_PCIX_SPEED_133:
-            hw->bus_speed = e1000_bus_speed_133;
-            break;
-        default:
-            hw->bus_speed = e1000_bus_speed_reserved;
-            break;
+        if(hw->device_id == E1000_DEV_ID_82546EB_QUAD_COPPER) {
+            hw->bus_speed = (hw->bus_type == e1000_bus_type_pci) ?
+                            e1000_bus_speed_66 : e1000_bus_speed_120;
+        } else if(hw->bus_type == e1000_bus_type_pci) {
+            hw->bus_speed = (status & E1000_STATUS_PCI66) ?
+                            e1000_bus_speed_66 : e1000_bus_speed_33;
+        } else {
+            switch (status & E1000_STATUS_PCIX_SPEED) {
+            case E1000_STATUS_PCIX_SPEED_66:
+                hw->bus_speed = e1000_bus_speed_66;
+                break;
+            case E1000_STATUS_PCIX_SPEED_100:
+                hw->bus_speed = e1000_bus_speed_100;
+                break;
+            case E1000_STATUS_PCIX_SPEED_133:
+                hw->bus_speed = e1000_bus_speed_133;
+                break;
+            default:
+                hw->bus_speed = e1000_bus_speed_reserved;
+                break;
+            }
         }
+        hw->bus_width = (status & E1000_STATUS_BUS64) ?
+                        e1000_bus_width_64 : e1000_bus_width_32;
+        break;
     }
-    hw->bus_width = (status & E1000_STATUS_BUS64) ?
-                    e1000_bus_width_64 : e1000_bus_width_32;
 }
 /******************************************************************************
  * Reads a value from one of the devices registers using port I/O (as opposed
@@ -4740,6 +4743,7 @@
     uint16_t agc_value = 0;
     uint16_t cur_agc, min_agc = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
     uint16_t i, phy_data;
+    uint16_t cable_length;
 
     DEBUGFUNC("e1000_get_cable_length");
 
@@ -4751,10 +4755,11 @@
                                      &phy_data);
         if(ret_val)
             return ret_val;
+        cable_length = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
+                       M88E1000_PSSR_CABLE_LENGTH_SHIFT;
 
         /* Convert the enum value to ranged values */
-        switch((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
-               M88E1000_PSSR_CABLE_LENGTH_SHIFT) {
+        switch (cable_length) {
         case e1000_cable_length_50:
             *min_length = 0;
             *max_length = e1000_igp_cable_length_50;
@@ -4921,8 +4926,7 @@
             return ret_val;
 
         hw->speed_downgraded = (phy_data & IGP01E1000_PLHR_SS_DOWNGRADE) ? 1 : 0;
-    }
-    else if(hw->phy_type == e1000_phy_m88) {
+    } else if(hw->phy_type == e1000_phy_m88) {
         ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
                                      &phy_data);
         if(ret_val)
diff -Nru a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
--- a/drivers/net/e1000/e1000_hw.h	2005-03-03 19:33:21 -05:00
+++ b/drivers/net/e1000/e1000_hw.h	2005-03-03 19:33:21 -05:00
@@ -36,7 +36,6 @@
 #include "e1000_osdep.h"
 
 
-
 /* Forward declarations of structures used by the shared code */
 struct e1000_hw;
 struct e1000_hw_stats;
@@ -370,6 +369,7 @@
 #define E1000_DEV_ID_82546GB_SERDES      0x107B
 #define E1000_DEV_ID_82546GB_PCIE        0x108A
 #define E1000_DEV_ID_82547EI             0x1019
+
 #define NODE_ADDRESS_SIZE 6
 #define ETH_LENGTH_OF_ADDRESS 6
 
@@ -1735,6 +1735,9 @@
 #define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */
 #define PHY_EXT_STATUS   0x0F /* Extended Status Reg */
 
+#define MAX_PHY_REG_ADDRESS        0x1F  /* 5 bit address bus (0-0x1F) */
+#define MAX_PHY_MULTI_PAGE_REG     0xF   /* Registers equal on all pages */
+
 /* M88E1000 Specific Registers */
 #define M88E1000_PHY_SPEC_CTRL     0x10  /* PHY Specific Control Register */
 #define M88E1000_PHY_SPEC_STATUS   0x11  /* PHY Specific Status Register */
@@ -1795,8 +1798,7 @@
 
 #define IGP01E1000_ANALOG_REGS_PAGE  0x20C0
 
-#define MAX_PHY_REG_ADDRESS 0x1F        /* 5 bit address bus (0-0x1F) */
-#define MAX_PHY_MULTI_PAGE_REG  0xF     /*Registers that are equal on all pages*/
+
 /* PHY Control Register */
 #define MII_CR_SPEED_SELECT_MSB 0x0040  /* bits 6,13: 10=1000, 01=100, 00=10 */
 #define MII_CR_COLL_TEST_ENABLE 0x0080  /* Collision test enable */
@@ -2099,7 +2101,11 @@
 #define IGP01E1000_ANALOG_FUSE_FINE_1               0x0080
 #define IGP01E1000_ANALOG_FUSE_FINE_10              0x0500
 
+
 /* Bit definitions for valid PHY IDs. */
+/* I = Integrated
+ * E = External
+ */
 #define M88E1000_E_PHY_ID  0x01410C50
 #define M88E1000_I_PHY_ID  0x01410C30
 #define M88E1011_I_PHY_ID  0x01410C20
diff -Nru a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
--- a/drivers/net/e1000/e1000_main.c	2005-03-03 19:33:21 -05:00
+++ b/drivers/net/e1000/e1000_main.c	2005-03-03 19:33:21 -05:00
@@ -34,6 +34,14 @@
  * - if_mii support and associated kcompat for older kernels
  * - More errlogging support from Jon Mason <jonmason@us.ibm.com>
  * - Fix TSO issues on PPC64 machines -- Jon Mason <jonmason@us.ibm.com>
+ * 5.7.1	12/16/04
+ * - Resurrect 82547EI/GI related fix in e1000_intr to avoid deadlocks. This
+ *   fix was removed as it caused system instability. The suspected cause of 
+ *   this is the called to e1000_irq_disable in e1000_intr. Inlined the 
+ *   required piece of e1000_irq_disable into e1000_intr.
+ * 5.7.0	12/10/04
+ * - include fix to the condition that determines when to quit NAPI - Robert Olsson
+ * - use netif_poll_{disable/enable} to synchronize between NAPI and i/f up/down
  * 5.6.5 	11/01/04
  * - Enabling NETIF_F_SG without checksum offload is illegal - 
      John Mason <jdmason@us.ibm.com>
@@ -41,8 +49,13 @@
  * - Remove redundant initialization - Jamal Hadi
  * - Reset buffer_info->dma in tx resource cleanup logic
  * 5.6.2	10/12/04
+ * - Avoid filling tx_ring completely - shemminger@osdl.org
+ * - Replace schedule_timeout() with msleep()/msleep_interruptible() -
+ *   nacc@us.ibm.com
  * - Sparse cleanup - shemminger@osdl.org
  * - Fix tx resource cleanup logic
+ * - LLTX support - ak@suse.de and hadi@cyberus.ca
+ * - {set, get}_wol is now symmetric for 82545EM adapters
  */
 
 char e1000_driver_name[] = "e1000";
@@ -52,7 +65,7 @@
 #else
 #define DRIVERNAPI "-NAPI"
 #endif
-char e1000_driver_version[] = "5.6.10.1-k1"DRIVERNAPI;
+char e1000_driver_version[] = "5.7.6-k1"DRIVERNAPI;
 char e1000_copyright[] = "Copyright (c) 1999-2004 Intel Corporation.";
 
 /* e1000_pci_tbl - PCI Device ID Table
@@ -76,6 +89,7 @@
 	INTEL_E1000_ETHERNET_DEVICE(0x1011),
 	INTEL_E1000_ETHERNET_DEVICE(0x1012),
 	INTEL_E1000_ETHERNET_DEVICE(0x1013),
+	INTEL_E1000_ETHERNET_DEVICE(0x1014),
 	INTEL_E1000_ETHERNET_DEVICE(0x1015),
 	INTEL_E1000_ETHERNET_DEVICE(0x1016),
 	INTEL_E1000_ETHERNET_DEVICE(0x1017),
@@ -303,6 +317,9 @@
 	mod_timer(&adapter->watchdog_timer, jiffies);
 	e1000_irq_enable(adapter);
 
+#ifdef CONFIG_E1000_NAPI
+	netif_poll_enable(netdev);
+#endif
 	return 0;
 }
 
@@ -316,6 +333,10 @@
 	del_timer_sync(&adapter->tx_fifo_stall_timer);
 	del_timer_sync(&adapter->watchdog_timer);
 	del_timer_sync(&adapter->phy_info_timer);
+
+#ifdef CONFIG_E1000_NAPI
+	netif_poll_disable(netdev);
+#endif
 	adapter->link_speed = 0;
 	adapter->link_duplex = 0;
 	netif_carrier_off(netdev);
@@ -409,6 +430,7 @@
 	int i;
 	int err;
 	uint16_t eeprom_data;
+	uint16_t eeprom_apme_mask = E1000_EEPROM_APME;
 
 	if((err = pci_enable_device(pdev)))
 		return err;
@@ -505,9 +527,6 @@
 	}
 
 #ifdef NETIF_F_TSO
-	/* Disbaled for now until root-cause is found for
-	 * hangs reported against non-IA archs.  TSO can be
-	 * enabled using ethtool -K eth<x> tso on */
 	if((adapter->hw.mac_type >= e1000_82544) &&
 	   (adapter->hw.mac_type != e1000_82547))
 		netdev->features |= NETIF_F_TSO;
@@ -576,6 +595,11 @@
 	case e1000_82542_rev2_1:
 	case e1000_82543:
 		break;
+	case e1000_82544:
+		e1000_read_eeprom(&adapter->hw,
+			EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
+		eeprom_apme_mask = E1000_EEPROM_82544_APM;
+		break;
 	case e1000_82546:
 	case e1000_82546_rev_3:
 		if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1)
@@ -590,7 +614,7 @@
 			EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
 		break;
 	}
-	if(eeprom_data & E1000_EEPROM_APME)
+	if(eeprom_data & eeprom_apme_mask)
 		adapter->wol |= E1000_WUFC_MAG;
 
 	/* reset the hardware with the new settings */
@@ -797,6 +821,31 @@
 }
 
 /**
+ * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary
+ * @adapter: address of board private structure
+ * @begin: address of beginning of memory
+ * @end: address of end of memory
+ **/
+static inline boolean_t
+e1000_check_64k_bound(struct e1000_adapter *adapter,
+		      void *start, unsigned long len)
+{
+	unsigned long begin = (unsigned long) start;
+	unsigned long end = begin + len;
+
+	/* first rev 82545 and 82546 need to not allow any memory
+	 * write location to cross a 64k boundary due to errata 23 */
+	if (adapter->hw.mac_type == e1000_82545 ||
+	    adapter->hw.mac_type == e1000_82546 ) {
+
+		/* check buffer doesn't cross 64kB */
+		return ((begin ^ (end - 1)) >> 16) != 0 ? FALSE : TRUE;
+	}
+
+	return TRUE;
+}
+
+/**
  * e1000_setup_tx_resources - allocate Tx resources (Descriptors)
  * @adapter: board private structure
  *
@@ -826,11 +875,42 @@
 
 	txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
 	if(!txdr->desc) {
+setup_tx_desc_die:
 		DPRINTK(PROBE, ERR, 
 		"Unable to Allocate Memory for the Transmit descriptor ring\n");
 		vfree(txdr->buffer_info);
 		return -ENOMEM;
 	}
+
+	/* fix for errata 23, cant cross 64kB boundary */
+	if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
+		void *olddesc = txdr->desc;
+		dma_addr_t olddma = txdr->dma;
+		DPRINTK(TX_ERR,ERR,"txdr align check failed: %u bytes at %p\n",
+		        txdr->size, txdr->desc);
+		/* try again, without freeing the previous */
+		txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
+		/* failed allocation, critial failure */
+		if(!txdr->desc) {
+			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
+			goto setup_tx_desc_die;
+		}
+
+		if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
+			/* give up */
+			pci_free_consistent(pdev, txdr->size,
+			     txdr->desc, txdr->dma);
+			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
+			DPRINTK(PROBE, ERR,
+			 "Unable to Allocate aligned Memory for the Transmit"
+		         " descriptor ring\n");
+			vfree(txdr->buffer_info);
+			return -ENOMEM;
+		} else {
+			/* free old, move on with the new one since its okay */
+			pci_free_consistent(pdev, txdr->size, olddesc, olddma);
+		}
+	}
 	memset(txdr->desc, 0, txdr->size);
 
 	txdr->next_to_use = 0;
@@ -948,11 +1028,43 @@
 	rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
 
 	if(!rxdr->desc) {
+setup_rx_desc_die:
 		DPRINTK(PROBE, ERR, 
-		"Unable to Allocate Memory for the Recieve descriptor ring\n");
+		"Unble to Allocate Memory for the Recieve descriptor ring\n");
 		vfree(rxdr->buffer_info);
 		return -ENOMEM;
 	}
+
+	/* fix for errata 23, cant cross 64kB boundary */
+	if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
+		void *olddesc = rxdr->desc;
+		dma_addr_t olddma = rxdr->dma;
+		DPRINTK(RX_ERR,ERR,
+			"rxdr align check failed: %u bytes at %p\n",
+			rxdr->size, rxdr->desc);
+		/* try again, without freeing the previous */
+		rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
+		/* failed allocation, critial failure */
+		if(!rxdr->desc) {
+			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
+			goto setup_rx_desc_die;
+		}
+
+		if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
+			/* give up */
+			pci_free_consistent(pdev, rxdr->size,
+			     rxdr->desc, rxdr->dma);
+			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
+			DPRINTK(PROBE, ERR, 
+				"Unable to Allocate aligned Memory for the"
+				" Receive descriptor ring\n");
+			vfree(rxdr->buffer_info);
+			return -ENOMEM;
+		} else {
+			/* free old, move on with the new one since its okay */
+			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
+		}
+	}
 	memset(rxdr->desc, 0, rxdr->size);
 
 	rxdr->next_to_clean = 0;
@@ -1086,6 +1198,7 @@
 			struct e1000_buffer *buffer_info)
 {
 	struct pci_dev *pdev = adapter->pdev;
+
 	if(buffer_info->dma) {
 		pci_unmap_page(pdev,
 			       buffer_info->dma,
@@ -1114,6 +1227,11 @@
 
 	/* Free all the Tx ring sk_buffs */
 
+	if (likely(adapter->previous_buffer_info.skb != NULL)) {
+		e1000_unmap_and_free_tx_resource(adapter, 
+				&adapter->previous_buffer_info);
+	}
+
 	for(i = 0; i < tx_ring->count; i++) {
 		buffer_info = &tx_ring->buffer_info[i];
 		e1000_unmap_and_free_tx_resource(adapter, buffer_info);
@@ -1415,7 +1533,6 @@
 	struct e1000_adapter *adapter = (struct e1000_adapter *) data;
 	struct net_device *netdev = adapter->netdev;
 	struct e1000_desc_ring *txdr = &adapter->tx_ring;
-	unsigned int i;
 	uint32_t link;
 
 	e1000_check_for_link(&adapter->hw);
@@ -1495,12 +1612,8 @@
 	/* Cause software interrupt to ensure rx ring is cleaned */
 	E1000_WRITE_REG(&adapter->hw, ICS, E1000_ICS_RXDMT0);
 
-	/* 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) &&
-	   !(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_TXOFF))
-		netif_stop_queue(netdev);
+	/* Force detection of hung controller every watchdog period*/
+	adapter->detect_tx_hung = TRUE;
 
 	/* Reset the timer */
 	mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
@@ -2132,10 +2245,28 @@
 		__netif_rx_schedule(netdev);
 	}
 #else
+	/* Writing IMC and IMS is needed for 82547.
+	   Due to Hub Link bus being occupied, an interrupt
+	   de-assertion message is not able to be sent.
+	   When an interrupt assertion message is generated later,
+	   two messages are re-ordered and sent out.
+	   That causes APIC to think 82547 is in de-assertion
+	   state, while 82547 is in assertion state, resulting
+	   in dead lock. Writing IMC forces 82547 into
+	   de-assertion state.
+	*/
+	if(hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2){
+		atomic_inc(&adapter->irq_sem);
+		E1000_WRITE_REG(&adapter->hw, IMC, ~0);
+	}
+
 	for(i = 0; i < E1000_MAX_INTR; i++)
 		if(unlikely(!e1000_clean_rx_irq(adapter) &
 		   !e1000_clean_tx_irq(adapter)))
 			break;
+
+	if(hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2)
+		e1000_irq_enable(adapter);
 #endif
 
 	return IRQ_HANDLED;
@@ -2155,24 +2286,21 @@
 	int tx_cleaned;
 	int work_done = 0;
 	
-	if (!netif_carrier_ok(netdev))
-		goto quit_polling;
-
 	tx_cleaned = e1000_clean_tx_irq(adapter);
 	e1000_clean_rx_irq(adapter, &work_done, work_to_do);
 
 	*budget -= work_done;
 	netdev->quota -= work_done;
 	
-	/* if no Rx and Tx cleanup work was done, exit the polling mode */
-	if(!tx_cleaned || (work_done < work_to_do) || 
+	/* if no Tx 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);
+		netif_rx_complete(netdev);
 		e1000_irq_enable(adapter);
 		return 0;
 	}
 
-	return (work_done >= work_to_do);
+	return 1;
 }
 
 #endif
@@ -2196,11 +2324,34 @@
 	eop_desc = E1000_TX_DESC(*tx_ring, eop);
 
 	while(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
+		/* pre-mature writeback of Tx descriptors     */
+		/* clear (free buffers and unmap pci_mapping) */
+		/* previous_buffer_info                       */
+		if (likely(adapter->previous_buffer_info.skb != NULL)) {
+			e1000_unmap_and_free_tx_resource(adapter, 
+					&adapter->previous_buffer_info);
+		}
+
 		for(cleaned = FALSE; !cleaned; ) {
 			tx_desc = E1000_TX_DESC(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
+			cleaned = (i == eop);
+
+			/* pre-mature writeback of Tx descriptors */
+			/* save the cleaning of the this for the  */
+			/* next iteration                         */
+			if (cleaned) {
+				memcpy(&adapter->previous_buffer_info,
+					buffer_info,
+					sizeof(struct e1000_buffer));
+				memset(buffer_info,
+					0,
+					sizeof(struct e1000_buffer));
+			} else {
+				e1000_unmap_and_free_tx_resource(adapter, 
+							buffer_info);
+			}
 
-			e1000_unmap_and_free_tx_resource(adapter, buffer_info);
 			tx_desc->buffer_addr = 0;
 			tx_desc->lower.data = 0;
 			tx_desc->upper.data = 0;
@@ -2222,6 +2373,16 @@
 		netif_wake_queue(netdev);
 
 	spin_unlock(&adapter->tx_lock);
+ 
+	if(adapter->detect_tx_hung) {
+		/* detect a transmit hang in hardware, this serializes the
+		 * check with the clearing of time_stamp and movement of i */
+		adapter->detect_tx_hung = FALSE;
+		if(tx_ring->buffer_info[i].dma &&
+		   time_after(jiffies, tx_ring->buffer_info[i].time_stamp + HZ) &&
+		   !(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_TXOFF))
+			netif_stop_queue(netdev);
+	}
 
 	return cleaned;
 }
@@ -2389,20 +2550,43 @@
 	struct e1000_buffer *buffer_info;
 	struct sk_buff *skb;
 	int reserve_len = 2;
-	unsigned int i;
+	unsigned int i, bufsz;
 
 	i = rx_ring->next_to_use;
 	buffer_info = &rx_ring->buffer_info[i];
 
 	while(!buffer_info->skb) {
+		bufsz = adapter->rx_buffer_len + reserve_len;
 
-		skb = dev_alloc_skb(adapter->rx_buffer_len + reserve_len);
-
+		skb = dev_alloc_skb(bufsz);
 		if(unlikely(!skb)) {
 			/* Better luck next round */
 			break;
 		}
 
+		/* fix for errata 23, cant cross 64kB boundary */
+		if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
+			struct sk_buff *oldskb = skb;
+			DPRINTK(RX_ERR,ERR,
+				"skb align check failed: %u bytes at %p\n",
+				bufsz, skb->data);
+			/* try again, without freeing the previous */
+			skb = dev_alloc_skb(bufsz);
+			if (!skb) {
+				dev_kfree_skb(oldskb);
+				break;
+			}
+			if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
+				/* give up */
+				dev_kfree_skb(skb);
+				dev_kfree_skb(oldskb);
+				break; /* while !buffer_info->skb */
+			} else {
+				/* move on with the new one */
+				dev_kfree_skb(oldskb);
+			}
+		}
+
 		/* Make buffer alignment 2 beyond a 16 byte boundary
 		 * this will result in a 16 byte aligned IP header after
 		 * the 14 byte MAC header is removed
@@ -2417,6 +2601,25 @@
 						  skb->data,
 						  adapter->rx_buffer_len,
 						  PCI_DMA_FROMDEVICE);
+
+		/* fix for errata 23, cant cross 64kB boundary */
+		if(!e1000_check_64k_bound(adapter,
+			                       (void *)(unsigned long)buffer_info->dma,
+			                       adapter->rx_buffer_len)) {
+			DPRINTK(RX_ERR,ERR,
+				"dma align check failed: %u bytes at %ld\n",
+				adapter->rx_buffer_len, (unsigned long)buffer_info->dma);
+
+			dev_kfree_skb(skb);
+			buffer_info->skb = NULL;
+
+			pci_unmap_single(pdev,
+					 buffer_info->dma,
+					 adapter->rx_buffer_len,
+					 PCI_DMA_FROMDEVICE);
+
+			break; /* while !buffer_info->skb */
+		}
 
 		rx_desc = E1000_RX_DESC(*rx_ring, i);
 		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
diff -Nru a/drivers/net/tulip/21142.c b/drivers/net/tulip/21142.c
--- a/drivers/net/tulip/21142.c	2005-03-03 19:33:21 -05:00
+++ b/drivers/net/tulip/21142.c	2005-03-03 19:33:21 -05:00
@@ -14,8 +14,8 @@
 
 */
 
-#include "tulip.h"
 #include <linux/pci.h>
+#include "tulip.h"
 #include <linux/delay.h>
 
 
diff -Nru a/drivers/net/tulip/eeprom.c b/drivers/net/tulip/eeprom.c
--- a/drivers/net/tulip/eeprom.c	2005-03-03 19:33:21 -05:00
+++ b/drivers/net/tulip/eeprom.c	2005-03-03 19:33:21 -05:00
@@ -14,6 +14,7 @@
 
 */
 
+#include <linux/pci.h>
 #include "tulip.h"
 #include <linux/init.h>
 #include <asm/unaligned.h>
diff -Nru a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c
--- a/drivers/net/tulip/interrupt.c	2005-03-03 19:33:21 -05:00
+++ b/drivers/net/tulip/interrupt.c	2005-03-03 19:33:21 -05:00
@@ -14,10 +14,10 @@
 
 */
 
+#include <linux/pci.h>
 #include "tulip.h"
 #include <linux/config.h>
 #include <linux/etherdevice.h>
-#include <linux/pci.h>
 
 
 int tulip_rx_copybreak;
diff -Nru a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c
--- a/drivers/net/tulip/media.c	2005-03-03 19:33:21 -05:00
+++ b/drivers/net/tulip/media.c	2005-03-03 19:33:21 -05:00
@@ -18,6 +18,7 @@
 #include <linux/mii.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/pci.h>
 #include "tulip.h"
 
 
diff -Nru a/drivers/net/tulip/pnic.c b/drivers/net/tulip/pnic.c
--- a/drivers/net/tulip/pnic.c	2005-03-03 19:33:21 -05:00
+++ b/drivers/net/tulip/pnic.c	2005-03-03 19:33:21 -05:00
@@ -15,6 +15,7 @@
 */
 
 #include <linux/kernel.h>
+#include <linux/pci.h>
 #include "tulip.h"
 
 
diff -Nru a/drivers/net/tulip/pnic2.c b/drivers/net/tulip/pnic2.c
--- a/drivers/net/tulip/pnic2.c	2005-03-03 19:33:21 -05:00
+++ b/drivers/net/tulip/pnic2.c	2005-03-03 19:33:21 -05:00
@@ -76,8 +76,8 @@
 
 
 
-#include "tulip.h"
 #include <linux/pci.h>
+#include "tulip.h"
 #include <linux/delay.h>
 
 
diff -Nru a/drivers/net/tulip/timer.c b/drivers/net/tulip/timer.c
--- a/drivers/net/tulip/timer.c	2005-03-03 19:33:21 -05:00
+++ b/drivers/net/tulip/timer.c	2005-03-03 19:33:21 -05:00
@@ -14,6 +14,7 @@
 
 */
 
+#include <linux/pci.h>
 #include "tulip.h"
 
 
diff -Nru a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h
--- a/drivers/net/tulip/tulip.h	2005-03-03 19:33:21 -05:00
+++ b/drivers/net/tulip/tulip.h	2005-03-03 19:33:21 -05:00
@@ -146,6 +146,9 @@
 	TxIntr = 0x01,
 };
 
+/* bit mask for CSR5 TX/RX process state */
+#define CSR5_TS	0x00700000
+#define CSR5_RS	0x000e0000
 
 enum tulip_mode_bits {
 	TxThreshold		= (1 << 22),
@@ -484,9 +487,19 @@
 	u32 csr6 = inl(ioaddr + CSR6);
 
 	if (csr6 & RxTx) {
+		unsigned i=1300/10;
 		outl(csr6 & ~RxTx, ioaddr + CSR6);
 		barrier();
-		(void) inl(ioaddr + CSR6); /* mmio sync */
+		/* wait until in-flight frame completes.
+		 * Max time @ 10BT: 1500*8b/10Mbps == 1200us (+ 100us margin)
+		 * Typically expect this loop to end in < 50us on 100BT.
+		 */
+		while (--i && (inl(ioaddr + CSR5) & (CSR5_TS|CSR5_RS))) 
+			udelay(10);
+
+		if (!i)
+			printk (KERN_DEBUG "%s: tulip_stop_rxtx() failed\n",
+					tp->pdev->slot_name);
 	}
 }
 
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-03 19:33:21 -05:00
+++ b/drivers/net/tulip/tulip_core.c	2005-03-03 19:33:21 -05:00
@@ -20,8 +20,8 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
-#include "tulip.h"
 #include <linux/pci.h>
+#include "tulip.h"
 #include <linux/init.h>
 #include <linux/etherdevice.h>
 #include <linux/delay.h>

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

* [BK PATCHES] 2.4.x net driver updates
@ 2004-08-29  0:26 Jeff Garzik
  0 siblings, 0 replies; 7+ messages in thread
From: Jeff Garzik @ 2004-08-29  0:26 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: netdev


Please do a

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

This will update the following files:

 drivers/net/e1000/e1000_param.c |    2 +-
 drivers/net/fealnx.c            |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

through these ChangeSets:

<ha505@hszk.bme.hu> (04/08/28 1.1550)
   [netdrvr fealnx] fix spin_unlock_irqrestore() usage

<tharbaugh@lnxi.com> (04/08/28 1.1549)
   [netdrvr e1000] disable DITR, which apparently hurts performance

diff -Nru a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c
--- a/drivers/net/e1000/e1000_param.c	2004-08-28 20:25:30 -04:00
+++ b/drivers/net/e1000/e1000_param.c	2004-08-28 20:25:30 -04:00
@@ -212,7 +212,7 @@
 #define MAX_TXABSDELAY            0xFFFF
 #define MIN_TXABSDELAY                 0
 
-#define DEFAULT_ITR                    1
+#define DEFAULT_ITR                 8000
 #define MAX_ITR                   100000
 #define MIN_ITR                      100
 
diff -Nru a/drivers/net/fealnx.c b/drivers/net/fealnx.c
--- a/drivers/net/fealnx.c	2004-08-28 20:25:30 -04:00
+++ b/drivers/net/fealnx.c	2004-08-28 20:25:30 -04:00
@@ -1796,7 +1796,7 @@
 	unsigned long flags;
 	spin_lock_irqsave(lp, flags);
 	__set_rx_mode(dev);
-	spin_unlock_irqrestore(&lp, flags);
+	spin_unlock_irqrestore(lp, flags);
 }
 
 

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

* [bk patches] 2.4.x net driver updates
@ 2003-09-01 15:49 Jeff Garzik
  0 siblings, 0 replies; 7+ messages in thread
From: Jeff Garzik @ 2003-09-01 15:49 UTC (permalink / raw)
  To: marcelo; +Cc: marcelo, linux-kernel, netdev


Marcelo, please do a

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

This will update the following files:

 drivers/net/8139cp.c  |   35 ++++++++-----------------
 drivers/net/8139too.c |   68 ++++++++++++++++++++++++--------------------------
 2 files changed, 44 insertions(+), 59 deletions(-)

through these ChangeSets:

<jgarzik@redhat.com> (03/08/31 1.1119)
   [netdrvr 8139cp] PCI MWI cleanup; remove unneeded workaround
   
   * The PCI layer now handles incorrect cacheline size settings,
     as it should.  Remove our own workarounds.
   * Move pci_set_mwi up much earlier in the probe process,
     and check its return value.
   * Call pci_clear_mwi() in ->probe error handling
   * Call pci_clear_mwi() in ->remove

<hirofumi@mail.parknet.co.jp> (03/08/31 1.1117)
   [netdrvr 8139too] don't start thread when it's not needed
   
       The thread for was unneeded on chips other than CH_8139_K/8129. So,
       this patch doesn't create the thread on chips other than
       CH_8139_K/8129.
   

<hirofumi@mail.parknet.co.jp> (03/08/31 1.1116)
   [netdrvr 8139too] remove driver-based poisoning of net_device
   
   Harmless in 2.4, but causes oopses on rmmod in 2.6.
   
   slab poisoning can take care of this for us, anyway.

<jgarzik@redhat.com> (03/08/31 1.1115)
   [netdrvr 8139cp] must call NAPI-specific vlan hook


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

* [bk patches] 2.4.x net driver updates
@ 2003-08-31 14:09 Jeff Garzik
  0 siblings, 0 replies; 7+ messages in thread
From: Jeff Garzik @ 2003-08-31 14:09 UTC (permalink / raw)
  To: marcelo; +Cc: marcelo, linux-kernel, netdev


Marcelo, please do a

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

This will update the following files:

 drivers/net/3c527.c             |    7 
 drivers/net/8139cp.c            |  331 ++++++++++++++++------------------------
 drivers/net/8139too.c           |   70 ++++----
 drivers/net/eth16i.c            |    3 
 drivers/net/fmv18x.c            |    3 
 drivers/net/pcmcia/3c574_cs.c   |    9 -
 drivers/net/pcmcia/axnet_cs.c   |    3 
 drivers/net/pcmcia/pcnet_cs.c   |    3 
 drivers/net/pcmcia/xirc2ps_cs.c |    9 -
 drivers/net/seeq8005.c          |    4 
 drivers/net/yellowfin.c         |    4 
 11 files changed, 199 insertions(+), 247 deletions(-)

through these ChangeSets:

<purna@jcom.home.ne.jp> (03/08/31 1.1114)
   [netdrvr] fix skb_padto bugs introduced when skb_padto was introduced
   
   It seems that skb_padto security fixes in 2.4 and 2.5 trying
   to fix "CAN-2003-0001:Multiple ethernet NID device drivers
   do not pad frames with null bytes", do not put the skb_padto
   blocks in proper places in the  3c527, eth16i, fmv18x, seeq8005,
   yellowfin device drivers.   
   
   In case a driver calls skb_padto(), it is possible
   that the space available in the original skb buffer tailroom is less
   than the space to pad. In this case, in short, the skb_padto()
   will create a new skb buffer, copy data from the original
   skb buffer to a new skb buffer, free the original buffer,
   and finally return the new buffer.
   
   If this happens to the aforementioned device drivers, they come to
   point to wrong data. And, for 3c527 and yellowfin, the drivers can
   unexpectedly double free the original skb buffers since they still
   point to the original skb buffers. The attached patch against
   2.4.23pre1 fixes these issues.

<jgarzik@redhat.com> (03/08/31 1.1113)
   [netdrvr 8139too] remove useless board names
   
   The only thing that differentiated most of the entries in the
   board_info[] table and the board_t type was the vendor branding
   string for the board.  This table is a pain to maintain, so we
   prefer to simply use "RTL8129" or "RTL8139".

<lethal@linux-sh.org> (03/08/31 1.1112)
   [netdrvr 8139too] fix and pci ids needed for SH platform
   
   a.k.a. Sega Broadband Adapter.

<jgarzik@redhat.com> (03/08/31 1.1111)
   [netdrvr pcmcia] support SIOC[GS]MII{PHY,REG} ioctls
   
   Updated drivers;  3c574_cs, axnet_cs, pcnet_cs, xirc2ps_cs
   
   Thanks to Komuro for pointing this out.

<jgarzik@redhat.com> (03/08/31 1.1110)
   [netdrvr 8139too] make features more persistent; fix PCI DAC mode
   
   * only set PCIDAC (64-bit PCI) bit in hardware if
     sizeof(dma_addr_t) > 32.  Need a better test for whether
     64-bit mode is _really_ needed.
   * cache chip command register in private struct.  this allows
     the setting of rx-vlan, rx-csum, and other features to be
     persistent across the entire lifetime of the net device.
   * remove dead private struct members frag_skb, dropping_frag,
     and pci_using_dac.

<jgarzik@redhat.com> (03/08/31 1.1109)
   [netdrvr 8139cp] stats improvements and fixes
   
   * make sure rx_frags is still accounted
   * query RxMissed register, and clear, upon each get-stats func call

<jgarzik@redhat.com> (03/08/30 1.1108)
   [netdrvr 8139cp] bump version

<jgarzik@redhat.com> (03/08/30 1.1107)
   [netdrvr 8139cp] fix NAPI bug; remove board_type distinction, not needed

<jgarzik@redhat.com> (03/08/30 1.1106)
   [netdrvr 8139cp] small cleanups
   
   * remove netif_queue_stopped test, netif_wake_queue already does that
   * move vlan stuff to top of file
   * remove __dev markers
   * update todo list at top of file
   * remove pci_set_dma_mask argument casts; ULL suffixes preferred.

<jgarzik@redhat.com> (03/08/30 1.1105)
   [netdrvr 8139cp] remove mentions of RTL8169 (now handled by "r8169")

<jgarzik@redhat.com> (03/08/30 1.1104)
   [netdrvr 8139cp] update todo list in header

<jgarzik@redhat.com> (03/08/30 1.1103)
   [netdrvr 8139cp] support NAPI on RX path; Ditch RX frag handling.
   
   NAPI is turned on unconditionally for the RX path.  The hardware
   supports interrupt mitigation, so that should be investigated too.
   
   RX fragment handling removed.  We simply ensure that we alloc
   buffers large enough to hold incoming packets.  Any stray RX
   frags that occur (shouldn't be any) will be dropped.

<jgarzik@redhat.com> (03/08/30 1.1102)
   [netdrvr 8139cp] build TX checksumming code, but default OFF
   
   (previously it was ifdef'd)
   
   Also, bump version to 1.0.



diff -Nru a/drivers/net/3c527.c b/drivers/net/3c527.c
--- a/drivers/net/3c527.c	Sun Aug 31 10:06:32 2003
+++ b/drivers/net/3c527.c	Sun Aug 31 10:06:32 2003
@@ -1083,15 +1083,16 @@
 	/* NP is the buffer we will be loading */
 	np=lp->tx_ring[lp->tx_ring_head].p; 
 
-	/* We will need this to flush the buffer out */
-	lp->tx_ring[lp->tx_ring_head].skb=skb;
-   	   
    	if(skb->len < ETH_ZLEN)
    	{
    		skb = skb_padto(skb, ETH_ZLEN);
    		if(skb == NULL)
    			goto out;
    	}
+
+	/* We will need this to flush the buffer out */
+	lp->tx_ring[lp->tx_ring_head].skb=skb;
+
 	np->length = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len; 
 			
 	np->data	= virt_to_bus(skb->data);
diff -Nru a/drivers/net/8139cp.c b/drivers/net/8139cp.c
--- a/drivers/net/8139cp.c	Sun Aug 31 10:06:32 2003
+++ b/drivers/net/8139cp.c	Sun Aug 31 10:06:32 2003
@@ -24,13 +24,13 @@
 		PCI suspend/resume  - Felipe Damasio <felipewd@terra.com.br>
 		LinkChg interrupt   - Felipe Damasio <felipewd@terra.com.br>
 			
-	TODO, in rough priority order:
+	TODO:
 	* Test Tx checksumming thoroughly
-	* dev->tx_timeout
-	* Constants (module parms?) for Rx work limit
+	* Implement dev->tx_timeout
+
+	Low priority TODO:
 	* Complete reset on PciErr
 	* Consider Rx interrupt mitigation using TimerIntr
-	* Handle netif_rx return value
 	* Investigate using skb->priority with h/w VLAN priority
 	* Investigate using High Priority Tx Queue with skb->priority
 	* Adjust Rx FIFO threshold and Max Rx DMA burst on Rx FIFO error
@@ -39,13 +39,17 @@
 	  Tx descriptor bit
 	* The real minimum of CP_MIN_MTU is 4 bytes.  However,
 	  for this to be supported, one must(?) turn on packet padding.
-	* Support external MII transceivers
+	* Support external MII transceivers (patch available)
+
+	NOTES:
+	* TX checksumming is considered experimental.  It is off by
+	  default, use ethtool to turn it on.
 
  */
 
 #define DRV_NAME		"8139cp"
-#define DRV_VERSION		"0.5"
-#define DRV_RELDATE		"Aug 26, 2003"
+#define DRV_VERSION		"1.1"
+#define DRV_RELDATE		"Aug 30, 2003"
 
 
 #include <linux/config.h>
@@ -68,9 +72,6 @@
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
-/* experimental TX checksumming feature enable/disable */
-#undef CP_TX_CHECKSUM
-
 /* VLAN tagging feature enable/disable */
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
 #define CP_VLAN_TAG_USED 1
@@ -83,7 +84,7 @@
 #endif
 
 /* These identify the driver base version and may not be removed. */
-static char version[] __devinitdata =
+static char version[] =
 KERN_INFO DRV_NAME ": 10/100 PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE ")\n";
 
 MODULE_AUTHOR("Jeff Garzik <jgarzik@pobox.com>");
@@ -157,6 +158,7 @@
 	TxConfig	= 0x40, /* Tx configuration */
 	ChipVersion	= 0x43, /* 8-bit chip version, inside TxConfig */
 	RxConfig	= 0x44, /* Rx configuration */
+	RxMissed	= 0x4C,	/* 24 bits valid, write clears */
 	Cfg9346		= 0x50, /* EEPROM select/control; Cfg reg [un]lock */
 	Config1		= 0x52, /* Config1 */
 	Config3		= 0x59, /* Config3 */
@@ -289,12 +291,11 @@
 	UWF             = (1 << 4),  /* Accept Unicast wakeup frame */
 	LANWake         = (1 << 1),  /* Enable LANWake signal */
 	PMEStatus	= (1 << 0),  /* PME status can be reset by PCI RST# */
-};
 
-static const unsigned int cp_intr_mask =
-	PciErr | LinkChg |
-	RxOK | RxErr | RxEmpty | RxFIFOOvr |
-	TxOK | TxErr | TxEmpty;
+	cp_norx_intr_mask = PciErr | LinkChg | TxOK | TxErr | TxEmpty,
+	cp_rx_intr_mask = RxOK | RxErr | RxEmpty | RxFIFOOvr,
+	cp_intr_mask = cp_rx_intr_mask | cp_norx_intr_mask,
+};
 
 static const unsigned int cp_rx_config =
 	  (RX_FIFO_THRESH << RxCfgFIFOShift) |
@@ -361,11 +362,7 @@
 
 	struct pci_dev		*pdev;
 	u32			rx_config;
-
-	struct sk_buff		*frag_skb;
-	unsigned		dropping_frag : 1;
-	unsigned		pci_using_dac : 1;
-	unsigned int		board_type;
+	u16			cpcmd;
 
 	unsigned int		wol_enabled : 1; /* Is Wake-on-LAN enabled? */
 	u32			power_state[16];
@@ -397,28 +394,9 @@
 static void cp_tx (struct cp_private *cp);
 static void cp_clean_rings (struct cp_private *cp);
 
-enum board_type {
-	RTL8139Cp,
-	RTL8169,
-};
-
-static struct cp_board_info {
-	const char *name;
-} cp_board_tbl[] __devinitdata = {
-	/* RTL8139Cp */
-	{ "RTL-8139C+" },
-
-	/* RTL8169 */
-	{ "RTL-8169" },
-};
-
 static struct pci_device_id cp_pci_tbl[] = {
 	{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139Cp },
-#if 0
-	{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8169,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8169 },
-#endif
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
 	{ },
 };
 MODULE_DEVICE_TABLE(pci, cp_pci_tbl);
@@ -443,6 +421,31 @@
 };
 
 
+#if CP_VLAN_TAG_USED
+static void cp_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
+{
+	struct cp_private *cp = dev->priv;
+
+	spin_lock_irq(&cp->lock);
+	cp->vlgrp = grp;
+	cp->cpcmd |= RxVlanOn;
+	cpw16(CpCmd, cp->cpcmd);
+	spin_unlock_irq(&cp->lock);
+}
+
+static void cp_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
+{
+	struct cp_private *cp = dev->priv;
+
+	spin_lock_irq(&cp->lock);
+	cp->cpcmd &= ~RxVlanOn;
+	cpw16(CpCmd, cp->cpcmd);
+	if (cp->vlgrp)
+		cp->vlgrp->vlan_devices[vid] = NULL;
+	spin_unlock_irq(&cp->lock);
+}
+#endif /* CP_VLAN_TAG_USED */
+
 static inline void cp_set_rxbufsize (struct cp_private *cp)
 {
 	unsigned int mtu = cp->dev->mtu;
@@ -468,7 +471,7 @@
 		vlan_hwaccel_rx(skb, cp->vlgrp, be16_to_cpu(desc->opts2 & 0xffff));
 	} else
 #endif
-		netif_rx(skb);
+		netif_receive_skb(skb);
 }
 
 static void cp_rx_err_acct (struct cp_private *cp, unsigned rx_tail,
@@ -483,81 +486,14 @@
 		cp->net_stats.rx_frame_errors++;
 	if (status & RxErrCRC)
 		cp->net_stats.rx_crc_errors++;
-	if (status & RxErrRunt)
+	if ((status & RxErrRunt) || (status & RxErrLong))
 		cp->net_stats.rx_length_errors++;
-	if (status & RxErrLong)
+	if ((status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag))
 		cp->net_stats.rx_length_errors++;
 	if (status & RxErrFIFO)
 		cp->net_stats.rx_fifo_errors++;
 }
 
-static void cp_rx_frag (struct cp_private *cp, unsigned rx_tail,
-			struct sk_buff *skb, u32 status, u32 len)
-{
-	struct sk_buff *copy_skb, *frag_skb = cp->frag_skb;
-	unsigned orig_len = frag_skb ? frag_skb->len : 0;
-	unsigned target_len = orig_len + len;
-	unsigned first_frag = status & FirstFrag;
-	unsigned last_frag = status & LastFrag;
-
-	if (netif_msg_rx_status (cp))
-		printk (KERN_DEBUG "%s: rx %s%sfrag, slot %d status 0x%x len %d\n",
-			cp->dev->name,
-			cp->dropping_frag ? "dropping " : "",
-			first_frag ? "first " :
-			last_frag ? "last " : "",
-			rx_tail, status, len);
-
-	cp->cp_stats.rx_frags++;
-
-	if (!frag_skb && !first_frag)
-		cp->dropping_frag = 1;
-	if (cp->dropping_frag)
-		goto drop_frag;
-
-	copy_skb = dev_alloc_skb (target_len + RX_OFFSET);
-	if (!copy_skb) {
-		printk(KERN_WARNING "%s: rx slot %d alloc failed\n",
-		       cp->dev->name, rx_tail);
-
-		cp->dropping_frag = 1;
-drop_frag:
-		if (frag_skb) {
-			dev_kfree_skb_irq(frag_skb);
-			cp->frag_skb = NULL;
-		}
-		if (last_frag) {
-			cp->net_stats.rx_dropped++;
-			cp->dropping_frag = 0;
-		}
-		return;
-	}
-
-	copy_skb->dev = cp->dev;
-	skb_reserve(copy_skb, RX_OFFSET);
-	skb_put(copy_skb, target_len);
-	if (frag_skb) {
-		memcpy(copy_skb->data, frag_skb->data, orig_len);
-		dev_kfree_skb_irq(frag_skb);
-	}
-	pci_dma_sync_single(cp->pdev, cp->rx_skb[rx_tail].mapping,
-			    len, PCI_DMA_FROMDEVICE);
-	memcpy(copy_skb->data + orig_len, skb->data, len);
-
-	copy_skb->ip_summed = CHECKSUM_NONE;
-
-	if (last_frag) {
-		if (status & (RxError | RxErrFIFO)) {
-			cp_rx_err_acct(cp, rx_tail, status, len);
-			dev_kfree_skb_irq(copy_skb);
-		} else
-			cp_rx_skb(cp, copy_skb, &cp->rx_ring[rx_tail]);
-		cp->frag_skb = NULL;
-	} else {
-		cp->frag_skb = copy_skb;
-	}
-}
-
 static inline unsigned int cp_rx_csum_ok (u32 status)
 {
 	unsigned int protocol = (status >> 16) & 0x3;
@@ -571,12 +507,18 @@
 	return 0;
 }
 
-static void cp_rx (struct cp_private *cp)
+static int cp_rx_poll (struct net_device *dev, int *budget)
 {
+	struct cp_private *cp = dev->priv;
 	unsigned rx_tail = cp->rx_tail;
-	unsigned rx_work = 100;
+	unsigned rx_work = dev->quota;
+	unsigned rx;
 
-	while (rx_work--) {
+rx_status_loop:
+	rx = 0;
+	cpw16(IntrStatus, cp_rx_intr_mask);
+
+	while (1) {
 		u32 status, len;
 		dma_addr_t mapping;
 		struct sk_buff *skb, *new_skb;
@@ -596,7 +538,14 @@
 		mapping = cp->rx_skb[rx_tail].mapping;
 
 		if ((status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag)) {
-			cp_rx_frag(cp, rx_tail, skb, status, len);
+			/* we don't support incoming fragmented frames.
+			 * instead, we attempt to ensure that the
+			 * pre-allocated RX skbs are properly sized such
+			 * that RX fragments are never encountered
+			 */
+			cp_rx_err_acct(cp, rx_tail, status, len);
+			cp->net_stats.rx_dropped++;
+			cp->cp_stats.rx_frags++;
 			goto rx_next;
 		}
 
@@ -637,6 +586,7 @@
 		cp->rx_skb[rx_tail].skb = new_skb;
 
 		cp_rx_skb(cp, skb, desc);
+		rx++;
 
 rx_next:
 		cp->rx_ring[rx_tail].opts2 = 0;
@@ -647,12 +597,30 @@
 		else
 			desc->opts1 = cpu_to_le32(DescOwn | cp->rx_buf_sz);
 		rx_tail = NEXT_RX(rx_tail);
-	}
 
-	if (!rx_work)
-		printk(KERN_WARNING "%s: rx work limit reached\n", cp->dev->name);
+		if (!rx_work--)
+			break;
+	}
 
 	cp->rx_tail = rx_tail;
+
+	dev->quota -= rx;
+	*budget -= rx;
+
+	/* if we did not reach work limit, then we're done with
+	 * this round of polling
+	 */
+	if (rx_work) {
+		if (cpr16(IntrStatus) & cp_rx_intr_mask)
+			goto rx_status_loop;
+
+		cpw16_f(IntrMask, cp_intr_mask);
+		netif_rx_complete(dev);
+
+		return 0;	/* done */
+	}
+
+	return 1;		/* not done */
 }
 
 static irqreturn_t
@@ -670,12 +638,16 @@
 		printk(KERN_DEBUG "%s: intr, status %04x cmd %02x cpcmd %04x\n",
 		        dev->name, status, cpr8(Cmd), cpr16(CpCmd));
 
-	cpw16_f(IntrStatus, status);
+	cpw16(IntrStatus, status & ~cp_rx_intr_mask);
 
 	spin_lock(&cp->lock);
 
-	if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr))
-		cp_rx(cp);
+	if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr)) {
+		if (netif_rx_schedule_prep(dev)) {
+			cpw16_f(IntrMask, cp_norx_intr_mask);
+			__netif_rx_schedule(dev);
+		}
+	}
 	if (status & (TxOK | TxErr | TxEmpty | SWInt))
 		cp_tx(cp);
 	if (status & LinkChg)
@@ -688,6 +660,8 @@
 		pci_write_config_word(cp->pdev, PCI_STATUS, pci_status);
 		printk(KERN_ERR "%s: PCI bus error, status=%04x, PCI status=%04x\n",
 		       dev->name, status, pci_status);
+
+		/* TODO: reset hardware */
 	}
 
 	spin_unlock(&cp->lock);
@@ -747,7 +721,7 @@
 
 	cp->tx_tail = tx_tail;
 
-	if (netif_queue_stopped(cp->dev) && (TX_BUFFS_AVAIL(cp) > (MAX_SKB_FRAGS + 1)))
+	if (TX_BUFFS_AVAIL(cp) > (MAX_SKB_FRAGS + 1))
 		netif_wake_queue(cp->dev);
 }
 
@@ -789,7 +763,6 @@
 		txd->addr = cpu_to_le64(mapping);
 		wmb();
 
-#ifdef CP_TX_CHECKSUM
 		if (skb->ip_summed == CHECKSUM_HW) {
 			const struct iphdr *ip = skb->nh.iph;
 			if (ip->protocol == IPPROTO_TCP)
@@ -803,7 +776,6 @@
 			else
 				BUG();
 		} else
-#endif
 			txd->opts1 = cpu_to_le32(eor | len | DescOwn |
 						 FirstFrag | LastFrag);
 		wmb();
@@ -817,9 +789,7 @@
 		u32 first_len, first_eor;
 		dma_addr_t first_mapping;
 		int frag, first_entry = entry;
-#ifdef CP_TX_CHECKSUM
 		const struct iphdr *ip = skb->nh.iph;
-#endif
 
 		/* We must give this initial chunk to the device last.
 		 * Otherwise we could race with the device.
@@ -845,7 +815,7 @@
 						  this_frag->page_offset),
 						 len, PCI_DMA_TODEVICE);
 			eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
-#ifdef CP_TX_CHECKSUM
+
 			if (skb->ip_summed == CHECKSUM_HW) {
 				ctrl = eor | len | DescOwn | IPCS;
 				if (ip->protocol == IPPROTO_TCP)
@@ -855,7 +825,6 @@
 				else
 					BUG();
 			} else
-#endif
 				ctrl = eor | len | DescOwn;
 
 			if (frag == skb_shinfo(skb)->nr_frags - 1)
@@ -880,7 +849,6 @@
 		txd->addr = cpu_to_le64(first_mapping);
 		wmb();
 
-#ifdef CP_TX_CHECKSUM
 		if (skb->ip_summed == CHECKSUM_HW) {
 			if (ip->protocol == IPPROTO_TCP)
 				txd->opts1 = cpu_to_le32(first_eor | first_len |
@@ -893,7 +861,6 @@
 			else
 				BUG();
 		} else
-#endif
 			txd->opts1 = cpu_to_le32(first_eor | first_len |
 						 FirstFrag | DescOwn);
 		wmb();
@@ -972,7 +939,9 @@
 
 static void __cp_get_stats(struct cp_private *cp)
 {
-	/* XXX implement */
+	/* only lower 24 bits valid; write any value to clear */
+	cp->net_stats.rx_missed_errors += (cpr32 (RxMissed) & 0xffffff);
+	cpw32 (RxMissed, 0);
 }
 
 static struct net_device_stats *cp_get_stats(struct net_device *dev)
@@ -992,11 +961,10 @@
 {
 	struct net_device *dev = cp->dev;
 
-	cpw16(IntrMask, 0);
-	cpr16(IntrMask);
+	cpw16(IntrStatus, ~(cpr16(IntrStatus)));
+	cpw16_f(IntrMask, 0);
 	cpw8(Cmd, 0);
-	cpw16(CpCmd, 0);
-	cpr16(CpCmd);
+	cpw16_f(CpCmd, 0);
 	cpw16(IntrStatus, ~(cpr16(IntrStatus)));
 	synchronize_irq();
 	udelay(10);
@@ -1028,11 +996,7 @@
 
 static inline void cp_start_hw (struct cp_private *cp)
 {
-	u16 pci_dac = cp->pci_using_dac ? PCIDAC : 0;
-	if (cp->board_type == RTL8169)
-		cpw16(CpCmd, pci_dac | PCIMulRW | RxChkSum);
-	else
-		cpw16(CpCmd, pci_dac | PCIMulRW | RxChkSum | CpRxOn | CpTxOn);
+	cpw16(CpCmd, cp->cpcmd);
 	cpw8(Cmd, RxOn | TxOn);
 }
 
@@ -1056,13 +1020,10 @@
 
 	cpw8(Config1, cpr8(Config1) | DriverLoaded | PMEnable);
 	/* Disable Wake-on-LAN. Can be turned on with ETHTOOL_SWOL */
-	if (cp->board_type == RTL8139Cp) {
-		cpw8(Config3, PARMEnable);
-		cp->wol_enabled = 0;
-	}
+	cpw8(Config3, PARMEnable);
+	cp->wol_enabled = 0;
+
 	cpw8(Config5, cpr8(Config5) & PMEStatus); 
-	if (cp->board_type == RTL8169)
-		cpw16(RxMaxSize, cp->rx_buf_sz);
 
 	cpw32_f(HiTxRingAddr, 0);
 	cpw32_f(HiTxRingAddr + 4, 0);
@@ -1255,8 +1216,6 @@
 
 	dev->mtu = new_mtu;
 	cp_set_rxbufsize(cp);		/* set new rx buf size */
-	if (cp->board_type == RTL8169)
-		cpw16(RxMaxSize, cp->rx_buf_sz);
 
 	rc = cp_init_rings(cp);		/* realloc and restart h/w */
 	cp_start_hw(cp);
@@ -1426,7 +1385,7 @@
 static int cp_set_rx_csum(struct net_device *dev, u32 data)
 {
 	struct cp_private *cp = dev->priv;
-	u16 cmd = cpr16(CpCmd), newcmd;
+	u16 cmd = cp->cpcmd, newcmd;
 
 	newcmd = cmd;
 
@@ -1437,6 +1396,7 @@
 
 	if (newcmd != cmd) {
 		spin_lock_irq(&cp->lock);
+		cp->cpcmd = newcmd;
 		cpw16_f(CpCmd, newcmd);
 		spin_unlock_irq(&cp->lock);
 	}
@@ -1581,29 +1541,6 @@
 	return rc;
 }
 
-#if CP_VLAN_TAG_USED
-static void cp_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
-{
-	struct cp_private *cp = dev->priv;
-
-	spin_lock_irq(&cp->lock);
-	cp->vlgrp = grp;
-	cpw16(CpCmd, cpr16(CpCmd) | RxVlanOn);
-	spin_unlock_irq(&cp->lock);
-}
-
-static void cp_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
-{
-	struct cp_private *cp = dev->priv;
-
-	spin_lock_irq(&cp->lock);
-	cpw16(CpCmd, cpr16(CpCmd) & ~RxVlanOn);
-	if (cp->vlgrp)
-		cp->vlgrp->vlan_devices[vid] = NULL;
-	spin_unlock_irq(&cp->lock);
-}
-#endif
-
 /* Serial EEPROM section. */
 
 /*  EEPROM_Ctrl bits. */
@@ -1626,7 +1563,7 @@
 #define EE_READ_CMD		(6)
 #define EE_ERASE_CMD	(7)
 
-static int __devinit read_eeprom (void *ioaddr, int location, int addr_len)
+static int read_eeprom (void *ioaddr, int location, int addr_len)
 {
 	int i;
 	unsigned retval = 0;
@@ -1672,17 +1609,15 @@
 	pci_set_power_state (cp->pdev, 3);
 }
 
-static int __devinit cp_init_one (struct pci_dev *pdev,
-				  const struct pci_device_id *ent)
+static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	struct net_device *dev;
 	struct cp_private *cp;
 	int rc;
 	void *regs;
 	long pciaddr;
-	unsigned int addr_len, i;
+	unsigned int addr_len, i, pci_using_dac;
 	u8 pci_rev, cache_size;
-	unsigned int board_type = (unsigned int) ent->driver_data;
 
 #ifndef MODULE
 	static int version_printed;
@@ -1706,7 +1641,6 @@
 	SET_MODULE_OWNER(dev);
 	cp = dev->priv;
 	cp->pdev = pdev;
-	cp->board_type = board_type;
 	cp->dev = dev;
 	cp->msg_enable = (debug < 0 ? CP_DEF_MSG_ENABLE : debug);
 	spin_lock_init (&cp->lock);
@@ -1747,18 +1681,22 @@
 	}
 
 	/* Configure DMA attributes. */
-	if (!pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL)) {
-		cp->pci_using_dac = 1;
+	if ((sizeof(dma_addr_t) > 32) &&
+	    !pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) {
+		pci_using_dac = 1;
 	} else {
-		rc = pci_set_dma_mask(pdev, (u64) 0xffffffff);
+		rc = pci_set_dma_mask(pdev, 0xffffffffULL);
 		if (rc) {
 			printk(KERN_ERR PFX "No usable DMA configuration, "
 			       "aborting.\n");
 			goto err_out_res;
 		}
-		cp->pci_using_dac = 0;
+		pci_using_dac = 0;
 	}
 
+	cp->cpcmd = (pci_using_dac ? PCIDAC : 0) |
+		    PCIMulRW | RxChkSum | CpRxOn | CpTxOn;
+
 	regs = ioremap_nocache(pciaddr, CP_REGS_SIZE);
 	if (!regs) {
 		rc = -EIO;
@@ -1783,6 +1721,8 @@
 	dev->hard_start_xmit = cp_start_xmit;
 	dev->get_stats = cp_get_stats;
 	dev->do_ioctl = cp_ioctl;
+	dev->poll = cp_rx_poll;
+	dev->weight = 16;	/* arbitrary? from NAPI_HOWTO.txt. */
 #ifdef BROKEN
 	dev->change_mtu = cp_change_mtu;
 #endif
@@ -1791,9 +1731,7 @@
 	dev->tx_timeout = cp_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
 #endif
-#ifdef CP_TX_CHECKSUM
-	dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-#endif
+
 #if CP_VLAN_TAG_USED
 	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
 	dev->vlan_rx_register = cp_vlan_rx_register;
@@ -1806,11 +1744,10 @@
 	if (rc)
 		goto err_out_iomap;
 
-	printk (KERN_INFO "%s: %s at 0x%lx, "
+	printk (KERN_INFO "%s: RTL-8139C+ at 0x%lx, "
 		"%02x:%02x:%02x:%02x:%02x:%02x, "
 		"IRQ %d\n",
 		dev->name,
-		cp_board_tbl[board_type].name,
 		dev->base_addr,
 		dev->dev_addr[0], dev->dev_addr[1],
 		dev->dev_addr[2], dev->dev_addr[3],
@@ -1858,7 +1795,7 @@
 	return rc;
 }
 
-static void __devexit cp_remove_one (struct pci_dev *pdev)
+static void cp_remove_one (struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct cp_private *cp = dev->priv;
@@ -1931,7 +1868,7 @@
 	.name         = DRV_NAME,
 	.id_table     = cp_pci_tbl,
 	.probe        =	cp_init_one,
-	.remove       = __devexit_p(cp_remove_one),
+	.remove       = cp_remove_one,
 #ifdef CONFIG_PM
 	.resume       = cp_resume,
 	.suspend      = cp_suspend,
diff -Nru a/drivers/net/8139too.c b/drivers/net/8139too.c
--- a/drivers/net/8139too.c	Sun Aug 31 10:06:32 2003
+++ b/drivers/net/8139too.c	Sun Aug 31 10:06:32 2003
@@ -122,6 +122,11 @@
 #define USE_IO_OPS 1
 #endif
 
+/* use a 16K rx ring buffer instead of the default 32K */
+#ifdef CONFIG_SH_DREAMCAST
+#define USE_BUF16K 1
+#endif
+
 /* define to 1 to enable copious debugging info */
 #undef RTL8139_DEBUG
 
@@ -164,7 +169,11 @@
 static int debug = -1;
 
 /* Size of the in-memory receive ring. */
+#ifdef USE_BUF16K
+#define RX_BUF_LEN_IDX	1	/* 0==8K, 1==16K, 2==32K, 3==64K */
+#else
 #define RX_BUF_LEN_IDX	2	/* 0==8K, 1==16K, 2==32K, 3==64K */
+#endif
 #define RX_BUF_LEN	(8192 << RX_BUF_LEN_IDX)
 #define RX_BUF_PAD	16
 #define RX_BUF_WRAP_PAD 2048 /* spare padding to handle lack of packet wrap */
@@ -211,18 +220,7 @@
 
 typedef enum {
 	RTL8139 = 0,
-	RTL8139_CB,
-	SMC1211TX,
-	/*MPX5030,*/
-	DELTA8139,
-	ADDTRON8139,
-	DFE538TX,
-	DFE690TXD,
-	FE2000VX,
-	ALLIED8139,
 	RTL8129,
-	FNW3603TX,
-	FNW3800TX,
 } board_t;
 
 
@@ -231,36 +229,29 @@
 	const char *name;
 	u32 hw_flags;
 } board_info[] __devinitdata = {
-	{ "RealTek RTL8139 Fast Ethernet", RTL8139_CAPS },
-	{ "RealTek RTL8139B PCI/CardBus", RTL8139_CAPS },
-	{ "SMC1211TX EZCard 10/100 (RealTek RTL8139)", RTL8139_CAPS },
-/*	{ MPX5030, "Accton MPX5030 (RealTek RTL8139)", RTL8139_CAPS },*/
-	{ "Delta Electronics 8139 10/100BaseTX", RTL8139_CAPS },
-	{ "Addtron Technolgy 8139 10/100BaseTX", RTL8139_CAPS },
-	{ "D-Link DFE-538TX (RealTek RTL8139)", RTL8139_CAPS },
-	{ "D-Link DFE-690TXD (RealTek RTL8139)", RTL8139_CAPS },
-	{ "AboCom FE2000VX (RealTek RTL8139)", RTL8139_CAPS },
-	{ "Allied Telesyn 8139 CardBus", RTL8139_CAPS },
+	{ "RealTek RTL8139", RTL8139_CAPS },
 	{ "RealTek RTL8129", RTL8129_CAPS },
-	{ "Planex FNW-3603-TX 10/100 CardBus", RTL8139_CAPS },
-	{ "Planex FNW-3800-TX 10/100 CardBus", RTL8139_CAPS },
 };
 
 
 static struct pci_device_id rtl8139_pci_tbl[] = {
 	{0x10ec, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-	{0x10ec, 0x8138, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139_CB },
-	{0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SMC1211TX },
-/*	{0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MPX5030 },*/
-	{0x1500, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DELTA8139 },
-	{0x4033, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ADDTRON8139 },
-	{0x1186, 0x1300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DFE538TX },
-	{0x1186, 0x1340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DFE690TXD },
-	{0x13d1, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, FE2000VX },
-	{0x1259, 0xa117, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ALLIED8139 },
-	{0x14ea, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, FNW3603TX },
-	{0x14ea, 0xab07, PCI_ANY_ID, PCI_ANY_ID, 0, 0, FNW3800TX },
-
+	{0x10ec, 0x8138, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+	{0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+	{0x1500, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+	{0x4033, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+	{0x1186, 0x1300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+	{0x1186, 0x1340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+	{0x13d1, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+	{0x1259, 0xa117, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+	{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 },
+
+#ifdef CONFIG_SH_SECUREEDGE5410
+	/* Bogus 8139 silicon reports 8129 without external PROM :-( */
+	{0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
+#endif
 #ifdef CONFIG_8139TOO_8129
 	{0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8129 },
 #endif
@@ -270,8 +261,8 @@
 	 * so we simply don't match on the main vendor id.
 	 */
 	{PCI_ANY_ID, 0x8139, 0x10ec, 0x8139, 0, 0, RTL8139 },
-	{PCI_ANY_ID, 0x8139, 0x1186, 0x1300, 0, 0, DFE538TX },
-	{PCI_ANY_ID, 0x8139, 0x13d1, 0xab06, 0, 0, FE2000VX },
+	{PCI_ANY_ID, 0x8139, 0x1186, 0x1300, 0, 0, RTL8139 },
+	{PCI_ANY_ID, 0x8139, 0x13d1, 0xab06, 0, 0, RTL8139 },
 
 	{0,}
 };
@@ -706,10 +697,17 @@
 	PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver |
 	TxErr | TxOK | RxErr | RxOK;
 
+#ifdef USE_BUF16K 
+static const unsigned int rtl8139_rx_config =
+	RxCfgRcv16K | RxNoWrap |
+	(RX_FIFO_THRESH << RxCfgFIFOShift) |
+	(RX_DMA_BURST << RxCfgDMAShift);
+#else
 static const unsigned int rtl8139_rx_config =
 	RxCfgRcv32K | RxNoWrap |
 	(RX_FIFO_THRESH << RxCfgFIFOShift) |
 	(RX_DMA_BURST << RxCfgDMAShift);
+#endif
 
 static const unsigned int rtl8139_tx_config =
 	(TX_DMA_BURST << TxDMAShift) | (TX_RETRY << TxRetryShift);
diff -Nru a/drivers/net/eth16i.c b/drivers/net/eth16i.c
--- a/drivers/net/eth16i.c	Sun Aug 31 10:06:32 2003
+++ b/drivers/net/eth16i.c	Sun Aug 31 10:06:32 2003
@@ -1057,7 +1057,7 @@
 	int ioaddr = dev->base_addr;
 	int status = 0;
 	ushort length = skb->len;
-	unsigned char *buf = skb->data;
+	unsigned char *buf;
 	unsigned long flags;
 
 	if(length < ETH_ZLEN)
@@ -1067,6 +1067,7 @@
 			return 0;
 		length = ETH_ZLEN;
 	}
+	buf = skb->data;
 
 	netif_stop_queue(dev);
 		
diff -Nru a/drivers/net/fmv18x.c b/drivers/net/fmv18x.c
--- a/drivers/net/fmv18x.c	Sun Aug 31 10:06:32 2003
+++ b/drivers/net/fmv18x.c	Sun Aug 31 10:06:32 2003
@@ -370,7 +370,7 @@
 	struct net_local *lp = dev->priv;
 	int ioaddr = dev->base_addr;
 	short length = skb->len;
-	unsigned char *buf = skb->data;
+	unsigned char *buf;
 	unsigned long flags;
 
 	/* Block a transmit from overlapping.  */
@@ -389,6 +389,7 @@
 			return 0;
 		length = ETH_ZLEN;
 	}
+	buf = skb->data;
 	
 	if (net_debug > 4)
 		printk("%s: Transmitting a packet of length %lu.\n", dev->name,
diff -Nru a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
--- a/drivers/net/pcmcia/3c574_cs.c	Sun Aug 31 10:06:32 2003
+++ b/drivers/net/pcmcia/3c574_cs.c	Sun Aug 31 10:06:32 2003
@@ -1216,9 +1216,11 @@
 		  data[0], data[1], data[2], data[3]);
 
     switch(cmd) {
-	case SIOCDEVPRIVATE:		/* Get the address of the PHY in use. */
+	case SIOCGMIIPHY:		/* Get the address of the PHY in use. */
+	case SIOCDEVPRIVATE:
 		data[0] = phy;
-	case SIOCDEVPRIVATE+1:		/* Read the specified MII register. */
+	case SIOCGMIIREG:		/* Read the specified MII register. */
+	case SIOCDEVPRIVATE+1:
 		{
 			int saved_window;
 			unsigned long flags;
@@ -1232,7 +1234,8 @@
 			restore_flags(flags);
 			return 0;
 		}
-	case SIOCDEVPRIVATE+2:		/* Write the specified MII register */
+	case SIOCSMIIREG:		/* Write the specified MII register */
+	case SIOCDEVPRIVATE+2:
 		{
 			int saved_window;
 			unsigned long flags;
diff -Nru a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
--- a/drivers/net/pcmcia/axnet_cs.c	Sun Aug 31 10:06:32 2003
+++ b/drivers/net/pcmcia/axnet_cs.c	Sun Aug 31 10:06:32 2003
@@ -843,11 +843,14 @@
     u16 *data = (u16 *)&rq->ifr_data;
     ioaddr_t mii_addr = dev->base_addr + AXNET_MII_EEP;
     switch (cmd) {
+    case SIOCGMIIPHY:
     case SIOCDEVPRIVATE:
 	data[0] = info->phy_id;
+    case SIOCGMIIREG:		/* Read MII PHY register. */
     case SIOCDEVPRIVATE+1:
 	data[3] = mdio_read(mii_addr, data[0], data[1] & 0x1f);
 	return 0;
+    case SIOCSMIIREG:		/* Write MII PHY register. */
     case SIOCDEVPRIVATE+2:
 	if (!capable(CAP_NET_ADMIN))
 	    return -EPERM;
diff -Nru a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
--- a/drivers/net/pcmcia/pcnet_cs.c	Sun Aug 31 10:06:32 2003
+++ b/drivers/net/pcmcia/pcnet_cs.c	Sun Aug 31 10:06:32 2003
@@ -1236,11 +1236,14 @@
     u16 *data = (u16 *)&rq->ifr_data;
     ioaddr_t mii_addr = dev->base_addr + DLINK_GPIO;
     switch (cmd) {
+    case SIOCGMIIPHY:
     case SIOCDEVPRIVATE:
 	data[0] = info->phy_id;
+    case SIOCGMIIREG:		/* Read MII PHY register. */
     case SIOCDEVPRIVATE+1:
 	data[3] = mdio_read(mii_addr, data[0], data[1] & 0x1f);
 	return 0;
+    case SIOCSMIIREG:		/* Write MII PHY register. */
     case SIOCDEVPRIVATE+2:
 	if (!capable(CAP_NET_ADMIN))
 	    return -EPERM;
diff -Nru a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
--- a/drivers/net/pcmcia/xirc2ps_cs.c	Sun Aug 31 10:06:32 2003
+++ b/drivers/net/pcmcia/xirc2ps_cs.c	Sun Aug 31 10:06:32 2003
@@ -1749,13 +1749,16 @@
 	return -EOPNOTSUPP;
 
     switch(cmd) {
-      case SIOCDEVPRIVATE:	/* Get the address of the PHY in use. */
+      case SIOCGMIIPHY:		/* Get the address of the PHY in use. */
+      case SIOCDEVPRIVATE:
 	data[0] = 0;		/* we have only this address */
 	/* fall trough */
-      case SIOCDEVPRIVATE+1:	/* Read the specified MII register. */
+      case SIOCGMIIREG:		/* Read the specified MII register. */
+      case SIOCDEVPRIVATE+1:
 	data[3] = mii_rd(ioaddr, data[0] & 0x1f, data[1] & 0x1f);
 	break;
-      case SIOCDEVPRIVATE+2:	/* Write the specified MII register */
+      case SIOCSMIIREG:		/* Write the specified MII register */
+      case SIOCDEVPRIVATE+2:
 	if (!capable(CAP_NET_ADMIN))
 	    return -EPERM;
 	mii_wr(ioaddr, data[0] & 0x1f, data[1] & 0x1f, data[2], 16);
diff -Nru a/drivers/net/seeq8005.c b/drivers/net/seeq8005.c
--- a/drivers/net/seeq8005.c	Sun Aug 31 10:06:32 2003
+++ b/drivers/net/seeq8005.c	Sun Aug 31 10:06:32 2003
@@ -379,7 +379,7 @@
 {
 	struct net_local *lp = (struct net_local *)dev->priv;
 	short length = skb->len;
-	unsigned char *buf = skb->data;
+	unsigned char *buf;
 
 	if(length < ETH_ZLEN)
 	{
@@ -388,6 +388,8 @@
 			return 0;
 		length = ETH_ZLEN;
 	}
+	buf = skb->data;
+
 	/* Block a timer-based transmit from overlapping */
 	netif_stop_queue(dev);
 	
diff -Nru a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
--- a/drivers/net/yellowfin.c	Sun Aug 31 10:06:32 2003
+++ b/drivers/net/yellowfin.c	Sun Aug 31 10:06:32 2003
@@ -867,8 +867,6 @@
 	/* Calculate the next Tx descriptor entry. */
 	entry = yp->cur_tx % TX_RING_SIZE;
 
-	yp->tx_skbuff[entry] = skb;
-
 	if (gx_fix) {	/* Note: only works for paddable protocols e.g.  IP. */
 		int cacheline_end = ((unsigned long)skb->data + skb->len) % 32;
 		/* Fix GX chipset errata. */
@@ -885,6 +883,8 @@
 			return 0;
 		}
 	}
+	yp->tx_skbuff[entry] = skb;
+
 #ifdef NO_TXSTATS
 	yp->tx_ring[entry].addr = cpu_to_le32(pci_map_single(yp->pci_dev, 
 		skb->data, len, PCI_DMA_TODEVICE));

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

* [bk patches] 2.4.x net driver updates
@ 2003-08-08  0:59 Jeff Garzik
  0 siblings, 0 replies; 7+ messages in thread
From: Jeff Garzik @ 2003-08-08  0:59 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel

(this will be sent to Marcelo when 2.4.23-pre1 opens)

BK users:

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

GNU diff:

ftp://ftp.??.kernel.org/pub/linux/kernel/people/jgarzik/patchkits/2.4/2.4.22-rc1-netdrvr1.patch.bz2

This will update the following files:

 drivers/net/bonding/bond_main.c |   17 +++--------------
 drivers/net/bonding/bonding.h   |    2 +-
 drivers/net/net_init.c          |    3 ++-
 drivers/net/wireless/airo.c     |   31 +++++++++++++++++++------------
 include/linux/netdevice.h       |    2 ++
 5 files changed, 27 insertions(+), 28 deletions(-)

through these ChangeSets:

<amir.noam@intel.com> (03/08/07 1.1072)
   [netdrvr bonding] embed stats struct inside bonding private struct
   
   Simplification: Don't allocate the stats struct via kmalloc,
   embed it inside it's parent bonding_t.

<amir.noam@intel.com> (03/08/07 1.1071)
   [net] export alloc_netdev

<achirica@telefonica.net> (03/08/07 1.1070)
   [PATCH] Fix adhoc config

<achirica@telefonica.net> (03/08/07 1.1069)
   [PATCH] Safer unload code

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

<achirica@telefonica.net> (03/08/07 1.1067)
   [PATCH] Missing lines for Wireless Extensions 16

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

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


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

end of thread, other threads:[~2005-04-27 21:18 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-10-14 19:01 [BK PATCHES] 2.4.x net driver updates Jeff Garzik
  -- strict thread matches above, loose matches on Subject: below --
2005-04-27 21:17 Jeff Garzik
2005-03-04  0:33 Jeff Garzik
2004-08-29  0:26 Jeff Garzik
2003-09-01 15:49 [bk patches] " Jeff Garzik
2003-08-31 14:09 Jeff Garzik
2003-08-08  0:59 Jeff Garzik

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.