All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Drake <dsd@gentoo.org>
To: Francois Romieu <romieu@fr.zoreil.com>
Cc: netdev@vger.kernel.org
Subject: Re: [2.6.18 backport] RTL8168 ethernet support in r8169
Date: Tue, 26 Sep 2006 18:52:13 -0400	[thread overview]
Message-ID: <4519AF1D.7020302@gentoo.org> (raw)
In-Reply-To: <20060926191458.GB15039@electric-eye.fr.zoreil.com>

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

Francois Romieu wrote:
> Daniel Drake <dsd@gentoo.org> :
> [...]
>  static struct pci_device_id rtl8169_pci_tbl[] = {
> -	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8169), },
> -	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8129), },
> -	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK,	0x4300), },
> -	{ PCI_DEVICE(0x16ec,			0x0116), },
> -	{ PCI_VENDOR_ID_LINKSYS,		0x1032, PCI_ANY_ID, 0x0024, },
> +	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8129), 0, 0, RTL_CFG_0 },
> +	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8136), 0, 0, RTL_CFG_1 },
> 
> Should be RTL_CFG_2 (but there are still issues with the link management).
> 
> +	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8167), 0, 0, RTL_CFG_1 },
>                                                                ^^^^^^^^^
> Should be RTL_CFG_1.
> 

Thanks. I only really wanted to include the patch for the 8168 support 
rather than the larger patch which has some unrelated changes. I went 
ahead and updated the patch with the above changes incase someone comes 
along with that hardware anyway :)



