diff options
author | françois romieu <romieu@fr.zoreil.com> | 2009-03-14 21:10:50 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-03-15 23:03:10 -0400 |
commit | ea8dbdd17099a9a5864ebd4c87e01e657b19c7ab (patch) | |
tree | 8d30419e013f0c7e75545e0c7ad03140a2acfc47 | |
parent | 97d477a914b146e7e6722ded21afa79886ae8ccd (diff) |
r8169: revert "r8169: read MAC address from EEPROM on init (2nd attempt)"
It fails on the following systems:
- RTL8169sc/8110sc (XID 18000000)
reported by Tim Durack <tdurack@gmail.com> (x86)
- RTL8169sb/8110sb (XID 10000000)
reported by Mikael Pettersson <mikpe@it.uu.se> (ARM)
The patch appeared to work on x86 for the following systems:
RTL8169sb/8110sb 10000000 PCI (EXT)
RTL8110s 04000000 PCI (EXT)
RTL8102e 24a00000 PCI-E (LOM)
RTL8168c/8111c 3c2000c0 PCI-E (LOM)
RTL8168b/8111b 38000000 PCI-E (LOM)
RTL8168b/8111b 38000000 PCI-E (EXT)
The patch exposes two problems:
1) while not completely wrong, mac addresses are not read correctly
from the EEPROM
2) the MAC address registers are not correctly set
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Tested-by: Mikael Pettersson <mikpe@it.uu.se>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/r8169.c | 114 |
1 files changed, 2 insertions, 112 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 352da2a43c9f..43fedb9ecedb 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -81,9 +81,9 @@ static const int multicast_filter_limit = 32; | |||
81 | #define RTL8169_TX_TIMEOUT (6*HZ) | 81 | #define RTL8169_TX_TIMEOUT (6*HZ) |
82 | #define RTL8169_PHY_TIMEOUT (10*HZ) | 82 | #define RTL8169_PHY_TIMEOUT (10*HZ) |
83 | 83 | ||
84 | #define RTL_EEPROM_SIG 0x8129 | 84 | #define RTL_EEPROM_SIG cpu_to_le32(0x8129) |
85 | #define RTL_EEPROM_SIG_MASK cpu_to_le32(0xffff) | ||
85 | #define RTL_EEPROM_SIG_ADDR 0x0000 | 86 | #define RTL_EEPROM_SIG_ADDR 0x0000 |
86 | #define RTL_EEPROM_MAC_ADDR 0x0007 | ||
87 | 87 | ||
88 | /* write/read MMIO register */ | 88 | /* write/read MMIO register */ |
89 | #define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg)) | 89 | #define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg)) |
@@ -293,11 +293,6 @@ enum rtl_register_content { | |||
293 | /* Cfg9346Bits */ | 293 | /* Cfg9346Bits */ |
294 | Cfg9346_Lock = 0x00, | 294 | Cfg9346_Lock = 0x00, |
295 | Cfg9346_Unlock = 0xc0, | 295 | Cfg9346_Unlock = 0xc0, |
296 | Cfg9346_Program = 0x80, /* Programming mode */ | ||
297 | Cfg9346_EECS = 0x08, /* Chip select */ | ||
298 | Cfg9346_EESK = 0x04, /* Serial data clock */ | ||
299 | Cfg9346_EEDI = 0x02, /* Data input */ | ||
300 | Cfg9346_EEDO = 0x01, /* Data output */ | ||
301 | 296 | ||
302 | /* rx_mode_bits */ | 297 | /* rx_mode_bits */ |
303 | AcceptErr = 0x20, | 298 | AcceptErr = 0x20, |
@@ -310,7 +305,6 @@ enum rtl_register_content { | |||
310 | /* RxConfigBits */ | 305 | /* RxConfigBits */ |
311 | RxCfgFIFOShift = 13, | 306 | RxCfgFIFOShift = 13, |
312 | RxCfgDMAShift = 8, | 307 | RxCfgDMAShift = 8, |
313 | RxCfg9356SEL = 6, /* EEPROM type: 0 = 9346, 1 = 9356 */ | ||
314 | 308 | ||
315 | /* TxConfigBits */ | 309 | /* TxConfigBits */ |
316 | TxInterFrameGapShift = 24, | 310 | TxInterFrameGapShift = 24, |
@@ -1969,108 +1963,6 @@ static const struct net_device_ops rtl8169_netdev_ops = { | |||
1969 | 1963 | ||
1970 | }; | 1964 | }; |
1971 | 1965 | ||
1972 | /* Delay between EEPROM clock transitions. Force out buffered PCI writes. */ | ||
1973 | #define RTL_EEPROM_DELAY() RTL_R8(Cfg9346) | ||
1974 | #define RTL_EEPROM_READ_CMD 6 | ||
1975 | |||
1976 | /* read 16bit word stored in EEPROM. EEPROM is addressed by words. */ | ||
1977 | static u16 rtl_eeprom_read(void __iomem *ioaddr, int addr) | ||
1978 | { | ||
1979 | u16 result = 0; | ||
1980 | int cmd, cmd_len, i; | ||
1981 | |||
1982 | /* check for EEPROM address size (in bits) */ | ||
1983 | if (RTL_R32(RxConfig) & (1 << RxCfg9356SEL)) { | ||
1984 | /* EEPROM is 93C56 */ | ||
1985 | cmd_len = 3 + 8; /* 3 bits for command id and 8 for address */ | ||
1986 | cmd = (RTL_EEPROM_READ_CMD << 8) | (addr & 0xff); | ||
1987 | } else { | ||
1988 | /* EEPROM is 93C46 */ | ||
1989 | cmd_len = 3 + 6; /* 3 bits for command id and 6 for address */ | ||
1990 | cmd = (RTL_EEPROM_READ_CMD << 6) | (addr & 0x3f); | ||
1991 | } | ||
1992 | |||
1993 | /* enter programming mode */ | ||
1994 | RTL_W8(Cfg9346, Cfg9346_Program | Cfg9346_EECS); | ||
1995 | RTL_EEPROM_DELAY(); | ||
1996 | |||
1997 | /* write command and requested address */ | ||
1998 | while (cmd_len--) { | ||
1999 | u8 x = Cfg9346_Program | Cfg9346_EECS; | ||
2000 | |||
2001 | x |= (cmd & (1 << cmd_len)) ? Cfg9346_EEDI : 0; | ||
2002 | |||
2003 | /* write a bit */ | ||
2004 | RTL_W8(Cfg9346, x); | ||
2005 | RTL_EEPROM_DELAY(); | ||
2006 | |||
2007 | /* raise clock */ | ||
2008 | RTL_W8(Cfg9346, x | Cfg9346_EESK); | ||
2009 | RTL_EEPROM_DELAY(); | ||
2010 | } | ||
2011 | |||
2012 | /* lower clock */ | ||
2013 | RTL_W8(Cfg9346, Cfg9346_Program | Cfg9346_EECS); | ||
2014 | RTL_EEPROM_DELAY(); | ||
2015 | |||
2016 | /* read back 16bit value */ | ||
2017 | for (i = 16; i > 0; i--) { | ||
2018 | /* raise clock */ | ||
2019 | RTL_W8(Cfg9346, Cfg9346_Program | Cfg9346_EECS | Cfg9346_EESK); | ||
2020 | RTL_EEPROM_DELAY(); | ||
2021 | |||
2022 | result <<= 1; | ||
2023 | result |= (RTL_R8(Cfg9346) & Cfg9346_EEDO) ? 1 : 0; | ||
2024 | |||
2025 | /* lower clock */ | ||
2026 | RTL_W8(Cfg9346, Cfg9346_Program | Cfg9346_EECS); | ||
2027 | RTL_EEPROM_DELAY(); | ||
2028 | } | ||
2029 | |||
2030 | RTL_W8(Cfg9346, Cfg9346_Program); | ||
2031 | /* leave programming mode */ | ||
2032 | RTL_W8(Cfg9346, Cfg9346_Lock); | ||
2033 | |||
2034 | return result; | ||
2035 | } | ||
2036 | |||
2037 | static void rtl_init_mac_address(struct rtl8169_private *tp, | ||
2038 | void __iomem *ioaddr) | ||
2039 | { | ||
2040 | struct pci_dev *pdev = tp->pci_dev; | ||
2041 | u16 x; | ||
2042 | u8 mac[8]; | ||
2043 | |||
2044 | /* read EEPROM signature */ | ||
2045 | x = rtl_eeprom_read(ioaddr, RTL_EEPROM_SIG_ADDR); | ||
2046 | |||
2047 | if (x != RTL_EEPROM_SIG) { | ||
2048 | dev_info(&pdev->dev, "Missing EEPROM signature: %04x\n", x); | ||
2049 | return; | ||
2050 | } | ||
2051 | |||
2052 | /* read MAC address */ | ||
2053 | x = rtl_eeprom_read(ioaddr, RTL_EEPROM_MAC_ADDR); | ||
2054 | mac[0] = x & 0xff; | ||
2055 | mac[1] = x >> 8; | ||
2056 | x = rtl_eeprom_read(ioaddr, RTL_EEPROM_MAC_ADDR + 1); | ||
2057 | mac[2] = x & 0xff; | ||
2058 | mac[3] = x >> 8; | ||
2059 | x = rtl_eeprom_read(ioaddr, RTL_EEPROM_MAC_ADDR + 2); | ||
2060 | mac[4] = x & 0xff; | ||
2061 | mac[5] = x >> 8; | ||
2062 | |||
2063 | if (netif_msg_probe(tp)) { | ||
2064 | DECLARE_MAC_BUF(buf); | ||
2065 | |||
2066 | dev_info(&pdev->dev, "MAC address found in EEPROM: %s\n", | ||
2067 | print_mac(buf, mac)); | ||
2068 | } | ||
2069 | |||
2070 | if (is_valid_ether_addr(mac)) | ||
2071 | rtl_rar_set(tp, mac); | ||
2072 | } | ||
2073 | |||
2074 | static int __devinit | 1966 | static int __devinit |
2075 | rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 1967 | rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
2076 | { | 1968 | { |
@@ -2249,8 +2141,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2249 | 2141 | ||
2250 | tp->mmio_addr = ioaddr; | 2142 | tp->mmio_addr = ioaddr; |
2251 | 2143 | ||
2252 | rtl_init_mac_address(tp, ioaddr); | ||
2253 | |||
2254 | /* Get MAC address */ | 2144 | /* Get MAC address */ |
2255 | for (i = 0; i < MAC_ADDR_LEN; i++) | 2145 | for (i = 0; i < MAC_ADDR_LEN; i++) |
2256 | dev->dev_addr[i] = RTL_R8(MAC0 + i); | 2146 | dev->dev_addr[i] = RTL_R8(MAC0 + i); |