Bug 51791 - mac 00:00:00:00:00:00 with natsemi DP83815 after driver load
Summary: mac 00:00:00:00:00:00 with natsemi DP83815 after driver load
Status: NEW
Alias: None
Product: Drivers
Classification: Unclassified
Component: Network (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: drivers_network@kernel-bugs.osdl.org
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-12-18 11:37 UTC by Roland Kletzing
Modified: 2016-02-15 21:58 UTC (History)
3 users (show)

See Also:
Kernel Version: 2.6.33 , 3.2.0
Subsystem:
Regression: No
Bisected commit-id:


Attachments

Description Roland Kletzing 2012-12-18 11:37:11 UTC
on compaq evo t20 (same hardware to wyse 3235le thin clients ) there seems an issue with the natsemi driver.

after driver load (natsemi.ko) eth0 has no valid mac adress, dmesg and
ifconfig shows just zero`s: 00:00:00:00:00:00.

despite that, the nic is working fine for me when i set the
mac manually,e.g. "ifconfig eth0 hw ether de:ad:be:ef:be:ef" 

apparently, the driver fails to read the proper mac from the eeprom, as
"natsemi-diag -ee" (from nictools-pci in debian squeeze) shows that there
is a valid "Ethernet MAC Station Address" stored inside the eeprom. (see
below)

#lspci

00:00.0 Host bridge: Cyrix Corporation PCI Master
00:0f.0 Ethernet controller: National Semiconductor Corporation DP83815
(MacPhyter) Ethernet Controller
00:12.0 ISA bridge: Cyrix Corporation 5530 Legacy [Kahlua] (rev 30)
00:12.1 Bridge: Cyrix Corporation 5530 SMI [Kahlua]
00:12.2 IDE interface: Cyrix Corporation 5530 IDE [Kahlua]
00:12.3 Multimedia audio controller: Cyrix Corporation 5530 Audio [Kahlua]
00:12.4 VGA compatible controller: Cyrix Corporation 5530 Video [Kahlua]
00:13.0 USB Controller: Compaq Computer Corporation ZFMicro Chipset USB (rev
06)

#dmesg |egrep "natsemi|eth"
natsemi dp8381x driver, version 2.1, Sept 11, 2006
natsemi 0000:00:0f.0: setting latency timer to 64
natsemi eth0: NatSemi DP8381[56] at 0x4010000 (0000:00:0f.0),
00:00:00:00:00:00, IRQ 10, port TP.
eth0: DSPCFG accepted after 0 usec.
eth0: link up.
eth0: Setting full-duplex based on negotiated link capability.

#natsemi-diag -aa
natsemi-diag.c:v2.08 2/28/2005 Donald Becker (becker@scyld.com)
 http://www.scyld.com/diag/index.html
Index #1: Found a NatSemi DP83815 adapter at 0xf800.
 Natsemi 83815 series with station address de:ad:be:ef:be:ef
 Transceiver setting Autonegotation advertise 10/100 Mbps half and full
duplex.
 This device appears to be active, so some registers will not be read.
 To see all register values use the '-f' flag.
NatSemi DP83815 chip registers at 0xf800
 0x000: 00000004 e805e000 00000002 00000000 ******** 00f1cd65 00000001
00000000
 0x020: 03abd200 d0f01002 00000000 00000000 03abd000 18700010 00000000
00000000
 0x040: ******** 00200000 00000004 0000efbe ffff000b 30303030 00000403
00000000
 0x060: ******** ******** ******** ******** ******** ******** ********
********
 0x080: 00003100 0000786d 00002000 00005c21 000005e1 000045e1 00000005
00002801
 0x0A0: ******** ******** ******** ******** ******** ******** ********
********
 0x0C0: 00000615 00000002 00000000 00000000 00000000 00000000 00000100
00000030
 0x0E0: 00000000 000000bf 00000804 00008200 00000000 00000000 00000000
00000000
  Interrupt sources are pending (00000200).
   Tx queue emptied indication.
  Receive mode is 0xc8200000: Normal unicast and hashed multicast.
  Rx filter contents:   adde efbe efbe 0000 0000 0000 0000 0000

#natsemi-diag -ee
natsemi-diag.c:v2.08 2/28/2005 Donald Becker (becker@scyld.com)
 http://www.scyld.com/diag/index.html
Index #1: Found a NatSemi DP83815 adapter at 0xf800.
 Natsemi 83815 series with station address de:ad:be:ef:be:ef
 Transceiver setting Autonegotation advertise 10/100 Mbps half and full
duplex.
 EEPROM address length 6, 64 words.
EEPROM contents (64 words):
0x00:  100b 0020 0b34 41fb 0000 0000 0000 4000
0x08:  0d32 dff4 1905 aa48 0000 0000 129c 4c4c
0x10:  ca52 2ccc 0cb2 9c6c 0c6c 8c0c 2020 6080
0x18:  0800 0000 0000 0000 0000 0000 0000 0000
0x20:  0000 0000 0000 0000 0000 0000 0000 0000
0x28:  0000 0000 0000 0000 0000 0000 0000 0000
0x30:  0000 0000 0000 0000 0000 0000 0000 0000
0x38:  0000 0000 0000 0000 0000 0000 0000 e418
Decoded EEPROM contents:
  PCI Subsystem IDs -- Vendor 0x100b, Device 0x0020.
  PCI timer settings -- minimum grant 11, maximum latency 52.
  Ethernet MAC Station Address 00:80:64:1a:e8:bf.
  Wake-On-LAN password 00:00:00:00:00:00.
  Transceiver setting 0x--f-: advertise 10/100 Mbps half and full duplex.
   Flow control enabled.
  EEPROM active region checksum read as aa48, vs aa48 calculated value.
Comment 1 Alan 2013-01-02 14:25:07 UTC
Bugzilla is just used to track bugs - with something like this where there is a good chance of someone being able to fix it I'd also suggest posting a copy of the report to netdev@vger.kernel.org (you don't need to be subscribed)
Comment 2 Roland Kletzing 2013-01-02 20:12:13 UTC
i have already posted that to netdev, but as there was no response i thought it would be better to put it here so it won`t get lost. pardon, forgot to mention that - here is the reference http://marc.info/?l=linux-netdev&m=135574795027455&w=2
Comment 3 Roland Kletzing 2014-11-14 23:45:21 UTC
no response from netdev so far, so putting it here for reference. maybe someone has a clue about the proper fix.


> Gesendet: Mittwoch, 12. November 2014 um 22:46 Uhr
> Von: devzero@web.de
> An: netdev@vger.kernel.org
> Cc: thockin@hockin.org
> Betreff: re: bug? mac 00:00:00:00:00:00 with natsemi DP83815 after driver
> load
>
> hi,
> as i`m doing a little project with this older devices, i have come across
> this issue again and had some fun to dig deeper into it.
> 
> it`s a little bit academic, as i can do ifconfig eth0 hw ether..... as a
> workaround, but it sucks to hack that into startup scripts and i also have
> seen udev not playing nicely with it.
> 
> apparently the problem is being caused by a timing issue in the natsemi
> driver.
> 
> i added some debug printk`s in natsemi.c -> eeprom_read() after each
> occurrence of eeprom_delay(ee_addr); , and the problem went away. 
> 
> there is a hint about timing sensitivity in the code:
> 
> /* Delay between EEPROM clock transitions.
>    No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
>    a delay.  Note that pre-2.0.34 kernels had a cache-alignment bug that
>    made udelay() unreliable.
>    The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is
>    deprecated.
> */
> 
> looking at the source of natsemi-diag.c made me wonder why that utility is
> using 
> 
> #define eeprom_delay(ee_addr)   inl(ee_addr)
> 
> instead of 
> 
> #define eeprom_delay(ee_addr)   readl(ee_addr)
> 
> and apparently, that also fixes the problem (but gives a compile warning):
> 
> drivers/net/ethernet/natsemi/natsemi.c: In function âeeprom_readâ:
> drivers/net/ethernet/natsemi/natsemi.c:1019:3: warning: passing argument 1 of
> âinlâ makes integer from pointer without a cast [enabled by default]
> In file included from include/linux/io.h:22:0,
>                  from include/linux/pci.h:54,
>                  from drivers/net/ethernet/natsemi/natsemi.c:38:
> 
> 
> looking at a more recent version of natsemi-diag.c ,  i even found this one:
> 
> ftp://ftp.gwdg.de/pub/linux/misc/donald.becker/diag/natsemi-diag.c
> 
> /* Delay between EEPROM clock transitions.
>    This flushes the write buffer to prevent quick double-writes.
> */
> #define eeprom_delay(ee_addr) inl(ee_addr); inl(ee_addr)
> 
> The question is how to make a proper fix, as i don`t know what to pass to
> inl() , as it seems it should not get an mmapped adress but an i/o port
> instead !?
> 
> "The  in*() functions return data read from the specified I/O port"
> 
> "The read*() functions read data from device memory previously mapped by
> map_memory()"
> 
> regards
> roland
> 
> ps: CC driver maintainer from Kernel Maintainers file.
>
Comment 4 Roland Kletzing 2014-11-17 20:17:00 UTC
also sent to netdev ML.

This one should fix Bugzilla #51791 (details below).

Natsemi driver does not read MAC correctly from eeprom, while natsemi-diag from nictools-pci does. Apparently, tt`s a timing issue in the kernel driver.

According to ftp://ftp.gwdg.de/pub/linux/misc/donald.becker/diag/natsemi-diag.c , eeprom_delay(ee_addr) is defined as follows:

/* Delay between EEPROM clock transitions.
This flushes the write buffer to prevent quick double-writes.
*/
#define eeprom_delay(ee_addr) inl(ee_addr); inl(ee_addr)

while in the natsemi linux kernel driver, the delay is done this way :

#define eeprom_delay(ee_addr) readl(ee_addr)

, which results in the MAC being all zero`s.

So i simply added a second readl() to increase delay (instead of turning into inl() as proposed before). This may look a little bit ugly, but it`s fixing the problem for me.

I´m not sure how many natsemi users being left on this planet (probably few), but i guess this change does not do any harm on platforms where the driver does not behave buggy, so please consider adding it to mainline/stable/longterm.

Signed-off-by: Roland Kletzing <devzero@web.de>

---
drivers/net/ethernet/natsemi/natsemi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/natsemi/natsemi.c b/drivers/net/ethernet/natsemi/natsemi.c
index b83f7c0..246bb91 100644
--- a/drivers/net/ethernet/natsemi/natsemi.c
+++ b/drivers/net/ethernet/natsemi/natsemi.c
@@ -987,7 +987,7 @@ static int natsemi_probe1(struct pci_dev *pdev, const struct pci_device_id *ent)
The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is
deprecated.
*/
-#define eeprom_delay(ee_addr) readl(ee_addr)
+#define eeprom_delay(ee_addr) readl(ee_addr); readl(ee_addr)

#define EE_Write0 (EE_ChipSelect)
#define EE_Write1 (EE_ChipSelect | EE_DataIn)
--

Note You need to log in before you can comment on or make changes to this bug.