[-- Attachment #2: 4010_r8169-8168.patch --]
[-- Type: text/x-patch, Size: 18335 bytes --]

From: Francois Romieu <romieu@fr.zoreil.com>
Date: Wed, 26 Jul 2006 21:14:13 +0000 (+0200)
Subject: r8169: sync with vendor's driver
X-Git-Tag: v2.6.18-rc3
X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=bcf0bf90cd9e9242b66e0563b6a8c8db2e4c262c

r8169: sync with vendor's driver

- add several PCI ID for the PCI-E adapters ;
- new identification strings ;
- the RTL_GIGA_MAC_VER_ defines have been renamed to closely match the
  out-of-tree driver. It makes the comparison less hairy ;
- various magic ;
- the PCI region for the device with PCI ID 0x8136 is guessed.
  Explanation: the in-kernel Linux driver is written to allow MM register
  accesses and avoid the IO tax. The relevant BAR register was found at
  base address 1 for the plain-old PCI 8169. User reported lspci show that
  it is found at base address 2 for the new Gigabit PCI-E 816{8/9}.
  Typically:
  01:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd.: Unknown device 8168 (rev 01)
          Subsystem: Unknown device 1631:e015
          Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
          Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
          Latency: 0, cache line size 20
          Interrupt: pin A routed to IRQ 16
          Region 0: I/O ports at b800 [size=256]
          Region 2: Memory at ff7ff000 (64-bit, non-prefetchable) [size=4K]
          ^^^^^^^^
  So far I have not received any lspci report for the 0x8136 and
  Realtek's driver do not help: be it under BSD or Linux, their r1000 driver
  include a USE_IO_SPACE #define but the bar address is always hardcoded
  to 1 in the MM case. :o/
- the 8168 has been reported to require an extra alignment for its receive
  buffers. The status of the 8167 and 8136 is not known in this regard.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Rediffed for 2.6.18 by Daniel Drake <dsd@gentoo.org>
Also includes commits d2eed8cff9a1a5d7e12ec9ddf71432c466b104d0 and
d81bf551103cc3bc9e4f7ddf337511d6da0d088f
---

Index: linux-2.6.18/drivers/net/r8169.c
===================================================================
--- linux-2.6.18.orig/drivers/net/r8169.c
+++ linux-2.6.18/drivers/net/r8169.c
@@ -150,11 +150,16 @@ static const int multicast_filter_limit 
 #define RTL_R32(reg)		((unsigned long) readl (ioaddr + (reg)))
 
 enum mac_version {
-	RTL_GIGA_MAC_VER_B = 0x00,
-	/* RTL_GIGA_MAC_VER_C = 0x03, */
-	RTL_GIGA_MAC_VER_D = 0x01,
-	RTL_GIGA_MAC_VER_E = 0x02,
-	RTL_GIGA_MAC_VER_X = 0x04	/* Greater than RTL_GIGA_MAC_VER_E */
+	RTL_GIGA_MAC_VER_01 = 0x00,
+	RTL_GIGA_MAC_VER_02 = 0x01,
+	RTL_GIGA_MAC_VER_03 = 0x02,
+	RTL_GIGA_MAC_VER_04 = 0x03,
+	RTL_GIGA_MAC_VER_05 = 0x04,
+	RTL_GIGA_MAC_VER_11 = 0x0b,
+	RTL_GIGA_MAC_VER_12 = 0x0c,
+	RTL_GIGA_MAC_VER_13 = 0x0d,
+	RTL_GIGA_MAC_VER_14 = 0x0e,
+	RTL_GIGA_MAC_VER_15 = 0x0f
 };
 
 enum phy_version {
@@ -166,7 +171,6 @@ enum phy_version {
 	RTL_GIGA_PHY_VER_H = 0x08, /* PHY Reg 0x03 bit0-3 == 0x0003 */
 };
 
-
 #define _R(NAME,MAC,MASK) \
 	{ .name = NAME, .mac_version = MAC, .RxConfigMask = MASK }
 
@@ -175,19 +179,44 @@ static const struct {
 	u8 mac_version;
 	u32 RxConfigMask;	/* Clears the bits supported by this chip */
 } rtl_chip_info[] = {
-	_R("RTL8169",		RTL_GIGA_MAC_VER_B, 0xff7e1880),
-	_R("RTL8169s/8110s",	RTL_GIGA_MAC_VER_D, 0xff7e1880),
-	_R("RTL8169s/8110s",	RTL_GIGA_MAC_VER_E, 0xff7e1880),
-	_R("RTL8169s/8110s",	RTL_GIGA_MAC_VER_X, 0xff7e1880),
+	_R("RTL8169",		RTL_GIGA_MAC_VER_01, 0xff7e1880),
+	_R("RTL8169s/8110s",	RTL_GIGA_MAC_VER_02, 0xff7e1880),
+	_R("RTL8169s/8110s",	RTL_GIGA_MAC_VER_03, 0xff7e1880),
+	_R("RTL8169sb/8110sb",	RTL_GIGA_MAC_VER_04, 0xff7e1880),
+	_R("RTL8169sc/8110sc",	RTL_GIGA_MAC_VER_05, 0xff7e1880),
+	_R("RTL8168b/8111b",	RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E
+	_R("RTL8168b/8111b",	RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E
+	_R("RTL8101e",		RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139
+	_R("RTL8100e",		RTL_GIGA_MAC_VER_14, 0xff7e1880), // PCI-E 8139
+	_R("RTL8100e",		RTL_GIGA_MAC_VER_15, 0xff7e1880)  // PCI-E 8139
 };
 #undef _R
 
+enum cfg_version {
+	RTL_CFG_0 = 0x00,
+	RTL_CFG_1,
+	RTL_CFG_2
+};
+
+static const struct {
+	unsigned int region;
+	unsigned int align;
+} rtl_cfg_info[] = {
+	[RTL_CFG_0] = { 1, NET_IP_ALIGN },
+	[RTL_CFG_1] = { 2, NET_IP_ALIGN },
+	[RTL_CFG_2] = { 2, 8 }
+};
+
 static struct pci_device_id rtl8169_pci_tbl[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8169), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8129), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK,	0x4300), },
-	{ PCI_DEVICE(0x16ec,			0x0116), },
-	{ PCI_VENDOR_ID_LINKSYS,		0x1032, PCI_ANY_ID, 0x0024, },
+	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8129), 0, 0, RTL_CFG_0 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8136), 0, 0, RTL_CFG_2 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8167), 0, 0, RTL_CFG_0 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8168), 0, 0, RTL_CFG_2 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8169), 0, 0, RTL_CFG_0 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK,	0x4300), 0, 0, RTL_CFG_0 },
+	{ PCI_DEVICE(0x16ec,			0x0116), 0, 0, RTL_CFG_0 },
+	{ PCI_VENDOR_ID_LINKSYS,		0x1032,
+		PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 },
 	{0,},
 };
 
