[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#439167: marked as done (linux-2.6: forcedeth MAC correction bug in Etch)



Your message dated Sat, 15 Nov 2008 15:19:07 +0100
with message-id <20081115141907.GA3801@galadriel.inutil.org>
and subject line Re: linux-2.6: forcedeth MAC correction bug in Etch
has caused the Debian Bug report #439167,
regarding linux-2.6: forcedeth MAC correction bug in Etch
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
439167: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=439167
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: linux-2.6
Version: 2.6.18.dfsg.1-13etch1
Severity: important

Hi Dann,
There's a nasty bug in NVidia onboard ethernet chipsets:
The MAC address provided by the BIOS is invalid (it's inverted); as a consequence
the kernel creates a random MAC as a workaround. In combination with udev this leads
to a new ethX device every time you reboot.

I've pulled the relevant fixes from git for the kernel in Univention Corporate
Server 2.0, a Debian-derived distribution based on Etch. We've updated the
Etch kernel with the attached patch and verified it to work on the system below:
http://www.asus.de/products.aspx?l1=1&l2=2&l3=407&l4=0&model=1155&modelmenu=2
(It should apply to a wide range of NVidia-based systems)

So, I propose to update forcedeth in the r2 point update. This is been fixed in
linux-2.6 in 2.6.20 or 2.6.21.

Cheers,
        Moritz

-- System Information:
Debian Release: lenny/sid
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: i386 (i686)

Kernel: Linux 2.6.22-1-686 (SMP w/1 CPU core)
Locale: LANG=C, LC_CTYPE=de_DE.ISO-8859-15@euro (charmap=ISO-8859-15)
Shell: /bin/sh linked to /bin/bash
diff -Naur linux-2.6-2.6.18.dfsg.1.orig/debian/patches/features/forcedeth-mac-correction.patch linux-2.6-2.6.18.dfsg.1/debian/patches/features/forcedeth-mac-correction.patch
--- linux-2.6-2.6.18.dfsg.1.orig/debian/patches/features/forcedeth-mac-correction.patch	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6-2.6.18.dfsg.1/debian/patches/features/forcedeth-mac-correction.patch	2007-08-18 13:21:11.000000000 +0200
@@ -0,0 +1,140 @@
+--- drivers/net/forcedeth.c.orig	2007-08-13 15:59:52.000000000 +0200
++++ a/drivers/net/forcedeth.c	2007-08-13 15:59:09.000000000 +0200
+@@ -168,6 +169,7 @@
+ #define DEV_HAS_PAUSEFRAME_TX   0x0200  /* device supports tx pause frames */
+ #define DEV_HAS_STATISTICS      0x0400  /* device supports hw statistics */
+ #define DEV_HAS_TEST_EXTENDED   0x0800  /* device supports extended diagnostic test */
++#define DEV_HAS_CORRECT_MACADDR 0x4000  /* device supports correct mac address order */
+ 
+ enum {
+ 	NvRegIrqStatus = 0x000,
+@@ -262,7 +264,8 @@
+ 	NvRegRingSizes = 0x108,
+ #define NVREG_RINGSZ_TXSHIFT 0
+ #define NVREG_RINGSZ_RXSHIFT 16
+-	NvRegUnknownTransmitterReg = 0x10c,
++	NvRegTransmitPoll = 0x10c,
++#define NVREG_TRANSMITPOLL_MAC_ADDR_REV	0x00008000
+ 	NvRegLinkSpeed = 0x110,
+ #define NVREG_LINKSPEED_FORCE 0x10000
+ #define NVREG_LINKSPEED_10	1000
+@@ -1178,7 +1181,7 @@
+ 			KERN_INFO "nv_stop_tx: TransmitterStatus remained busy");
+ 
+ 	udelay(NV_TXSTOP_DELAY2);
+-	writel(0, base + NvRegUnknownTransmitterReg);
++	writel(readl(base + NvRegTransmitPoll) & NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + NvRegTransmitPoll);
+ }
+ 
+ static void nv_txrx_reset(struct net_device *dev)
+@@ -3918,7 +3921,7 @@
+ 	oom = nv_init_ring(dev);
+ 
+ 	writel(0, base + NvRegLinkSpeed);
+-	writel(0, base + NvRegUnknownTransmitterReg);
++	writel(readl(base + NvRegTransmitPoll) & NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + NvRegTransmitPoll);
+ 	nv_txrx_reset(dev);
+ 	writel(0, base + NvRegUnknownSetupReg6);
+ 
+@@ -4094,7 +4097,7 @@
+ 	unsigned long addr;
+ 	u8 __iomem *base;
+ 	int err, i;
+-	u32 powerstate;
++	u32 powerstate, txreg;
+ 
+ 	dev = alloc_etherdev(sizeof(struct fe_priv));
+ 	err = -ENOMEM;
+@@ -4281,12 +4284,31 @@
+ 	np->orig_mac[0] = readl(base + NvRegMacAddrA);
+ 	np->orig_mac[1] = readl(base + NvRegMacAddrB);
+ 
+-	dev->dev_addr[0] = (np->orig_mac[1] >>  8) & 0xff;
+-	dev->dev_addr[1] = (np->orig_mac[1] >>  0) & 0xff;
+-	dev->dev_addr[2] = (np->orig_mac[0] >> 24) & 0xff;
+-	dev->dev_addr[3] = (np->orig_mac[0] >> 16) & 0xff;
+-	dev->dev_addr[4] = (np->orig_mac[0] >>  8) & 0xff;
+-	dev->dev_addr[5] = (np->orig_mac[0] >>  0) & 0xff;
++	/* check the workaround bit for correct mac address order */
++	txreg = readl(base + NvRegTransmitPoll);
++	if ((txreg & NVREG_TRANSMITPOLL_MAC_ADDR_REV) ||
++	    (id->driver_data & DEV_HAS_CORRECT_MACADDR)) {
++		/* mac address is already in correct order */
++		dev->dev_addr[0] = (np->orig_mac[0] >>  0) & 0xff;
++		dev->dev_addr[1] = (np->orig_mac[0] >>  8) & 0xff;
++		dev->dev_addr[2] = (np->orig_mac[0] >> 16) & 0xff;
++		dev->dev_addr[3] = (np->orig_mac[0] >> 24) & 0xff;
++		dev->dev_addr[4] = (np->orig_mac[1] >>  0) & 0xff;
++		dev->dev_addr[5] = (np->orig_mac[1] >>  8) & 0xff;
++	} else {
++		/* need to reverse mac address to correct order */
++		dev->dev_addr[0] = (np->orig_mac[1] >>  8) & 0xff;
++		dev->dev_addr[1] = (np->orig_mac[1] >>  0) & 0xff;
++		dev->dev_addr[2] = (np->orig_mac[0] >> 24) & 0xff;
++		dev->dev_addr[3] = (np->orig_mac[0] >> 16) & 0xff;
++		dev->dev_addr[4] = (np->orig_mac[0] >>  8) & 0xff;
++		dev->dev_addr[5] = (np->orig_mac[0] >>  0) & 0xff;
++		/* set permanent address to be correct aswell */
++		np->orig_mac[0] = (dev->dev_addr[0] << 0) + (dev->dev_addr[1] << 8) +
++			(dev->dev_addr[2] << 16) + (dev->dev_addr[3] << 24);
++		np->orig_mac[1] = (dev->dev_addr[4] << 0) + (dev->dev_addr[5] << 8);
++		writel(txreg|NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + NvRegTransmitPoll);
++	}
+ 	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
+ 
+ 	if (!is_valid_ether_addr(dev->perm_addr)) {
+@@ -4496,35 +4518,35 @@
+ 	},
+ 	{	/* MCP61 Ethernet Controller */
+ 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_16),
+-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED,
++		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR,
+ 	},
+ 	{	/* MCP61 Ethernet Controller */
+ 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_17),
+-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED,
++		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR,
+ 	},
+ 	{	/* MCP61 Ethernet Controller */
+ 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_18),
+-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED,
++		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR,
+ 	},
+ 	{	/* MCP61 Ethernet Controller */
+ 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_19),
+-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED,
++		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR,
+ 	},
+ 	{	/* MCP65 Ethernet Controller */
+ 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_20),
+-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED,
++		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR,
+ 	},
+ 	{	/* MCP65 Ethernet Controller */
+ 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_21),
+-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED,
++		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR,
+ 	},
+ 	{	/* MCP65 Ethernet Controller */
+ 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_22),
+-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED,
++		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR,
+ 	},
+ 	{	/* MCP65 Ethernet Controller */
+ 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_23),
+-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED,
++		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR,
+ 	},
+ 	{0,},
+ };
+
+
+
+
+
+
+
+
+
+
+

--- End Message ---
--- Begin Message ---
Version: 2.6.21-1

On Wed, Aug 22, 2007 at 10:37:54PM +0200, Moritz Muehlenhoff wrote:
> Package: linux-2.6
> Version: 2.6.18.dfsg.1-13etch1
> Severity: important
> 
> Hi Dann,
> There's a nasty bug in NVidia onboard ethernet chipsets:
> The MAC address provided by the BIOS is invalid (it's inverted); as a consequence
> the kernel creates a random MAC as a workaround. In combination with udev this leads
> to a new ethX device every time you reboot.

This was fixed upstream in 2.6.21.

Cheers,
        Moritz


--- End Message ---

Reply to: