diff options
Diffstat (limited to 'drivers/net/r8169.c')
-rw-r--r-- | drivers/net/r8169.c | 966 |
1 files changed, 863 insertions, 103 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 0f6f9747d255..c821da21d8eb 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #define assert(expr) \ | 36 | #define assert(expr) \ |
37 | if (!(expr)) { \ | 37 | if (!(expr)) { \ |
38 | printk( "Assertion failed! %s,%s,%s,line=%d\n", \ | 38 | printk( "Assertion failed! %s,%s,%s,line=%d\n", \ |
39 | #expr,__FILE__,__FUNCTION__,__LINE__); \ | 39 | #expr,__FILE__,__func__,__LINE__); \ |
40 | } | 40 | } |
41 | #define dprintk(fmt, args...) \ | 41 | #define dprintk(fmt, args...) \ |
42 | do { printk(KERN_DEBUG PFX fmt, ## args); } while (0) | 42 | do { printk(KERN_DEBUG PFX fmt, ## args); } while (0) |
@@ -61,6 +61,7 @@ static const int multicast_filter_limit = 32; | |||
61 | /* MAC address length */ | 61 | /* MAC address length */ |
62 | #define MAC_ADDR_LEN 6 | 62 | #define MAC_ADDR_LEN 6 |
63 | 63 | ||
64 | #define MAX_READ_REQUEST_SHIFT 12 | ||
64 | #define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */ | 65 | #define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */ |
65 | #define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ | 66 | #define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ |
66 | #define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ | 67 | #define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ |
@@ -95,6 +96,10 @@ enum mac_version { | |||
95 | RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB | 96 | RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB |
96 | RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd | 97 | RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd |
97 | RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe | 98 | RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe |
99 | RTL_GIGA_MAC_VER_07 = 0x07, // 8102e | ||
100 | RTL_GIGA_MAC_VER_08 = 0x08, // 8102e | ||
101 | RTL_GIGA_MAC_VER_09 = 0x09, // 8102e | ||
102 | RTL_GIGA_MAC_VER_10 = 0x0a, // 8101e | ||
98 | RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb | 103 | RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb |
99 | RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be | 104 | RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be |
100 | RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb | 105 | RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb |
@@ -104,7 +109,12 @@ enum mac_version { | |||
104 | RTL_GIGA_MAC_VER_17 = 0x10, // 8168Bf | 109 | RTL_GIGA_MAC_VER_17 = 0x10, // 8168Bf |
105 | RTL_GIGA_MAC_VER_18 = 0x12, // 8168CP | 110 | RTL_GIGA_MAC_VER_18 = 0x12, // 8168CP |
106 | RTL_GIGA_MAC_VER_19 = 0x13, // 8168C | 111 | RTL_GIGA_MAC_VER_19 = 0x13, // 8168C |
107 | RTL_GIGA_MAC_VER_20 = 0x14 // 8168C | 112 | RTL_GIGA_MAC_VER_20 = 0x14, // 8168C |
113 | RTL_GIGA_MAC_VER_21 = 0x15, // 8168C | ||
114 | RTL_GIGA_MAC_VER_22 = 0x16, // 8168C | ||
115 | RTL_GIGA_MAC_VER_23 = 0x17, // 8168CP | ||
116 | RTL_GIGA_MAC_VER_24 = 0x18, // 8168CP | ||
117 | RTL_GIGA_MAC_VER_25 = 0x19 // 8168D | ||
108 | }; | 118 | }; |
109 | 119 | ||
110 | #define _R(NAME,MAC,MASK) \ | 120 | #define _R(NAME,MAC,MASK) \ |
@@ -121,6 +131,10 @@ static const struct { | |||
121 | _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB | 131 | _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB |
122 | _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd | 132 | _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd |
123 | _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe | 133 | _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe |
134 | _R("RTL8102e", RTL_GIGA_MAC_VER_07, 0xff7e1880), // PCI-E | ||
135 | _R("RTL8102e", RTL_GIGA_MAC_VER_08, 0xff7e1880), // PCI-E | ||
136 | _R("RTL8102e", RTL_GIGA_MAC_VER_09, 0xff7e1880), // PCI-E | ||
137 | _R("RTL8101e", RTL_GIGA_MAC_VER_10, 0xff7e1880), // PCI-E | ||
124 | _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E | 138 | _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E |
125 | _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E | 139 | _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E |
126 | _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139 | 140 | _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139 |
@@ -130,7 +144,12 @@ static const struct { | |||
130 | _R("RTL8101e", RTL_GIGA_MAC_VER_16, 0xff7e1880), // PCI-E | 144 | _R("RTL8101e", RTL_GIGA_MAC_VER_16, 0xff7e1880), // PCI-E |
131 | _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_18, 0xff7e1880), // PCI-E | 145 | _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_18, 0xff7e1880), // PCI-E |
132 | _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_19, 0xff7e1880), // PCI-E | 146 | _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_19, 0xff7e1880), // PCI-E |
133 | _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_20, 0xff7e1880) // PCI-E | 147 | _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_20, 0xff7e1880), // PCI-E |
148 | _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_21, 0xff7e1880), // PCI-E | ||
149 | _R("RTL8168c/8111c", RTL_GIGA_MAC_VER_22, 0xff7e1880), // PCI-E | ||
150 | _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_23, 0xff7e1880), // PCI-E | ||
151 | _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_24, 0xff7e1880), // PCI-E | ||
152 | _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_25, 0xff7e1880) // PCI-E | ||
134 | }; | 153 | }; |
135 | #undef _R | 154 | #undef _R |
136 | 155 | ||
@@ -196,9 +215,6 @@ enum rtl_registers { | |||
196 | Config5 = 0x56, | 215 | Config5 = 0x56, |
197 | MultiIntr = 0x5c, | 216 | MultiIntr = 0x5c, |
198 | PHYAR = 0x60, | 217 | PHYAR = 0x60, |
199 | TBICSR = 0x64, | ||
200 | TBI_ANAR = 0x68, | ||
201 | TBI_LPAR = 0x6a, | ||
202 | PHYstatus = 0x6c, | 218 | PHYstatus = 0x6c, |
203 | RxMaxSize = 0xda, | 219 | RxMaxSize = 0xda, |
204 | CPlusCmd = 0xe0, | 220 | CPlusCmd = 0xe0, |
@@ -212,6 +228,32 @@ enum rtl_registers { | |||
212 | FuncForceEvent = 0xfc, | 228 | FuncForceEvent = 0xfc, |
213 | }; | 229 | }; |
214 | 230 | ||
231 | enum rtl8110_registers { | ||
232 | TBICSR = 0x64, | ||
233 | TBI_ANAR = 0x68, | ||
234 | TBI_LPAR = 0x6a, | ||
235 | }; | ||
236 | |||
237 | enum rtl8168_8101_registers { | ||
238 | CSIDR = 0x64, | ||
239 | CSIAR = 0x68, | ||
240 | #define CSIAR_FLAG 0x80000000 | ||
241 | #define CSIAR_WRITE_CMD 0x80000000 | ||
242 | #define CSIAR_BYTE_ENABLE 0x0f | ||
243 | #define CSIAR_BYTE_ENABLE_SHIFT 12 | ||
244 | #define CSIAR_ADDR_MASK 0x0fff | ||
245 | |||
246 | EPHYAR = 0x80, | ||
247 | #define EPHYAR_FLAG 0x80000000 | ||
248 | #define EPHYAR_WRITE_CMD 0x80000000 | ||
249 | #define EPHYAR_REG_MASK 0x1f | ||
250 | #define EPHYAR_REG_SHIFT 16 | ||
251 | #define EPHYAR_DATA_MASK 0xffff | ||
252 | DBG_REG = 0xd1, | ||
253 | #define FIX_NAK_1 (1 << 4) | ||
254 | #define FIX_NAK_2 (1 << 3) | ||
255 | }; | ||
256 | |||
215 | enum rtl_register_content { | 257 | enum rtl_register_content { |
216 | /* InterruptStatusBits */ | 258 | /* InterruptStatusBits */ |
217 | SYSErr = 0x8000, | 259 | SYSErr = 0x8000, |
@@ -265,7 +307,13 @@ enum rtl_register_content { | |||
265 | TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ | 307 | TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ |
266 | 308 | ||
267 | /* Config1 register p.24 */ | 309 | /* Config1 register p.24 */ |
310 | LEDS1 = (1 << 7), | ||
311 | LEDS0 = (1 << 6), | ||
268 | MSIEnable = (1 << 5), /* Enable Message Signaled Interrupt */ | 312 | MSIEnable = (1 << 5), /* Enable Message Signaled Interrupt */ |
313 | Speed_down = (1 << 4), | ||
314 | MEMMAP = (1 << 3), | ||
315 | IOMAP = (1 << 2), | ||
316 | VPD = (1 << 1), | ||
269 | PMEnable = (1 << 0), /* Power Management Enable */ | 317 | PMEnable = (1 << 0), /* Power Management Enable */ |
270 | 318 | ||
271 | /* Config2 register p. 25 */ | 319 | /* Config2 register p. 25 */ |
@@ -275,6 +323,7 @@ enum rtl_register_content { | |||
275 | /* Config3 register p.25 */ | 323 | /* Config3 register p.25 */ |
276 | MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */ | 324 | MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */ |
277 | LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */ | 325 | LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */ |
326 | Beacon_en = (1 << 0), /* 8168 only. Reserved in the 8168b */ | ||
278 | 327 | ||
279 | /* Config5 register p.27 */ | 328 | /* Config5 register p.27 */ |
280 | BWF = (1 << 6), /* Accept Broadcast wakeup frame */ | 329 | BWF = (1 << 6), /* Accept Broadcast wakeup frame */ |
@@ -292,7 +341,16 @@ enum rtl_register_content { | |||
292 | TBINwComplete = 0x01000000, | 341 | TBINwComplete = 0x01000000, |
293 | 342 | ||
294 | /* CPlusCmd p.31 */ | 343 | /* CPlusCmd p.31 */ |
295 | PktCntrDisable = (1 << 7), // 8168 | 344 | EnableBist = (1 << 15), // 8168 8101 |
345 | Mac_dbgo_oe = (1 << 14), // 8168 8101 | ||
346 | Normal_mode = (1 << 13), // unused | ||
347 | Force_half_dup = (1 << 12), // 8168 8101 | ||
348 | Force_rxflow_en = (1 << 11), // 8168 8101 | ||
349 | Force_txflow_en = (1 << 10), // 8168 8101 | ||
350 | Cxpl_dbg_sel = (1 << 9), // 8168 8101 | ||
351 | ASF = (1 << 8), // 8168 8101 | ||
352 | PktCntrDisable = (1 << 7), // 8168 8101 | ||
353 | Mac_dbgo_sel = 0x001c, // 8168 | ||
296 | RxVlan = (1 << 6), | 354 | RxVlan = (1 << 6), |
297 | RxChkSum = (1 << 5), | 355 | RxChkSum = (1 << 5), |
298 | PCIDAC = (1 << 4), | 356 | PCIDAC = (1 << 4), |
@@ -370,8 +428,9 @@ struct ring_info { | |||
370 | }; | 428 | }; |
371 | 429 | ||
372 | enum features { | 430 | enum features { |
373 | RTL_FEATURE_WOL = (1 << 0), | 431 | RTL_FEATURE_WOL = (1 << 0), |
374 | RTL_FEATURE_MSI = (1 << 1), | 432 | RTL_FEATURE_MSI = (1 << 1), |
433 | RTL_FEATURE_GMII = (1 << 2), | ||
375 | }; | 434 | }; |
376 | 435 | ||
377 | struct rtl8169_private { | 436 | struct rtl8169_private { |
@@ -406,13 +465,16 @@ struct rtl8169_private { | |||
406 | struct vlan_group *vlgrp; | 465 | struct vlan_group *vlgrp; |
407 | #endif | 466 | #endif |
408 | int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex); | 467 | int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex); |
409 | void (*get_settings)(struct net_device *, struct ethtool_cmd *); | 468 | int (*get_settings)(struct net_device *, struct ethtool_cmd *); |
410 | void (*phy_reset_enable)(void __iomem *); | 469 | void (*phy_reset_enable)(void __iomem *); |
411 | void (*hw_start)(struct net_device *); | 470 | void (*hw_start)(struct net_device *); |
412 | unsigned int (*phy_reset_pending)(void __iomem *); | 471 | unsigned int (*phy_reset_pending)(void __iomem *); |
413 | unsigned int (*link_ok)(void __iomem *); | 472 | unsigned int (*link_ok)(void __iomem *); |
473 | int pcie_cap; | ||
414 | struct delayed_work task; | 474 | struct delayed_work task; |
415 | unsigned features; | 475 | unsigned features; |
476 | |||
477 | struct mii_if_info mii; | ||
416 | }; | 478 | }; |
417 | 479 | ||
418 | MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); | 480 | MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); |
@@ -482,6 +544,94 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr) | |||
482 | return value; | 544 | return value; |
483 | } | 545 | } |
484 | 546 | ||
547 | static void mdio_patch(void __iomem *ioaddr, int reg_addr, int value) | ||
548 | { | ||
549 | mdio_write(ioaddr, reg_addr, mdio_read(ioaddr, reg_addr) | value); | ||
550 | } | ||
551 | |||
552 | static void rtl_mdio_write(struct net_device *dev, int phy_id, int location, | ||
553 | int val) | ||
554 | { | ||
555 | struct rtl8169_private *tp = netdev_priv(dev); | ||
556 | void __iomem *ioaddr = tp->mmio_addr; | ||
557 | |||
558 | mdio_write(ioaddr, location, val); | ||
559 | } | ||
560 | |||
561 | static int rtl_mdio_read(struct net_device *dev, int phy_id, int location) | ||
562 | { | ||
563 | struct rtl8169_private *tp = netdev_priv(dev); | ||
564 | void __iomem *ioaddr = tp->mmio_addr; | ||
565 | |||
566 | return mdio_read(ioaddr, location); | ||
567 | } | ||
568 | |||
569 | static void rtl_ephy_write(void __iomem *ioaddr, int reg_addr, int value) | ||
570 | { | ||
571 | unsigned int i; | ||
572 | |||
573 | RTL_W32(EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) | | ||
574 | (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT); | ||
575 | |||
576 | for (i = 0; i < 100; i++) { | ||
577 | if (!(RTL_R32(EPHYAR) & EPHYAR_FLAG)) | ||
578 | break; | ||
579 | udelay(10); | ||
580 | } | ||
581 | } | ||
582 | |||
583 | static u16 rtl_ephy_read(void __iomem *ioaddr, int reg_addr) | ||
584 | { | ||
585 | u16 value = 0xffff; | ||
586 | unsigned int i; | ||
587 | |||
588 | RTL_W32(EPHYAR, (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT); | ||
589 | |||
590 | for (i = 0; i < 100; i++) { | ||
591 | if (RTL_R32(EPHYAR) & EPHYAR_FLAG) { | ||
592 | value = RTL_R32(EPHYAR) & EPHYAR_DATA_MASK; | ||
593 | break; | ||
594 | } | ||
595 | udelay(10); | ||
596 | } | ||
597 | |||
598 | return value; | ||
599 | } | ||
600 | |||
601 | static void rtl_csi_write(void __iomem *ioaddr, int addr, int value) | ||
602 | { | ||
603 | unsigned int i; | ||
604 | |||
605 | RTL_W32(CSIDR, value); | ||
606 | RTL_W32(CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) | | ||
607 | CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT); | ||
608 | |||
609 | for (i = 0; i < 100; i++) { | ||
610 | if (!(RTL_R32(CSIAR) & CSIAR_FLAG)) | ||
611 | break; | ||
612 | udelay(10); | ||
613 | } | ||
614 | } | ||
615 | |||
616 | static u32 rtl_csi_read(void __iomem *ioaddr, int addr) | ||
617 | { | ||
618 | u32 value = ~0x00; | ||
619 | unsigned int i; | ||
620 | |||
621 | RTL_W32(CSIAR, (addr & CSIAR_ADDR_MASK) | | ||
622 | CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT); | ||
623 | |||
624 | for (i = 0; i < 100; i++) { | ||
625 | if (RTL_R32(CSIAR) & CSIAR_FLAG) { | ||
626 | value = RTL_R32(CSIDR); | ||
627 | break; | ||
628 | } | ||
629 | udelay(10); | ||
630 | } | ||
631 | |||
632 | return value; | ||
633 | } | ||
634 | |||
485 | static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr) | 635 | static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr) |
486 | { | 636 | { |
487 | RTL_W16(IntrMask, 0x0000); | 637 | RTL_W16(IntrMask, 0x0000); |
@@ -619,6 +769,7 @@ static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
619 | tp->features |= RTL_FEATURE_WOL; | 769 | tp->features |= RTL_FEATURE_WOL; |
620 | else | 770 | else |
621 | tp->features &= ~RTL_FEATURE_WOL; | 771 | tp->features &= ~RTL_FEATURE_WOL; |
772 | device_set_wakeup_enable(&tp->pci_dev->dev, wol->wolopts); | ||
622 | 773 | ||
623 | spin_unlock_irq(&tp->lock); | 774 | spin_unlock_irq(&tp->lock); |
624 | 775 | ||
@@ -705,8 +856,12 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, | |||
705 | } | 856 | } |
706 | } | 857 | } |
707 | 858 | ||
708 | /* The 8100e/8101e do Fast Ethernet only. */ | 859 | /* The 8100e/8101e/8102e do Fast Ethernet only. */ |
709 | if ((tp->mac_version == RTL_GIGA_MAC_VER_13) || | 860 | if ((tp->mac_version == RTL_GIGA_MAC_VER_07) || |
861 | (tp->mac_version == RTL_GIGA_MAC_VER_08) || | ||
862 | (tp->mac_version == RTL_GIGA_MAC_VER_09) || | ||
863 | (tp->mac_version == RTL_GIGA_MAC_VER_10) || | ||
864 | (tp->mac_version == RTL_GIGA_MAC_VER_13) || | ||
710 | (tp->mac_version == RTL_GIGA_MAC_VER_14) || | 865 | (tp->mac_version == RTL_GIGA_MAC_VER_14) || |
711 | (tp->mac_version == RTL_GIGA_MAC_VER_15) || | 866 | (tp->mac_version == RTL_GIGA_MAC_VER_15) || |
712 | (tp->mac_version == RTL_GIGA_MAC_VER_16)) { | 867 | (tp->mac_version == RTL_GIGA_MAC_VER_16)) { |
@@ -720,9 +875,13 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, | |||
720 | 875 | ||
721 | auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; | 876 | auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; |
722 | 877 | ||
723 | if ((tp->mac_version == RTL_GIGA_MAC_VER_12) || | 878 | if ((tp->mac_version == RTL_GIGA_MAC_VER_11) || |
724 | (tp->mac_version == RTL_GIGA_MAC_VER_17)) { | 879 | (tp->mac_version == RTL_GIGA_MAC_VER_12) || |
725 | /* Vendor specific (0x1f) and reserved (0x0e) MII registers. */ | 880 | (tp->mac_version >= RTL_GIGA_MAC_VER_17)) { |
881 | /* | ||
882 | * Wake up the PHY. | ||
883 | * Vendor specific (0x1f) and reserved (0x0e) MII registers. | ||
884 | */ | ||
726 | mdio_write(ioaddr, 0x1f, 0x0000); | 885 | mdio_write(ioaddr, 0x1f, 0x0000); |
727 | mdio_write(ioaddr, 0x0e, 0x0000); | 886 | mdio_write(ioaddr, 0x0e, 0x0000); |
728 | } | 887 | } |
@@ -850,7 +1009,7 @@ static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc, | |||
850 | 1009 | ||
851 | #endif | 1010 | #endif |
852 | 1011 | ||
853 | static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd) | 1012 | static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd) |
854 | { | 1013 | { |
855 | struct rtl8169_private *tp = netdev_priv(dev); | 1014 | struct rtl8169_private *tp = netdev_priv(dev); |
856 | void __iomem *ioaddr = tp->mmio_addr; | 1015 | void __iomem *ioaddr = tp->mmio_addr; |
@@ -867,65 +1026,29 @@ static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd) | |||
867 | 1026 | ||
868 | cmd->speed = SPEED_1000; | 1027 | cmd->speed = SPEED_1000; |
869 | cmd->duplex = DUPLEX_FULL; /* Always set */ | 1028 | cmd->duplex = DUPLEX_FULL; /* Always set */ |
1029 | |||
1030 | return 0; | ||
870 | } | 1031 | } |
871 | 1032 | ||
872 | static void rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd) | 1033 | static int rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd) |
873 | { | 1034 | { |
874 | struct rtl8169_private *tp = netdev_priv(dev); | 1035 | struct rtl8169_private *tp = netdev_priv(dev); |
875 | void __iomem *ioaddr = tp->mmio_addr; | 1036 | |
876 | u8 status; | 1037 | return mii_ethtool_gset(&tp->mii, cmd); |
877 | |||
878 | cmd->supported = SUPPORTED_10baseT_Half | | ||
879 | SUPPORTED_10baseT_Full | | ||
880 | SUPPORTED_100baseT_Half | | ||
881 | SUPPORTED_100baseT_Full | | ||
882 | SUPPORTED_1000baseT_Full | | ||
883 | SUPPORTED_Autoneg | | ||
884 | SUPPORTED_TP; | ||
885 | |||
886 | cmd->autoneg = 1; | ||
887 | cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg; | ||
888 | |||
889 | if (tp->phy_auto_nego_reg & ADVERTISE_10HALF) | ||
890 | cmd->advertising |= ADVERTISED_10baseT_Half; | ||
891 | if (tp->phy_auto_nego_reg & ADVERTISE_10FULL) | ||
892 | cmd->advertising |= ADVERTISED_10baseT_Full; | ||
893 | if (tp->phy_auto_nego_reg & ADVERTISE_100HALF) | ||
894 | cmd->advertising |= ADVERTISED_100baseT_Half; | ||
895 | if (tp->phy_auto_nego_reg & ADVERTISE_100FULL) | ||
896 | cmd->advertising |= ADVERTISED_100baseT_Full; | ||
897 | if (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL) | ||
898 | cmd->advertising |= ADVERTISED_1000baseT_Full; | ||
899 | |||
900 | status = RTL_R8(PHYstatus); | ||
901 | |||
902 | if (status & _1000bpsF) | ||
903 | cmd->speed = SPEED_1000; | ||
904 | else if (status & _100bps) | ||
905 | cmd->speed = SPEED_100; | ||
906 | else if (status & _10bps) | ||
907 | cmd->speed = SPEED_10; | ||
908 | |||
909 | if (status & TxFlowCtrl) | ||
910 | cmd->advertising |= ADVERTISED_Asym_Pause; | ||
911 | if (status & RxFlowCtrl) | ||
912 | cmd->advertising |= ADVERTISED_Pause; | ||
913 | |||
914 | cmd->duplex = ((status & _1000bpsF) || (status & FullDup)) ? | ||
915 | DUPLEX_FULL : DUPLEX_HALF; | ||
916 | } | 1038 | } |
917 | 1039 | ||
918 | static int rtl8169_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | 1040 | static int rtl8169_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) |
919 | { | 1041 | { |
920 | struct rtl8169_private *tp = netdev_priv(dev); | 1042 | struct rtl8169_private *tp = netdev_priv(dev); |
921 | unsigned long flags; | 1043 | unsigned long flags; |
1044 | int rc; | ||
922 | 1045 | ||
923 | spin_lock_irqsave(&tp->lock, flags); | 1046 | spin_lock_irqsave(&tp->lock, flags); |
924 | 1047 | ||
925 | tp->get_settings(dev, cmd); | 1048 | rc = tp->get_settings(dev, cmd); |
926 | 1049 | ||
927 | spin_unlock_irqrestore(&tp->lock, flags); | 1050 | spin_unlock_irqrestore(&tp->lock, flags); |
928 | return 0; | 1051 | return rc; |
929 | } | 1052 | } |
930 | 1053 | ||
931 | static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs, | 1054 | static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs, |
@@ -1103,11 +1226,19 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, | |||
1103 | u32 val; | 1226 | u32 val; |
1104 | int mac_version; | 1227 | int mac_version; |
1105 | } mac_info[] = { | 1228 | } mac_info[] = { |
1106 | /* 8168B family. */ | 1229 | /* 8168D family. */ |
1107 | { 0x7c800000, 0x3c800000, RTL_GIGA_MAC_VER_18 }, | 1230 | { 0x7c800000, 0x28000000, RTL_GIGA_MAC_VER_25 }, |
1231 | |||
1232 | /* 8168C family. */ | ||
1233 | { 0x7cf00000, 0x3ca00000, RTL_GIGA_MAC_VER_24 }, | ||
1234 | { 0x7cf00000, 0x3c900000, RTL_GIGA_MAC_VER_23 }, | ||
1235 | { 0x7cf00000, 0x3c800000, RTL_GIGA_MAC_VER_18 }, | ||
1236 | { 0x7c800000, 0x3c800000, RTL_GIGA_MAC_VER_24 }, | ||
1108 | { 0x7cf00000, 0x3c000000, RTL_GIGA_MAC_VER_19 }, | 1237 | { 0x7cf00000, 0x3c000000, RTL_GIGA_MAC_VER_19 }, |
1109 | { 0x7cf00000, 0x3c200000, RTL_GIGA_MAC_VER_20 }, | 1238 | { 0x7cf00000, 0x3c200000, RTL_GIGA_MAC_VER_20 }, |
1110 | { 0x7c800000, 0x3c000000, RTL_GIGA_MAC_VER_20 }, | 1239 | { 0x7cf00000, 0x3c300000, RTL_GIGA_MAC_VER_21 }, |
1240 | { 0x7cf00000, 0x3c400000, RTL_GIGA_MAC_VER_22 }, | ||
1241 | { 0x7c800000, 0x3c000000, RTL_GIGA_MAC_VER_22 }, | ||
1111 | 1242 | ||
1112 | /* 8168B family. */ | 1243 | /* 8168B family. */ |
1113 | { 0x7cf00000, 0x38000000, RTL_GIGA_MAC_VER_12 }, | 1244 | { 0x7cf00000, 0x38000000, RTL_GIGA_MAC_VER_12 }, |
@@ -1116,8 +1247,17 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, | |||
1116 | { 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 }, | 1247 | { 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 }, |
1117 | 1248 | ||
1118 | /* 8101 family. */ | 1249 | /* 8101 family. */ |
1250 | { 0x7cf00000, 0x34a00000, RTL_GIGA_MAC_VER_09 }, | ||
1251 | { 0x7cf00000, 0x24a00000, RTL_GIGA_MAC_VER_09 }, | ||
1252 | { 0x7cf00000, 0x34900000, RTL_GIGA_MAC_VER_08 }, | ||
1253 | { 0x7cf00000, 0x24900000, RTL_GIGA_MAC_VER_08 }, | ||
1254 | { 0x7cf00000, 0x34800000, RTL_GIGA_MAC_VER_07 }, | ||
1255 | { 0x7cf00000, 0x24800000, RTL_GIGA_MAC_VER_07 }, | ||
1119 | { 0x7cf00000, 0x34000000, RTL_GIGA_MAC_VER_13 }, | 1256 | { 0x7cf00000, 0x34000000, RTL_GIGA_MAC_VER_13 }, |
1257 | { 0x7cf00000, 0x34300000, RTL_GIGA_MAC_VER_10 }, | ||
1120 | { 0x7cf00000, 0x34200000, RTL_GIGA_MAC_VER_16 }, | 1258 | { 0x7cf00000, 0x34200000, RTL_GIGA_MAC_VER_16 }, |
1259 | { 0x7c800000, 0x34800000, RTL_GIGA_MAC_VER_09 }, | ||
1260 | { 0x7c800000, 0x24800000, RTL_GIGA_MAC_VER_09 }, | ||
1121 | { 0x7c800000, 0x34000000, RTL_GIGA_MAC_VER_16 }, | 1261 | { 0x7c800000, 0x34000000, RTL_GIGA_MAC_VER_16 }, |
1122 | /* FIXME: where did these entries come from ? -- FR */ | 1262 | /* FIXME: where did these entries come from ? -- FR */ |
1123 | { 0xfc800000, 0x38800000, RTL_GIGA_MAC_VER_15 }, | 1263 | { 0xfc800000, 0x38800000, RTL_GIGA_MAC_VER_15 }, |
@@ -1228,7 +1368,31 @@ static void rtl8169sb_hw_phy_config(void __iomem *ioaddr) | |||
1228 | rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); | 1368 | rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); |
1229 | } | 1369 | } |
1230 | 1370 | ||
1231 | static void rtl8168cp_hw_phy_config(void __iomem *ioaddr) | 1371 | static void rtl8168bb_hw_phy_config(void __iomem *ioaddr) |
1372 | { | ||
1373 | struct phy_reg phy_reg_init[] = { | ||
1374 | { 0x10, 0xf41b }, | ||
1375 | { 0x1f, 0x0000 } | ||
1376 | }; | ||
1377 | |||
1378 | mdio_write(ioaddr, 0x1f, 0x0001); | ||
1379 | mdio_patch(ioaddr, 0x16, 1 << 0); | ||
1380 | |||
1381 | rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); | ||
1382 | } | ||
1383 | |||
1384 | static void rtl8168bef_hw_phy_config(void __iomem *ioaddr) | ||
1385 | { | ||
1386 | struct phy_reg phy_reg_init[] = { | ||
1387 | { 0x1f, 0x0001 }, | ||
1388 | { 0x10, 0xf41b }, | ||
1389 | { 0x1f, 0x0000 } | ||
1390 | }; | ||
1391 | |||
1392 | rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); | ||
1393 | } | ||
1394 | |||
1395 | static void rtl8168cp_1_hw_phy_config(void __iomem *ioaddr) | ||
1232 | { | 1396 | { |
1233 | struct phy_reg phy_reg_init[] = { | 1397 | struct phy_reg phy_reg_init[] = { |
1234 | { 0x1f, 0x0000 }, | 1398 | { 0x1f, 0x0000 }, |
@@ -1241,7 +1405,22 @@ static void rtl8168cp_hw_phy_config(void __iomem *ioaddr) | |||
1241 | rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); | 1405 | rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); |
1242 | } | 1406 | } |
1243 | 1407 | ||
1244 | static void rtl8168c_hw_phy_config(void __iomem *ioaddr) | 1408 | static void rtl8168cp_2_hw_phy_config(void __iomem *ioaddr) |
1409 | { | ||
1410 | struct phy_reg phy_reg_init[] = { | ||
1411 | { 0x1f, 0x0001 }, | ||
1412 | { 0x1d, 0x3d98 }, | ||
1413 | { 0x1f, 0x0000 } | ||
1414 | }; | ||
1415 | |||
1416 | mdio_write(ioaddr, 0x1f, 0x0000); | ||
1417 | mdio_patch(ioaddr, 0x14, 1 << 5); | ||
1418 | mdio_patch(ioaddr, 0x0d, 1 << 5); | ||
1419 | |||
1420 | rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); | ||
1421 | } | ||
1422 | |||
1423 | static void rtl8168c_1_hw_phy_config(void __iomem *ioaddr) | ||
1245 | { | 1424 | { |
1246 | struct phy_reg phy_reg_init[] = { | 1425 | struct phy_reg phy_reg_init[] = { |
1247 | { 0x1f, 0x0001 }, | 1426 | { 0x1f, 0x0001 }, |
@@ -1257,25 +1436,157 @@ static void rtl8168c_hw_phy_config(void __iomem *ioaddr) | |||
1257 | { 0x1f, 0x0003 }, | 1436 | { 0x1f, 0x0003 }, |
1258 | { 0x12, 0xc096 }, | 1437 | { 0x12, 0xc096 }, |
1259 | { 0x16, 0x000a }, | 1438 | { 0x16, 0x000a }, |
1260 | { 0x1f, 0x0000 } | 1439 | { 0x1f, 0x0000 }, |
1440 | { 0x1f, 0x0000 }, | ||
1441 | { 0x09, 0x2000 }, | ||
1442 | { 0x09, 0x0000 } | ||
1261 | }; | 1443 | }; |
1262 | 1444 | ||
1263 | rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); | 1445 | rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); |
1446 | |||
1447 | mdio_patch(ioaddr, 0x14, 1 << 5); | ||
1448 | mdio_patch(ioaddr, 0x0d, 1 << 5); | ||
1449 | mdio_write(ioaddr, 0x1f, 0x0000); | ||
1264 | } | 1450 | } |
1265 | 1451 | ||
1266 | static void rtl8168cx_hw_phy_config(void __iomem *ioaddr) | 1452 | static void rtl8168c_2_hw_phy_config(void __iomem *ioaddr) |
1267 | { | 1453 | { |
1268 | struct phy_reg phy_reg_init[] = { | 1454 | struct phy_reg phy_reg_init[] = { |
1269 | { 0x1f, 0x0000 }, | 1455 | { 0x1f, 0x0001 }, |
1270 | { 0x12, 0x2300 }, | 1456 | { 0x12, 0x2300 }, |
1457 | { 0x03, 0x802f }, | ||
1458 | { 0x02, 0x4f02 }, | ||
1459 | { 0x01, 0x0409 }, | ||
1460 | { 0x00, 0xf099 }, | ||
1461 | { 0x04, 0x9800 }, | ||
1462 | { 0x04, 0x9000 }, | ||
1463 | { 0x1d, 0x3d98 }, | ||
1464 | { 0x1f, 0x0002 }, | ||
1465 | { 0x0c, 0x7eb8 }, | ||
1466 | { 0x06, 0x0761 }, | ||
1271 | { 0x1f, 0x0003 }, | 1467 | { 0x1f, 0x0003 }, |
1272 | { 0x16, 0x0f0a }, | 1468 | { 0x16, 0x0f0a }, |
1273 | { 0x1f, 0x0000 }, | 1469 | { 0x1f, 0x0000 } |
1470 | }; | ||
1471 | |||
1472 | rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); | ||
1473 | |||
1474 | mdio_patch(ioaddr, 0x16, 1 << 0); | ||
1475 | mdio_patch(ioaddr, 0x14, 1 << 5); | ||
1476 | mdio_patch(ioaddr, 0x0d, 1 << 5); | ||
1477 | mdio_write(ioaddr, 0x1f, 0x0000); | ||
1478 | } | ||
1479 | |||
1480 | static void rtl8168c_3_hw_phy_config(void __iomem *ioaddr) | ||
1481 | { | ||
1482 | struct phy_reg phy_reg_init[] = { | ||
1483 | { 0x1f, 0x0001 }, | ||
1484 | { 0x12, 0x2300 }, | ||
1485 | { 0x1d, 0x3d98 }, | ||
1274 | { 0x1f, 0x0002 }, | 1486 | { 0x1f, 0x0002 }, |
1275 | { 0x0c, 0x7eb8 }, | 1487 | { 0x0c, 0x7eb8 }, |
1488 | { 0x06, 0x5461 }, | ||
1489 | { 0x1f, 0x0003 }, | ||
1490 | { 0x16, 0x0f0a }, | ||
1491 | { 0x1f, 0x0000 } | ||
1492 | }; | ||
1493 | |||
1494 | rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); | ||
1495 | |||
1496 | mdio_patch(ioaddr, 0x16, 1 << 0); | ||
1497 | mdio_patch(ioaddr, 0x14, 1 << 5); | ||
1498 | mdio_patch(ioaddr, 0x0d, 1 << 5); | ||
1499 | mdio_write(ioaddr, 0x1f, 0x0000); | ||
1500 | } | ||
1501 | |||
1502 | static void rtl8168c_4_hw_phy_config(void __iomem *ioaddr) | ||
1503 | { | ||
1504 | rtl8168c_3_hw_phy_config(ioaddr); | ||
1505 | } | ||
1506 | |||
1507 | static void rtl8168d_hw_phy_config(void __iomem *ioaddr) | ||
1508 | { | ||
1509 | struct phy_reg phy_reg_init_0[] = { | ||
1510 | { 0x1f, 0x0001 }, | ||
1511 | { 0x09, 0x2770 }, | ||
1512 | { 0x08, 0x04d0 }, | ||
1513 | { 0x0b, 0xad15 }, | ||
1514 | { 0x0c, 0x5bf0 }, | ||
1515 | { 0x1c, 0xf101 }, | ||
1516 | { 0x1f, 0x0003 }, | ||
1517 | { 0x14, 0x94d7 }, | ||
1518 | { 0x12, 0xf4d6 }, | ||
1519 | { 0x09, 0xca0f }, | ||
1520 | { 0x1f, 0x0002 }, | ||
1521 | { 0x0b, 0x0b10 }, | ||
1522 | { 0x0c, 0xd1f7 }, | ||
1523 | { 0x1f, 0x0002 }, | ||
1524 | { 0x06, 0x5461 }, | ||
1525 | { 0x1f, 0x0002 }, | ||
1526 | { 0x05, 0x6662 }, | ||
1527 | { 0x1f, 0x0000 }, | ||
1528 | { 0x14, 0x0060 }, | ||
1529 | { 0x1f, 0x0000 }, | ||
1530 | { 0x0d, 0xf8a0 }, | ||
1531 | { 0x1f, 0x0005 }, | ||
1532 | { 0x05, 0xffc2 } | ||
1533 | }; | ||
1534 | |||
1535 | rtl_phy_write(ioaddr, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0)); | ||
1536 | |||
1537 | if (mdio_read(ioaddr, 0x06) == 0xc400) { | ||
1538 | struct phy_reg phy_reg_init_1[] = { | ||
1539 | { 0x1f, 0x0005 }, | ||
1540 | { 0x01, 0x0300 }, | ||
1541 | { 0x1f, 0x0000 }, | ||
1542 | { 0x11, 0x401c }, | ||
1543 | { 0x16, 0x4100 }, | ||
1544 | { 0x1f, 0x0005 }, | ||
1545 | { 0x07, 0x0010 }, | ||
1546 | { 0x05, 0x83dc }, | ||
1547 | { 0x06, 0x087d }, | ||
1548 | { 0x05, 0x8300 }, | ||
1549 | { 0x06, 0x0101 }, | ||
1550 | { 0x06, 0x05f8 }, | ||
1551 | { 0x06, 0xf9fa }, | ||
1552 | { 0x06, 0xfbef }, | ||
1553 | { 0x06, 0x79e2 }, | ||
1554 | { 0x06, 0x835f }, | ||
1555 | { 0x06, 0xe0f8 }, | ||
1556 | { 0x06, 0x9ae1 }, | ||
1557 | { 0x06, 0xf89b }, | ||
1558 | { 0x06, 0xef31 }, | ||
1559 | { 0x06, 0x3b65 }, | ||
1560 | { 0x06, 0xaa07 }, | ||
1561 | { 0x06, 0x81e4 }, | ||
1562 | { 0x06, 0xf89a }, | ||
1563 | { 0x06, 0xe5f8 }, | ||
1564 | { 0x06, 0x9baf }, | ||
1565 | { 0x06, 0x06ae }, | ||
1566 | { 0x05, 0x83dc }, | ||
1567 | { 0x06, 0x8300 }, | ||
1568 | }; | ||
1569 | |||
1570 | rtl_phy_write(ioaddr, phy_reg_init_1, | ||
1571 | ARRAY_SIZE(phy_reg_init_1)); | ||
1572 | } | ||
1573 | |||
1574 | mdio_write(ioaddr, 0x1f, 0x0000); | ||
1575 | } | ||
1576 | |||
1577 | static void rtl8102e_hw_phy_config(void __iomem *ioaddr) | ||
1578 | { | ||
1579 | struct phy_reg phy_reg_init[] = { | ||
1580 | { 0x1f, 0x0003 }, | ||
1581 | { 0x08, 0x441d }, | ||
1582 | { 0x01, 0x9100 }, | ||
1276 | { 0x1f, 0x0000 } | 1583 | { 0x1f, 0x0000 } |
1277 | }; | 1584 | }; |
1278 | 1585 | ||
1586 | mdio_write(ioaddr, 0x1f, 0x0000); | ||
1587 | mdio_patch(ioaddr, 0x11, 1 << 12); | ||
1588 | mdio_patch(ioaddr, 0x19, 1 << 13); | ||
1589 | |||
1279 | rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); | 1590 | rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init)); |
1280 | } | 1591 | } |
1281 | 1592 | ||
@@ -1296,15 +1607,43 @@ static void rtl_hw_phy_config(struct net_device *dev) | |||
1296 | case RTL_GIGA_MAC_VER_04: | 1607 | case RTL_GIGA_MAC_VER_04: |
1297 | rtl8169sb_hw_phy_config(ioaddr); | 1608 | rtl8169sb_hw_phy_config(ioaddr); |
1298 | break; | 1609 | break; |
1610 | case RTL_GIGA_MAC_VER_07: | ||
1611 | case RTL_GIGA_MAC_VER_08: | ||
1612 | case RTL_GIGA_MAC_VER_09: | ||
1613 | rtl8102e_hw_phy_config(ioaddr); | ||
1614 | break; | ||
1615 | case RTL_GIGA_MAC_VER_11: | ||
1616 | rtl8168bb_hw_phy_config(ioaddr); | ||
1617 | break; | ||
1618 | case RTL_GIGA_MAC_VER_12: | ||
1619 | rtl8168bef_hw_phy_config(ioaddr); | ||
1620 | break; | ||
1621 | case RTL_GIGA_MAC_VER_17: | ||
1622 | rtl8168bef_hw_phy_config(ioaddr); | ||
1623 | break; | ||
1299 | case RTL_GIGA_MAC_VER_18: | 1624 | case RTL_GIGA_MAC_VER_18: |
1300 | rtl8168cp_hw_phy_config(ioaddr); | 1625 | rtl8168cp_1_hw_phy_config(ioaddr); |
1301 | break; | 1626 | break; |
1302 | case RTL_GIGA_MAC_VER_19: | 1627 | case RTL_GIGA_MAC_VER_19: |
1303 | rtl8168c_hw_phy_config(ioaddr); | 1628 | rtl8168c_1_hw_phy_config(ioaddr); |
1304 | break; | 1629 | break; |
1305 | case RTL_GIGA_MAC_VER_20: | 1630 | case RTL_GIGA_MAC_VER_20: |
1306 | rtl8168cx_hw_phy_config(ioaddr); | 1631 | rtl8168c_2_hw_phy_config(ioaddr); |
1632 | break; | ||
1633 | case RTL_GIGA_MAC_VER_21: | ||
1634 | rtl8168c_3_hw_phy_config(ioaddr); | ||
1635 | break; | ||
1636 | case RTL_GIGA_MAC_VER_22: | ||
1637 | rtl8168c_4_hw_phy_config(ioaddr); | ||
1307 | break; | 1638 | break; |
1639 | case RTL_GIGA_MAC_VER_23: | ||
1640 | case RTL_GIGA_MAC_VER_24: | ||
1641 | rtl8168cp_2_hw_phy_config(ioaddr); | ||
1642 | break; | ||
1643 | case RTL_GIGA_MAC_VER_25: | ||
1644 | rtl8168d_hw_phy_config(ioaddr); | ||
1645 | break; | ||
1646 | |||
1308 | default: | 1647 | default: |
1309 | break; | 1648 | break; |
1310 | } | 1649 | } |
@@ -1513,7 +1852,7 @@ static const struct rtl_cfg_info { | |||
1513 | unsigned int align; | 1852 | unsigned int align; |
1514 | u16 intr_event; | 1853 | u16 intr_event; |
1515 | u16 napi_event; | 1854 | u16 napi_event; |
1516 | unsigned msi; | 1855 | unsigned features; |
1517 | } rtl_cfg_infos [] = { | 1856 | } rtl_cfg_infos [] = { |
1518 | [RTL_CFG_0] = { | 1857 | [RTL_CFG_0] = { |
1519 | .hw_start = rtl_hw_start_8169, | 1858 | .hw_start = rtl_hw_start_8169, |
@@ -1522,7 +1861,7 @@ static const struct rtl_cfg_info { | |||
1522 | .intr_event = SYSErr | LinkChg | RxOverflow | | 1861 | .intr_event = SYSErr | LinkChg | RxOverflow | |
1523 | RxFIFOOver | TxErr | TxOK | RxOK | RxErr, | 1862 | RxFIFOOver | TxErr | TxOK | RxOK | RxErr, |
1524 | .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow, | 1863 | .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow, |
1525 | .msi = 0 | 1864 | .features = RTL_FEATURE_GMII |
1526 | }, | 1865 | }, |
1527 | [RTL_CFG_1] = { | 1866 | [RTL_CFG_1] = { |
1528 | .hw_start = rtl_hw_start_8168, | 1867 | .hw_start = rtl_hw_start_8168, |
@@ -1531,7 +1870,7 @@ static const struct rtl_cfg_info { | |||
1531 | .intr_event = SYSErr | LinkChg | RxOverflow | | 1870 | .intr_event = SYSErr | LinkChg | RxOverflow | |
1532 | TxErr | TxOK | RxOK | RxErr, | 1871 | TxErr | TxOK | RxOK | RxErr, |
1533 | .napi_event = TxErr | TxOK | RxOK | RxOverflow, | 1872 | .napi_event = TxErr | TxOK | RxOK | RxOverflow, |
1534 | .msi = RTL_FEATURE_MSI | 1873 | .features = RTL_FEATURE_GMII | RTL_FEATURE_MSI |
1535 | }, | 1874 | }, |
1536 | [RTL_CFG_2] = { | 1875 | [RTL_CFG_2] = { |
1537 | .hw_start = rtl_hw_start_8101, | 1876 | .hw_start = rtl_hw_start_8101, |
@@ -1540,7 +1879,7 @@ static const struct rtl_cfg_info { | |||
1540 | .intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout | | 1879 | .intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout | |
1541 | RxFIFOOver | TxErr | TxOK | RxOK | RxErr, | 1880 | RxFIFOOver | TxErr | TxOK | RxOK | RxErr, |
1542 | .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow, | 1881 | .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow, |
1543 | .msi = RTL_FEATURE_MSI | 1882 | .features = RTL_FEATURE_MSI |
1544 | } | 1883 | } |
1545 | }; | 1884 | }; |
1546 | 1885 | ||
@@ -1552,7 +1891,7 @@ static unsigned rtl_try_msi(struct pci_dev *pdev, void __iomem *ioaddr, | |||
1552 | u8 cfg2; | 1891 | u8 cfg2; |
1553 | 1892 | ||
1554 | cfg2 = RTL_R8(Config2) & ~MSIEnable; | 1893 | cfg2 = RTL_R8(Config2) & ~MSIEnable; |
1555 | if (cfg->msi) { | 1894 | if (cfg->features & RTL_FEATURE_MSI) { |
1556 | if (pci_enable_msi(pdev)) { | 1895 | if (pci_enable_msi(pdev)) { |
1557 | dev_info(&pdev->dev, "no MSI. Back to INTx.\n"); | 1896 | dev_info(&pdev->dev, "no MSI. Back to INTx.\n"); |
1558 | } else { | 1897 | } else { |
@@ -1572,12 +1911,81 @@ static void rtl_disable_msi(struct pci_dev *pdev, struct rtl8169_private *tp) | |||
1572 | } | 1911 | } |
1573 | } | 1912 | } |
1574 | 1913 | ||
1914 | static int rtl_eeprom_read(struct pci_dev *pdev, int cap, int addr, __le32 *val) | ||
1915 | { | ||
1916 | int ret, count = 100; | ||
1917 | u16 status = 0; | ||
1918 | u32 value; | ||
1919 | |||
1920 | ret = pci_write_config_word(pdev, cap + PCI_VPD_ADDR, addr); | ||
1921 | if (ret < 0) | ||
1922 | return ret; | ||
1923 | |||
1924 | do { | ||
1925 | udelay(10); | ||
1926 | ret = pci_read_config_word(pdev, cap + PCI_VPD_ADDR, &status); | ||
1927 | if (ret < 0) | ||
1928 | return ret; | ||
1929 | } while (!(status & PCI_VPD_ADDR_F) && --count); | ||
1930 | |||
1931 | if (!(status & PCI_VPD_ADDR_F)) | ||
1932 | return -ETIMEDOUT; | ||
1933 | |||
1934 | ret = pci_read_config_dword(pdev, cap + PCI_VPD_DATA, &value); | ||
1935 | if (ret < 0) | ||
1936 | return ret; | ||
1937 | |||
1938 | *val = cpu_to_le32(value); | ||
1939 | |||
1940 | return 0; | ||
1941 | } | ||
1942 | |||
1943 | static void rtl_init_mac_address(struct rtl8169_private *tp, | ||
1944 | void __iomem *ioaddr) | ||
1945 | { | ||
1946 | struct pci_dev *pdev = tp->pci_dev; | ||
1947 | u8 cfg1; | ||
1948 | int vpd_cap; | ||
1949 | u8 mac[8]; | ||
1950 | DECLARE_MAC_BUF(buf); | ||
1951 | |||
1952 | cfg1 = RTL_R8(Config1); | ||
1953 | if (!(cfg1 & VPD)) { | ||
1954 | dprintk("VPD access not enabled, enabling\n"); | ||
1955 | RTL_W8(Cfg9346, Cfg9346_Unlock); | ||
1956 | RTL_W8(Config1, cfg1 | VPD); | ||
1957 | RTL_W8(Cfg9346, Cfg9346_Lock); | ||
1958 | } | ||
1959 | |||
1960 | vpd_cap = pci_find_capability(pdev, PCI_CAP_ID_VPD); | ||
1961 | if (!vpd_cap) | ||
1962 | return; | ||
1963 | |||
1964 | /* MAC address is stored in EEPROM at offset 0x0e | ||
1965 | * Realtek says: "The VPD address does not have to be a DWORD-aligned | ||
1966 | * address as defined in the PCI 2.2 Specifications, but the VPD data | ||
1967 | * is always consecutive 4-byte data starting from the VPD address | ||
1968 | * specified." | ||
1969 | */ | ||
1970 | if (rtl_eeprom_read(pdev, vpd_cap, 0x000e, (__le32*)&mac[0]) < 0 || | ||
1971 | rtl_eeprom_read(pdev, vpd_cap, 0x0012, (__le32*)&mac[4]) < 0) { | ||
1972 | dprintk("Reading MAC address from EEPROM failed\n"); | ||
1973 | return; | ||
1974 | } | ||
1975 | |||
1976 | dprintk("MAC address found in EEPROM: %s\n", print_mac(buf, mac)); | ||
1977 | |||
1978 | /* Write MAC address */ | ||
1979 | rtl_rar_set(tp, mac); | ||
1980 | } | ||
1981 | |||
1575 | static int __devinit | 1982 | static int __devinit |
1576 | rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 1983 | rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
1577 | { | 1984 | { |
1578 | const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data; | 1985 | const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data; |
1579 | const unsigned int region = cfg->region; | 1986 | const unsigned int region = cfg->region; |
1580 | struct rtl8169_private *tp; | 1987 | struct rtl8169_private *tp; |
1988 | struct mii_if_info *mii; | ||
1581 | struct net_device *dev; | 1989 | struct net_device *dev; |
1582 | void __iomem *ioaddr; | 1990 | void __iomem *ioaddr; |
1583 | unsigned int i; | 1991 | unsigned int i; |
@@ -1602,6 +2010,14 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1602 | tp->pci_dev = pdev; | 2010 | tp->pci_dev = pdev; |
1603 | tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT); | 2011 | tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT); |
1604 | 2012 | ||
2013 | mii = &tp->mii; | ||
2014 | mii->dev = dev; | ||
2015 | mii->mdio_read = rtl_mdio_read; | ||
2016 | mii->mdio_write = rtl_mdio_write; | ||
2017 | mii->phy_id_mask = 0x1f; | ||
2018 | mii->reg_num_mask = 0x1f; | ||
2019 | mii->supports_gmii = !!(cfg->features & RTL_FEATURE_GMII); | ||
2020 | |||
1605 | /* enable device (incl. PCI PM wakeup and hotplug setup) */ | 2021 | /* enable device (incl. PCI PM wakeup and hotplug setup) */ |
1606 | rc = pci_enable_device(pdev); | 2022 | rc = pci_enable_device(pdev); |
1607 | if (rc < 0) { | 2023 | if (rc < 0) { |
@@ -1670,6 +2086,10 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1670 | goto err_out_free_res_4; | 2086 | goto err_out_free_res_4; |
1671 | } | 2087 | } |
1672 | 2088 | ||
2089 | tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); | ||
2090 | if (!tp->pcie_cap && netif_msg_probe(tp)) | ||
2091 | dev_info(&pdev->dev, "no PCI Express capability\n"); | ||
2092 | |||
1673 | /* Unneeded ? Don't mess with Mrs. Murphy. */ | 2093 | /* Unneeded ? Don't mess with Mrs. Murphy. */ |
1674 | rtl8169_irq_mask_and_ack(ioaddr); | 2094 | rtl8169_irq_mask_and_ack(ioaddr); |
1675 | 2095 | ||
@@ -1706,6 +2126,10 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1706 | RTL_W8(Cfg9346, Cfg9346_Unlock); | 2126 | RTL_W8(Cfg9346, Cfg9346_Unlock); |
1707 | RTL_W8(Config1, RTL_R8(Config1) | PMEnable); | 2127 | RTL_W8(Config1, RTL_R8(Config1) | PMEnable); |
1708 | RTL_W8(Config5, RTL_R8(Config5) & PMEStatus); | 2128 | RTL_W8(Config5, RTL_R8(Config5) & PMEStatus); |
2129 | if ((RTL_R8(Config3) & (LinkUp | MagicPacket)) != 0) | ||
2130 | tp->features |= RTL_FEATURE_WOL; | ||
2131 | if ((RTL_R8(Config5) & (UWF | BWF | MWF)) != 0) | ||
2132 | tp->features |= RTL_FEATURE_WOL; | ||
1709 | tp->features |= rtl_try_msi(pdev, ioaddr, cfg); | 2133 | tp->features |= rtl_try_msi(pdev, ioaddr, cfg); |
1710 | RTL_W8(Cfg9346, Cfg9346_Lock); | 2134 | RTL_W8(Cfg9346, Cfg9346_Lock); |
1711 | 2135 | ||
@@ -1728,7 +2152,13 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1728 | dev->do_ioctl = rtl8169_ioctl; | 2152 | dev->do_ioctl = rtl8169_ioctl; |
1729 | } | 2153 | } |
1730 | 2154 | ||
1731 | /* Get MAC address. FIXME: read EEPROM */ | 2155 | spin_lock_init(&tp->lock); |
2156 | |||
2157 | tp->mmio_addr = ioaddr; | ||
2158 | |||
2159 | rtl_init_mac_address(tp, ioaddr); | ||
2160 | |||
2161 | /* Get MAC address */ | ||
1732 | for (i = 0; i < MAC_ADDR_LEN; i++) | 2162 | for (i = 0; i < MAC_ADDR_LEN; i++) |
1733 | dev->dev_addr[i] = RTL_R8(MAC0 + i); | 2163 | dev->dev_addr[i] = RTL_R8(MAC0 + i); |
1734 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); | 2164 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); |
@@ -1758,7 +2188,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1758 | #endif | 2188 | #endif |
1759 | 2189 | ||
1760 | tp->intr_mask = 0xffff; | 2190 | tp->intr_mask = 0xffff; |
1761 | tp->mmio_addr = ioaddr; | ||
1762 | tp->align = cfg->align; | 2191 | tp->align = cfg->align; |
1763 | tp->hw_start = cfg->hw_start; | 2192 | tp->hw_start = cfg->hw_start; |
1764 | tp->intr_event = cfg->intr_event; | 2193 | tp->intr_event = cfg->intr_event; |
@@ -1768,8 +2197,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1768 | tp->timer.data = (unsigned long) dev; | 2197 | tp->timer.data = (unsigned long) dev; |
1769 | tp->timer.function = rtl8169_phy_timer; | 2198 | tp->timer.function = rtl8169_phy_timer; |
1770 | 2199 | ||
1771 | spin_lock_init(&tp->lock); | ||
1772 | |||
1773 | rc = register_netdev(dev); | 2200 | rc = register_netdev(dev); |
1774 | if (rc < 0) | 2201 | if (rc < 0) |
1775 | goto err_out_msi_5; | 2202 | goto err_out_msi_5; |
@@ -1791,6 +2218,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1791 | } | 2218 | } |
1792 | 2219 | ||
1793 | rtl8169_init_phy(dev, tp); | 2220 | rtl8169_init_phy(dev, tp); |
2221 | device_set_wakeup_enable(&pdev->dev, tp->features & RTL_FEATURE_WOL); | ||
1794 | 2222 | ||
1795 | out: | 2223 | out: |
1796 | return rc; | 2224 | return rc; |
@@ -2061,12 +2489,209 @@ static void rtl_hw_start_8169(struct net_device *dev) | |||
2061 | RTL_W16(IntrMask, tp->intr_event); | 2489 | RTL_W16(IntrMask, tp->intr_event); |
2062 | } | 2490 | } |
2063 | 2491 | ||
2492 | static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force) | ||
2493 | { | ||
2494 | struct net_device *dev = pci_get_drvdata(pdev); | ||
2495 | struct rtl8169_private *tp = netdev_priv(dev); | ||
2496 | int cap = tp->pcie_cap; | ||
2497 | |||
2498 | if (cap) { | ||
2499 | u16 ctl; | ||
2500 | |||
2501 | pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl); | ||
2502 | ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | force; | ||
2503 | pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl); | ||
2504 | } | ||
2505 | } | ||
2506 | |||
2507 | static void rtl_csi_access_enable(void __iomem *ioaddr) | ||
2508 | { | ||
2509 | u32 csi; | ||
2510 | |||
2511 | csi = rtl_csi_read(ioaddr, 0x070c) & 0x00ffffff; | ||
2512 | rtl_csi_write(ioaddr, 0x070c, csi | 0x27000000); | ||
2513 | } | ||
2514 | |||
2515 | struct ephy_info { | ||
2516 | unsigned int offset; | ||
2517 | u16 mask; | ||
2518 | u16 bits; | ||
2519 | }; | ||
2520 | |||
2521 | static void rtl_ephy_init(void __iomem *ioaddr, struct ephy_info *e, int len) | ||
2522 | { | ||
2523 | u16 w; | ||
2524 | |||
2525 | while (len-- > 0) { | ||
2526 | w = (rtl_ephy_read(ioaddr, e->offset) & ~e->mask) | e->bits; | ||
2527 | rtl_ephy_write(ioaddr, e->offset, w); | ||
2528 | e++; | ||
2529 | } | ||
2530 | } | ||
2531 | |||
2532 | static void rtl_disable_clock_request(struct pci_dev *pdev) | ||
2533 | { | ||
2534 | struct net_device *dev = pci_get_drvdata(pdev); | ||
2535 | struct rtl8169_private *tp = netdev_priv(dev); | ||
2536 | int cap = tp->pcie_cap; | ||
2537 | |||
2538 | if (cap) { | ||
2539 | u16 ctl; | ||
2540 | |||
2541 | pci_read_config_word(pdev, cap + PCI_EXP_LNKCTL, &ctl); | ||
2542 | ctl &= ~PCI_EXP_LNKCTL_CLKREQ_EN; | ||
2543 | pci_write_config_word(pdev, cap + PCI_EXP_LNKCTL, ctl); | ||
2544 | } | ||
2545 | } | ||
2546 | |||
2547 | #define R8168_CPCMD_QUIRK_MASK (\ | ||
2548 | EnableBist | \ | ||
2549 | Mac_dbgo_oe | \ | ||
2550 | Force_half_dup | \ | ||
2551 | Force_rxflow_en | \ | ||
2552 | Force_txflow_en | \ | ||
2553 | Cxpl_dbg_sel | \ | ||
2554 | ASF | \ | ||
2555 | PktCntrDisable | \ | ||
2556 | Mac_dbgo_sel) | ||
2557 | |||
2558 | static void rtl_hw_start_8168bb(void __iomem *ioaddr, struct pci_dev *pdev) | ||
2559 | { | ||
2560 | RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); | ||
2561 | |||
2562 | RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); | ||
2563 | |||
2564 | rtl_tx_performance_tweak(pdev, | ||
2565 | (0x5 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN); | ||
2566 | } | ||
2567 | |||
2568 | static void rtl_hw_start_8168bef(void __iomem *ioaddr, struct pci_dev *pdev) | ||
2569 | { | ||
2570 | rtl_hw_start_8168bb(ioaddr, pdev); | ||
2571 | |||
2572 | RTL_W8(EarlyTxThres, EarlyTxThld); | ||
2573 | |||
2574 | RTL_W8(Config4, RTL_R8(Config4) & ~(1 << 0)); | ||
2575 | } | ||
2576 | |||
2577 | static void __rtl_hw_start_8168cp(void __iomem *ioaddr, struct pci_dev *pdev) | ||
2578 | { | ||
2579 | RTL_W8(Config1, RTL_R8(Config1) | Speed_down); | ||
2580 | |||
2581 | RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); | ||
2582 | |||
2583 | rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); | ||
2584 | |||
2585 | rtl_disable_clock_request(pdev); | ||
2586 | |||
2587 | RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); | ||
2588 | } | ||
2589 | |||
2590 | static void rtl_hw_start_8168cp_1(void __iomem *ioaddr, struct pci_dev *pdev) | ||
2591 | { | ||
2592 | static struct ephy_info e_info_8168cp[] = { | ||
2593 | { 0x01, 0, 0x0001 }, | ||
2594 | { 0x02, 0x0800, 0x1000 }, | ||
2595 | { 0x03, 0, 0x0042 }, | ||
2596 | { 0x06, 0x0080, 0x0000 }, | ||
2597 | { 0x07, 0, 0x2000 } | ||
2598 | }; | ||
2599 | |||
2600 | rtl_csi_access_enable(ioaddr); | ||
2601 | |||
2602 | rtl_ephy_init(ioaddr, e_info_8168cp, ARRAY_SIZE(e_info_8168cp)); | ||
2603 | |||
2604 | __rtl_hw_start_8168cp(ioaddr, pdev); | ||
2605 | } | ||
2606 | |||
2607 | static void rtl_hw_start_8168cp_2(void __iomem *ioaddr, struct pci_dev *pdev) | ||
2608 | { | ||
2609 | rtl_csi_access_enable(ioaddr); | ||
2610 | |||
2611 | RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); | ||
2612 | |||
2613 | rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); | ||
2614 | |||
2615 | RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); | ||
2616 | } | ||
2617 | |||
2618 | static void rtl_hw_start_8168cp_3(void __iomem *ioaddr, struct pci_dev *pdev) | ||
2619 | { | ||
2620 | rtl_csi_access_enable(ioaddr); | ||
2621 | |||
2622 | RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); | ||
2623 | |||
2624 | /* Magic. */ | ||
2625 | RTL_W8(DBG_REG, 0x20); | ||
2626 | |||
2627 | RTL_W8(EarlyTxThres, EarlyTxThld); | ||
2628 | |||
2629 | rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); | ||
2630 | |||
2631 | RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); | ||
2632 | } | ||
2633 | |||
2634 | static void rtl_hw_start_8168c_1(void __iomem *ioaddr, struct pci_dev *pdev) | ||
2635 | { | ||
2636 | static struct ephy_info e_info_8168c_1[] = { | ||
2637 | { 0x02, 0x0800, 0x1000 }, | ||
2638 | { 0x03, 0, 0x0002 }, | ||
2639 | { 0x06, 0x0080, 0x0000 } | ||
2640 | }; | ||
2641 | |||
2642 | rtl_csi_access_enable(ioaddr); | ||
2643 | |||
2644 | RTL_W8(DBG_REG, 0x06 | FIX_NAK_1 | FIX_NAK_2); | ||
2645 | |||
2646 | rtl_ephy_init(ioaddr, e_info_8168c_1, ARRAY_SIZE(e_info_8168c_1)); | ||
2647 | |||
2648 | __rtl_hw_start_8168cp(ioaddr, pdev); | ||
2649 | } | ||
2650 | |||
2651 | static void rtl_hw_start_8168c_2(void __iomem *ioaddr, struct pci_dev *pdev) | ||
2652 | { | ||
2653 | static struct ephy_info e_info_8168c_2[] = { | ||
2654 | { 0x01, 0, 0x0001 }, | ||
2655 | { 0x03, 0x0400, 0x0220 } | ||
2656 | }; | ||
2657 | |||
2658 | rtl_csi_access_enable(ioaddr); | ||
2659 | |||
2660 | rtl_ephy_init(ioaddr, e_info_8168c_2, ARRAY_SIZE(e_info_8168c_2)); | ||
2661 | |||
2662 | __rtl_hw_start_8168cp(ioaddr, pdev); | ||
2663 | } | ||
2664 | |||
2665 | static void rtl_hw_start_8168c_3(void __iomem *ioaddr, struct pci_dev *pdev) | ||
2666 | { | ||
2667 | rtl_hw_start_8168c_2(ioaddr, pdev); | ||
2668 | } | ||
2669 | |||
2670 | static void rtl_hw_start_8168c_4(void __iomem *ioaddr, struct pci_dev *pdev) | ||
2671 | { | ||
2672 | rtl_csi_access_enable(ioaddr); | ||
2673 | |||
2674 | __rtl_hw_start_8168cp(ioaddr, pdev); | ||
2675 | } | ||
2676 | |||
2677 | static void rtl_hw_start_8168d(void __iomem *ioaddr, struct pci_dev *pdev) | ||
2678 | { | ||
2679 | rtl_csi_access_enable(ioaddr); | ||
2680 | |||
2681 | rtl_disable_clock_request(pdev); | ||
2682 | |||
2683 | RTL_W8(EarlyTxThres, EarlyTxThld); | ||
2684 | |||
2685 | rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); | ||
2686 | |||
2687 | RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); | ||
2688 | } | ||
2689 | |||
2064 | static void rtl_hw_start_8168(struct net_device *dev) | 2690 | static void rtl_hw_start_8168(struct net_device *dev) |
2065 | { | 2691 | { |
2066 | struct rtl8169_private *tp = netdev_priv(dev); | 2692 | struct rtl8169_private *tp = netdev_priv(dev); |
2067 | void __iomem *ioaddr = tp->mmio_addr; | 2693 | void __iomem *ioaddr = tp->mmio_addr; |
2068 | struct pci_dev *pdev = tp->pci_dev; | 2694 | struct pci_dev *pdev = tp->pci_dev; |
2069 | u8 ctl; | ||
2070 | 2695 | ||
2071 | RTL_W8(Cfg9346, Cfg9346_Unlock); | 2696 | RTL_W8(Cfg9346, Cfg9346_Unlock); |
2072 | 2697 | ||
@@ -2074,17 +2699,10 @@ static void rtl_hw_start_8168(struct net_device *dev) | |||
2074 | 2699 | ||
2075 | rtl_set_rx_max_size(ioaddr); | 2700 | rtl_set_rx_max_size(ioaddr); |
2076 | 2701 | ||
2077 | rtl_set_rx_tx_config_registers(tp); | ||
2078 | |||
2079 | tp->cp_cmd |= RTL_R16(CPlusCmd) | PktCntrDisable | INTT_1; | 2702 | tp->cp_cmd |= RTL_R16(CPlusCmd) | PktCntrDisable | INTT_1; |
2080 | 2703 | ||
2081 | RTL_W16(CPlusCmd, tp->cp_cmd); | 2704 | RTL_W16(CPlusCmd, tp->cp_cmd); |
2082 | 2705 | ||
2083 | /* Tx performance tweak. */ | ||
2084 | pci_read_config_byte(pdev, 0x69, &ctl); | ||
2085 | ctl = (ctl & ~0x70) | 0x50; | ||
2086 | pci_write_config_byte(pdev, 0x69, ctl); | ||
2087 | |||
2088 | RTL_W16(IntrMitigate, 0x5151); | 2706 | RTL_W16(IntrMitigate, 0x5151); |
2089 | 2707 | ||
2090 | /* Work around for RxFIFO overflow. */ | 2708 | /* Work around for RxFIFO overflow. */ |
@@ -2095,21 +2713,134 @@ static void rtl_hw_start_8168(struct net_device *dev) | |||
2095 | 2713 | ||
2096 | rtl_set_rx_tx_desc_registers(tp, ioaddr); | 2714 | rtl_set_rx_tx_desc_registers(tp, ioaddr); |
2097 | 2715 | ||
2098 | RTL_W8(Cfg9346, Cfg9346_Lock); | 2716 | rtl_set_rx_mode(dev); |
2717 | |||
2718 | RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) | | ||
2719 | (InterFrameGap << TxInterFrameGapShift)); | ||
2099 | 2720 | ||
2100 | RTL_R8(IntrMask); | 2721 | RTL_R8(IntrMask); |
2101 | 2722 | ||
2102 | RTL_W32(RxMissed, 0); | 2723 | switch (tp->mac_version) { |
2724 | case RTL_GIGA_MAC_VER_11: | ||
2725 | rtl_hw_start_8168bb(ioaddr, pdev); | ||
2726 | break; | ||
2103 | 2727 | ||
2104 | rtl_set_rx_mode(dev); | 2728 | case RTL_GIGA_MAC_VER_12: |
2729 | case RTL_GIGA_MAC_VER_17: | ||
2730 | rtl_hw_start_8168bef(ioaddr, pdev); | ||
2731 | break; | ||
2732 | |||
2733 | case RTL_GIGA_MAC_VER_18: | ||
2734 | rtl_hw_start_8168cp_1(ioaddr, pdev); | ||
2735 | break; | ||
2736 | |||
2737 | case RTL_GIGA_MAC_VER_19: | ||
2738 | rtl_hw_start_8168c_1(ioaddr, pdev); | ||
2739 | break; | ||
2740 | |||
2741 | case RTL_GIGA_MAC_VER_20: | ||
2742 | rtl_hw_start_8168c_2(ioaddr, pdev); | ||
2743 | break; | ||
2744 | |||
2745 | case RTL_GIGA_MAC_VER_21: | ||
2746 | rtl_hw_start_8168c_3(ioaddr, pdev); | ||
2747 | break; | ||
2748 | |||
2749 | case RTL_GIGA_MAC_VER_22: | ||
2750 | rtl_hw_start_8168c_4(ioaddr, pdev); | ||
2751 | break; | ||
2752 | |||
2753 | case RTL_GIGA_MAC_VER_23: | ||
2754 | rtl_hw_start_8168cp_2(ioaddr, pdev); | ||
2755 | break; | ||
2756 | |||
2757 | case RTL_GIGA_MAC_VER_24: | ||
2758 | rtl_hw_start_8168cp_3(ioaddr, pdev); | ||
2759 | break; | ||
2760 | |||
2761 | case RTL_GIGA_MAC_VER_25: | ||
2762 | rtl_hw_start_8168d(ioaddr, pdev); | ||
2763 | break; | ||
2764 | |||
2765 | default: | ||
2766 | printk(KERN_ERR PFX "%s: unknown chipset (mac_version = %d).\n", | ||
2767 | dev->name, tp->mac_version); | ||
2768 | break; | ||
2769 | } | ||
2105 | 2770 | ||
2106 | RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); | 2771 | RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); |
2107 | 2772 | ||
2773 | RTL_W8(Cfg9346, Cfg9346_Lock); | ||
2774 | |||
2108 | RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); | 2775 | RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); |
2109 | 2776 | ||
2110 | RTL_W16(IntrMask, tp->intr_event); | 2777 | RTL_W16(IntrMask, tp->intr_event); |
2111 | } | 2778 | } |
2112 | 2779 | ||
2780 | #define R810X_CPCMD_QUIRK_MASK (\ | ||
2781 | EnableBist | \ | ||
2782 | Mac_dbgo_oe | \ | ||
2783 | Force_half_dup | \ | ||
2784 | Force_half_dup | \ | ||
2785 | Force_txflow_en | \ | ||
2786 | Cxpl_dbg_sel | \ | ||
2787 | ASF | \ | ||
2788 | PktCntrDisable | \ | ||
2789 | PCIDAC | \ | ||
2790 | PCIMulRW) | ||
2791 | |||
2792 | static void rtl_hw_start_8102e_1(void __iomem *ioaddr, struct pci_dev *pdev) | ||
2793 | { | ||
2794 | static struct ephy_info e_info_8102e_1[] = { | ||
2795 | { 0x01, 0, 0x6e65 }, | ||
2796 | { 0x02, 0, 0x091f }, | ||
2797 | { 0x03, 0, 0xc2f9 }, | ||
2798 | { 0x06, 0, 0xafb5 }, | ||
2799 | { 0x07, 0, 0x0e00 }, | ||
2800 | { 0x19, 0, 0xec80 }, | ||
2801 | { 0x01, 0, 0x2e65 }, | ||
2802 | { 0x01, 0, 0x6e65 } | ||
2803 | }; | ||
2804 | u8 cfg1; | ||
2805 | |||
2806 | rtl_csi_access_enable(ioaddr); | ||
2807 | |||
2808 | RTL_W8(DBG_REG, FIX_NAK_1); | ||
2809 | |||
2810 | rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); | ||
2811 | |||
2812 | RTL_W8(Config1, | ||
2813 | LEDS1 | LEDS0 | Speed_down | MEMMAP | IOMAP | VPD | PMEnable); | ||
2814 | RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); | ||
2815 | |||
2816 | cfg1 = RTL_R8(Config1); | ||
2817 | if ((cfg1 & LEDS0) && (cfg1 & LEDS1)) | ||
2818 | RTL_W8(Config1, cfg1 & ~LEDS0); | ||
2819 | |||
2820 | RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK); | ||
2821 | |||
2822 | rtl_ephy_init(ioaddr, e_info_8102e_1, ARRAY_SIZE(e_info_8102e_1)); | ||
2823 | } | ||
2824 | |||
2825 | static void rtl_hw_start_8102e_2(void __iomem *ioaddr, struct pci_dev *pdev) | ||
2826 | { | ||
2827 | rtl_csi_access_enable(ioaddr); | ||
2828 | |||
2829 | rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); | ||
2830 | |||
2831 | RTL_W8(Config1, MEMMAP | IOMAP | VPD | PMEnable); | ||
2832 | RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); | ||
2833 | |||
2834 | RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK); | ||
2835 | } | ||
2836 | |||
2837 | static void rtl_hw_start_8102e_3(void __iomem *ioaddr, struct pci_dev *pdev) | ||
2838 | { | ||
2839 | rtl_hw_start_8102e_2(ioaddr, pdev); | ||
2840 | |||
2841 | rtl_ephy_write(ioaddr, 0x03, 0xc2f9); | ||
2842 | } | ||
2843 | |||
2113 | static void rtl_hw_start_8101(struct net_device *dev) | 2844 | static void rtl_hw_start_8101(struct net_device *dev) |
2114 | { | 2845 | { |
2115 | struct rtl8169_private *tp = netdev_priv(dev); | 2846 | struct rtl8169_private *tp = netdev_priv(dev); |
@@ -2118,8 +2849,26 @@ static void rtl_hw_start_8101(struct net_device *dev) | |||
2118 | 2849 | ||
2119 | if ((tp->mac_version == RTL_GIGA_MAC_VER_13) || | 2850 | if ((tp->mac_version == RTL_GIGA_MAC_VER_13) || |
2120 | (tp->mac_version == RTL_GIGA_MAC_VER_16)) { | 2851 | (tp->mac_version == RTL_GIGA_MAC_VER_16)) { |
2121 | pci_write_config_word(pdev, 0x68, 0x00); | 2852 | int cap = tp->pcie_cap; |
2122 | pci_write_config_word(pdev, 0x69, 0x08); | 2853 | |
2854 | if (cap) { | ||
2855 | pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, | ||
2856 | PCI_EXP_DEVCTL_NOSNOOP_EN); | ||
2857 | } | ||
2858 | } | ||
2859 | |||
2860 | switch (tp->mac_version) { | ||
2861 | case RTL_GIGA_MAC_VER_07: | ||
2862 | rtl_hw_start_8102e_1(ioaddr, pdev); | ||
2863 | break; | ||
2864 | |||
2865 | case RTL_GIGA_MAC_VER_08: | ||
2866 | rtl_hw_start_8102e_3(ioaddr, pdev); | ||
2867 | break; | ||
2868 | |||
2869 | case RTL_GIGA_MAC_VER_09: | ||
2870 | rtl_hw_start_8102e_2(ioaddr, pdev); | ||
2871 | break; | ||
2123 | } | 2872 | } |
2124 | 2873 | ||
2125 | RTL_W8(Cfg9346, Cfg9346_Unlock); | 2874 | RTL_W8(Cfg9346, Cfg9346_Unlock); |
@@ -2143,8 +2892,6 @@ static void rtl_hw_start_8101(struct net_device *dev) | |||
2143 | 2892 | ||
2144 | RTL_R8(IntrMask); | 2893 | RTL_R8(IntrMask); |
2145 | 2894 | ||
2146 | RTL_W32(RxMissed, 0); | ||
2147 | |||
2148 | rtl_set_rx_mode(dev); | 2895 | rtl_set_rx_mode(dev); |
2149 | 2896 | ||
2150 | RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); | 2897 | RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); |
@@ -2922,6 +3669,17 @@ static int rtl8169_poll(struct napi_struct *napi, int budget) | |||
2922 | return work_done; | 3669 | return work_done; |
2923 | } | 3670 | } |
2924 | 3671 | ||
3672 | static void rtl8169_rx_missed(struct net_device *dev, void __iomem *ioaddr) | ||
3673 | { | ||
3674 | struct rtl8169_private *tp = netdev_priv(dev); | ||
3675 | |||
3676 | if (tp->mac_version > RTL_GIGA_MAC_VER_06) | ||
3677 | return; | ||
3678 | |||
3679 | dev->stats.rx_missed_errors += (RTL_R32(RxMissed) & 0xffffff); | ||
3680 | RTL_W32(RxMissed, 0); | ||
3681 | } | ||
3682 | |||
2925 | static void rtl8169_down(struct net_device *dev) | 3683 | static void rtl8169_down(struct net_device *dev) |
2926 | { | 3684 | { |
2927 | struct rtl8169_private *tp = netdev_priv(dev); | 3685 | struct rtl8169_private *tp = netdev_priv(dev); |
@@ -2939,9 +3697,7 @@ core_down: | |||
2939 | 3697 | ||
2940 | rtl8169_asic_down(ioaddr); | 3698 | rtl8169_asic_down(ioaddr); |
2941 | 3699 | ||
2942 | /* Update the error counts. */ | 3700 | rtl8169_rx_missed(dev, ioaddr); |
2943 | dev->stats.rx_missed_errors += RTL_R32(RxMissed); | ||
2944 | RTL_W32(RxMissed, 0); | ||
2945 | 3701 | ||
2946 | spin_unlock_irq(&tp->lock); | 3702 | spin_unlock_irq(&tp->lock); |
2947 | 3703 | ||
@@ -3063,8 +3819,7 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev) | |||
3063 | 3819 | ||
3064 | if (netif_running(dev)) { | 3820 | if (netif_running(dev)) { |
3065 | spin_lock_irqsave(&tp->lock, flags); | 3821 | spin_lock_irqsave(&tp->lock, flags); |
3066 | dev->stats.rx_missed_errors += RTL_R32(RxMissed); | 3822 | rtl8169_rx_missed(dev, ioaddr); |
3067 | RTL_W32(RxMissed, 0); | ||
3068 | spin_unlock_irqrestore(&tp->lock, flags); | 3823 | spin_unlock_irqrestore(&tp->lock, flags); |
3069 | } | 3824 | } |
3070 | 3825 | ||
@@ -3089,8 +3844,7 @@ static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state) | |||
3089 | 3844 | ||
3090 | rtl8169_asic_down(ioaddr); | 3845 | rtl8169_asic_down(ioaddr); |
3091 | 3846 | ||
3092 | dev->stats.rx_missed_errors += RTL_R32(RxMissed); | 3847 | rtl8169_rx_missed(dev, ioaddr); |
3093 | RTL_W32(RxMissed, 0); | ||
3094 | 3848 | ||
3095 | spin_unlock_irq(&tp->lock); | 3849 | spin_unlock_irq(&tp->lock); |
3096 | 3850 | ||
@@ -3121,6 +3875,11 @@ out: | |||
3121 | return 0; | 3875 | return 0; |
3122 | } | 3876 | } |
3123 | 3877 | ||
3878 | static void rtl_shutdown(struct pci_dev *pdev) | ||
3879 | { | ||
3880 | rtl8169_suspend(pdev, PMSG_SUSPEND); | ||
3881 | } | ||
3882 | |||
3124 | #endif /* CONFIG_PM */ | 3883 | #endif /* CONFIG_PM */ |
3125 | 3884 | ||
3126 | static struct pci_driver rtl8169_pci_driver = { | 3885 | static struct pci_driver rtl8169_pci_driver = { |
@@ -3131,6 +3890,7 @@ static struct pci_driver rtl8169_pci_driver = { | |||
3131 | #ifdef CONFIG_PM | 3890 | #ifdef CONFIG_PM |
3132 | .suspend = rtl8169_suspend, | 3891 | .suspend = rtl8169_suspend, |
3133 | .resume = rtl8169_resume, | 3892 | .resume = rtl8169_resume, |
3893 | .shutdown = rtl_shutdown, | ||
3134 | #endif | 3894 | #endif |
3135 | }; | 3895 | }; |
3136 | 3896 | ||