@@ -346,6 +375,7 @@ enum RTL8169_register_content {
 	PHY_Cap_100_Full = 0x0100,
 
 	/* PHY_1000_CTRL_REG = 9 */
+	PHY_Cap_1000_Half = 0x0100,
 	PHY_Cap_1000_Full = 0x0200,
 
 	PHY_Cap_Null = 0x0,
@@ -433,6 +463,7 @@ struct rtl8169_private {
 	dma_addr_t RxPhyAddr;
 	struct sk_buff *Rx_skbuff[NUM_RX_DESC];	/* Rx data buffers */
 	struct ring_info tx_skb[NUM_TX_DESC];	/* Tx data buffers */
+	unsigned align;
 	unsigned rx_buf_sz;
 	struct timer_list timer;
 	u16 cp_cmd;
@@ -749,25 +780,43 @@ static int rtl8169_set_speed_xmii(struct
 	auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_10_Full |
 		       PHY_Cap_100_Half | PHY_Cap_100_Full);
 	giga_ctrl = mdio_read(ioaddr, PHY_1000_CTRL_REG);
-	giga_ctrl &= ~(PHY_Cap_1000_Full | PHY_Cap_Null);
+	giga_ctrl &= ~(PHY_Cap_1000_Full | PHY_Cap_1000_Half | PHY_Cap_Null);
 
 	if (autoneg == AUTONEG_ENABLE) {
 		auto_nego |= (PHY_Cap_10_Half | PHY_Cap_10_Full |
 			      PHY_Cap_100_Half | PHY_Cap_100_Full);
-		giga_ctrl |= PHY_Cap_1000_Full;
+		giga_ctrl |= PHY_Cap_1000_Full | PHY_Cap_1000_Half;
 	} else {
 		if (speed == SPEED_10)
 			auto_nego |= PHY_Cap_10_Half | PHY_Cap_10_Full;
 		else if (speed == SPEED_100)
 			auto_nego |= PHY_Cap_100_Half | PHY_Cap_100_Full;
 		else if (speed == SPEED_1000)
-			giga_ctrl |= PHY_Cap_1000_Full;
+			giga_ctrl |= PHY_Cap_1000_Full | PHY_Cap_1000_Half;
 
 		if (duplex == DUPLEX_HALF)
 			auto_nego &= ~(PHY_Cap_10_Full | PHY_Cap_100_Full);
 
 		if (duplex == DUPLEX_FULL)
 			auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_100_Half);
+
+		/* This tweak comes straight from Realtek's driver. */
+		if ((speed == SPEED_100) && (duplex == DUPLEX_HALF) &&
+		    (tp->mac_version == RTL_GIGA_MAC_VER_13)) {
+			auto_nego = PHY_Cap_100_Half | 0x01;
+		}
+	}
+
+	/* The 8100e/8101e do Fast Ethernet only. */
+	if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
+	    (tp->mac_version == RTL_GIGA_MAC_VER_14) ||
+	    (tp->mac_version == RTL_GIGA_MAC_VER_15)) {
+		if ((giga_ctrl & (PHY_Cap_1000_Full | PHY_Cap_1000_Half)) &&
+		    netif_msg_link(tp)) {
+			printk(KERN_INFO "%s: PHY does not support 1000Mbps.\n",
+			       dev->name);
+		}
+		giga_ctrl &= ~(PHY_Cap_1000_Full | PHY_Cap_1000_Half);
 	}
 
 	tp->phy_auto_nego_reg = auto_nego;
