netdev.vger.kernel.org archive mirror
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).