All of lore.kernel.org
 help / color / mirror / Atom feed
* [DESC 2.6.8.1-mm4] r8169 patches
@ 2004-08-23 22:41 Francois Romieu
  2004-08-23 22:44 ` [PATCH 2.6.8.1-mm4 1/11] r8169: add ethtool_ops.{get_regs_len/get_regs} Francois Romieu
  2004-08-27 15:09 ` [DESC 2.6.8.1-mm4] r8169 patches Jon Mason
  0 siblings, 2 replies; 17+ messages in thread
From: Francois Romieu @ 2004-08-23 22:41 UTC (permalink / raw)
  To: jgarzik; +Cc: akpm, netdev

Here comes a new serie of r8169 related patches which should allow
the motivated users to experiment new features, namely:
- Rx/Tx checksum offload;
- vlan support;
- better ethtool integration.

Tx code apart, the changes exhibit some strong similarity with the
8139cp driver.

I have not done vlan-dedicated test and there are no figures to highlight
any performance improvement. The code does not crash in a (really slow)
debug enabled -mm kernel and it does not seem to add huge leak.

Remarks/comments/test reports welcome.

--
Ueimor

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

* [PATCH 2.6.8.1-mm4 1/11] r8169: add ethtool_ops.{get_regs_len/get_regs}
  2004-08-23 22:41 [DESC 2.6.8.1-mm4] r8169 patches Francois Romieu
@ 2004-08-23 22:44 ` Francois Romieu
  2004-08-23 22:45   ` [PATCH 2.6.8.1-mm4 2/11] r8169: per device receive buffer size Francois Romieu
  2004-08-27 15:09 ` [DESC 2.6.8.1-mm4] r8169 patches Jon Mason
  1 sibling, 1 reply; 17+ messages in thread
From: Francois Romieu @ 2004-08-23 22:44 UTC (permalink / raw)
  To: jgarzik; +Cc: akpm, netdev


- ethtool_ops.{get_regs_len/get_regs} for r8169;
- fix a dubious check: datasheet v1.21 claims on p.44 that io/memory space
  is exactly 256 bytes wide;
- use SET_ETHTOOL_OPS().

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

diff -puN drivers/net/r8169.c~r8169-000 drivers/net/r8169.c
--- linux-2.6.8.1/drivers/net/r8169.c~r8169-000	2004-08-23 23:29:58.000000000 +0200
+++ linux-2.6.8.1-fr/drivers/net/r8169.c	2004-08-23 23:29:58.000000000 +0200
@@ -99,6 +99,7 @@ static int multicast_filter_limit = 32;
 #define RxPacketMaxSize	0x0800	/* Maximum size supported is 16K-1 */
 #define InterFrameGap	0x03	/* 3 means InterFrameGap = the shortest one */
 
+#define R8169_REGS_SIZE		256
 #define R8169_NAPI_WEIGHT	64
 #define NUM_TX_DESC	64	/* Number of Tx descriptor registers */
 #define NUM_RX_DESC	256	/* Number of Rx descriptor registers */
@@ -106,7 +107,6 @@ static int multicast_filter_limit = 32;
 #define R8169_TX_RING_BYTES	(NUM_TX_DESC * sizeof(struct TxDesc))
 #define R8169_RX_RING_BYTES	(NUM_RX_DESC * sizeof(struct RxDesc))
 
-#define RTL_MIN_IO_SIZE 0x80
 #define RTL8169_TX_TIMEOUT	(6*HZ)
 #define RTL8169_PHY_TIMEOUT	(10*HZ)
 
@@ -508,6 +508,11 @@ static void rtl8169_get_drvinfo(struct n
 	strcpy(info->bus_info, pci_name(tp->pci_dev));
 }
 
+static int rtl8169_get_regs_len(struct net_device *dev)
+{
+	return R8169_REGS_SIZE;
+}
+
 static int rtl8169_set_speed_tbi(struct net_device *dev,
 				 u8 autoneg, u16 speed, u8 duplex)
 {
@@ -671,12 +676,27 @@ static int rtl8169_get_settings(struct n
 	return 0;
 }
 
+static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+			     void *p)
+{
+        struct rtl8169_private *tp = netdev_priv(dev);
+        unsigned long flags;
+
+        if (regs->len > R8169_REGS_SIZE)
+        	regs->len = R8169_REGS_SIZE;
+
+        spin_lock_irqsave(&tp->lock, flags);
+        memcpy_fromio(p, tp->mmio_addr, regs->len);
+        spin_unlock_irqrestore(&tp->lock, flags);
+}
 
 static struct ethtool_ops rtl8169_ethtool_ops = {
 	.get_drvinfo		= rtl8169_get_drvinfo,
+	.get_regs_len		= rtl8169_get_regs_len,
 	.get_link		= ethtool_op_get_link,
 	.get_settings		= rtl8169_get_settings,
 	.set_settings		= rtl8169_set_settings,
+	.get_regs		= rtl8169_get_regs,
 };
 
 static void rtl8169_write_gmii_reg_bit(void *ioaddr, int reg, int bitnum,
@@ -968,7 +988,7 @@ rtl8169_init_board(struct pci_dev *pdev,
 		goto err_out_disable;
 	}
 	// check for weird/broken PCI region reporting
-	if (mmio_len < RTL_MIN_IO_SIZE) {
+	if (mmio_len < R8169_REGS_SIZE) {
 		printk(KERN_ERR PFX "Invalid PCI region size(s), aborting\n");
 		rc = -ENODEV;
 		goto err_out_disable;
@@ -1105,7 +1125,7 @@ rtl8169_init_one(struct pci_dev *pdev, c
 	dev->open = rtl8169_open;
 	dev->hard_start_xmit = rtl8169_start_xmit;
 	dev->get_stats = rtl8169_get_stats;
-	dev->ethtool_ops = &rtl8169_ethtool_ops;
+	SET_ETHTOOL_OPS(dev, &rtl8169_ethtool_ops);
 	dev->stop = rtl8169_close;
 	dev->tx_timeout = rtl8169_tx_timeout;
 	dev->set_multicast_list = rtl8169_set_rx_mode;

_

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

* [PATCH 2.6.8.1-mm4 2/11] r8169: per device receive buffer size
  2004-08-23 22:44 ` [PATCH 2.6.8.1-mm4 1/11] r8169: add ethtool_ops.{get_regs_len/get_regs} Francois Romieu
@ 2004-08-23 22:45   ` Francois Romieu
  2004-08-23 22:47     ` [PATCH 2.6.8.1-mm4 3/11] r8169: code cleanup Francois Romieu
  0 siblings, 1 reply; 17+ messages in thread
From: Francois Romieu @ 2004-08-23 22:45 UTC (permalink / raw)
  To: jgarzik; +Cc: akpm, netdev

Turn the Rx receive buffer size into a per device variable.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

diff -puN drivers/net/r8169.c~r8169-010 drivers/net/r8169.c
--- linux-2.6.8.1/drivers/net/r8169.c~r8169-010	2004-08-23 23:29:59.000000000 +0200
+++ linux-2.6.8.1-fr/drivers/net/r8169.c	2004-08-23 23:29:59.000000000 +0200
@@ -341,6 +341,7 @@ struct rtl8169_private {
 	dma_addr_t RxPhyAddr;
 	struct sk_buff *Rx_skbuff[NUM_RX_DESC];	/* Rx data buffers */
 	struct sk_buff *Tx_skbuff[NUM_TX_DESC];	/* Tx data buffers */
+	unsigned rx_buf_sz;
 	struct timer_list timer;
 	u16 cp_cmd;
 	u16 intr_mask;
@@ -1056,6 +1057,8 @@ rtl8169_init_board(struct pci_dev *pdev,
 	}
 	tp->chipset = i;
 
+	tp->rx_buf_sz = RX_BUF_SIZE;
+
 	*ioaddr_out = ioaddr;
 	*dev_out = dev;
 	return 0;
@@ -1377,46 +1380,48 @@ static inline void rtl8169_make_unusable
 	desc->status &= ~cpu_to_le32(OWNbit | RsvdMask);
 }
 
