aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/r8169.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-03-05 05:45:22 -0500
committerIngo Molnar <mingo@elte.hu>2009-03-05 05:45:22 -0500
commita140feab42d1cfd811930ab76104559c19dfc4b0 (patch)
tree41fd871990e888dd5616a6bf1891a1ff307221df /drivers/net/r8169.c
parent1075414b06109a99b0e87601e84c74a95bd45681 (diff)
parentfec6c6fec3e20637bee5d276fb61dd8b49a3f9cc (diff)
Merge commit 'v2.6.29-rc7' into core/locking
Diffstat (limited to 'drivers/net/r8169.c')
-rw-r--r--drivers/net/r8169.c207
1 files changed, 170 insertions, 37 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 2c73ca606b35..b3473401c83a 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 cpu_to_le32(0x8129) 84#define RTL_EEPROM_SIG 0x8129
85#define RTL_EEPROM_SIG_MASK cpu_to_le32(0xffff)
86#define RTL_EEPROM_SIG_ADDR 0x0000 85#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,6 +293,11 @@ 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 */
296 301
297 /* rx_mode_bits */ 302 /* rx_mode_bits */
298 AcceptErr = 0x20, 303 AcceptErr = 0x20,
@@ -305,6 +310,7 @@ enum rtl_register_content {
305 /* RxConfigBits */ 310 /* RxConfigBits */
306 RxCfgFIFOShift = 13, 311 RxCfgFIFOShift = 13,
307 RxCfgDMAShift = 8, 312 RxCfgDMAShift = 8,
313 RxCfg9356SEL = 6, /* EEPROM type: 0 = 9346, 1 = 9356 */
308 314
309 /* TxConfigBits */ 315 /* TxConfigBits */
310 TxInterFrameGapShift = 24, 316 TxInterFrameGapShift = 24,
@@ -437,6 +443,22 @@ enum features {
437 RTL_FEATURE_GMII = (1 << 2), 443 RTL_FEATURE_GMII = (1 << 2),
438}; 444};
439 445
446struct rtl8169_counters {
447 __le64 tx_packets;
448 __le64 rx_packets;
449 __le64 tx_errors;
450 __le32 rx_errors;
451 __le16 rx_missed;
452 __le16 align_errors;
453 __le32 tx_one_collision;
454 __le32 tx_multi_collision;
455 __le64 rx_unicast;
456 __le64 rx_broadcast;
457 __le32 rx_multicast;
458 __le16 tx_aborted;
459 __le16 tx_underun;
460};
461
440struct rtl8169_private { 462struct rtl8169_private {
441 void __iomem *mmio_addr; /* memory map physical address */ 463 void __iomem *mmio_addr; /* memory map physical address */
442 struct pci_dev *pci_dev; /* Index of PCI device */ 464 struct pci_dev *pci_dev; /* Index of PCI device */
@@ -480,6 +502,7 @@ struct rtl8169_private {
480 unsigned features; 502 unsigned features;
481 503
482 struct mii_if_info mii; 504 struct mii_if_info mii;
505 struct rtl8169_counters counters;
483}; 506};
484 507
485MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); 508MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
@@ -1100,22 +1123,6 @@ static const char rtl8169_gstrings[][ETH_GSTRING_LEN] = {
1100 "tx_underrun", 1123 "tx_underrun",
1101}; 1124};
1102 1125
1103struct rtl8169_counters {
1104 __le64 tx_packets;
1105 __le64 rx_packets;
1106 __le64 tx_errors;
1107 __le32 rx_errors;
1108 __le16 rx_missed;
1109 __le16 align_errors;
1110 __le32 tx_one_collision;
1111 __le32 tx_multi_collision;
1112 __le64 rx_unicast;
1113 __le64 rx_broadcast;
1114 __le32 rx_multicast;
1115 __le16 tx_aborted;
1116 __le16 tx_underun;
1117};
1118
1119static int rtl8169_get_sset_count(struct net_device *dev, int sset) 1126static int rtl8169_get_sset_count(struct net_device *dev, int sset)
1120{ 1127{
1121 switch (sset) { 1128 switch (sset) {
@@ -1126,16 +1133,21 @@ static int rtl8169_get_sset_count(struct net_device *dev, int sset)
1126 } 1133 }
1127} 1134}
1128 1135
1129static void rtl8169_get_ethtool_stats(struct net_device *dev, 1136static void rtl8169_update_counters(struct net_device *dev)
1130 struct ethtool_stats *stats, u64 *data)
1131{ 1137{
1132 struct rtl8169_private *tp = netdev_priv(dev); 1138 struct rtl8169_private *tp = netdev_priv(dev);
1133 void __iomem *ioaddr = tp->mmio_addr; 1139 void __iomem *ioaddr = tp->mmio_addr;
1134 struct rtl8169_counters *counters; 1140 struct rtl8169_counters *counters;
1135 dma_addr_t paddr; 1141 dma_addr_t paddr;
1136 u32 cmd; 1142 u32 cmd;
1143 int wait = 1000;
1137 1144
1138 ASSERT_RTNL(); 1145 /*
1146 * Some chips are unable to dump tally counters when the receiver
1147 * is disabled.
1148 */
1149 if ((RTL_R8(ChipCmd) & CmdRxEnb) == 0)
1150 return;
1139 1151
1140 counters = pci_alloc_consistent(tp->pci_dev, sizeof(*counters), &paddr); 1152 counters = pci_alloc_consistent(tp->pci_dev, sizeof(*counters), &paddr);
1141 if (!counters) 1153 if (!counters)
@@ -1146,31 +1158,45 @@ static void rtl8169_get_ethtool_stats(struct net_device *dev,
1146 RTL_W32(CounterAddrLow, cmd); 1158 RTL_W32(CounterAddrLow, cmd);
1147 RTL_W32(CounterAddrLow, cmd | CounterDump); 1159 RTL_W32(CounterAddrLow, cmd | CounterDump);
1148 1160
1149 while (RTL_R32(CounterAddrLow) & CounterDump) { 1161 while (wait--) {
1150 if (msleep_interruptible(1)) 1162 if ((RTL_R32(CounterAddrLow) & CounterDump) == 0) {
1163 /* copy updated counters */
1164 memcpy(&tp->counters, counters, sizeof(*counters));
1151 break; 1165 break;
1166 }
1167 udelay(10);
1152 } 1168 }
1153 1169
1154 RTL_W32(CounterAddrLow, 0); 1170 RTL_W32(CounterAddrLow, 0);
1155 RTL_W32(CounterAddrHigh, 0); 1171 RTL_W32(CounterAddrHigh, 0);
1156 1172
1157 data[0] = le64_to_cpu(counters->tx_packets);
1158 data[1] = le64_to_cpu(counters->rx_packets);
1159 data[2] = le64_to_cpu(counters->tx_errors);
1160 data[3] = le32_to_cpu(counters->rx_errors);
1161 data[4] = le16_to_cpu(counters->rx_missed);
1162 data[5] = le16_to_cpu(counters->align_errors);
1163 data[6] = le32_to_cpu(counters->tx_one_collision);
1164 data[7] = le32_to_cpu(counters->tx_multi_collision);
1165 data[8] = le64_to_cpu(counters->rx_unicast);
1166 data[9] = le64_to_cpu(counters->rx_broadcast);
1167 data[10] = le32_to_cpu(counters->rx_multicast);
1168 data[11] = le16_to_cpu(counters->tx_aborted);
1169 data[12] = le16_to_cpu(counters->tx_underun);
1170
1171 pci_free_consistent(tp->pci_dev, sizeof(*counters), counters, paddr); 1173 pci_free_consistent(tp->pci_dev, sizeof(*counters), counters, paddr);
1172} 1174}
1173 1175
1176static void rtl8169_get_ethtool_stats(struct net_device *dev,
1177 struct ethtool_stats *stats, u64 *data)
1178{
1179 struct rtl8169_private *tp = netdev_priv(dev);
1180
1181 ASSERT_RTNL();
1182
1183 rtl8169_update_counters(dev);
1184
1185 data[0] = le64_to_cpu(tp->counters.tx_packets);
1186 data[1] = le64_to_cpu(tp->counters.rx_packets);
1187 data[2] = le64_to_cpu(tp->counters.tx_errors);
1188 data[3] = le32_to_cpu(tp->counters.rx_errors);
1189 data[4] = le16_to_cpu(tp->counters.rx_missed);
1190 data[5] = le16_to_cpu(tp->counters.align_errors);
1191 data[6] = le32_to_cpu(tp->counters.tx_one_collision);
1192 data[7] = le32_to_cpu(tp->counters.tx_multi_collision);
1193 data[8] = le64_to_cpu(tp->counters.rx_unicast);
1194 data[9] = le64_to_cpu(tp->counters.rx_broadcast);
1195 data[10] = le32_to_cpu(tp->counters.rx_multicast);
1196 data[11] = le16_to_cpu(tp->counters.tx_aborted);
1197 data[12] = le16_to_cpu(tp->counters.tx_underun);
1198}
1199
1174static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data) 1200static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data)
1175{ 1201{
1176 switch(stringset) { 1202 switch(stringset) {
@@ -1943,6 +1969,108 @@ static const struct net_device_ops rtl8169_netdev_ops = {
1943 1969
1944}; 1970};
1945 1971
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. */
1977static 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
2037static 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
1946static int __devinit 2074static int __devinit
1947rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) 2075rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1948{ 2076{
@@ -2121,6 +2249,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2121 2249
2122 tp->mmio_addr = ioaddr; 2250 tp->mmio_addr = ioaddr;
2123 2251
2252 rtl_init_mac_address(tp, ioaddr);
2253
2124 /* Get MAC address */ 2254 /* Get MAC address */
2125 for (i = 0; i < MAC_ADDR_LEN; i++) 2255 for (i = 0; i < MAC_ADDR_LEN; i++)
2126 dev->dev_addr[i] = RTL_R8(MAC0 + i); 2256 dev->dev_addr[i] = RTL_R8(MAC0 + i);
@@ -3682,6 +3812,9 @@ static int rtl8169_close(struct net_device *dev)
3682 struct rtl8169_private *tp = netdev_priv(dev); 3812 struct rtl8169_private *tp = netdev_priv(dev);
3683 struct pci_dev *pdev = tp->pci_dev; 3813 struct pci_dev *pdev = tp->pci_dev;
3684 3814
3815 /* update counters before going down */
3816 rtl8169_update_counters(dev);
3817
3685 rtl8169_down(dev); 3818 rtl8169_down(dev);
3686 3819
3687 free_irq(dev->irq, dev); 3820 free_irq(dev->irq, dev);