Bug 51791
Summary: | mac 00:00:00:00:00:00 with natsemi DP83815 after driver load | ||
---|---|---|---|
Product: | Drivers | Reporter: | Roland Kletzing (devzero) |
Component: | Network | Assignee: | drivers_network (drivers_network) |
Status: | NEW --- | ||
Severity: | normal | CC: | alan, devzero, szg00000 |
Priority: | P1 | ||
Hardware: | All | ||
OS: | Linux | ||
Kernel Version: | 2.6.33 , 3.2.0 | Subsystem: | |
Regression: | No | Bisected commit-id: |
Description
Roland Kletzing
2012-12-18 11:37:11 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) 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 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. > 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) -- |