@@ -1140,10 +1189,16 @@ static void rtl8169_get_mac_version(stru
 		u32 mask;
 		int mac_version;
 	} mac_info[] = {
-		{ 0x1 << 28,	RTL_GIGA_MAC_VER_X },
-		{ 0x1 << 26,	RTL_GIGA_MAC_VER_E },
-		{ 0x1 << 23,	RTL_GIGA_MAC_VER_D }, 
-		{ 0x00000000,	RTL_GIGA_MAC_VER_B } /* Catch-all */
+		{ 0x38800000,	RTL_GIGA_MAC_VER_15 },
+		{ 0x38000000,	RTL_GIGA_MAC_VER_12 },
+		{ 0x34000000,	RTL_GIGA_MAC_VER_13 },
+		{ 0x30800000,	RTL_GIGA_MAC_VER_14 },
+		{ 0x30000000,   RTL_GIGA_MAC_VER_11 },
+		{ 0x18000000,	RTL_GIGA_MAC_VER_05 },
+		{ 0x10000000,	RTL_GIGA_MAC_VER_04 },
+		{ 0x04000000,	RTL_GIGA_MAC_VER_03 },
+		{ 0x00800000,	RTL_GIGA_MAC_VER_02 },
+		{ 0x00000000,	RTL_GIGA_MAC_VER_01 }	/* Catch-all */
 	}, *p = mac_info;
 	u32 reg;
 