-static void rtl8169_free_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff,
-				struct RxDesc *desc)
+static void rtl8169_free_rx_skb(struct rtl8169_private *tp,
+				struct sk_buff **sk_buff, struct RxDesc *desc)
 {
-	pci_unmap_single(pdev, le64_to_cpu(desc->addr), RX_BUF_SIZE,
+	struct pci_dev *pdev = tp->pci_dev;
+
+	pci_unmap_single(pdev, le64_to_cpu(desc->addr), tp->rx_buf_sz,
 			 PCI_DMA_FROMDEVICE);
 	dev_kfree_skb(*sk_buff);
 	*sk_buff = NULL;
 	rtl8169_make_unusable_by_asic(desc);
 }
 
-static inline void rtl8169_return_to_asic(struct RxDesc *desc)
+static inline void rtl8169_return_to_asic(struct RxDesc *desc, int rx_buf_sz)
 {
-	desc->status |= cpu_to_le32(OWNbit + RX_BUF_SIZE);
+	desc->status |= cpu_to_le32(OWNbit + rx_buf_sz);
 }
 
-static inline void rtl8169_give_to_asic(struct RxDesc *desc, dma_addr_t mapping)
+static inline void rtl8169_give_to_asic(struct RxDesc *desc, dma_addr_t mapping,
+					int rx_buf_sz)
 {
 	desc->addr = cpu_to_le64(mapping);
-	desc->status |= cpu_to_le32(OWNbit + RX_BUF_SIZE);
+	desc->status |= cpu_to_le32(OWNbit + rx_buf_sz);
 }
 
-static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct net_device *dev,
-				struct sk_buff **sk_buff, struct RxDesc *desc)
+static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff,
+				struct RxDesc *desc, int rx_buf_sz)
 {
 	struct sk_buff *skb;
 	dma_addr_t mapping;
 	int ret = 0;
 
-	skb = dev_alloc_skb(RX_BUF_SIZE);
+	skb = dev_alloc_skb(rx_buf_sz);
 	if (!skb)
 		goto err_out;
 
-	skb->dev = dev;
 	skb_reserve(skb, 2);
 	*sk_buff = skb;
 
-	mapping = pci_map_single(pdev, skb->tail, RX_BUF_SIZE,
+	mapping = pci_map_single(pdev, skb->tail, rx_buf_sz,
 				 PCI_DMA_FROMDEVICE);
 
-	rtl8169_give_to_asic(desc, mapping);
+	rtl8169_give_to_asic(desc, mapping, rx_buf_sz);
 
 out:
 	return ret;
@@ -1433,7 +1438,7 @@ static void rtl8169_rx_clear(struct rtl8
 
 	for (i = 0; i < NUM_RX_DESC; i++) {
 		if (tp->Rx_skbuff[i]) {
-			rtl8169_free_rx_skb(tp->pci_dev, tp->Rx_skbuff + i,
+			rtl8169_free_rx_skb(tp, tp->Rx_skbuff + i,
 					    tp->RxDescArray + i);
 		}
 	}
@@ -1450,8 +1455,8 @@ static u32 rtl8169_rx_fill(struct rtl816
 		if (tp->Rx_skbuff[i])
 			continue;
 			
-		ret = rtl8169_alloc_rx_skb(tp->pci_dev, dev, tp->Rx_skbuff + i,
-					   tp->RxDescArray + i);
+		ret = rtl8169_alloc_rx_skb(tp->pci_dev, tp->Rx_skbuff + i,
+					   tp->RxDescArray + i, tp->rx_buf_sz);
 		if (ret < 0)
 			break;
 	}
@@ -1646,8 +1651,7 @@ rtl8169_tx_interrupt(struct net_device *
 }
 
 static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size,
-				      struct RxDesc *desc,
-				      struct net_device *dev)
+				      struct RxDesc *desc, int rx_buf_sz)
 {
 	int ret = -1;
 
@@ -1656,11 +1660,10 @@ static inline int rtl8169_try_rx_copy(st
 
 		skb = dev_alloc_skb(pkt_size + 2);
 		if (skb) {
-			skb->dev = dev;
 			skb_reserve(skb, 2);
 			eth_copy_and_sum(skb, sk_buff[0]->tail, pkt_size, 0);
 			*sk_buff = skb;
-			rtl8169_return_to_asic(desc);
+			rtl8169_return_to_asic(desc, rx_buf_sz);
 			ret = 0;
 		}
 	}
@@ -1707,17 +1710,19 @@ rtl8169_rx_interrupt(struct net_device *
 
 
 			pci_dma_sync_single_for_cpu(tp->pci_dev,
-				le64_to_cpu(desc->addr), RX_BUF_SIZE,
+				le64_to_cpu(desc->addr), tp->rx_buf_sz,
 				PCI_DMA_FROMDEVICE);
 
-			if (rtl8169_try_rx_copy(&skb, pkt_size, desc, dev)) {
+			if (rtl8169_try_rx_copy(&skb, pkt_size, desc,
+						tp->rx_buf_sz)) {
 				pci_action = pci_unmap_single;
 				tp->Rx_skbuff[entry] = NULL;
 			}
 
 			pci_action(tp->pci_dev, le64_to_cpu(desc->addr),
-				   RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+				   tp->rx_buf_sz, PCI_DMA_FROMDEVICE);
 
+			skb->dev = dev;
 			skb_put(skb, pkt_size);
 			skb->protocol = eth_type_trans(skb, dev);
 			rtl8169_rx_skb(skb);

_

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

* [PATCH 2.6.8.1-mm4 3/11] r8169: code cleanup
  2004-08-23 22:45   ` [PATCH 2.6.8.1-mm4 2/11] r8169: per device receive buffer size Francois Romieu
@ 2004-08-23 22:47     ` Francois Romieu
  2004-08-23 22:48       ` [PATCH 2.6.8.1-mm4 4/11] r8169: enable MWI Francois Romieu
  0 siblings, 1 reply; 17+ messages in thread
From: Francois Romieu @ 2004-08-23 22:47 UTC (permalink / raw)
  To: jgarzik; +Cc: akpm, netdev

Cleanup/code removal:
- MAX_ETH_FRAME_SIZE is not used;
- removal of assertion for impossible condition (if it happens, it will _not_
  take long to notice anyway)
- introduce rtl8169_release_board() to factor out some code;
- rtl8169_init_board:
  - some variables are not really needed nor do they help read the code;
  - more explicit name for label;
- tp->{Rx/Tx}DescArray: no need to zeroize coherent DMA mapping.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

diff -puN drivers/net/r8169.c~r8169-020 drivers/net/r8169.c
--- linux-2.6.8.1/drivers/net/r8169.c~r8169-020	2004-08-23 23:29:59.000000000 +0200
+++ linux-2.6.8.1-fr/drivers/net/r8169.c	2004-08-23 23:29:59.000000000 +0200
@@ -87,9 +87,6 @@ static int multicast_filter_limit = 32;
 /* MAC address length*/
 #define MAC_ADDR_LEN	6
 
-/* max supported gigabit ethernet frame size -- must be at least (dev->mtu+14+4).*/
-#define MAX_ETH_FRAME_SIZE	1536
-
 #define TX_FIFO_THRESH 256	/* In bytes */
 
 #define RX_FIFO_THRESH	7	/* 7 means NO threshold, Rx buffer level before first PCI xfer.  */
@@ -928,28 +925,31 @@ static inline void rtl8169_request_timer
 	add_timer(timer);
 }
 
+static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev,
+				  void *ioaddr)
+{
+	iounmap(ioaddr);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+	free_netdev(dev);
+}
+
 static int __devinit
 rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
 		   void **ioaddr_out)
 {
-	void *ioaddr = NULL;
+	void *ioaddr;
 	struct net_device *dev;
 	struct rtl8169_private *tp;
-	unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
-	int rc, i, acpi_idle_state = 0, pm_cap;
+	int rc = -ENOMEM, i, acpi_idle_state = 0, pm_cap;
 
-
-	assert(pdev != NULL);
 	assert(ioaddr_out != NULL);
 
-	*ioaddr_out = NULL;
-	*dev_out = NULL;
-
 	// dev zeroed in alloc_etherdev 
 	dev = alloc_etherdev(sizeof (*tp));
 	if (dev == NULL) {
 		printk(KERN_ERR PFX "unable to alloc new ethernet\n");
-		return -ENOMEM;
+		goto err_out;
 	}
 
 	SET_MODULE_OWNER(dev);
@@ -960,7 +960,7 @@ rtl8169_init_board(struct pci_dev *pdev,
 	rc = pci_enable_device(pdev);
 	if (rc) {
 		printk(KERN_ERR PFX "%s: enable failure\n", pdev->slot_name);
-		goto err_out;
+		goto err_out_free_dev;
 	}
 
 	/* save power state before pci_enable_device overwrites it */
@@ -976,20 +976,15 @@ rtl8169_init_board(struct pci_dev *pdev,
 		goto err_out_free_res;
 	}
 
-	mmio_start = pci_resource_start(pdev, 1);
-	mmio_end = pci_resource_end(pdev, 1);
-	mmio_flags = pci_resource_flags(pdev, 1);
-	mmio_len = pci_resource_len(pdev, 1);
-
 	// make sure PCI base addr 1 is MMIO
-	if (!(mmio_flags & IORESOURCE_MEM)) {
+	if (!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
 		printk(KERN_ERR PFX
 		       "region #1 not an MMIO resource, aborting\n");
 		rc = -ENODEV;
 		goto err_out_disable;
 	}
 	// check for weird/broken PCI region reporting
-	if (mmio_len < R8169_REGS_SIZE) {
+	if (pci_resource_len(pdev, 1) < R8169_REGS_SIZE) {
 		printk(KERN_ERR PFX "Invalid PCI region size(s), aborting\n");
 		rc = -ENODEV;
 		goto err_out_disable;
@@ -1020,7 +1015,7 @@ rtl8169_init_board(struct pci_dev *pdev,
 	pci_set_master(pdev);
 
 	// ioremap MMIO region 
-	ioaddr = ioremap(mmio_start, mmio_len);
+	ioaddr = ioremap(pci_resource_start(pdev, 1), R8169_REGS_SIZE);
 	if (ioaddr == NULL) {
 		printk(KERN_ERR PFX "cannot remap MMIO, aborting\n");
 		rc = -EIO;
@@ -1061,7 +1056,8 @@ rtl8169_init_board(struct pci_dev *pdev,
 
 	*ioaddr_out = ioaddr;
 	*dev_out = dev;
-	return 0;
+out:
+	return rc;
 
 err_out_free_res:
 	pci_release_regions(pdev);
@@ -1069,16 +1065,19 @@ err_out_free_res:
 err_out_disable:
 	pci_disable_device(pdev);
 
-err_out:
+err_out_free_dev:
 	free_netdev(dev);
-	return rc;
+err_out:
+	*ioaddr_out = NULL;
+	*dev_out = NULL;
+	goto out;
 }
 
 static int __devinit
 rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	struct net_device *dev = NULL;
-	struct rtl8169_private *tp = NULL;
+	struct rtl8169_private *tp;
 	void *ioaddr = NULL;
 	static int board_idx = -1;
 	static int printed_version = 0;
@@ -1102,8 +1101,6 @@ rtl8169_init_one(struct pci_dev *pdev, c
 
 	tp = dev->priv;
 	assert(ioaddr != NULL);
-	assert(dev != NULL);
-	assert(tp != NULL);
 
 	if (RTL_R8(PHYstatus) & TBI_Enable) {
 		tp->set_speed = rtl8169_set_speed_tbi;
@@ -1148,10 +1145,7 @@ rtl8169_init_one(struct pci_dev *pdev, c
 
 	rc = register_netdev(dev);
 	if (rc) {
-		iounmap(ioaddr);
-		pci_release_regions(pdev);
-		pci_disable_device(pdev);
-		free_netdev(dev);
+		rtl8169_release_board(pdev, dev, ioaddr);
 		return rc;
 	}
 
@@ -1207,11 +1201,7 @@ rtl8169_remove_one(struct pci_dev *pdev)
 	assert(tp != NULL);
 
 	unregister_netdev(dev);
-	iounmap(tp->mmio_addr);
-	pci_release_regions(pdev);
-
-	pci_disable_device(pdev);
-	free_netdev(dev);
+	rtl8169_release_board(pdev, dev, tp->mmio_addr);
 	pci_set_drvdata(pdev, NULL);
 }
 
@@ -1474,8 +1464,6 @@ static int rtl8169_init_ring(struct net_
 
 	tp->cur_rx = tp->dirty_rx = 0;
 	tp->cur_tx = tp->dirty_tx = 0;
-	memset(tp->TxDescArray, 0x0, NUM_TX_DESC * sizeof (struct TxDesc));
-	memset(tp->RxDescArray, 0x0, NUM_RX_DESC * sizeof (struct RxDesc));
 
 	memset(tp->Tx_skbuff, 0x0, NUM_TX_DESC * sizeof(struct sk_buff *));
 	memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *));

_

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

* [PATCH 2.6.8.1-mm4 4/11] r8169: enable MWI
  2004-08-23 22:47     ` [PATCH 2.6.8.1-mm4 3/11] r8169: code cleanup Francois Romieu
@ 2004-08-23 22:48       ` Francois Romieu
  2004-08-23 22:49         ` [PATCH 2.6.8.1-mm4 5/11] r8169: bump version number Francois Romieu
  0 siblings, 1 reply; 17+ messages in thread
From: Francois Romieu @ 2004-08-23 22:48 UTC (permalink / raw)
  To: jgarzik; +Cc: akpm, netdev


- enable Memory Write and Invalidate (disabled after reset);
- fix wrong goto.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

diff -puN drivers/net/r8169.c~r8169-030 drivers/net/r8169.c
--- linux-2.6.8.1/drivers/net/r8169.c~r8169-030	2004-08-23 23:30:00.000000000 +0200
+++ linux-2.6.8.1-fr/drivers/net/r8169.c	2004-08-23 23:30:00.000000000 +0200
@@ -32,7 +32,6 @@ VERSION 1.2	<2002/11/30>
 	- Use ether_crc in stock kernel (linux/crc32.h)
 	- Copy mc_filter setup code from 8139cp
 	  (includes an optimization, and avoids set_bit use)
-
 */
 
 #include <linux/module.h>
@@ -963,6 +962,10 @@ rtl8169_init_board(struct pci_dev *pdev,
 		goto err_out_free_dev;
 	}
 
+	rc = pci_set_mwi(pdev);
+	if (rc < 0)
+		goto err_out_disable;
+
 	/* save power state before pci_enable_device overwrites it */
 	pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
 	if (pm_cap) {
@@ -973,7 +976,7 @@ rtl8169_init_board(struct pci_dev *pdev,
 	} else {
 		printk(KERN_ERR PFX
 		       "Cannot find PowerManagement capability, aborting.\n");
-		goto err_out_free_res;
+		goto err_out_mwi;
 	}
 
 	// make sure PCI base addr 1 is MMIO
@@ -981,20 +984,20 @@ rtl8169_init_board(struct pci_dev *pdev,
 		printk(KERN_ERR PFX
 		       "region #1 not an MMIO resource, aborting\n");
 		rc = -ENODEV;
-		goto err_out_disable;
+		goto err_out_mwi;
 	}
 	// check for weird/broken PCI region reporting
 	if (pci_resource_len(pdev, 1) < R8169_REGS_SIZE) {
 		printk(KERN_ERR PFX "Invalid PCI region size(s), aborting\n");
 		rc = -ENODEV;
-		goto err_out_disable;
+		goto err_out_mwi;
 	}
 
 	rc = pci_request_regions(pdev, MODULENAME);
 	if (rc) {
 		printk(KERN_ERR PFX "%s: could not request regions.\n",
 		       pdev->slot_name);
-		goto err_out_disable;
+		goto err_out_mwi;
 	}
 
 	tp->cp_cmd = PCIMulRW | RxChkSum;
@@ -1011,7 +1014,6 @@ rtl8169_init_board(struct pci_dev *pdev,
 	}
 
 
-	// enable PCI bus-mastering
 	pci_set_master(pdev);
 
 	// ioremap MMIO region 
@@ -1062,6 +1064,9 @@ out:
 err_out_free_res:
 	pci_release_regions(pdev);
 
+err_out_mwi:
+	pci_clear_mwi(pdev);
+
 err_out_disable:
 	pci_disable_device(pdev);
 

_

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

* [PATCH 2.6.8.1-mm4 5/11] r8169: bump version number
  2004-08-23 22:48       ` [PATCH 2.6.8.1-mm4 4/11] r8169: enable MWI Francois Romieu
@ 2004-08-23 22:49         ` Francois Romieu
  2004-08-23 22:51           ` [PATCH 2.6.8.1-mm4 6/11] r8169: sync the names of a few bits with the 8139cp driver Francois Romieu
  0 siblings, 1 reply; 17+ messages in thread
From: Francois Romieu @ 2004-08-23 22:49 UTC (permalink / raw)
  To: jgarzik; +Cc: akpm, netdev

Help reviewers realize that the in-kernel driver has evolved lately.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

diff -puN drivers/net/r8169.c~r8169-040 drivers/net/r8169.c
--- linux-2.6.8.1/drivers/net/r8169.c~r8169-040	2004-08-23 23:30:00.000000000 +0200
+++ linux-2.6.8.1-fr/drivers/net/r8169.c	2004-08-23 23:30:00.000000000 +0200
@@ -6,6 +6,7 @@
  History:
  Feb  4 2002	- created initially by ShuChen <shuchen@realtek.com.tw>.
  May 20 2002	- Add link status force-mode and TBI mode support.
+        2004	- Massive updates. See kernel SCM system for details.
 =========================================================================
   1. [DEPRECATED: use ethtool instead] The media can be forced in 5 modes.
 	 Command: 'insmod r8169 media = SET_MEDIA'
@@ -32,6 +33,14 @@ VERSION 1.2	<2002/11/30>
 	- Use ether_crc in stock kernel (linux/crc32.h)
 	- Copy mc_filter setup code from 8139cp
 	  (includes an optimization, and avoids set_bit use)
+
+VERSION 1.6LK	<2004/04/14>
+
+	- Merge of Realtek's version 1.6
+	- Conversion to DMA API
+	- Suspend/resume
+	- Endianness
+	- Misc Rx/Tx bugs
 */
 
 #include <linux/module.h>
@@ -47,7 +56,7 @@ VERSION 1.2	<2002/11/30>
 
 #include <asm/io.h>
 
-#define RTL8169_VERSION "1.2"
+#define RTL8169_VERSION "1.6LK"
 #define MODULENAME "r8169"
 #define RTL8169_DRIVER_NAME   MODULENAME " Gigabit Ethernet driver " RTL8169_VERSION
 #define PFX MODULENAME ": "

_

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

* [PATCH 2.6.8.1-mm4 6/11] r8169: sync the names of a few bits with the 8139cp driver
  2004-08-23 22:49         ` [PATCH 2.6.8.1-mm4 5/11] r8169: bump version number Francois Romieu
@ 2004-08-23 22:51           ` Francois Romieu
  2004-08-23 22:53             ` [PATCH 2.6.8.1-mm4 7/11] r8169: comment a gcc 2.95.x bug Francois Romieu
  0 siblings, 1 reply; 17+ messages in thread
From: Francois Romieu @ 2004-08-23 22:51 UTC (permalink / raw)
  To: jgarzik; +Cc: akpm, netdev


Sync the names of the descriptor with these which are used in the 8139cp
driver. Though not exactly identical the descriptors are forward compatible.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

diff -puN drivers/net/r8169.c~r8169-060 drivers/net/r8169.c
--- linux-2.6.8.1/drivers/net/r8169.c~r8169-060	2004-08-23 23:30:01.000000000 +0200
+++ linux-2.6.8.1-fr/drivers/net/r8169.c	2004-08-23 23:30:01.000000000 +0200
@@ -308,23 +308,23 @@ enum RTL8169_register_content {
 };
 
 enum _DescStatusBit {
-	OWNbit = 0x80000000,
-	EORbit = 0x40000000,
-	FSbit = 0x20000000,
-	LSbit = 0x10000000,
+	DescOwn		= (1 << 31), /* Descriptor is owned by NIC */
+	RingEnd		= (1 << 30), /* End of descriptor ring */
+	FirstFrag	= (1 << 29), /* First segment of a packet */
+	LastFrag	= (1 << 28), /* Final segment of a packet */
 };
 
 #define RsvdMask	0x3fffc000
 
 struct TxDesc {
-	u32 status;
-	u32 vlan_tag;
+	u32 opts1;
+	u32 opts2;
 	u64 addr;
 };
 
 struct RxDesc {
-	u32 status;
-	u32 vlan_tag;
+	u32 opts1;
+	u32 opts2;
 	u64 addr;
 };
 
@@ -1381,7 +1381,7 @@ rtl8169_hw_start(struct net_device *dev)
 static inline void rtl8169_make_unusable_by_asic(struct RxDesc *desc)
 {
 	desc->addr = 0x0badbadbadbadbadull;
-	desc->status &= ~cpu_to_le32(OWNbit | RsvdMask);
+	desc->opts1 &= ~cpu_to_le32(DescOwn | RsvdMask);
 }
 
 static void rtl8169_free_rx_skb(struct rtl8169_private *tp,
@@ -1398,14 +1398,14 @@ static void rtl8169_free_rx_skb(struct r
 
 static inline void rtl8169_return_to_asic(struct RxDesc *desc, int rx_buf_sz)
 {
-	desc->status |= cpu_to_le32(OWNbit + rx_buf_sz);
+	desc->opts1 |= cpu_to_le32(DescOwn + rx_buf_sz);
 }
 
 static inline void rtl8169_give_to_asic(struct RxDesc *desc, dma_addr_t mapping,
 					int rx_buf_sz)
 {
 	desc->addr = cpu_to_le64(mapping);
-	desc->status |= cpu_to_le32(OWNbit + rx_buf_sz);
+	desc->opts1 |= cpu_to_le32(DescOwn + rx_buf_sz);
 }
 
 static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff,
@@ -1469,7 +1469,7 @@ static u32 rtl8169_rx_fill(struct rtl816
 
 static inline void rtl8169_mark_as_last_descriptor(struct RxDesc *desc)
 {
-	desc->status |= cpu_to_le32(EORbit);
+	desc->opts1 |= cpu_to_le32(RingEnd);
 }
 
 static int rtl8169_init_ring(struct net_device *dev)
@@ -1565,7 +1565,7 @@ rtl8169_start_xmit(struct sk_buff *skb, 
 		len = ETH_ZLEN;
 	}
 	
-	if (!(le32_to_cpu(tp->TxDescArray[entry].status) & OWNbit)) {
+	if (!(le32_to_cpu(tp->TxDescArray[entry].opts1) & DescOwn)) {
 		dma_addr_t mapping;
 		u32 status;
 
@@ -1576,9 +1576,9 @@ rtl8169_start_xmit(struct sk_buff *skb, 
 		tp->TxDescArray[entry].addr = cpu_to_le64(mapping);
 
 		/* anti gcc 2.95.3 bugware */
-		status = OWNbit | FSbit | LSbit | len |
-			 (EORbit * !((entry + 1) % NUM_TX_DESC));
-		tp->TxDescArray[entry].status = cpu_to_le32(status);
+		status = DescOwn | FirstFrag | LastFrag | len |
+			 (RingEnd * !((entry + 1) % NUM_TX_DESC));
+		tp->TxDescArray[entry].opts1 = cpu_to_le32(status);
 			
 		RTL_W8(TxPoll, 0x40);	//set polling bit
 
@@ -1628,8 +1628,8 @@ rtl8169_tx_interrupt(struct net_device *
 		u32 status;
 
 		rmb();
-		status = le32_to_cpu(tp->TxDescArray[entry].status);
-		if (status & OWNbit)
+		status = le32_to_cpu(tp->TxDescArray[entry].opts1);
+		if (status & DescOwn)
 			break;
 
 		/* FIXME: is it really accurate for TxErr ? */
@@ -1692,9 +1692,9 @@ rtl8169_rx_interrupt(struct net_device *
 		u32 status;
 
 		rmb();
-		status = le32_to_cpu(tp->RxDescArray[entry].status);
+		status = le32_to_cpu(tp->RxDescArray[entry].opts1);
 
-		if (status & OWNbit)
+		if (status & DescOwn)
 			break;
 		if (status & RxRES) {
 			printk(KERN_INFO "%s: Rx ERROR!!!\n", dev->name);

_

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

* [PATCH 2.6.8.1-mm4 7/11] r8169: comment a gcc 2.95.x bug
  2004-08-23 22:51           ` [PATCH 2.6.8.1-mm4 6/11] r8169: sync the names of a few bits with the 8139cp driver Francois Romieu
@ 2004-08-23 22:53             ` Francois Romieu
  2004-08-23 22:55               ` [PATCH 2.6.8.1-mm4 8/11] r8169: Tx checksum offload Francois Romieu
  0 siblings, 1 reply; 17+ messages in thread
From: Francois Romieu @ 2004-08-23 22:53 UTC (permalink / raw)
  To: jgarzik; +Cc: akpm, netdev


gcc 2.95.3 bug has been experienced on gcc 2.95.4.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

diff -puN drivers/net/r8169.c~r8169-070 drivers/net/r8169.c
--- linux-2.6.8.1/drivers/net/r8169.c~r8169-070	2004-08-23 23:30:03.000000000 +0200
+++ linux-2.6.8.1-fr/drivers/net/r8169.c	2004-08-23 23:30:03.000000000 +0200
@@ -1575,7 +1575,7 @@ rtl8169_start_xmit(struct sk_buff *skb, 
 		tp->Tx_skbuff[entry] = skb;
 		tp->TxDescArray[entry].addr = cpu_to_le64(mapping);
 
-		/* anti gcc 2.95.3 bugware */
+		/* anti gcc 2.95.[3/4] bugware - do not merge these lines */
 		status = DescOwn | FirstFrag | LastFrag | len |
 			 (RingEnd * !((entry + 1) % NUM_TX_DESC));
 		tp->TxDescArray[entry].opts1 = cpu_to_le32(status);

_

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

* [PATCH 2.6.8.1-mm4 8/11] r8169: Tx checksum offload
  2004-08-23 22:53             ` [PATCH 2.6.8.1-mm4 7/11] r8169: comment a gcc 2.95.x bug Francois Romieu
@ 2004-08-23 22:55               ` Francois Romieu
  2004-08-23 22:56                 ` [PATCH 2.6.8.1-mm4 9/11] r8169: advertise DMA to high memory Francois Romieu
  2004-08-28 23:15                 ` [PATCH 2.6.8.1-mm4 8/11] r8169: Tx checksum offload Jeff Garzik
  0 siblings, 2 replies; 17+ messages in thread
From: Francois Romieu @ 2004-08-23 22:55 UTC (permalink / raw)
  To: jgarzik; +Cc: akpm, netdev

SG and IP checksumming support on output.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

diff -puN drivers/net/r8169.c~r8169-080 drivers/net/r8169.c
--- linux-2.6.8.1/drivers/net/r8169.c~r8169-080	2004-08-23 23:30:04.000000000 +0200
+++ linux-2.6.8.1-fr/drivers/net/r8169.c	2004-08-23 23:30:04.000000000 +0200
@@ -51,6 +51,9 @@ VERSION 1.6LK	<2004/04/14>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
 #include <linux/crc32.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
 
@@ -312,6 +315,11 @@ enum _DescStatusBit {
 	RingEnd		= (1 << 30), /* End of descriptor ring */
 	FirstFrag	= (1 << 29), /* First segment of a packet */
 	LastFrag	= (1 << 28), /* Final segment of a packet */
+
+	/* Tx private */
+	IPCS		= (1 << 18), /* Calculate IP checksum */
+	UDPCS		= (1 << 17), /* Calculate UDP/IP checksum */
+	TCPCS		= (1 << 16), /* Calculate TCP/IP checksum */
 };
 
 #define RsvdMask	0x3fffc000
@@ -328,6 +336,12 @@ struct RxDesc {
 	u64 addr;
 };
 
+struct ring_info {
+	struct sk_buff	*skb;
+	u32		len;
+	u8		__pad[sizeof(void *) - sizeof(u32)];
+};
+
 struct rtl8169_private {
 	void *mmio_addr;		/* memory map physical address */
 	struct pci_dev *pci_dev;	/* Index of PCI device  */
@@ -345,7 +359,7 @@ struct rtl8169_private {
 	dma_addr_t TxPhyAddr;
 	dma_addr_t RxPhyAddr;
 	struct sk_buff *Rx_skbuff[NUM_RX_DESC];	/* Rx data buffers */
-	struct sk_buff *Tx_skbuff[NUM_TX_DESC];	/* Tx data buffers */
+	struct ring_info tx_skb[NUM_TX_DESC];	/* Tx data buffers */
 	unsigned rx_buf_sz;
 	struct timer_list timer;
 	u16 cp_cmd;
@@ -702,6 +716,10 @@ static struct ethtool_ops rtl8169_ethtoo
 	.get_link		= ethtool_op_get_link,
 	.get_settings		= rtl8169_get_settings,
 	.set_settings		= rtl8169_set_settings,
+	.get_tx_csum		= ethtool_op_get_tx_csum,
+	.set_tx_csum		= ethtool_op_set_tx_csum,
+	.get_sg			= ethtool_op_get_sg,
+	.set_sg			= ethtool_op_set_sg,
 	.get_regs		= rtl8169_get_regs,
 };
 
@@ -1479,7 +1497,7 @@ static int rtl8169_init_ring(struct net_
 	tp->cur_rx = tp->dirty_rx = 0;
 	tp->cur_tx = tp->dirty_tx = 0;
 
-	memset(tp->Tx_skbuff, 0x0, NUM_TX_DESC * sizeof(struct sk_buff *));
+	memset(tp->tx_skb, 0x0, NUM_TX_DESC * sizeof(struct ring_info));
 	memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *));
 
 	if (rtl8169_rx_fill(tp, dev, 0, NUM_RX_DESC) != NUM_RX_DESC)
@@ -1494,33 +1512,38 @@ err_out:
 	return -ENOMEM;
 }
 
-static void rtl8169_unmap_tx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff,
+static void rtl8169_unmap_tx_skb(struct pci_dev *pdev, struct ring_info *tx_skb,
 				 struct TxDesc *desc)
 {
-	u32 len = sk_buff[0]->len;
+	unsigned int len = tx_skb->len;
 
-	pci_unmap_single(pdev, le64_to_cpu(desc->addr),
-			 len < ETH_ZLEN ? ETH_ZLEN : len, PCI_DMA_TODEVICE);
+	pci_unmap_single(pdev, le64_to_cpu(desc->addr), len, PCI_DMA_TODEVICE);
 	desc->addr = 0x00;
-	*sk_buff = NULL;
+	tx_skb->len = 0;
 }
 
-static void
-rtl8169_tx_clear(struct rtl8169_private *tp)
+static void rtl8169_tx_clear(struct rtl8169_private *tp)
 {
-	int i;
+	unsigned int i;
 
-	tp->cur_tx = 0;
-	for (i = 0; i < NUM_TX_DESC; i++) {
-		struct sk_buff *skb = tp->Tx_skbuff[i];
+	for (i = tp->dirty_tx; i < tp->dirty_tx + NUM_TX_DESC; i++) {
+		unsigned int entry = i % NUM_TX_DESC;
+		struct ring_info *tx_skb = tp->tx_skb + entry;
+		unsigned int len = tx_skb->len;
 
-		if (skb) {
-			rtl8169_unmap_tx_skb(tp->pci_dev, tp->Tx_skbuff + i,
-					     tp->TxDescArray + i);
-			dev_kfree_skb(skb);
+		if (len) {
+			struct sk_buff *skb = tx_skb->skb;
+
+			rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb,
+					     tp->TxDescArray + entry);
+			if (skb) {
+				dev_kfree_skb(skb);
+				tx_skb->skb = NULL;
+			}
 			tp->stats.tx_dropped++;
 		}
 	}
+	tp->cur_tx = tp->dirty_tx = 0;
 }
 
 static void
@@ -1550,51 +1573,121 @@ rtl8169_tx_timeout(struct net_device *de
 	netif_wake_queue(dev);
 }
 
-static int
-rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb,
+			      u32 opts1)
+{
+	struct skb_shared_info *info = skb_shinfo(skb);
+	unsigned int cur_frag, entry;
+	struct TxDesc *txd;
+
+	entry = tp->cur_tx;
+	for (cur_frag = 0; cur_frag < info->nr_frags; cur_frag++) {
+		skb_frag_t *frag = info->frags + cur_frag;
+		dma_addr_t mapping;
+		u32 status, len;
+		void *addr;
+
+		entry = (entry + 1) % NUM_TX_DESC;
+
+		txd = tp->TxDescArray + entry;
+		len = frag->size;
+		addr = ((void *) page_address(frag->page)) + frag->page_offset;
+		mapping = pci_map_single(tp->pci_dev, addr, len, PCI_DMA_TODEVICE);
+
+		/* anti gcc 2.95.3 bugware (sic) */
+		status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC));
+
+		txd->opts1 = cpu_to_le32(status);
+		txd->addr = cpu_to_le64(mapping);
+
+		tp->tx_skb[entry].len = len;
+	}
+
+	if (cur_frag) {
+		tp->tx_skb[entry].skb = skb;
+		txd->opts1 |= cpu_to_le32(LastFrag);
+	}
+
+	return cur_frag;
+}
+
+static inline u32 rtl8169_tx_csum(struct sk_buff *skb)
+{
+	if (skb->ip_summed == CHECKSUM_HW) {
+		const struct iphdr *ip = skb->nh.iph;
+
+		if (ip->protocol == IPPROTO_TCP)
+			return IPCS | TCPCS;
+		else if (ip->protocol == IPPROTO_UDP)
+			return IPCS | UDPCS;
+		BUG();
+	}
+	return 0;
+}
+
+static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
+	unsigned int frags, entry = tp->cur_tx % NUM_TX_DESC;
+	struct TxDesc *txd = tp->TxDescArray + entry;
 	void *ioaddr = tp->mmio_addr;
-	unsigned int entry = tp->cur_tx % NUM_TX_DESC;
-	u32 len = skb->len;
+	dma_addr_t mapping;
+	u32 status, len;
+	u32 opts1;
+	
+	if (unlikely(tp->cur_tx - tp->dirty_tx < skb_shinfo(skb)->nr_frags)) {
+		netif_stop_queue(dev);
+		printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
+		       dev->name);
+		return 1;
+	}
+
+	if (unlikely(le32_to_cpu(txd->opts1) & DescOwn))
+		goto err_drop;
+
+	opts1 = DescOwn | rtl8169_tx_csum(skb);
+
+	frags = rtl8169_xmit_frags(tp, skb, opts1);
+	if (frags) {
+		len = skb_headlen(skb);
+		opts1 |= FirstFrag;
+	} else {
+		len = skb->len;
+
+		if (unlikely(len < ETH_ZLEN)) {
+			skb = skb_padto(skb, ETH_ZLEN);
+			if (!skb)
+				goto err_update_stats;
+			len = ETH_ZLEN;
+		}
 
-	if (unlikely(skb->len < ETH_ZLEN)) {
-		skb = skb_padto(skb, ETH_ZLEN);
-		if (!skb)
-			goto err_update_stats;
-		len = ETH_ZLEN;
+		opts1 |= FirstFrag | LastFrag;
+		tp->tx_skb[entry].skb = skb;
 	}
-	
-	if (!(le32_to_cpu(tp->TxDescArray[entry].opts1) & DescOwn)) {
-		dma_addr_t mapping;
-		u32 status;
 
-		mapping = pci_map_single(tp->pci_dev, skb->data, len,
-					 PCI_DMA_TODEVICE);
+	mapping = pci_map_single(tp->pci_dev, skb->data, len, PCI_DMA_TODEVICE);
 
-		tp->Tx_skbuff[entry] = skb;
-		tp->TxDescArray[entry].addr = cpu_to_le64(mapping);
+	tp->tx_skb[entry].len = len;
+	txd->addr = cpu_to_le64(mapping);
 
-		/* anti gcc 2.95.[3/4] bugware - do not merge these lines */
-		status = DescOwn | FirstFrag | LastFrag | len |
-			 (RingEnd * !((entry + 1) % NUM_TX_DESC));
-		tp->TxDescArray[entry].opts1 = cpu_to_le32(status);
-			
-		RTL_W8(TxPoll, 0x40);	//set polling bit
+	wmb();
 
-		dev->trans_start = jiffies;
+	/* anti gcc 2.95.3 bugware (sic) */
+	status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC));
+	txd->opts1 = cpu_to_le32(status);
 
-		tp->cur_tx++;
-		smp_wmb();
-	} else
-		goto err_drop;
+	dev->trans_start = jiffies;
 
-	if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx) {
-		u32 dirty = tp->dirty_tx;
-	
+	tp->cur_tx += frags + 1;
+
+	smp_wmb();
+
+	RTL_W8(TxPoll, 0x40);	//set polling bit
+
+	if (tp->cur_tx - tp->dirty_tx < MAX_SKB_FRAGS) {
 		netif_stop_queue(dev);
 		smp_rmb();
-		if (dirty != tp->dirty_tx)
+		if (tp->cur_tx - tp->dirty_tx >= MAX_SKB_FRAGS)
 			netif_wake_queue(dev);
 	}
 
@@ -1624,7 +1717,8 @@ rtl8169_tx_interrupt(struct net_device *
 
 	while (tx_left > 0) {
 		unsigned int entry = dirty_tx % NUM_TX_DESC;
-		struct sk_buff *skb = tp->Tx_skbuff[entry];
+		struct ring_info *tx_skb = tp->tx_skb + entry;
+		u32 len = tx_skb->len;
 		u32 status;
 
 		rmb();
@@ -1632,14 +1726,15 @@ rtl8169_tx_interrupt(struct net_device *
 		if (status & DescOwn)
 			break;
 
-		/* FIXME: is it really accurate for TxErr ? */
-		tp->stats.tx_bytes += skb->len >= ETH_ZLEN ?
-				      skb->len : ETH_ZLEN;
+		tp->stats.tx_bytes += len;
 		tp->stats.tx_packets++;
-		rtl8169_unmap_tx_skb(tp->pci_dev, tp->Tx_skbuff + entry,
-				     tp->TxDescArray + entry);
-		dev_kfree_skb_irq(skb);
-		tp->Tx_skbuff[entry] = NULL;
+
+		rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, tp->TxDescArray + entry);
+
+		if (status & LastFrag) {
+			dev_kfree_skb_irq(tx_skb->skb);
+			tx_skb->skb = NULL;
+		}
 		dirty_tx++;
 		tx_left--;
 	}

_

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

* [PATCH 2.6.8.1-mm4 9/11] r8169: advertise DMA to high memory
  2004-08-23 22:55               ` [PATCH 2.6.8.1-mm4 8/11] r8169: Tx checksum offload Francois Romieu
@ 2004-08-23 22:56                 ` Francois Romieu
  2004-08-23 22:57                   ` [PATCH 2.6.8.1-mm4 10/11] r8169: Rx checksum support Francois Romieu
  2004-08-28 23:15                 ` [PATCH 2.6.8.1-mm4 8/11] r8169: Tx checksum offload Jeff Garzik
  1 sibling, 1 reply; 17+ messages in thread
From: Francois Romieu @ 2004-08-23 22:56 UTC (permalink / raw)
  To: jgarzik; +Cc: akpm, netdev

Advertise the ability to DMA to high memory.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

diff -puN drivers/net/r8169.c~r8169-090 drivers/net/r8169.c
--- linux-2.6.8.1/drivers/net/r8169.c~r8169-090	2004-08-23 23:30:06.000000000 +0200
+++ linux-2.6.8.1-fr/drivers/net/r8169.c	2004-08-23 23:30:06.000000000 +0200
@@ -1029,10 +1029,10 @@ rtl8169_init_board(struct pci_dev *pdev,
 
 	tp->cp_cmd = PCIMulRW | RxChkSum;
 
-	if ((sizeof(dma_addr_t) > 32) &&
-	    !pci_set_dma_mask(pdev, DMA_64BIT_MASK))
+	if ((sizeof(dma_addr_t) > 32) && !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
 		tp->cp_cmd |= PCIDAC;
-	else {
+		dev->features |= NETIF_F_HIGHDMA;
+	} else {
 		rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
 		if (rc < 0) {
 			printk(KERN_ERR PFX "DMA configuration failed.\n");
@@ -1040,7 +1040,6 @@ rtl8169_init_board(struct pci_dev *pdev,
 		}
 	}
 
-
 	pci_set_master(pdev);
 
 	// ioremap MMIO region 

_

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

* [PATCH 2.6.8.1-mm4 10/11] r8169: Rx checksum support
  2004-08-23 22:56                 ` [PATCH 2.6.8.1-mm4 9/11] r8169: advertise DMA to high memory Francois Romieu
@ 2004-08-23 22:57                   ` Francois Romieu
  2004-08-23 22:59                     ` [PATCH 2.6.8.1-mm4 11/11] r8169: vlan support Francois Romieu
  0 siblings, 1 reply; 17+ messages in thread
From: Francois Romieu @ 2004-08-23 22:57 UTC (permalink / raw)
  To: jgarzik; +Cc: akpm, netdev

Rx IP checksumming support.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

diff -puN drivers/net/r8169.c~r8169-100 drivers/net/r8169.c
--- linux-2.6.8.1/drivers/net/r8169.c~r8169-100	2004-08-23 23:30:08.000000000 +0200
+++ linux-2.6.8.1-fr/drivers/net/r8169.c	2004-08-23 23:30:08.000000000 +0200
@@ -320,6 +320,19 @@ enum _DescStatusBit {
 	IPCS		= (1 << 18), /* Calculate IP checksum */
 	UDPCS		= (1 << 17), /* Calculate UDP/IP checksum */
 	TCPCS		= (1 << 16), /* Calculate TCP/IP checksum */
+
+	/* Rx private */
+	PID1		= (1 << 18), /* Protocol ID bit 1/2 */
+	PID0		= (1 << 17), /* Protocol ID bit 2/2 */
+
+#define RxProtoUDP	(PID1)
+#define RxProtoTCP	(PID0)
+#define RxProtoIP	(PID1 | PID0)
+#define RxProtoMask	RxProtoIP
+
+	IPFail		= (1 << 16), /* IP checksum failed */
+	UDPFail		= (1 << 15), /* UDP/IP checksum failed */
+	TCPFail		= (1 << 14), /* TCP/IP checksum failed */
 };
 
 #define RsvdMask	0x3fffc000
@@ -623,6 +636,34 @@ static int rtl8169_set_settings(struct n
 	return ret;
 }
 
+static u32 rtl8169_get_rx_csum(struct net_device *dev)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+
+	return !!(tp->cp_cmd & RxChkSum);
+}
+
+static int rtl8169_set_rx_csum(struct net_device *dev,  u32 data)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+	void *ioaddr = tp->mmio_addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&tp->lock, flags);
+
+	if (data)
+		tp->cp_cmd |= RxChkSum;
+	else
+		tp->cp_cmd &= ~RxChkSum;
+
+	RTL_W16(CPlusCmd, tp->cp_cmd);
+	RTL_R16(CPlusCmd);
+
+	spin_unlock_irqrestore(&tp->lock, flags);
+
+	return 0;
+}
+
 static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
@@ -716,6 +757,8 @@ static struct ethtool_ops rtl8169_ethtoo
 	.get_link		= ethtool_op_get_link,
 	.get_settings		= rtl8169_get_settings,
 	.set_settings		= rtl8169_set_settings,
+	.get_rx_csum		= rtl8169_get_rx_csum,
+	.set_rx_csum		= rtl8169_set_rx_csum,
 	.get_tx_csum		= ethtool_op_get_tx_csum,
 	.set_tx_csum		= ethtool_op_set_tx_csum,
 	.get_sg			= ethtool_op_get_sg,
@@ -1746,6 +1789,19 @@ rtl8169_tx_interrupt(struct net_device *
 	}
 }
 
+static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc)
+{
+	u32 opts1 = desc->opts1;
+	u32 status = opts1 & RxProtoMask;
+
+	if (((status == RxProtoTCP) && !(opts1 & TCPFail)) ||
+	    ((status == RxProtoUDP) && !(opts1 & UDPFail)) ||
+	    ((status == RxProtoIP) && !(opts1 & IPFail)))
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
+	else
+		skb->ip_summed = CHECKSUM_NONE;
+}
+
 static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size,
 				      struct RxDesc *desc, int rx_buf_sz)
 {
@@ -1804,7 +1860,8 @@ rtl8169_rx_interrupt(struct net_device *
 			void (*pci_action)(struct pci_dev *, dma_addr_t,
 				size_t, int) = pci_dma_sync_single_for_device;
 
-
+			rtl8169_rx_csum(skb, desc);
+			
 			pci_dma_sync_single_for_cpu(tp->pci_dev,
 				le64_to_cpu(desc->addr), tp->rx_buf_sz,
 				PCI_DMA_FROMDEVICE);

_

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

* [PATCH 2.6.8.1-mm4 11/11] r8169: vlan support
  2004-08-23 22:57                   ` [PATCH 2.6.8.1-mm4 10/11] r8169: Rx checksum support Francois Romieu
@ 2004-08-23 22:59                     ` Francois Romieu
  2004-08-28 23:21                       ` Jeff Garzik
  0 siblings, 1 reply; 17+ messages in thread
From: Francois Romieu @ 2004-08-23 22:59 UTC (permalink / raw)
  To: jgarzik; +Cc: akpm, netdev

802.1Q support.
Mostly stolen from the 8139cp.c driver. The relevant registers and
descriptors bits are identical for both chipsets.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

diff -puN drivers/net/r8169.c~r8169-110 drivers/net/r8169.c
--- linux-2.6.8.1/drivers/net/r8169.c~r8169-110	2004-08-23 23:31:33.000000000 +0200
+++ linux-2.6.8.1-fr/drivers/net/r8169.c	2004-08-23 23:31:33.000000000 +0200
@@ -50,6 +50,7 @@ VERSION 1.6LK	<2004/04/14>
 #include <linux/delay.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
+#include <linux/if_vlan.h>
 #include <linux/crc32.h>
 #include <linux/in.h>
 #include <linux/ip.h>
@@ -78,9 +79,11 @@ VERSION 1.6LK	<2004/04/14>
 
 #ifdef CONFIG_R8169_NAPI
 #define rtl8169_rx_skb			netif_receive_skb
+#define rtl8169_rx_hwaccel_skb		vlan_hwaccel_rx
 #define rtl8169_rx_quota(count, quota)	min(count, quota)
 #else
 #define rtl8169_rx_skb			netif_rx
+#define rtl8169_rx_hwaccel_skb		vlan_hwaccel_receive_skb
 #define rtl8169_rx_quota(count, quota)	count
 #endif
 
@@ -320,6 +323,7 @@ enum _DescStatusBit {
 	IPCS		= (1 << 18), /* Calculate IP checksum */
 	UDPCS		= (1 << 17), /* Calculate UDP/IP checksum */
 	TCPCS		= (1 << 16), /* Calculate TCP/IP checksum */
+	TxVlanTag	= (1 << 17), /* Add VLAN tag */
 
 	/* Rx private */
 	PID1		= (1 << 18), /* Protocol ID bit 1/2 */
@@ -333,6 +337,7 @@ enum _DescStatusBit {
 	IPFail		= (1 << 16), /* IP checksum failed */
 	UDPFail		= (1 << 15), /* UDP/IP checksum failed */
 	TCPFail		= (1 << 14), /* TCP/IP checksum failed */
+	RxVlanTag	= (1 << 16), /* VLAN tag available */
 };
 
 #define RsvdMask	0x3fffc000
@@ -379,7 +384,9 @@ struct rtl8169_private {
 	u16 intr_mask;
 	int phy_auto_nego_reg;
 	int phy_1000_ctrl_reg;
-
+#ifdef CONFIG_R8169_VLAN
+	struct vlan_group *vlgrp;
+#endif
 	int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex);
 	void (*get_settings)(struct net_device *, struct ethtool_cmd *);
 	void (*phy_reset_enable)(void *);
@@ -664,6 +671,77 @@ static int rtl8169_set_rx_csum(struct ne
 	return 0;
 }
 
+#ifdef CONFIG_R8169_VLAN
+
+static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp,
+				      struct sk_buff *skb)
+{
+	return (tp->vlgrp && vlan_tx_tag_present(skb)) ?
+		TxVlanTag | cpu_to_be16(vlan_tx_tag_get(skb)) : 0x00;
+}
+
+static void rtl8169_vlan_rx_register(struct net_device *dev,
+				     struct vlan_group *grp)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+	void *ioaddr = tp->mmio_addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&tp->lock, flags);
+	tp->vlgrp = grp;
+	tp->cp_cmd |= RxVlan;
+	RTL_W16(CPlusCmd, tp->cp_cmd);
+	RTL_R16(CPlusCmd);
+	spin_unlock_irqrestore(&tp->lock, flags);
+}
+
+static void rtl8169_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+	void *ioaddr = tp->mmio_addr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&tp->lock, flags);
+	tp->cp_cmd &= ~RxVlan;
+	RTL_W16(CPlusCmd, tp->cp_cmd);
+	RTL_R16(CPlusCmd);
+	if (tp->vlgrp)
+		tp->vlgrp->vlan_devices[vid] = NULL;
+	spin_unlock_irqrestore(&tp->lock, flags);
+}
+
+static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
+			       struct sk_buff *skb)
+{
+	u32 opts2 = desc->opts2;
+	int ret;
+
+	if (tp->vlgrp && (opts2 & RxVlanTag)) {
+		rtl8169_rx_hwaccel_skb(skb, tp->vlgrp,
+				       be16_to_cpu(opts2 & 0xffff));
+		ret = 0;
+	} else
+		ret = -1;
+	desc->opts2 = 0;
+	return ret;
+}
+
+#else /* !CONFIG_R8169_VLAN */
+
+static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp,
+				      struct sk_buff *skb)
+{
+	return 0;
+}
+
+static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
+			       struct sk_buff *skb)
+{
+	return -1;
+}
+
+#endif
+
 static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
@@ -1072,6 +1150,8 @@ rtl8169_init_board(struct pci_dev *pdev,
 
 	tp->cp_cmd = PCIMulRW | RxChkSum;
 
+	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+
 	if ((sizeof(dma_addr_t) > 32) && !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
 		tp->cp_cmd |= PCIDAC;
 		dev->features |= NETIF_F_HIGHDMA;
@@ -1206,11 +1286,19 @@ rtl8169_init_one(struct pci_dev *pdev, c
 	dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
 	dev->irq = pdev->irq;
 	dev->base_addr = (unsigned long) ioaddr;
+
 #ifdef CONFIG_R8169_NAPI
 	dev->poll = rtl8169_poll;
 	dev->weight = R8169_NAPI_WEIGHT;
 	printk(KERN_INFO PFX "NAPI enabled\n");
 #endif
+
+#ifdef CONFIG_R8169_VLAN
+	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+	dev->vlan_rx_register = rtl8169_vlan_rx_register;
+	dev->vlan_rx_kill_vid = rtl8169_vlan_rx_kill_vid;
+#endif
+
 	tp->intr_mask = 0xffff;
 	tp->pci_dev = pdev;
 	tp->mmio_addr = ioaddr;
@@ -1560,6 +1648,7 @@ static void rtl8169_unmap_tx_skb(struct 
 	unsigned int len = tx_skb->len;
 
 	pci_unmap_single(pdev, le64_to_cpu(desc->addr), len, PCI_DMA_TODEVICE);
+	desc->opts2 = 0x00;
 	desc->addr = 0x00;
 	tx_skb->len = 0;
 }
@@ -1711,6 +1800,7 @@ static int rtl8169_start_xmit(struct sk_
 
 	tp->tx_skb[entry].len = len;
 	txd->addr = cpu_to_le64(mapping);
+	txd->opts2 = rtl8169_tx_vlan_tag(tp, skb);
 
 	wmb();
 
@@ -1878,7 +1968,9 @@ rtl8169_rx_interrupt(struct net_device *
 			skb->dev = dev;
 			skb_put(skb, pkt_size);
 			skb->protocol = eth_type_trans(skb, dev);
-			rtl8169_rx_skb(skb);
+
+			if (rtl8169_rx_vlan_skb(tp, desc, skb) < 0)
+				rtl8169_rx_skb(skb);
 
 			dev->last_rx = jiffies;
 			tp->stats.rx_bytes += pkt_size;
diff -puN drivers/net/Kconfig~r8169-110 drivers/net/Kconfig
--- linux-2.6.8.1/drivers/net/Kconfig~r8169-110	2004-08-23 23:31:33.000000000 +0200
+++ linux-2.6.8.1-fr/drivers/net/Kconfig	2004-08-23 23:31:33.000000000 +0200
@@ -2061,6 +2061,15 @@ config R8169_NAPI
 
 	  If in doubt, say N.
 
+config R8169_VLAN
+	bool "VLAN support"
+	depends on R8169 && VLAN_8021Q
+	---help---
+	  Say Y here for the r8169 driver to support the functions required
+	  by the kernel 802.1Q code.
+	  
+	  If in doubt, say Y.
+
 config SK98LIN
 	tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support"
 	depends on PCI

_

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

* Re: [DESC 2.6.8.1-mm4] r8169 patches
  2004-08-23 22:41 [DESC 2.6.8.1-mm4] r8169 patches Francois Romieu
  2004-08-23 22:44 ` [PATCH 2.6.8.1-mm4 1/11] r8169: add ethtool_ops.{get_regs_len/get_regs} Francois Romieu
@ 2004-08-27 15:09 ` Jon Mason
  1 sibling, 0 replies; 17+ messages in thread
From: Jon Mason @ 2004-08-27 15:09 UTC (permalink / raw)
  To: Francois Romieu; +Cc: jgarzik, akpm, netdev

I've been running the driver with all of the new patchs on my AMD64 system for 
over 36 hours without any problems.  I have Rx/TX checksumming enabled, but 
have not tried the VLAN changes.

On Monday 23 August 2004 05:41 pm, Francois Romieu wrote:
> Here comes a new serie of r8169 related patches which should allow
> the motivated users to experiment new features, namely:
> - Rx/Tx checksum offload;
> - vlan support;
> - better ethtool integration.
>
> Tx code apart, the changes exhibit some strong similarity with the
> 8139cp driver.
>
> I have not done vlan-dedicated test and there are no figures to highlight
> any performance improvement. The code does not crash in a (really slow)
> debug enabled -mm kernel and it does not seem to add huge leak.
>
> Remarks/comments/test reports welcome.
>
> --
> Ueimor

-- 
Jon Mason
jdmason@us.ibm.com

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

* Re: [PATCH 2.6.8.1-mm4 8/11] r8169: Tx checksum offload
  2004-08-23 22:55               ` [PATCH 2.6.8.1-mm4 8/11] r8169: Tx checksum offload Francois Romieu
  2004-08-23 22:56                 ` [PATCH 2.6.8.1-mm4 9/11] r8169: advertise DMA to high memory Francois Romieu
@ 2004-08-28 23:15                 ` Jeff Garzik
  1 sibling, 0 replies; 17+ messages in thread
From: Jeff Garzik @ 2004-08-28 23:15 UTC (permalink / raw)
  To: Francois Romieu; +Cc: akpm, netdev

Francois Romieu wrote:
> +static inline u32 rtl8169_tx_csum(struct sk_buff *skb)
> +{
> +	if (skb->ip_summed == CHECKSUM_HW) {
> +		const struct iphdr *ip = skb->nh.iph;
> +
> +		if (ip->protocol == IPPROTO_TCP)
> +			return IPCS | TCPCS;
> +		else if (ip->protocol == IPPROTO_UDP)
> +			return IPCS | UDPCS;
> +		BUG();
> +	}
> +	return 0;
> +}

I am applying this patch BUT...  BUG() is a bit too "rude" when you can 
obviously return safely.  Prefer WARN_ON() because we don't need to kill 
the machine for this condition.

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

* Re: [PATCH 2.6.8.1-mm4 11/11] r8169: vlan support
  2004-08-23 22:59                     ` [PATCH 2.6.8.1-mm4 11/11] r8169: vlan support Francois Romieu
@ 2004-08-28 23:21                       ` Jeff Garzik
  2004-08-29 21:00                         ` Francois Romieu
  0 siblings, 1 reply; 17+ messages in thread
From: Jeff Garzik @ 2004-08-28 23:21 UTC (permalink / raw)
  To: Francois Romieu; +Cc: akpm, netdev

applied all 11 patches to netdev-2.6.

does this series of patches imply that a librealtek kernel module is 
coming soon?  There's an awful lot of code duplication (due to hardware 
similarties) in r8169, 8139cp, and 8139too.

	Jeff

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

* Re: [PATCH 2.6.8.1-mm4 11/11] r8169: vlan support
  2004-08-28 23:21                       ` Jeff Garzik
@ 2004-08-29 21:00                         ` Francois Romieu
  2004-08-29 21:23                           ` Jeff Garzik
  0 siblings, 1 reply; 17+ messages in thread
From: Francois Romieu @ 2004-08-29 21:00 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: akpm, netdev

Jeff Garzik <jgarzik@pobox.com> :
[...]
> does this series of patches imply that a librealtek kernel module is 
> coming soon?  There's an awful lot of code duplication (due to hardware 
> similarties) in r8169, 8139cp, and 8139too.

I have not really considered 8139too so far as its hardware is a bit
"different" but why not.

soon ? What have you done to the real Jeff ?

--
Ueimor

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

* Re: [PATCH 2.6.8.1-mm4 11/11] r8169: vlan support
  2004-08-29 21:00                         ` Francois Romieu
@ 2004-08-29 21:23                           ` Jeff Garzik
  0 siblings, 0 replies; 17+ messages in thread
From: Jeff Garzik @ 2004-08-29 21:23 UTC (permalink / raw)
  To: Francois Romieu; +Cc: akpm, netdev

Francois Romieu wrote:
> Jeff Garzik <jgarzik@pobox.com> :
> [...]
> 
>>does this series of patches imply that a librealtek kernel module is 
>>coming soon?  There's an awful lot of code duplication (due to hardware 
>>similarties) in r8169, 8139cp, and 8139too.
> 
> 
> I have not really considered 8139too so far as its hardware is a bit
> "different" but why not.

8139cp and 8139too both share the same phy code, and 8139cp and r8169 
both share the same RX/TX code.


> soon ? What have you done to the real Jeff ?

hehe :)

	Jeff

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

end of thread, other threads:[~2004-08-29 21:23 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-08-23 22:41 [DESC 2.6.8.1-mm4] r8169 patches Francois Romieu
2004-08-23 22:44 ` [PATCH 2.6.8.1-mm4 1/11] r8169: add ethtool_ops.{get_regs_len/get_regs} Francois Romieu
2004-08-23 22:45   ` [PATCH 2.6.8.1-mm4 2/11] r8169: per device receive buffer size Francois Romieu
2004-08-23 22:47     ` [PATCH 2.6.8.1-mm4 3/11] r8169: code cleanup Francois Romieu
2004-08-23 22:48       ` [PATCH 2.6.8.1-mm4 4/11] r8169: enable MWI Francois Romieu
2004-08-23 22:49         ` [PATCH 2.6.8.1-mm4 5/11] r8169: bump version number Francois Romieu
2004-08-23 22:51           ` [PATCH 2.6.8.1-mm4 6/11] r8169: sync the names of a few bits with the 8139cp driver Francois Romieu
2004-08-23 22:53             ` [PATCH 2.6.8.1-mm4 7/11] r8169: comment a gcc 2.95.x bug Francois Romieu
2004-08-23 22:55               ` [PATCH 2.6.8.1-mm4 8/11] r8169: Tx checksum offload Francois Romieu
2004-08-23 22:56                 ` [PATCH 2.6.8.1-mm4 9/11] r8169: advertise DMA to high memory Francois Romieu
2004-08-23 22:57                   ` [PATCH 2.6.8.1-mm4 10/11] r8169: Rx checksum support Francois Romieu
2004-08-23 22:59                     ` [PATCH 2.6.8.1-mm4 11/11] r8169: vlan support Francois Romieu
2004-08-28 23:21                       ` Jeff Garzik
2004-08-29 21:00                         ` Francois Romieu
2004-08-29 21:23                           ` Jeff Garzik
2004-08-28 23:15                 ` [PATCH 2.6.8.1-mm4 8/11] r8169: Tx checksum offload Jeff Garzik
2004-08-27 15:09 ` [DESC 2.6.8.1-mm4] r8169 patches Jon Mason

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.