diff options
author | Michael Chan <mchan@broadcom.com> | 2006-03-28 02:14:53 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-03-28 20:02:35 -0500 |
commit | 008652b337364ee994a0cd71d88a0fe9f00fc7ca (patch) | |
tree | 1a92b594cf22327ac92484e37129d86bac6f663c /drivers/net/tg3.c | |
parent | ca9ba4471c1203bb6e759b76e83167fec54fe590 (diff) |
[TG3]: Fix probe failure due to invalid MAC address
Some older bootcode in some devices may report 0 MAC address in
SRAM when booting up from low power state. This patch fixes the
problem by checking for a valid MAC address in SRAM and falling back
to NVRAM if necessary.
Thanks to walt <wa1ter@myrealbox.com> for reporting the problem
and helping to debug it.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r-- | drivers/net/tg3.c | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index b5473325bff4..c41dbb0e8f14 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -10531,6 +10531,7 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) | |||
10531 | { | 10531 | { |
10532 | struct net_device *dev = tp->dev; | 10532 | struct net_device *dev = tp->dev; |
10533 | u32 hi, lo, mac_offset; | 10533 | u32 hi, lo, mac_offset; |
10534 | int addr_ok = 0; | ||
10534 | 10535 | ||
10535 | #ifdef CONFIG_SPARC64 | 10536 | #ifdef CONFIG_SPARC64 |
10536 | if (!tg3_get_macaddr_sparc(tp)) | 10537 | if (!tg3_get_macaddr_sparc(tp)) |
@@ -10560,29 +10561,34 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) | |||
10560 | dev->dev_addr[3] = (lo >> 16) & 0xff; | 10561 | dev->dev_addr[3] = (lo >> 16) & 0xff; |
10561 | dev->dev_addr[4] = (lo >> 8) & 0xff; | 10562 | dev->dev_addr[4] = (lo >> 8) & 0xff; |
10562 | dev->dev_addr[5] = (lo >> 0) & 0xff; | 10563 | dev->dev_addr[5] = (lo >> 0) & 0xff; |
10563 | } | ||
10564 | /* Next, try NVRAM. */ | ||
10565 | else if (!(tp->tg3_flags & TG3_FLG2_SUN_570X) && | ||
10566 | !tg3_nvram_read(tp, mac_offset + 0, &hi) && | ||
10567 | !tg3_nvram_read(tp, mac_offset + 4, &lo)) { | ||
10568 | dev->dev_addr[0] = ((hi >> 16) & 0xff); | ||
10569 | dev->dev_addr[1] = ((hi >> 24) & 0xff); | ||
10570 | dev->dev_addr[2] = ((lo >> 0) & 0xff); | ||
10571 | dev->dev_addr[3] = ((lo >> 8) & 0xff); | ||
10572 | dev->dev_addr[4] = ((lo >> 16) & 0xff); | ||
10573 | dev->dev_addr[5] = ((lo >> 24) & 0xff); | ||
10574 | } | ||
10575 | /* Finally just fetch it out of the MAC control regs. */ | ||
10576 | else { | ||
10577 | hi = tr32(MAC_ADDR_0_HIGH); | ||
10578 | lo = tr32(MAC_ADDR_0_LOW); | ||
10579 | 10564 | ||
10580 | dev->dev_addr[5] = lo & 0xff; | 10565 | /* Some old bootcode may report a 0 MAC address in SRAM */ |
10581 | dev->dev_addr[4] = (lo >> 8) & 0xff; | 10566 | addr_ok = is_valid_ether_addr(&dev->dev_addr[0]); |
10582 | dev->dev_addr[3] = (lo >> 16) & 0xff; | 10567 | } |
10583 | dev->dev_addr[2] = (lo >> 24) & 0xff; | 10568 | if (!addr_ok) { |
10584 | dev->dev_addr[1] = hi & 0xff; | 10569 | /* Next, try NVRAM. */ |
10585 | dev->dev_addr[0] = (hi >> 8) & 0xff; | 10570 | if (!(tp->tg3_flags & TG3_FLG2_SUN_570X) && |
10571 | !tg3_nvram_read(tp, mac_offset + 0, &hi) && | ||
10572 | !tg3_nvram_read(tp, mac_offset + 4, &lo)) { | ||
10573 | dev->dev_addr[0] = ((hi >> 16) & 0xff); | ||
10574 | dev->dev_addr[1] = ((hi >> 24) & 0xff); | ||
10575 | dev->dev_addr[2] = ((lo >> 0) & 0xff); | ||
10576 | dev->dev_addr[3] = ((lo >> 8) & 0xff); | ||
10577 | dev->dev_addr[4] = ((lo >> 16) & 0xff); | ||
10578 | dev->dev_addr[5] = ((lo >> 24) & 0xff); | ||
10579 | } | ||
10580 | /* Finally just fetch it out of the MAC control regs. */ | ||
10581 | else { | ||
10582 | hi = tr32(MAC_ADDR_0_HIGH); | ||
10583 | lo = tr32(MAC_ADDR_0_LOW); | ||
10584 | |||
10585 | dev->dev_addr[5] = lo & 0xff; | ||
10586 | dev->dev_addr[4] = (lo >> 8) & 0xff; | ||
10587 | dev->dev_addr[3] = (lo >> 16) & 0xff; | ||
10588 | dev->dev_addr[2] = (lo >> 24) & 0xff; | ||
10589 | dev->dev_addr[1] = hi & 0xff; | ||
10590 | dev->dev_addr[0] = (hi >> 8) & 0xff; | ||
10591 | } | ||
10586 | } | 10592 | } |
10587 | 10593 | ||
10588 | if (!is_valid_ether_addr(&dev->dev_addr[0])) { | 10594 | if (!is_valid_ether_addr(&dev->dev_addr[0])) { |