@@ -1155,24 +1210,7 @@ static void rtl8169_get_mac_version(stru
 
 static void rtl8169_print_mac_version(struct rtl8169_private *tp)
 {
-	struct {
-		int version;
-		char *msg;
-	} mac_print[] = {
-		{ RTL_GIGA_MAC_VER_E, "RTL_GIGA_MAC_VER_E" },
-		{ RTL_GIGA_MAC_VER_D, "RTL_GIGA_MAC_VER_D" },
-		{ RTL_GIGA_MAC_VER_B, "RTL_GIGA_MAC_VER_B" },
-		{ 0, NULL }
-	}, *p;
-
-	for (p = mac_print; p->msg; p++) {
-		if (tp->mac_version == p->version) {
-			dprintk("mac_version == %s (%04d)\n", p->msg,
-				  p->version);
-			return;
-		}
-	}
-	dprintk("mac_version == Unknown\n");
+	dprintk("mac_version = 0x%02x\n", tp->mac_version);
 }
 
 static void rtl8169_get_phy_version(struct rtl8169_private *tp, void __iomem *ioaddr)
@@ -1257,7 +1295,7 @@ static void rtl8169_hw_phy_config(struct
 	rtl8169_print_mac_version(tp);
 	rtl8169_print_phy_version(tp);
 
-	if (tp->mac_version <= RTL_GIGA_MAC_VER_B)
+	if (tp->mac_version <= RTL_GIGA_MAC_VER_01)
 		return;
 	if (tp->phy_version >= RTL_GIGA_PHY_VER_H)
 		return;
@@ -1267,7 +1305,7 @@ static void rtl8169_hw_phy_config(struct
 
 	/* Shazam ! */
 
-	if (tp->mac_version == RTL_GIGA_MAC_VER_X) {
+	if (tp->mac_version == RTL_GIGA_MAC_VER_04) {
 		mdio_write(ioaddr, 31, 0x0001);
 		mdio_write(ioaddr,  9, 0x273a);
 		mdio_write(ioaddr, 14, 0x7bfb);
@@ -1306,7 +1344,7 @@ static void rtl8169_phy_timer(unsigned l
 	void __iomem *ioaddr = tp->mmio_addr;
 	unsigned long timeout = RTL8169_PHY_TIMEOUT;
 
-	assert(tp->mac_version > RTL_GIGA_MAC_VER_B);
+	assert(tp->mac_version > RTL_GIGA_MAC_VER_01);
 	assert(tp->phy_version < RTL_GIGA_PHY_VER_H);
 
 	if (!(tp->phy_1000_ctrl_reg & PHY_Cap_1000_Full))
@@ -1342,7 +1380,7 @@ static inline void rtl8169_delete_timer(
 	struct rtl8169_private *tp = netdev_priv(dev);
 	struct timer_list *timer = &tp->timer;
 
-	if ((tp->mac_version <= RTL_GIGA_MAC_VER_B) ||
+	if ((tp->mac_version <= RTL_GIGA_MAC_VER_01) ||
 	    (tp->phy_version >= RTL_GIGA_PHY_VER_H))
 		return;
 
@@ -1354,7 +1392,7 @@ static inline void rtl8169_request_timer
 	struct rtl8169_private *tp = netdev_priv(dev);
 	struct timer_list *timer = &tp->timer;
 
-	if ((tp->mac_version <= RTL_GIGA_MAC_VER_B) ||
+	if ((tp->mac_version <= RTL_GIGA_MAC_VER_01) ||
 	    (tp->phy_version >= RTL_GIGA_PHY_VER_H))
 		return;
 
@@ -1393,8 +1431,9 @@ static void rtl8169_release_board(struct
 
 static int __devinit
 rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
-		   void __iomem **ioaddr_out)
+		   void __iomem **ioaddr_out, const struct pci_device_id *ent)
 {
+	const unsigned int region = rtl_cfg_info[ent->driver_data].region;
 	void __iomem *ioaddr;
 	struct net_device *dev;
 	struct rtl8169_private *tp;
@@ -1441,7 +1480,7 @@ rtl8169_init_board(struct pci_dev *pdev,
 	}
 
 	/* make sure PCI base addr 1 is MMIO */
-	if (!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
+	if (!(pci_resource_flags(pdev, region) & IORESOURCE_MEM)) {
 		if (netif_msg_probe(tp))
 			dev_err(&pdev->dev,
 			       "region #1 not an MMIO resource, aborting\n");
@@ -1449,7 +1488,7 @@ rtl8169_init_board(struct pci_dev *pdev,
 		goto err_out_mwi;
 	}
 	/* check for weird/broken PCI region reporting */
-	if (pci_resource_len(pdev, 1) < R8169_REGS_SIZE) {
+	if (pci_resource_len(pdev, region) < R8169_REGS_SIZE) {
 		if (netif_msg_probe(tp))
 			dev_err(&pdev->dev,
 			       "Invalid PCI region size(s), aborting\n");
@@ -1483,7 +1522,7 @@ rtl8169_init_board(struct pci_dev *pdev,
 	pci_set_master(pdev);
 
 	/* ioremap MMIO region */
-	ioaddr = ioremap(pci_resource_start(pdev, 1), R8169_REGS_SIZE);
+	ioaddr = ioremap(pci_resource_start(pdev, region), R8169_REGS_SIZE);
 	if (ioaddr == NULL) {
 		if (netif_msg_probe(tp))
 			dev_err(&pdev->dev, "cannot remap MMIO, aborting\n");
@@ -1574,7 +1613,7 @@ rtl8169_init_one(struct pci_dev *pdev, c
 		       MODULENAME, RTL8169_VERSION);
 	}
 
-	rc = rtl8169_init_board(pdev, &dev, &ioaddr);
+	rc = rtl8169_init_board(pdev, &dev, &ioaddr, ent);
 	if (rc)
 		return rc;
 
@@ -1632,6 +1671,7 @@ rtl8169_init_one(struct pci_dev *pdev, c
 	tp->intr_mask = 0xffff;
 	tp->pci_dev = pdev;
 	tp->mmio_addr = ioaddr;
+	tp->align = rtl_cfg_info[ent->driver_data].align;
 
 	spin_lock_init(&tp->lock);
 
@@ -1641,11 +1681,6 @@ rtl8169_init_one(struct pci_dev *pdev, c
 		return rc;
 	}
 
-	if (netif_msg_probe(tp)) {
-		printk(KERN_DEBUG "%s: Identified chip type is '%s'.\n",
-		       dev->name, rtl_chip_info[tp->chipset].name);
-	}
-
 	pci_set_drvdata(pdev, dev);
 
 	if (netif_msg_probe(tp)) {
@@ -1653,7 +1688,7 @@ rtl8169_init_one(struct pci_dev *pdev, c
 		       "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
 		       "IRQ %d\n",
 		       dev->name,
-		       rtl_chip_info[ent->driver_data].name,
+		       rtl_chip_info[tp->chipset].name,
 		       dev->base_addr,
 		       dev->dev_addr[0], dev->dev_addr[1],
 		       dev->dev_addr[2], dev->dev_addr[3],
@@ -1665,12 +1700,12 @@ rtl8169_init_one(struct pci_dev *pdev, c
 	dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
 	RTL_W8(0x82, 0x01);
 
-	if (tp->mac_version < RTL_GIGA_MAC_VER_E) {
+	if (tp->mac_version < RTL_GIGA_MAC_VER_03) {
 		dprintk("Set PCI Latency=0x40\n");
 		pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
 	}
 
-	if (tp->mac_version == RTL_GIGA_MAC_VER_D) {
+	if (tp->mac_version == RTL_GIGA_MAC_VER_02) {
 		dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
 		RTL_W8(0x82, 0x01);
 		dprintk("Set PHY Reg 0x0bh = 0x00h\n");
@@ -1780,6 +1815,7 @@ rtl8169_hw_start(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
+	struct pci_dev *pdev = tp->pci_dev;
 	u32 i;
 
 	/* Soft reset the chip. */
@@ -1792,8 +1828,28 @@ rtl8169_hw_start(struct net_device *dev)
 		udelay(10);
 	}
 
+	if (tp->mac_version == RTL_GIGA_MAC_VER_13) {
+		pci_write_config_word(pdev, 0x68, 0x00);
+		pci_write_config_word(pdev, 0x69, 0x08);
+	}
+
+	/* Undocumented stuff. */
+	if (tp->mac_version == RTL_GIGA_MAC_VER_05) {
+		u16 cmd;
+
+		/* Realtek's r1000_n.c driver uses '&& 0x01' here. Well... */
+		if ((RTL_R8(Config2) & 0x07) & 0x01)
+			RTL_W32(0x7c, 0x0007ffff);
+
+		RTL_W32(0x7c, 0x0007ff00);
+
+		pci_read_config_word(pdev, PCI_COMMAND, &cmd);
+		cmd = cmd & 0xef;
+		pci_write_config_word(pdev, PCI_COMMAND, cmd);
+	}
+
+
 	RTL_W8(Cfg9346, Cfg9346_Unlock);
-	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
 	RTL_W8(EarlyTxThres, EarlyTxThld);
 
 	/* Low hurts. Let's disable the filtering. */
@@ -1808,17 +1864,18 @@ rtl8169_hw_start(struct net_device *dev)
 	RTL_W32(TxConfig,
 		(TX_DMA_BURST << TxDMAShift) | (InterFrameGap <<
 						TxInterFrameGapShift));
-	tp->cp_cmd |= RTL_R16(CPlusCmd);
-	RTL_W16(CPlusCmd, tp->cp_cmd);
 
-	if ((tp->mac_version == RTL_GIGA_MAC_VER_D) ||
-	    (tp->mac_version == RTL_GIGA_MAC_VER_E)) {
+	tp->cp_cmd |= RTL_R16(CPlusCmd) | PCIMulRW;
+
+	if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
+	    (tp->mac_version == RTL_GIGA_MAC_VER_03)) {
 		dprintk(KERN_INFO PFX "Set MAC Reg C+CR Offset 0xE0. "
 			"Bit-3 and bit-14 MUST be 1\n");
-		tp->cp_cmd |= (1 << 14) | PCIMulRW;
-		RTL_W16(CPlusCmd, tp->cp_cmd);
+		tp->cp_cmd |= (1 << 14);
 	}
 
+	RTL_W16(CPlusCmd, tp->cp_cmd);
+
 	/*
 	 * Undocumented corner. Supposedly:
 	 * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets
@@ -1829,6 +1886,7 @@ rtl8169_hw_start(struct net_device *dev)
 	RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr >> 32));
 	RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_32BIT_MASK));
 	RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr >> 32));
+	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
 	RTL_W8(Cfg9346, Cfg9346_Lock);
 	udelay(10);
 
@@ -1910,17 +1968,18 @@ static inline void rtl8169_map_to_asic(s
 }
 
 static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff,
-				struct RxDesc *desc, int rx_buf_sz)
+				struct RxDesc *desc, int rx_buf_sz,
+				unsigned int align)
 {
 	struct sk_buff *skb;
 	dma_addr_t mapping;
 	int ret = 0;
 
-	skb = dev_alloc_skb(rx_buf_sz + NET_IP_ALIGN);
+	skb = dev_alloc_skb(rx_buf_sz + align);
 	if (!skb)
 		goto err_out;
 
-	skb_reserve(skb, NET_IP_ALIGN);
+	skb_reserve(skb, align);
 	*sk_buff = skb;
 
 	mapping = pci_map_single(pdev, skb->data, rx_buf_sz,
@@ -1959,9 +2018,9 @@ static u32 rtl8169_rx_fill(struct rtl816
 
 		if (tp->Rx_skbuff[i])
 			continue;
-			
+
 		ret = rtl8169_alloc_rx_skb(tp->pci_dev, tp->Rx_skbuff + i,
-					   tp->RxDescArray + i, tp->rx_buf_sz);
+			tp->RxDescArray + i, tp->rx_buf_sz, tp->align);
 		if (ret < 0)
 			break;
 	}
@@ -2372,16 +2431,17 @@ static inline void rtl8169_rx_csum(struc
 }
 
 static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size,
-				      struct RxDesc *desc, int rx_buf_sz)
+				      struct RxDesc *desc, int rx_buf_sz,
+				      unsigned int align)
 {
 	int ret = -1;
 
 	if (pkt_size < rx_copybreak) {
 		struct sk_buff *skb;
 
-		skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
+		skb = dev_alloc_skb(pkt_size + align);
 		if (skb) {
-			skb_reserve(skb, NET_IP_ALIGN);
+			skb_reserve(skb, align);
 			eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0);
 			*sk_buff = skb;
 			rtl8169_mark_to_asic(desc, rx_buf_sz);
@@ -2447,13 +2507,13 @@ rtl8169_rx_interrupt(struct net_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);
 
 			if (rtl8169_try_rx_copy(&skb, pkt_size, desc,
-						tp->rx_buf_sz)) {
+						tp->rx_buf_sz, tp->align)) {
 				pci_action = pci_unmap_single;
 				tp->Rx_skbuff[entry] = NULL;
 			}
@@ -2716,6 +2776,15 @@ rtl8169_set_rx_mode(struct net_device *d
 	tmp = rtl8169_rx_config | rx_mode |
 	      (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
 
+	if ((tp->mac_version == RTL_GIGA_MAC_VER_11) ||
+	    (tp->mac_version == RTL_GIGA_MAC_VER_12) ||
+	    (tp->mac_version == RTL_GIGA_MAC_VER_13) ||
+	    (tp->mac_version == RTL_GIGA_MAC_VER_14) ||
+	    (tp->mac_version == RTL_GIGA_MAC_VER_15)) {
+		mc_filter[0] = 0xffffffff;
+		mc_filter[1] = 0xffffffff;
+	}
+
 	RTL_W32(RxConfig, tmp);
 	RTL_W32(MAR0 + 0, mc_filter[0]);
 	RTL_W32(MAR0 + 4, mc_filter[1]);

  reply	other threads:[~2006-09-26 22:52 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-09-26 18:34 [2.6.18 backport] RTL8168 ethernet support in r8169 Daniel Drake
2006-09-26 19:14 ` Francois Romieu
2006-09-26 22:52   ` Daniel Drake [this message]
2006-09-29  2:46   ` Samir Bellabes
2006-09-29  7:00     ` Francois Romieu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4519AF1D.7020302@gentoo.org \
    --to=dsd@gentoo.org \
    --cc=netdev@vger.kernel.org \
    --cc=romieu@fr.zoreil.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.