diff options
author | Jeff Garzik <jeff@garzik.org> | 2007-10-23 20:13:24 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-10-23 20:13:24 -0400 |
commit | 43cd73658d8077ee6899b0b5029aad0cba1e9f92 (patch) | |
tree | 86204ed58e56e16d8bbb0a9ce578122f6ee553ea /drivers/net | |
parent | 01e7ae8c13bb06a2ce622ebace33bb7e28ef596c (diff) | |
parent | 7da97ec96a0934319c7fbedd3d38baf533e20640 (diff) |
Merge branch 'upstream-jeff' of git://git.kernel.org/pub/scm/linux/kernel/git/romieu/netdev-2.6 into upstream
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/r8169.c | 406 |
1 files changed, 265 insertions, 141 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 419c00cbe6e9..e8960f294a6e 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -44,7 +44,8 @@ | |||
44 | printk( "Assertion failed! %s,%s,%s,line=%d\n", \ | 44 | printk( "Assertion failed! %s,%s,%s,line=%d\n", \ |
45 | #expr,__FILE__,__FUNCTION__,__LINE__); \ | 45 | #expr,__FILE__,__FUNCTION__,__LINE__); \ |
46 | } | 46 | } |
47 | #define dprintk(fmt, args...) do { printk(PFX fmt, ## args); } while (0) | 47 | #define dprintk(fmt, args...) \ |
48 | do { printk(KERN_DEBUG PFX fmt, ## args); } while (0) | ||
48 | #else | 49 | #else |
49 | #define assert(expr) do {} while (0) | 50 | #define assert(expr) do {} while (0) |
50 | #define dprintk(fmt, args...) do {} while (0) | 51 | #define dprintk(fmt, args...) do {} while (0) |
@@ -111,19 +112,15 @@ enum mac_version { | |||
111 | RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd | 112 | RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd |
112 | RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe | 113 | RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe |
113 | RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb | 114 | RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb |
114 | RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be 8168Bf | 115 | RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be |
115 | RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb 8101Ec | 116 | RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb |
116 | RTL_GIGA_MAC_VER_14 = 0x0e, // 8101 | 117 | RTL_GIGA_MAC_VER_14 = 0x0e, // 8101 ? |
117 | RTL_GIGA_MAC_VER_15 = 0x0f // 8101 | 118 | RTL_GIGA_MAC_VER_15 = 0x0f, // 8101 ? |
118 | }; | 119 | RTL_GIGA_MAC_VER_16 = 0x11, // 8101Ec |
119 | 120 | RTL_GIGA_MAC_VER_17 = 0x10, // 8168Bf | |
120 | enum phy_version { | 121 | RTL_GIGA_MAC_VER_18 = 0x12, // 8168CP |
121 | RTL_GIGA_PHY_VER_C = 0x03, /* PHY Reg 0x03 bit0-3 == 0x0000 */ | 122 | RTL_GIGA_MAC_VER_19 = 0x13, // 8168C |
122 | RTL_GIGA_PHY_VER_D = 0x04, /* PHY Reg 0x03 bit0-3 == 0x0000 */ | 123 | RTL_GIGA_MAC_VER_20 = 0x14 // 8168C |
123 | RTL_GIGA_PHY_VER_E = 0x05, /* PHY Reg 0x03 bit0-3 == 0x0000 */ | ||
124 | RTL_GIGA_PHY_VER_F = 0x06, /* PHY Reg 0x03 bit0-3 == 0x0001 */ | ||
125 | RTL_GIGA_PHY_VER_G = 0x07, /* PHY Reg 0x03 bit0-3 == 0x0002 */ | ||
126 | RTL_GIGA_PHY_VER_H = 0x08, /* PHY Reg 0x03 bit0-3 == 0x0003 */ | ||
127 | }; | 124 | }; |
128 | 125 | ||
129 | #define _R(NAME,MAC,MASK) \ | 126 | #define _R(NAME,MAC,MASK) \ |
@@ -144,7 +141,12 @@ static const struct { | |||
144 | _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E | 141 | _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E |
145 | _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139 | 142 | _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139 |
146 | _R("RTL8100e", RTL_GIGA_MAC_VER_14, 0xff7e1880), // PCI-E 8139 | 143 | _R("RTL8100e", RTL_GIGA_MAC_VER_14, 0xff7e1880), // PCI-E 8139 |
147 | _R("RTL8100e", RTL_GIGA_MAC_VER_15, 0xff7e1880) // PCI-E 8139 | 144 | _R("RTL8100e", RTL_GIGA_MAC_VER_15, 0xff7e1880), // PCI-E 8139 |
145 | _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_17, 0xff7e1880), // PCI-E | ||
146 | _R("RTL8101e", RTL_GIGA_MAC_VER_16, 0xff7e1880), // PCI-E | ||
147 | _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_18, 0xff7e1880), // PCI-E | ||
148 | _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_19, 0xff7e1880), // PCI-E | ||
149 | _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_20, 0xff7e1880) // PCI-E | ||
148 | }; | 150 | }; |
149 | #undef _R | 151 | #undef _R |
150 | 152 | ||
@@ -165,7 +167,7 @@ static struct pci_device_id rtl8169_pci_tbl[] = { | |||
165 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_1 }, | 167 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_1 }, |
166 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, | 168 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, |
167 | { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, | 169 | { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, |
168 | { PCI_DEVICE(0x1259, 0xc107), 0, 0, RTL_CFG_0 }, | 170 | { PCI_DEVICE(PCI_VENDOR_ID_AT, 0xc107), 0, 0, RTL_CFG_0 }, |
169 | { PCI_DEVICE(0x16ec, 0x0116), 0, 0, RTL_CFG_0 }, | 171 | { PCI_DEVICE(0x16ec, 0x0116), 0, 0, RTL_CFG_0 }, |
170 | { PCI_VENDOR_ID_LINKSYS, 0x1032, | 172 | { PCI_VENDOR_ID_LINKSYS, 0x1032, |
171 | PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 }, | 173 | PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 }, |
@@ -277,6 +279,7 @@ enum rtl_register_content { | |||
277 | TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ | 279 | TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ |
278 | 280 | ||
279 | /* Config1 register p.24 */ | 281 | /* Config1 register p.24 */ |
282 | MSIEnable = (1 << 5), /* Enable Message Signaled Interrupt */ | ||
280 | PMEnable = (1 << 0), /* Power Management Enable */ | 283 | PMEnable = (1 << 0), /* Power Management Enable */ |
281 | 284 | ||
282 | /* Config2 register p. 25 */ | 285 | /* Config2 register p. 25 */ |
@@ -380,17 +383,20 @@ struct ring_info { | |||
380 | u8 __pad[sizeof(void *) - sizeof(u32)]; | 383 | u8 __pad[sizeof(void *) - sizeof(u32)]; |
381 | }; | 384 | }; |
382 | 385 | ||
386 | enum features { | ||
387 | RTL_FEATURE_WOL = (1 << 0), | ||
388 | RTL_FEATURE_MSI = (1 << 1), | ||
389 | }; | ||
390 | |||
383 | struct rtl8169_private { | 391 | struct rtl8169_private { |
384 | void __iomem *mmio_addr; /* memory map physical address */ | 392 | void __iomem *mmio_addr; /* memory map physical address */ |
385 | struct pci_dev *pci_dev; /* Index of PCI device */ | 393 | struct pci_dev *pci_dev; /* Index of PCI device */ |
386 | struct net_device *dev; | 394 | struct net_device *dev; |
387 | struct napi_struct napi; | 395 | struct napi_struct napi; |
388 | struct net_device_stats stats; /* statistics of net device */ | ||
389 | spinlock_t lock; /* spin lock flag */ | 396 | spinlock_t lock; /* spin lock flag */ |
390 | u32 msg_enable; | 397 | u32 msg_enable; |
391 | int chipset; | 398 | int chipset; |
392 | int mac_version; | 399 | int mac_version; |
393 | int phy_version; | ||
394 | u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ | 400 | u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */ |
395 | u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ | 401 | u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */ |
396 | u32 dirty_rx; | 402 | u32 dirty_rx; |
@@ -420,7 +426,7 @@ struct rtl8169_private { | |||
420 | unsigned int (*phy_reset_pending)(void __iomem *); | 426 | unsigned int (*phy_reset_pending)(void __iomem *); |
421 | unsigned int (*link_ok)(void __iomem *); | 427 | unsigned int (*link_ok)(void __iomem *); |
422 | struct delayed_work task; | 428 | struct delayed_work task; |
423 | unsigned wol_enabled : 1; | 429 | unsigned features; |
424 | }; | 430 | }; |
425 | 431 | ||
426 | MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); | 432 | MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); |
@@ -626,7 +632,10 @@ static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
626 | 632 | ||
627 | RTL_W8(Cfg9346, Cfg9346_Lock); | 633 | RTL_W8(Cfg9346, Cfg9346_Lock); |
628 | 634 | ||
629 | tp->wol_enabled = (wol->wolopts) ? 1 : 0; | 635 | if (wol->wolopts) |
636 | tp->features |= RTL_FEATURE_WOL; | ||
637 | else | ||
638 | tp->features &= ~RTL_FEATURE_WOL; | ||
630 | 639 | ||
631 | spin_unlock_irq(&tp->lock); | 640 | spin_unlock_irq(&tp->lock); |
632 | 641 | ||
@@ -707,7 +716,8 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, | |||
707 | 716 | ||
708 | /* This tweak comes straight from Realtek's driver. */ | 717 | /* This tweak comes straight from Realtek's driver. */ |
709 | if ((speed == SPEED_100) && (duplex == DUPLEX_HALF) && | 718 | if ((speed == SPEED_100) && (duplex == DUPLEX_HALF) && |
710 | (tp->mac_version == RTL_GIGA_MAC_VER_13)) { | 719 | ((tp->mac_version == RTL_GIGA_MAC_VER_13) || |
720 | (tp->mac_version == RTL_GIGA_MAC_VER_16))) { | ||
711 | auto_nego = ADVERTISE_100HALF | ADVERTISE_CSMA; | 721 | auto_nego = ADVERTISE_100HALF | ADVERTISE_CSMA; |
712 | } | 722 | } |
713 | } | 723 | } |
@@ -715,7 +725,8 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, | |||
715 | /* The 8100e/8101e do Fast Ethernet only. */ | 725 | /* The 8100e/8101e do Fast Ethernet only. */ |
716 | if ((tp->mac_version == RTL_GIGA_MAC_VER_13) || | 726 | if ((tp->mac_version == RTL_GIGA_MAC_VER_13) || |
717 | (tp->mac_version == RTL_GIGA_MAC_VER_14) || | 727 | (tp->mac_version == RTL_GIGA_MAC_VER_14) || |
718 | (tp->mac_version == RTL_GIGA_MAC_VER_15)) { | 728 | (tp->mac_version == RTL_GIGA_MAC_VER_15) || |
729 | (tp->mac_version == RTL_GIGA_MAC_VER_16)) { | ||
719 | if ((giga_ctrl & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) && | 730 | if ((giga_ctrl & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) && |
720 | netif_msg_link(tp)) { | 731 | netif_msg_link(tp)) { |
721 | printk(KERN_INFO "%s: PHY does not support 1000Mbps.\n", | 732 | printk(KERN_INFO "%s: PHY does not support 1000Mbps.\n", |
@@ -726,7 +737,8 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, | |||
726 | 737 | ||
727 | auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; | 738 | auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; |
728 | 739 | ||
729 | if (tp->mac_version == RTL_GIGA_MAC_VER_12) { | 740 | if ((tp->mac_version == RTL_GIGA_MAC_VER_12) || |
741 | (tp->mac_version == RTL_GIGA_MAC_VER_17)) { | ||
730 | /* Vendor specific (0x1f) and reserved (0x0e) MII registers. */ | 742 | /* Vendor specific (0x1f) and reserved (0x0e) MII registers. */ |
731 | mdio_write(ioaddr, 0x1f, 0x0000); | 743 | mdio_write(ioaddr, 0x1f, 0x0000); |
732 | mdio_write(ioaddr, 0x0e, 0x0000); | 744 | mdio_write(ioaddr, 0x0e, 0x0000); |
@@ -1104,26 +1116,51 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, | |||
1104 | */ | 1116 | */ |
1105 | const struct { | 1117 | const struct { |
1106 | u32 mask; | 1118 | u32 mask; |
1119 | u32 val; | ||
1107 | int mac_version; | 1120 | int mac_version; |
1108 | } mac_info[] = { | 1121 | } mac_info[] = { |
1109 | { 0x38800000, RTL_GIGA_MAC_VER_15 }, | 1122 | /* 8168B family. */ |
1110 | { 0x38000000, RTL_GIGA_MAC_VER_12 }, | 1123 | { 0x7c800000, 0x3c800000, RTL_GIGA_MAC_VER_18 }, |
1111 | { 0x34000000, RTL_GIGA_MAC_VER_13 }, | 1124 | { 0x7cf00000, 0x3c000000, RTL_GIGA_MAC_VER_19 }, |
1112 | { 0x30800000, RTL_GIGA_MAC_VER_14 }, | 1125 | { 0x7cf00000, 0x3c200000, RTL_GIGA_MAC_VER_20 }, |
1113 | { 0x30000000, RTL_GIGA_MAC_VER_11 }, | 1126 | { 0x7c800000, 0x3c000000, RTL_GIGA_MAC_VER_20 }, |
1114 | { 0x98000000, RTL_GIGA_MAC_VER_06 }, | 1127 | |
1115 | { 0x18000000, RTL_GIGA_MAC_VER_05 }, | 1128 | /* 8168B family. */ |
1116 | { 0x10000000, RTL_GIGA_MAC_VER_04 }, | 1129 | { 0x7cf00000, 0x38000000, RTL_GIGA_MAC_VER_12 }, |
1117 | { 0x04000000, RTL_GIGA_MAC_VER_03 }, | 1130 | { 0x7cf00000, 0x38500000, RTL_GIGA_MAC_VER_17 }, |
1118 | { 0x00800000, RTL_GIGA_MAC_VER_02 }, | 1131 | { 0x7c800000, 0x38000000, RTL_GIGA_MAC_VER_17 }, |
1119 | { 0x00000000, RTL_GIGA_MAC_VER_01 } /* Catch-all */ | 1132 | { 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 }, |
1133 | |||
1134 | /* 8101 family. */ | ||
1135 | { 0x7cf00000, 0x34000000, RTL_GIGA_MAC_VER_13 }, | ||
1136 | { 0x7cf00000, 0x34200000, RTL_GIGA_MAC_VER_16 }, | ||
1137 | { 0x7c800000, 0x34000000, RTL_GIGA_MAC_VER_16 }, | ||
1138 | /* FIXME: where did these entries come from ? -- FR */ | ||
1139 | { 0xfc800000, 0x38800000, RTL_GIGA_MAC_VER_15 }, | ||
1140 | { 0xfc800000, 0x30800000, RTL_GIGA_MAC_VER_14 }, | ||
1141 | |||
1142 | /* 8110 family. */ | ||
1143 | { 0xfc800000, 0x98000000, RTL_GIGA_MAC_VER_06 }, | ||
1144 | { 0xfc800000, 0x18000000, RTL_GIGA_MAC_VER_05 }, | ||
1145 | { 0xfc800000, 0x10000000, RTL_GIGA_MAC_VER_04 }, | ||
1146 | { 0xfc800000, 0x04000000, RTL_GIGA_MAC_VER_03 }, | ||
1147 | { 0xfc800000, 0x00800000, RTL_GIGA_MAC_VER_02 }, | ||
1148 | { 0xfc800000, 0x00000000, RTL_GIGA_MAC_VER_01 }, | ||
1149 | |||
1150 | { 0x00000000, 0x00000000, RTL_GIGA_MAC_VER_01 } /* Catch-all */ | ||
1120 | }, *p = mac_info; | 1151 | }, *p = mac_info; |
1121 | u32 reg; | 1152 | u32 reg; |
1122 | 1153 | ||
1123 | reg = RTL_R32(TxConfig) & 0xfc800000; | 1154 | reg = RTL_R32(TxConfig); |
1124 | while ((reg & p->mask) != p->mask) | 1155 | while ((reg & p->mask) != p->val) |
1125 | p++; | 1156 | p++; |
1126 | tp->mac_version = p->mac_version; | 1157 | tp->mac_version = p->mac_version; |
1158 | |||
1159 | if (p->mask == 0x00000000) { | ||
1160 | struct pci_dev *pdev = tp->pci_dev; | ||
1161 | |||
1162 | dev_info(&pdev->dev, "unknown MAC (%08x)\n", reg); | ||
1163 | } | ||
1127 | } | 1164 | } |
1128 | 1165 | ||
1129 | static void rtl8169_print_mac_version(struct rtl8169_private *tp) | 1166 | static void rtl8169_print_mac_version(struct rtl8169_private *tp) |
@@ -1131,54 +1168,21 @@ static void rtl8169_print_mac_version(struct rtl8169_private *tp) | |||
1131 | dprintk("mac_version = 0x%02x\n", tp->mac_version); | 1168 | dprintk("mac_version = 0x%02x\n", tp->mac_version); |
1132 | } | 1169 | } |
1133 | 1170 | ||
1134 | static void rtl8169_get_phy_version(struct rtl8169_private *tp, | 1171 | struct phy_reg { |
1135 | void __iomem *ioaddr) | ||
1136 | { | ||
1137 | const struct { | ||
1138 | u16 mask; | ||
1139 | u16 set; | ||
1140 | int phy_version; | ||
1141 | } phy_info[] = { | ||
1142 | { 0x000f, 0x0002, RTL_GIGA_PHY_VER_G }, | ||
1143 | { 0x000f, 0x0001, RTL_GIGA_PHY_VER_F }, | ||
1144 | { 0x000f, 0x0000, RTL_GIGA_PHY_VER_E }, | ||
1145 | { 0x0000, 0x0000, RTL_GIGA_PHY_VER_D } /* Catch-all */ | ||
1146 | }, *p = phy_info; | ||
1147 | u16 reg; | 1172 | u16 reg; |
1173 | u16 val; | ||
1174 | }; | ||
1148 | 1175 | ||
1149 | reg = mdio_read(ioaddr, MII_PHYSID2) & 0xffff; | 1176 | static void rtl_phy_write(void __iomem *ioaddr, struct phy_reg *regs, int len) |
1150 | while ((reg & p->mask) != p->set) | ||
1151 | p++; | ||
1152 | tp->phy_version = p->phy_version; | ||
1153 | } | ||
1154 | |||
1155 | static void rtl8169_print_phy_version(struct rtl8169_private *tp) | ||
1156 | { | 1177 | { |
1157 | struct { | 1178 | while (len-- > 0) { |
1158 | int version; | 1179 | mdio_write(ioaddr, regs->reg, regs->val); |
1159 | char *msg; | 1180 | regs++; |
1160 | u32 reg; | ||
1161 | } phy_print[] = { | ||
1162 | { RTL_GIGA_PHY_VER_G, "RTL_GIGA_PHY_VER_G", 0x0002 }, | ||
1163 | { RTL_GIGA_PHY_VER_F, "RTL_GIGA_PHY_VER_F", 0x0001 }, | ||
1164 | { RTL_GIGA_PHY_VER_E, "RTL_GIGA_PHY_VER_E", 0x0000 }, | ||
1165 | { RTL_GIGA_PHY_VER_D, "RTL_GIGA_PHY_VER_D", 0x0000 }, | ||
1166 | { 0, NULL, 0x0000 } | ||
1167 | }, *p; | ||
1168 | |||
1169 | for (p = phy_print; p->msg; p++) { | ||
1170 | if (tp->phy_version == p->version) { | ||
1171 | dprintk("phy_version == %s (%04x)\n", p->msg, p->reg); | ||
1172 | return; | ||
1173 | } | ||
1174 | } | 1181 | } |
1175 | dprintk("phy_version == Unknown\n"); | ||
1176 | } | 1182 | } |
1177 | 1183 | ||
1178 | static void rtl8169_hw_phy_config(struct net_device *dev) | 1184 | static void rtl8169s_hw_phy_config(void __iomem *ioaddr) |
1179 | { | 1185 | { |
1180 | struct rtl8169_private *tp = netdev_priv(dev); | ||
1181 | void __iomem *ioaddr = tp->mmio_addr; | ||
1182 | struct { | 1186 | struct { |
1183 | u16 regs[5]; /* Beware of bit-sign propagation */ | 1187 | u16 regs[5]; /* Beware of bit-sign propagation */ |
1184 | } phy_magic[5] = { { | 1188 | } phy_magic[5] = { { |
@@ -1211,33 +1215,9 @@ static void rtl8169_hw_phy_config(struct net_device *dev) | |||
1211 | }, *p = phy_magic; | 1215 | }, *p = phy_magic; |
1212 | unsigned int i; | 1216 | unsigned int i; |
1213 | 1217 | ||
1214 | rtl8169_print_mac_version(tp); | 1218 | mdio_write(ioaddr, 0x1f, 0x0001); //w 31 2 0 1 |
1215 | rtl8169_print_phy_version(tp); | 1219 | mdio_write(ioaddr, 0x15, 0x1000); //w 21 15 0 1000 |
1216 | 1220 | mdio_write(ioaddr, 0x18, 0x65c7); //w 24 15 0 65c7 | |
1217 | if (tp->mac_version <= RTL_GIGA_MAC_VER_01) | ||
1218 | return; | ||
1219 | if (tp->phy_version >= RTL_GIGA_PHY_VER_H) | ||
1220 | return; | ||
1221 | |||
1222 | dprintk("MAC version != 0 && PHY version == 0 or 1\n"); | ||
1223 | dprintk("Do final_reg2.cfg\n"); | ||
1224 | |||
1225 | /* Shazam ! */ | ||
1226 | |||
1227 | if (tp->mac_version == RTL_GIGA_MAC_VER_04) { | ||
1228 | mdio_write(ioaddr, 31, 0x0002); | ||
1229 | mdio_write(ioaddr, 1, 0x90d0); | ||
1230 | mdio_write(ioaddr, 31, 0x0000); | ||
1231 | return; | ||
1232 | } | ||
1233 | |||
1234 | if ((tp->mac_version != RTL_GIGA_MAC_VER_02) && | ||
1235 | (tp->mac_version != RTL_GIGA_MAC_VER_03)) | ||
1236 | return; | ||
1237 | |||
1238 | mdio_write(ioaddr, 31, 0x0001); //w 31 2 0 1 | ||
1239 | mdio_write(ioaddr, 21, 0x1000); //w 21 15 0 1000 | ||
1240 | mdio_write(ioaddr, 24, 0x65c7); //w 24 15 0 65c7 | ||
1241 | rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 0); //w 4 11 11 0 | 1221 | rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 0); //w 4 11 11 0 |
1242 | 1222 | ||
1243 | for (i = 0; i < ARRAY_SIZE(phy_magic); i++, p++) { | 1223 | for (i = 0; i < ARRAY_SIZE(phy_magic); i++, p++) { |
@@ -1250,7 +1230,115 @@ static void rtl8169_hw_phy_config(struct net_device *dev) | |||
1250 | rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 1); //w 4 11 11 1 | 1230 | rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 1); //w 4 11 11 1 |
1251 | rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 0); //w 4 11 11 0 | 1231 | rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 0); //w 4 11 11 0 |
1252 | } | 1232 | } |
1253 | mdio_write(ioaddr, 31, 0x0000); //w 31 2 0 0 | 1233 | mdio_write(ioaddr, 0x1f, 0x0000); //w 31 2 0 0 |
1234 | } | ||
1235 | |||
1236 | static void rtl8169sb_hw_phy_config(void __iomem *ioaddr) | ||
1237 | { | ||
1238 | struct phy_reg phy_reg_init[] = { | ||
1239 | { 0x1f, 0x0002 }, | ||
1240 | { 0x01, 0x90d0 }, | ||
1241 | { 0x1f, 0x0000 } | ||
1242 | }; | ||
1243 | |||
1244 | rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); | ||
1245 | } | ||
1246 | static void rtl8168b_hw_phy_config(void __iomem *ioaddr) | ||
1247 | { | ||
1248 | struct phy_reg phy_reg_init[] = { | ||
1249 | { 0x1f, 0x0000 }, | ||
1250 | { 0x10, 0xf41b }, | ||
1251 | { 0x1f, 0x0000 } | ||
1252 | }; | ||
1253 | |||
1254 | rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); | ||
1255 | } | ||
1256 | |||
1257 | static void rtl8168cp_hw_phy_config(void __iomem *ioaddr) | ||
1258 | { | ||
1259 | struct phy_reg phy_reg_init[] = { | ||
1260 | { 0x1f, 0x0000 }, | ||
1261 | { 0x1d, 0x0f00 }, | ||
1262 | { 0x1f, 0x0002 }, | ||
1263 | { 0x0c, 0x1ec8 }, | ||
1264 | { 0x1f, 0x0000 } | ||
1265 | }; | ||
1266 | |||
1267 | rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); | ||
1268 | } | ||
1269 | |||
1270 | static void rtl8168c_hw_phy_config(void __iomem *ioaddr) | ||
1271 | { | ||
1272 | struct phy_reg phy_reg_init[] = { | ||
1273 | { 0x1f, 0x0001 }, | ||
1274 | { 0x12, 0x2300 }, | ||
1275 | { 0x1f, 0x0002 }, | ||
1276 | { 0x00, 0x88d4 }, | ||
1277 | { 0x01, 0x82b1 }, | ||
1278 | { 0x03, 0x7002 }, | ||
1279 | { 0x08, 0x9e30 }, | ||
1280 | { 0x09, 0x01f0 }, | ||
1281 | { 0x0a, 0x5500 }, | ||
1282 | { 0x0c, 0x00c8 }, | ||
1283 | { 0x1f, 0x0003 }, | ||
1284 | { 0x12, 0xc096 }, | ||
1285 | { 0x16, 0x000a }, | ||
1286 | { 0x1f, 0x0000 } | ||
1287 | }; | ||
1288 | |||
1289 | rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); | ||
1290 | } | ||
1291 | |||
1292 | static void rtl8168cx_hw_phy_config(void __iomem *ioaddr) | ||
1293 | { | ||
1294 | struct phy_reg phy_reg_init[] = { | ||
1295 | { 0x1f, 0x0000 }, | ||
1296 | { 0x12, 0x2300 }, | ||
1297 | { 0x1f, 0x0003 }, | ||
1298 | { 0x16, 0x0f0a }, | ||
1299 | { 0x1f, 0x0000 }, | ||
1300 | { 0x1f, 0x0002 }, | ||
1301 | { 0x0c, 0x7eb8 }, | ||
1302 | { 0x1f, 0x0000 } | ||
1303 | }; | ||
1304 | |||
1305 | rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); | ||
1306 | } | ||
1307 | |||
1308 | static void rtl_hw_phy_config(struct net_device *dev) | ||
1309 | { | ||
1310 | struct rtl8169_private *tp = netdev_priv(dev); | ||
1311 | void __iomem *ioaddr = tp->mmio_addr; | ||
1312 | |||
1313 | rtl8169_print_mac_version(tp); | ||
1314 | |||
1315 | switch (tp->mac_version) { | ||
1316 | case RTL_GIGA_MAC_VER_01: | ||
1317 | break; | ||
1318 | case RTL_GIGA_MAC_VER_02: | ||
1319 | case RTL_GIGA_MAC_VER_03: | ||
1320 | rtl8169s_hw_phy_config(ioaddr); | ||
1321 | break; | ||
1322 | case RTL_GIGA_MAC_VER_04: | ||
1323 | rtl8169sb_hw_phy_config(ioaddr); | ||
1324 | break; | ||
1325 | case RTL_GIGA_MAC_VER_11: | ||
1326 | case RTL_GIGA_MAC_VER_12: | ||
1327 | case RTL_GIGA_MAC_VER_17: | ||
1328 | rtl8168b_hw_phy_config(ioaddr); | ||
1329 | break; | ||
1330 | case RTL_GIGA_MAC_VER_18: | ||
1331 | rtl8168cp_hw_phy_config(ioaddr); | ||
1332 | break; | ||
1333 | case RTL_GIGA_MAC_VER_19: | ||
1334 | rtl8168c_hw_phy_config(ioaddr); | ||
1335 | break; | ||
1336 | case RTL_GIGA_MAC_VER_20: | ||
1337 | rtl8168cx_hw_phy_config(ioaddr); | ||
1338 | break; | ||
1339 | default: | ||
1340 | break; | ||
1341 | } | ||
1254 | } | 1342 | } |
1255 | 1343 | ||
1256 | static void rtl8169_phy_timer(unsigned long __opaque) | 1344 | static void rtl8169_phy_timer(unsigned long __opaque) |
@@ -1262,7 +1350,6 @@ static void rtl8169_phy_timer(unsigned long __opaque) | |||
1262 | unsigned long timeout = RTL8169_PHY_TIMEOUT; | 1350 | unsigned long timeout = RTL8169_PHY_TIMEOUT; |
1263 | 1351 | ||
1264 | assert(tp->mac_version > RTL_GIGA_MAC_VER_01); | 1352 | assert(tp->mac_version > RTL_GIGA_MAC_VER_01); |
1265 | assert(tp->phy_version < RTL_GIGA_PHY_VER_H); | ||
1266 | 1353 | ||
1267 | if (!(tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL)) | 1354 | if (!(tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL)) |
1268 | return; | 1355 | return; |
@@ -1297,8 +1384,7 @@ static inline void rtl8169_delete_timer(struct net_device *dev) | |||
1297 | struct rtl8169_private *tp = netdev_priv(dev); | 1384 | struct rtl8169_private *tp = netdev_priv(dev); |
1298 | struct timer_list *timer = &tp->timer; | 1385 | struct timer_list *timer = &tp->timer; |
1299 | 1386 | ||
1300 | if ((tp->mac_version <= RTL_GIGA_MAC_VER_01) || | 1387 | if (tp->mac_version <= RTL_GIGA_MAC_VER_01) |
1301 | (tp->phy_version >= RTL_GIGA_PHY_VER_H)) | ||
1302 | return; | 1388 | return; |
1303 | 1389 | ||
1304 | del_timer_sync(timer); | 1390 | del_timer_sync(timer); |
@@ -1309,8 +1395,7 @@ static inline void rtl8169_request_timer(struct net_device *dev) | |||
1309 | struct rtl8169_private *tp = netdev_priv(dev); | 1395 | struct rtl8169_private *tp = netdev_priv(dev); |
1310 | struct timer_list *timer = &tp->timer; | 1396 | struct timer_list *timer = &tp->timer; |
1311 | 1397 | ||
1312 | if ((tp->mac_version <= RTL_GIGA_MAC_VER_01) || | 1398 | if (tp->mac_version <= RTL_GIGA_MAC_VER_01) |
1313 | (tp->phy_version >= RTL_GIGA_PHY_VER_H)) | ||
1314 | return; | 1399 | return; |
1315 | 1400 | ||
1316 | mod_timer(timer, jiffies + RTL8169_PHY_TIMEOUT); | 1401 | mod_timer(timer, jiffies + RTL8169_PHY_TIMEOUT); |
@@ -1362,7 +1447,7 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp) | |||
1362 | { | 1447 | { |
1363 | void __iomem *ioaddr = tp->mmio_addr; | 1448 | void __iomem *ioaddr = tp->mmio_addr; |
1364 | 1449 | ||
1365 | rtl8169_hw_phy_config(dev); | 1450 | rtl_hw_phy_config(dev); |
1366 | 1451 | ||
1367 | dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); | 1452 | dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n"); |
1368 | RTL_W8(0x82, 0x01); | 1453 | RTL_W8(0x82, 0x01); |
@@ -1457,6 +1542,7 @@ static const struct rtl_cfg_info { | |||
1457 | unsigned int align; | 1542 | unsigned int align; |
1458 | u16 intr_event; | 1543 | u16 intr_event; |
1459 | u16 napi_event; | 1544 | u16 napi_event; |
1545 | unsigned msi; | ||
1460 | } rtl_cfg_infos [] = { | 1546 | } rtl_cfg_infos [] = { |
1461 | [RTL_CFG_0] = { | 1547 | [RTL_CFG_0] = { |
1462 | .hw_start = rtl_hw_start_8169, | 1548 | .hw_start = rtl_hw_start_8169, |
@@ -1464,7 +1550,8 @@ static const struct rtl_cfg_info { | |||
1464 | .align = 0, | 1550 | .align = 0, |
1465 | .intr_event = SYSErr | LinkChg | RxOverflow | | 1551 | .intr_event = SYSErr | LinkChg | RxOverflow | |
1466 | RxFIFOOver | TxErr | TxOK | RxOK | RxErr, | 1552 | RxFIFOOver | TxErr | TxOK | RxOK | RxErr, |
1467 | .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow | 1553 | .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow, |
1554 | .msi = 0 | ||
1468 | }, | 1555 | }, |
1469 | [RTL_CFG_1] = { | 1556 | [RTL_CFG_1] = { |
1470 | .hw_start = rtl_hw_start_8168, | 1557 | .hw_start = rtl_hw_start_8168, |
@@ -1472,7 +1559,8 @@ static const struct rtl_cfg_info { | |||
1472 | .align = 8, | 1559 | .align = 8, |
1473 | .intr_event = SYSErr | LinkChg | RxOverflow | | 1560 | .intr_event = SYSErr | LinkChg | RxOverflow | |
1474 | TxErr | TxOK | RxOK | RxErr, | 1561 | TxErr | TxOK | RxOK | RxErr, |
1475 | .napi_event = TxErr | TxOK | RxOK | RxOverflow | 1562 | .napi_event = TxErr | TxOK | RxOK | RxOverflow, |
1563 | .msi = RTL_FEATURE_MSI | ||
1476 | }, | 1564 | }, |
1477 | [RTL_CFG_2] = { | 1565 | [RTL_CFG_2] = { |
1478 | .hw_start = rtl_hw_start_8101, | 1566 | .hw_start = rtl_hw_start_8101, |
@@ -1480,10 +1568,39 @@ static const struct rtl_cfg_info { | |||
1480 | .align = 8, | 1568 | .align = 8, |
1481 | .intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout | | 1569 | .intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout | |
1482 | RxFIFOOver | TxErr | TxOK | RxOK | RxErr, | 1570 | RxFIFOOver | TxErr | TxOK | RxOK | RxErr, |
1483 | .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow | 1571 | .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow, |
1572 | .msi = RTL_FEATURE_MSI | ||
1484 | } | 1573 | } |
1485 | }; | 1574 | }; |
1486 | 1575 | ||
1576 | /* Cfg9346_Unlock assumed. */ | ||
1577 | static unsigned rtl_try_msi(struct pci_dev *pdev, void __iomem *ioaddr, | ||
1578 | const struct rtl_cfg_info *cfg) | ||
1579 | { | ||
1580 | unsigned msi = 0; | ||
1581 | u8 cfg2; | ||
1582 | |||
1583 | cfg2 = RTL_R8(Config2) & ~MSIEnable; | ||
1584 | if (cfg->msi) { | ||
1585 | if (pci_enable_msi(pdev)) { | ||
1586 | dev_info(&pdev->dev, "no MSI. Back to INTx.\n"); | ||
1587 | } else { | ||
1588 | cfg2 |= MSIEnable; | ||
1589 | msi = RTL_FEATURE_MSI; | ||
1590 | } | ||
1591 | } | ||
1592 | RTL_W8(Config2, cfg2); | ||
1593 | return msi; | ||
1594 | } | ||
1595 | |||
1596 | static void rtl_disable_msi(struct pci_dev *pdev, struct rtl8169_private *tp) | ||
1597 | { | ||
1598 | if (tp->features & RTL_FEATURE_MSI) { | ||
1599 | pci_disable_msi(pdev); | ||
1600 | tp->features &= ~RTL_FEATURE_MSI; | ||
1601 | } | ||
1602 | } | ||
1603 | |||
1487 | static int __devinit | 1604 | static int __devinit |
1488 | rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 1605 | rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
1489 | { | 1606 | { |
@@ -1596,10 +1713,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1596 | 1713 | ||
1597 | /* Identify chip attached to board */ | 1714 | /* Identify chip attached to board */ |
1598 | rtl8169_get_mac_version(tp, ioaddr); | 1715 | rtl8169_get_mac_version(tp, ioaddr); |
1599 | rtl8169_get_phy_version(tp, ioaddr); | ||
1600 | 1716 | ||
1601 | rtl8169_print_mac_version(tp); | 1717 | rtl8169_print_mac_version(tp); |
1602 | rtl8169_print_phy_version(tp); | ||
1603 | 1718 | ||
1604 | for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--) { | 1719 | for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--) { |
1605 | if (tp->mac_version == rtl_chip_info[i].mac_version) | 1720 | if (tp->mac_version == rtl_chip_info[i].mac_version) |
@@ -1619,6 +1734,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1619 | RTL_W8(Cfg9346, Cfg9346_Unlock); | 1734 | RTL_W8(Cfg9346, Cfg9346_Unlock); |
1620 | RTL_W8(Config1, RTL_R8(Config1) | PMEnable); | 1735 | RTL_W8(Config1, RTL_R8(Config1) | PMEnable); |
1621 | RTL_W8(Config5, RTL_R8(Config5) & PMEStatus); | 1736 | RTL_W8(Config5, RTL_R8(Config5) & PMEStatus); |
1737 | tp->features |= rtl_try_msi(pdev, ioaddr, cfg); | ||
1622 | RTL_W8(Cfg9346, Cfg9346_Lock); | 1738 | RTL_W8(Cfg9346, Cfg9346_Lock); |
1623 | 1739 | ||
1624 | if (RTL_R8(PHYstatus) & TBI_Enable) { | 1740 | if (RTL_R8(PHYstatus) & TBI_Enable) { |
@@ -1686,7 +1802,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1686 | 1802 | ||
1687 | rc = register_netdev(dev); | 1803 | rc = register_netdev(dev); |
1688 | if (rc < 0) | 1804 | if (rc < 0) |
1689 | goto err_out_unmap_5; | 1805 | goto err_out_msi_5; |
1690 | 1806 | ||
1691 | pci_set_drvdata(pdev, dev); | 1807 | pci_set_drvdata(pdev, dev); |
1692 | 1808 | ||
@@ -1709,7 +1825,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1709 | out: | 1825 | out: |
1710 | return rc; | 1826 | return rc; |
1711 | 1827 | ||
1712 | err_out_unmap_5: | 1828 | err_out_msi_5: |
1829 | rtl_disable_msi(pdev, tp); | ||
1713 | iounmap(ioaddr); | 1830 | iounmap(ioaddr); |
1714 | err_out_free_res_4: | 1831 | err_out_free_res_4: |
1715 | pci_release_regions(pdev); | 1832 | pci_release_regions(pdev); |
@@ -1730,6 +1847,7 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) | |||
1730 | flush_scheduled_work(); | 1847 | flush_scheduled_work(); |
1731 | 1848 | ||
1732 | unregister_netdev(dev); | 1849 | unregister_netdev(dev); |
1850 | rtl_disable_msi(pdev, tp); | ||
1733 | rtl8169_release_board(pdev, dev, tp->mmio_addr); | 1851 | rtl8169_release_board(pdev, dev, tp->mmio_addr); |
1734 | pci_set_drvdata(pdev, NULL); | 1852 | pci_set_drvdata(pdev, NULL); |
1735 | } | 1853 | } |
@@ -1773,7 +1891,8 @@ static int rtl8169_open(struct net_device *dev) | |||
1773 | 1891 | ||
1774 | smp_mb(); | 1892 | smp_mb(); |
1775 | 1893 | ||
1776 | retval = request_irq(dev->irq, rtl8169_interrupt, IRQF_SHARED, | 1894 | retval = request_irq(dev->irq, rtl8169_interrupt, |
1895 | (tp->features & RTL_FEATURE_MSI) ? 0 : IRQF_SHARED, | ||
1777 | dev->name, dev); | 1896 | dev->name, dev); |
1778 | if (retval < 0) | 1897 | if (retval < 0) |
1779 | goto err_release_ring_2; | 1898 | goto err_release_ring_2; |
@@ -1933,7 +2052,7 @@ static void rtl_hw_start_8169(struct net_device *dev) | |||
1933 | 2052 | ||
1934 | if ((tp->mac_version == RTL_GIGA_MAC_VER_02) || | 2053 | if ((tp->mac_version == RTL_GIGA_MAC_VER_02) || |
1935 | (tp->mac_version == RTL_GIGA_MAC_VER_03)) { | 2054 | (tp->mac_version == RTL_GIGA_MAC_VER_03)) { |
1936 | dprintk(KERN_INFO PFX "Set MAC Reg C+CR Offset 0xE0. " | 2055 | dprintk("Set MAC Reg C+CR Offset 0xE0. " |
1937 | "Bit-3 and bit-14 MUST be 1\n"); | 2056 | "Bit-3 and bit-14 MUST be 1\n"); |
1938 | tp->cp_cmd |= (1 << 14); | 2057 | tp->cp_cmd |= (1 << 14); |
1939 | } | 2058 | } |
@@ -2029,7 +2148,8 @@ static void rtl_hw_start_8101(struct net_device *dev) | |||
2029 | void __iomem *ioaddr = tp->mmio_addr; | 2148 | void __iomem *ioaddr = tp->mmio_addr; |
2030 | struct pci_dev *pdev = tp->pci_dev; | 2149 | struct pci_dev *pdev = tp->pci_dev; |
2031 | 2150 | ||
2032 | if (tp->mac_version == RTL_GIGA_MAC_VER_13) { | 2151 | if ((tp->mac_version == RTL_GIGA_MAC_VER_13) || |
2152 | (tp->mac_version == RTL_GIGA_MAC_VER_16)) { | ||
2033 | pci_write_config_word(pdev, 0x68, 0x00); | 2153 | pci_write_config_word(pdev, 0x68, 0x00); |
2034 | pci_write_config_word(pdev, 0x69, 0x08); | 2154 | pci_write_config_word(pdev, 0x69, 0x08); |
2035 | } | 2155 | } |
@@ -2259,7 +2379,7 @@ static void rtl8169_tx_clear(struct rtl8169_private *tp) | |||
2259 | dev_kfree_skb(skb); | 2379 | dev_kfree_skb(skb); |
2260 | tx_skb->skb = NULL; | 2380 | tx_skb->skb = NULL; |
2261 | } | 2381 | } |
2262 | tp->stats.tx_dropped++; | 2382 | tp->dev->stats.tx_dropped++; |
2263 | } | 2383 | } |
2264 | } | 2384 | } |
2265 | tp->cur_tx = tp->dirty_tx = 0; | 2385 | tp->cur_tx = tp->dirty_tx = 0; |
@@ -2310,7 +2430,7 @@ static void rtl8169_reinit_task(struct work_struct *work) | |||
2310 | ret = rtl8169_open(dev); | 2430 | ret = rtl8169_open(dev); |
2311 | if (unlikely(ret < 0)) { | 2431 | if (unlikely(ret < 0)) { |
2312 | if (net_ratelimit() && netif_msg_drv(tp)) { | 2432 | if (net_ratelimit() && netif_msg_drv(tp)) { |
2313 | printk(PFX KERN_ERR "%s: reinit failure (status = %d)." | 2433 | printk(KERN_ERR PFX "%s: reinit failure (status = %d)." |
2314 | " Rescheduling.\n", dev->name, ret); | 2434 | " Rescheduling.\n", dev->name, ret); |
2315 | } | 2435 | } |
2316 | rtl8169_schedule_work(dev, rtl8169_reinit_task); | 2436 | rtl8169_schedule_work(dev, rtl8169_reinit_task); |
@@ -2340,9 +2460,10 @@ static void rtl8169_reset_task(struct work_struct *work) | |||
2340 | rtl8169_init_ring_indexes(tp); | 2460 | rtl8169_init_ring_indexes(tp); |
2341 | rtl_hw_start(dev); | 2461 | rtl_hw_start(dev); |
2342 | netif_wake_queue(dev); | 2462 | netif_wake_queue(dev); |
2463 | rtl8169_check_link_status(dev, tp, tp->mmio_addr); | ||
2343 | } else { | 2464 | } else { |
2344 | if (net_ratelimit() && netif_msg_intr(tp)) { | 2465 | if (net_ratelimit() && netif_msg_intr(tp)) { |
2345 | printk(PFX KERN_EMERG "%s: Rx buffers shortage\n", | 2466 | printk(KERN_EMERG PFX "%s: Rx buffers shortage\n", |
2346 | dev->name); | 2467 | dev->name); |
2347 | } | 2468 | } |
2348 | rtl8169_schedule_work(dev, rtl8169_reset_task); | 2469 | rtl8169_schedule_work(dev, rtl8169_reset_task); |
@@ -2496,7 +2617,7 @@ err_stop: | |||
2496 | netif_stop_queue(dev); | 2617 | netif_stop_queue(dev); |
2497 | ret = NETDEV_TX_BUSY; | 2618 | ret = NETDEV_TX_BUSY; |
2498 | err_update_stats: | 2619 | err_update_stats: |
2499 | tp->stats.tx_dropped++; | 2620 | dev->stats.tx_dropped++; |
2500 | goto out; | 2621 | goto out; |
2501 | } | 2622 | } |
2502 | 2623 | ||
@@ -2571,8 +2692,8 @@ static void rtl8169_tx_interrupt(struct net_device *dev, | |||
2571 | if (status & DescOwn) | 2692 | if (status & DescOwn) |
2572 | break; | 2693 | break; |
2573 | 2694 | ||
2574 | tp->stats.tx_bytes += len; | 2695 | dev->stats.tx_bytes += len; |
2575 | tp->stats.tx_packets++; | 2696 | dev->stats.tx_packets++; |
2576 | 2697 | ||
2577 | rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, tp->TxDescArray + entry); | 2698 | rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, tp->TxDescArray + entry); |
2578 | 2699 | ||
@@ -2672,14 +2793,14 @@ static int rtl8169_rx_interrupt(struct net_device *dev, | |||
2672 | "%s: Rx ERROR. status = %08x\n", | 2793 | "%s: Rx ERROR. status = %08x\n", |
2673 | dev->name, status); | 2794 | dev->name, status); |
2674 | } | 2795 | } |
2675 | tp->stats.rx_errors++; | 2796 | dev->stats.rx_errors++; |
2676 | if (status & (RxRWT | RxRUNT)) | 2797 | if (status & (RxRWT | RxRUNT)) |
2677 | tp->stats.rx_length_errors++; | 2798 | dev->stats.rx_length_errors++; |
2678 | if (status & RxCRC) | 2799 | if (status & RxCRC) |
2679 | tp->stats.rx_crc_errors++; | 2800 | dev->stats.rx_crc_errors++; |
2680 | if (status & RxFOVF) { | 2801 | if (status & RxFOVF) { |
2681 | rtl8169_schedule_work(dev, rtl8169_reset_task); | 2802 | rtl8169_schedule_work(dev, rtl8169_reset_task); |
2682 | tp->stats.rx_fifo_errors++; | 2803 | dev->stats.rx_fifo_errors++; |
2683 | } | 2804 | } |
2684 | rtl8169_mark_to_asic(desc, tp->rx_buf_sz); | 2805 | rtl8169_mark_to_asic(desc, tp->rx_buf_sz); |
2685 | } else { | 2806 | } else { |
@@ -2694,8 +2815,8 @@ static int rtl8169_rx_interrupt(struct net_device *dev, | |||
2694 | * sized frames. | 2815 | * sized frames. |
2695 | */ | 2816 | */ |
2696 | if (unlikely(rtl8169_fragmented_frame(status))) { | 2817 | if (unlikely(rtl8169_fragmented_frame(status))) { |
2697 | tp->stats.rx_dropped++; | 2818 | dev->stats.rx_dropped++; |
2698 | tp->stats.rx_length_errors++; | 2819 | dev->stats.rx_length_errors++; |
2699 | rtl8169_mark_to_asic(desc, tp->rx_buf_sz); | 2820 | rtl8169_mark_to_asic(desc, tp->rx_buf_sz); |
2700 | continue; | 2821 | continue; |
2701 | } | 2822 | } |
@@ -2719,8 +2840,8 @@ static int rtl8169_rx_interrupt(struct net_device *dev, | |||
2719 | rtl8169_rx_skb(skb); | 2840 | rtl8169_rx_skb(skb); |
2720 | 2841 | ||
2721 | dev->last_rx = jiffies; | 2842 | dev->last_rx = jiffies; |
2722 | tp->stats.rx_bytes += pkt_size; | 2843 | dev->stats.rx_bytes += pkt_size; |
2723 | tp->stats.rx_packets++; | 2844 | dev->stats.rx_packets++; |
2724 | } | 2845 | } |
2725 | 2846 | ||
2726 | /* Work around for AMD plateform. */ | 2847 | /* Work around for AMD plateform. */ |
@@ -2881,7 +3002,7 @@ core_down: | |||
2881 | rtl8169_asic_down(ioaddr); | 3002 | rtl8169_asic_down(ioaddr); |
2882 | 3003 | ||
2883 | /* Update the error counts. */ | 3004 | /* Update the error counts. */ |
2884 | tp->stats.rx_missed_errors += RTL_R32(RxMissed); | 3005 | dev->stats.rx_missed_errors += RTL_R32(RxMissed); |
2885 | RTL_W32(RxMissed, 0); | 3006 | RTL_W32(RxMissed, 0); |
2886 | 3007 | ||
2887 | spin_unlock_irq(&tp->lock); | 3008 | spin_unlock_irq(&tp->lock); |
@@ -2984,7 +3105,9 @@ static void rtl_set_rx_mode(struct net_device *dev) | |||
2984 | (tp->mac_version == RTL_GIGA_MAC_VER_12) || | 3105 | (tp->mac_version == RTL_GIGA_MAC_VER_12) || |
2985 | (tp->mac_version == RTL_GIGA_MAC_VER_13) || | 3106 | (tp->mac_version == RTL_GIGA_MAC_VER_13) || |
2986 | (tp->mac_version == RTL_GIGA_MAC_VER_14) || | 3107 | (tp->mac_version == RTL_GIGA_MAC_VER_14) || |
2987 | (tp->mac_version == RTL_GIGA_MAC_VER_15)) { | 3108 | (tp->mac_version == RTL_GIGA_MAC_VER_15) || |
3109 | (tp->mac_version == RTL_GIGA_MAC_VER_16) || | ||
3110 | (tp->mac_version == RTL_GIGA_MAC_VER_17)) { | ||
2988 | mc_filter[0] = 0xffffffff; | 3111 | mc_filter[0] = 0xffffffff; |
2989 | mc_filter[1] = 0xffffffff; | 3112 | mc_filter[1] = 0xffffffff; |
2990 | } | 3113 | } |
@@ -3011,12 +3134,12 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev) | |||
3011 | 3134 | ||
3012 | if (netif_running(dev)) { | 3135 | if (netif_running(dev)) { |
3013 | spin_lock_irqsave(&tp->lock, flags); | 3136 | spin_lock_irqsave(&tp->lock, flags); |
3014 | tp->stats.rx_missed_errors += RTL_R32(RxMissed); | 3137 | dev->stats.rx_missed_errors += RTL_R32(RxMissed); |
3015 | RTL_W32(RxMissed, 0); | 3138 | RTL_W32(RxMissed, 0); |
3016 | spin_unlock_irqrestore(&tp->lock, flags); | 3139 | spin_unlock_irqrestore(&tp->lock, flags); |
3017 | } | 3140 | } |
3018 | 3141 | ||
3019 | return &tp->stats; | 3142 | return &dev->stats; |
3020 | } | 3143 | } |
3021 | 3144 | ||
3022 | #ifdef CONFIG_PM | 3145 | #ifdef CONFIG_PM |
@@ -3037,14 +3160,15 @@ static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state) | |||
3037 | 3160 | ||
3038 | rtl8169_asic_down(ioaddr); | 3161 | rtl8169_asic_down(ioaddr); |
3039 | 3162 | ||
3040 | tp->stats.rx_missed_errors += RTL_R32(RxMissed); | 3163 | dev->stats.rx_missed_errors += RTL_R32(RxMissed); |
3041 | RTL_W32(RxMissed, 0); | 3164 | RTL_W32(RxMissed, 0); |
3042 | 3165 | ||
3043 | spin_unlock_irq(&tp->lock); | 3166 | spin_unlock_irq(&tp->lock); |
3044 | 3167 | ||
3045 | out_pci_suspend: | 3168 | out_pci_suspend: |
3046 | pci_save_state(pdev); | 3169 | pci_save_state(pdev); |
3047 | pci_enable_wake(pdev, pci_choose_state(pdev, state), tp->wol_enabled); | 3170 | pci_enable_wake(pdev, pci_choose_state(pdev, state), |
3171 | (tp->features & RTL_FEATURE_WOL) ? 1 : 0); | ||
3048 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 3172 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); |
3049 | 3173 | ||
3050 | return 0; | 3174 | return 0; |