diff options
author | françois romieu <romieu@fr.zoreil.com> | 2011-01-03 10:08:37 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-01-04 12:48:35 -0500 |
commit | e6de30d63eb17c5cbb7affdfc71df95286bfa7d9 (patch) | |
tree | f1f143415b7262d4321b2234c2127128ceac5a18 /drivers/net/r8169.c | |
parent | 650e8d5d1fdd5e55869136e2df54287a4432d87f (diff) |
r8169: more 8168dp support.
Adapted from version 8.019.00 of Realtek's r8168 driver
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Hayes <hayeswang@realtek.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/r8169.c')
-rw-r--r-- | drivers/net/r8169.c | 145 |
1 files changed, 136 insertions, 9 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index a468ee98ab9e..27a7c20f64cd 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -121,7 +121,8 @@ enum mac_version { | |||
121 | RTL_GIGA_MAC_VER_24 = 0x18, // 8168CP | 121 | RTL_GIGA_MAC_VER_24 = 0x18, // 8168CP |
122 | RTL_GIGA_MAC_VER_25 = 0x19, // 8168D | 122 | RTL_GIGA_MAC_VER_25 = 0x19, // 8168D |
123 | RTL_GIGA_MAC_VER_26 = 0x1a, // 8168D | 123 | RTL_GIGA_MAC_VER_26 = 0x1a, // 8168D |
124 | RTL_GIGA_MAC_VER_27 = 0x1b // 8168DP | 124 | RTL_GIGA_MAC_VER_27 = 0x1b, // 8168DP |
125 | RTL_GIGA_MAC_VER_28 = 0x1c, // 8168DP | ||
125 | }; | 126 | }; |
126 | 127 | ||
127 | #define _R(NAME,MAC,MASK) \ | 128 | #define _R(NAME,MAC,MASK) \ |
@@ -158,7 +159,8 @@ static const struct { | |||
158 | _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_24, 0xff7e1880), // PCI-E | 159 | _R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_24, 0xff7e1880), // PCI-E |
159 | _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_25, 0xff7e1880), // PCI-E | 160 | _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_25, 0xff7e1880), // PCI-E |
160 | _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_26, 0xff7e1880), // PCI-E | 161 | _R("RTL8168d/8111d", RTL_GIGA_MAC_VER_26, 0xff7e1880), // PCI-E |
161 | _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_27, 0xff7e1880) // PCI-E | 162 | _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_27, 0xff7e1880), // PCI-E |
163 | _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_28, 0xff7e1880) // PCI-E | ||
162 | }; | 164 | }; |
163 | #undef _R | 165 | #undef _R |
164 | 166 | ||
@@ -301,6 +303,7 @@ enum rtl8168_registers { | |||
301 | #define OCPAR_FLAG 0x80000000 | 303 | #define OCPAR_FLAG 0x80000000 |
302 | #define OCPAR_GPHY_WRITE_CMD 0x8000f060 | 304 | #define OCPAR_GPHY_WRITE_CMD 0x8000f060 |
303 | #define OCPAR_GPHY_READ_CMD 0x0000f060 | 305 | #define OCPAR_GPHY_READ_CMD 0x0000f060 |
306 | RDSAR1 = 0xd0 /* 8168c only. Undocumented on 8168dp */ | ||
304 | }; | 307 | }; |
305 | 308 | ||
306 | enum rtl_register_content { | 309 | enum rtl_register_content { |
@@ -748,6 +751,40 @@ static int r8168dp_1_mdio_read(void __iomem *ioaddr, int reg_addr) | |||
748 | return RTL_R32(OCPDR) & OCPDR_DATA_MASK; | 751 | return RTL_R32(OCPDR) & OCPDR_DATA_MASK; |
749 | } | 752 | } |
750 | 753 | ||
754 | #define R8168DP_1_MDIO_ACCESS_BIT 0x00020000 | ||
755 | |||
756 | static void r8168dp_2_mdio_start(void __iomem *ioaddr) | ||
757 | { | ||
758 | RTL_W32(0xd0, RTL_R32(0xd0) & ~R8168DP_1_MDIO_ACCESS_BIT); | ||
759 | } | ||
760 | |||
761 | static void r8168dp_2_mdio_stop(void __iomem *ioaddr) | ||
762 | { | ||
763 | RTL_W32(0xd0, RTL_R32(0xd0) | R8168DP_1_MDIO_ACCESS_BIT); | ||
764 | } | ||
765 | |||
766 | static void r8168dp_2_mdio_write(void __iomem *ioaddr, int reg_addr, int value) | ||
767 | { | ||
768 | r8168dp_2_mdio_start(ioaddr); | ||
769 | |||
770 | r8169_mdio_write(ioaddr, reg_addr, value); | ||
771 | |||
772 | r8168dp_2_mdio_stop(ioaddr); | ||
773 | } | ||
774 | |||
775 | static int r8168dp_2_mdio_read(void __iomem *ioaddr, int reg_addr) | ||
776 | { | ||
777 | int value; | ||
778 | |||
779 | r8168dp_2_mdio_start(ioaddr); | ||
780 | |||
781 | value = r8169_mdio_read(ioaddr, reg_addr); | ||
782 | |||
783 | r8168dp_2_mdio_stop(ioaddr); | ||
784 | |||
785 | return value; | ||
786 | } | ||
787 | |||
751 | static void rtl_writephy(struct rtl8169_private *tp, int location, u32 val) | 788 | static void rtl_writephy(struct rtl8169_private *tp, int location, u32 val) |
752 | { | 789 | { |
753 | tp->mdio_ops.write(tp->mmio_addr, location, val); | 790 | tp->mdio_ops.write(tp->mmio_addr, location, val); |
@@ -1495,9 +1532,12 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, | |||
1495 | /* 8168D family. */ | 1532 | /* 8168D family. */ |
1496 | { 0x7cf00000, 0x28300000, RTL_GIGA_MAC_VER_26 }, | 1533 | { 0x7cf00000, 0x28300000, RTL_GIGA_MAC_VER_26 }, |
1497 | { 0x7cf00000, 0x28100000, RTL_GIGA_MAC_VER_25 }, | 1534 | { 0x7cf00000, 0x28100000, RTL_GIGA_MAC_VER_25 }, |
1498 | { 0x7c800000, 0x28800000, RTL_GIGA_MAC_VER_27 }, | ||
1499 | { 0x7c800000, 0x28000000, RTL_GIGA_MAC_VER_26 }, | 1535 | { 0x7c800000, 0x28000000, RTL_GIGA_MAC_VER_26 }, |
1500 | 1536 | ||
1537 | /* 8168DP family. */ | ||
1538 | { 0x7cf00000, 0x28800000, RTL_GIGA_MAC_VER_27 }, | ||
1539 | { 0x7cf00000, 0x28a00000, RTL_GIGA_MAC_VER_28 }, | ||
1540 | |||
1501 | /* 8168C family. */ | 1541 | /* 8168C family. */ |
1502 | { 0x7cf00000, 0x3cb00000, RTL_GIGA_MAC_VER_24 }, | 1542 | { 0x7cf00000, 0x3cb00000, RTL_GIGA_MAC_VER_24 }, |
1503 | { 0x7cf00000, 0x3c900000, RTL_GIGA_MAC_VER_23 }, | 1543 | { 0x7cf00000, 0x3c900000, RTL_GIGA_MAC_VER_23 }, |
@@ -2246,6 +2286,22 @@ static void rtl8168d_3_hw_phy_config(struct rtl8169_private *tp) | |||
2246 | rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); | 2286 | rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); |
2247 | } | 2287 | } |
2248 | 2288 | ||
2289 | static void rtl8168d_4_hw_phy_config(struct rtl8169_private *tp) | ||
2290 | { | ||
2291 | static const struct phy_reg phy_reg_init[] = { | ||
2292 | { 0x1f, 0x0001 }, | ||
2293 | { 0x17, 0x0cc0 }, | ||
2294 | |||
2295 | { 0x1f, 0x0007 }, | ||
2296 | { 0x1e, 0x002d }, | ||
2297 | { 0x18, 0x0040 }, | ||
2298 | { 0x1f, 0x0000 } | ||
2299 | }; | ||
2300 | |||
2301 | rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); | ||
2302 | rtl_patchphy(tp, 0x0d, 1 << 5); | ||
2303 | } | ||
2304 | |||
2249 | static void rtl8102e_hw_phy_config(struct rtl8169_private *tp) | 2305 | static void rtl8102e_hw_phy_config(struct rtl8169_private *tp) |
2250 | { | 2306 | { |
2251 | static const struct phy_reg phy_reg_init[] = { | 2307 | static const struct phy_reg phy_reg_init[] = { |
@@ -2327,6 +2383,9 @@ static void rtl_hw_phy_config(struct net_device *dev) | |||
2327 | case RTL_GIGA_MAC_VER_27: | 2383 | case RTL_GIGA_MAC_VER_27: |
2328 | rtl8168d_3_hw_phy_config(tp); | 2384 | rtl8168d_3_hw_phy_config(tp); |
2329 | break; | 2385 | break; |
2386 | case RTL_GIGA_MAC_VER_28: | ||
2387 | rtl8168d_4_hw_phy_config(tp); | ||
2388 | break; | ||
2330 | 2389 | ||
2331 | default: | 2390 | default: |
2332 | break; | 2391 | break; |
@@ -2636,6 +2695,10 @@ static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp) | |||
2636 | ops->write = r8168dp_1_mdio_write; | 2695 | ops->write = r8168dp_1_mdio_write; |
2637 | ops->read = r8168dp_1_mdio_read; | 2696 | ops->read = r8168dp_1_mdio_read; |
2638 | break; | 2697 | break; |
2698 | case RTL_GIGA_MAC_VER_28: | ||
2699 | ops->write = r8168dp_2_mdio_write; | ||
2700 | ops->read = r8168dp_2_mdio_read; | ||
2701 | break; | ||
2639 | default: | 2702 | default: |
2640 | ops->write = r8169_mdio_write; | 2703 | ops->write = r8169_mdio_write; |
2641 | ops->read = r8169_mdio_read; | 2704 | ops->read = r8169_mdio_read; |
@@ -2778,6 +2841,7 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) | |||
2778 | case RTL_GIGA_MAC_VER_25: | 2841 | case RTL_GIGA_MAC_VER_25: |
2779 | case RTL_GIGA_MAC_VER_26: | 2842 | case RTL_GIGA_MAC_VER_26: |
2780 | case RTL_GIGA_MAC_VER_27: | 2843 | case RTL_GIGA_MAC_VER_27: |
2844 | case RTL_GIGA_MAC_VER_28: | ||
2781 | ops->down = r8168_pll_power_down; | 2845 | ops->down = r8168_pll_power_down; |
2782 | ops->up = r8168_pll_power_up; | 2846 | ops->up = r8168_pll_power_up; |
2783 | break; | 2847 | break; |
@@ -3000,8 +3064,10 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3000 | dev->base_addr, dev->dev_addr, | 3064 | dev->base_addr, dev->dev_addr, |
3001 | (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), dev->irq); | 3065 | (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), dev->irq); |
3002 | 3066 | ||
3003 | if (tp->mac_version == RTL_GIGA_MAC_VER_27) | 3067 | if ((tp->mac_version == RTL_GIGA_MAC_VER_27) || |
3068 | (tp->mac_version == RTL_GIGA_MAC_VER_28)) { | ||
3004 | rtl8168_driver_start(tp); | 3069 | rtl8168_driver_start(tp); |
3070 | } | ||
3005 | 3071 | ||
3006 | rtl8169_init_phy(dev, tp); | 3072 | rtl8169_init_phy(dev, tp); |
3007 | 3073 | ||
@@ -3038,8 +3104,10 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) | |||
3038 | struct net_device *dev = pci_get_drvdata(pdev); | 3104 | struct net_device *dev = pci_get_drvdata(pdev); |
3039 | struct rtl8169_private *tp = netdev_priv(dev); | 3105 | struct rtl8169_private *tp = netdev_priv(dev); |
3040 | 3106 | ||
3041 | if (tp->mac_version == RTL_GIGA_MAC_VER_27) | 3107 | if ((tp->mac_version == RTL_GIGA_MAC_VER_27) || |
3108 | (tp->mac_version == RTL_GIGA_MAC_VER_28)) { | ||
3042 | rtl8168_driver_stop(tp); | 3109 | rtl8168_driver_stop(tp); |
3110 | } | ||
3043 | 3111 | ||
3044 | cancel_delayed_work_sync(&tp->task); | 3112 | cancel_delayed_work_sync(&tp->task); |
3045 | 3113 | ||
@@ -3122,11 +3190,19 @@ err_pm_runtime_put: | |||
3122 | goto out; | 3190 | goto out; |
3123 | } | 3191 | } |
3124 | 3192 | ||
3125 | static void rtl8169_hw_reset(void __iomem *ioaddr) | 3193 | static void rtl8169_hw_reset(struct rtl8169_private *tp) |
3126 | { | 3194 | { |
3195 | void __iomem *ioaddr = tp->mmio_addr; | ||
3196 | |||
3127 | /* Disable interrupts */ | 3197 | /* Disable interrupts */ |
3128 | rtl8169_irq_mask_and_ack(ioaddr); | 3198 | rtl8169_irq_mask_and_ack(ioaddr); |
3129 | 3199 | ||
3200 | if (tp->mac_version == RTL_GIGA_MAC_VER_28) { | ||
3201 | while (RTL_R8(TxPoll) & NPQ) | ||
3202 | udelay(20); | ||
3203 | |||
3204 | } | ||
3205 | |||
3130 | /* Reset the chipset */ | 3206 | /* Reset the chipset */ |
3131 | RTL_W8(ChipCmd, CmdReset); | 3207 | RTL_W8(ChipCmd, CmdReset); |
3132 | 3208 | ||
@@ -3318,6 +3394,11 @@ static void rtl_csi_access_enable(void __iomem *ioaddr, u32 bits) | |||
3318 | rtl_csi_write(ioaddr, 0x070c, csi | bits); | 3394 | rtl_csi_write(ioaddr, 0x070c, csi | bits); |
3319 | } | 3395 | } |
3320 | 3396 | ||
3397 | static void rtl_csi_access_enable_1(void __iomem *ioaddr) | ||
3398 | { | ||
3399 | rtl_csi_access_enable(ioaddr, 0x17000000); | ||
3400 | } | ||
3401 | |||
3321 | static void rtl_csi_access_enable_2(void __iomem *ioaddr) | 3402 | static void rtl_csi_access_enable_2(void __iomem *ioaddr) |
3322 | { | 3403 | { |
3323 | rtl_csi_access_enable(ioaddr, 0x27000000); | 3404 | rtl_csi_access_enable(ioaddr, 0x27000000); |
@@ -3355,6 +3436,21 @@ static void rtl_disable_clock_request(struct pci_dev *pdev) | |||
3355 | } | 3436 | } |
3356 | } | 3437 | } |
3357 | 3438 | ||
3439 | static void rtl_enable_clock_request(struct pci_dev *pdev) | ||
3440 | { | ||
3441 | struct net_device *dev = pci_get_drvdata(pdev); | ||
3442 | struct rtl8169_private *tp = netdev_priv(dev); | ||
3443 | int cap = tp->pcie_cap; | ||
3444 | |||
3445 | if (cap) { | ||
3446 | u16 ctl; | ||
3447 | |||
3448 | pci_read_config_word(pdev, cap + PCI_EXP_LNKCTL, &ctl); | ||
3449 | ctl |= PCI_EXP_LNKCTL_CLKREQ_EN; | ||
3450 | pci_write_config_word(pdev, cap + PCI_EXP_LNKCTL, ctl); | ||
3451 | } | ||
3452 | } | ||
3453 | |||
3358 | #define R8168_CPCMD_QUIRK_MASK (\ | 3454 | #define R8168_CPCMD_QUIRK_MASK (\ |
3359 | EnableBist | \ | 3455 | EnableBist | \ |
3360 | Mac_dbgo_oe | \ | 3456 | Mac_dbgo_oe | \ |
@@ -3498,6 +3594,32 @@ static void rtl_hw_start_8168d(void __iomem *ioaddr, struct pci_dev *pdev) | |||
3498 | RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); | 3594 | RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); |
3499 | } | 3595 | } |
3500 | 3596 | ||
3597 | static void rtl_hw_start_8168d_4(void __iomem *ioaddr, struct pci_dev *pdev) | ||
3598 | { | ||
3599 | static const struct ephy_info e_info_8168d_4[] = { | ||
3600 | { 0x0b, ~0, 0x48 }, | ||
3601 | { 0x19, 0x20, 0x50 }, | ||
3602 | { 0x0c, ~0, 0x20 } | ||
3603 | }; | ||
3604 | int i; | ||
3605 | |||
3606 | rtl_csi_access_enable_1(ioaddr); | ||
3607 | |||
3608 | rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); | ||
3609 | |||
3610 | RTL_W8(MaxTxPacketSize, TxPacketMax); | ||
3611 | |||
3612 | for (i = 0; i < ARRAY_SIZE(e_info_8168d_4); i++) { | ||
3613 | const struct ephy_info *e = e_info_8168d_4 + i; | ||
3614 | u16 w; | ||
3615 | |||
3616 | w = rtl_ephy_read(ioaddr, e->offset); | ||
3617 | rtl_ephy_write(ioaddr, 0x03, (w & e->mask) | e->bits); | ||
3618 | } | ||
3619 | |||
3620 | rtl_enable_clock_request(pdev); | ||
3621 | } | ||
3622 | |||
3501 | static void rtl_hw_start_8168(struct net_device *dev) | 3623 | static void rtl_hw_start_8168(struct net_device *dev) |
3502 | { | 3624 | { |
3503 | struct rtl8169_private *tp = netdev_priv(dev); | 3625 | struct rtl8169_private *tp = netdev_priv(dev); |
@@ -3575,6 +3697,10 @@ static void rtl_hw_start_8168(struct net_device *dev) | |||
3575 | rtl_hw_start_8168d(ioaddr, pdev); | 3697 | rtl_hw_start_8168d(ioaddr, pdev); |
3576 | break; | 3698 | break; |
3577 | 3699 | ||
3700 | case RTL_GIGA_MAC_VER_28: | ||
3701 | rtl_hw_start_8168d_4(ioaddr, pdev); | ||
3702 | break; | ||
3703 | |||
3578 | default: | 3704 | default: |
3579 | printk(KERN_ERR PFX "%s: unknown chipset (mac_version = %d).\n", | 3705 | printk(KERN_ERR PFX "%s: unknown chipset (mac_version = %d).\n", |
3580 | dev->name, tp->mac_version); | 3706 | dev->name, tp->mac_version); |
@@ -3987,7 +4113,7 @@ static void rtl8169_tx_timeout(struct net_device *dev) | |||
3987 | { | 4113 | { |
3988 | struct rtl8169_private *tp = netdev_priv(dev); | 4114 | struct rtl8169_private *tp = netdev_priv(dev); |
3989 | 4115 | ||
3990 | rtl8169_hw_reset(tp->mmio_addr); | 4116 | rtl8169_hw_reset(tp); |
3991 | 4117 | ||
3992 | /* Let's wait a bit while any (async) irq lands on */ | 4118 | /* Let's wait a bit while any (async) irq lands on */ |
3993 | rtl8169_schedule_work(dev, rtl8169_reset_task); | 4119 | rtl8169_schedule_work(dev, rtl8169_reset_task); |
@@ -4145,7 +4271,6 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) | |||
4145 | { | 4271 | { |
4146 | struct rtl8169_private *tp = netdev_priv(dev); | 4272 | struct rtl8169_private *tp = netdev_priv(dev); |
4147 | struct pci_dev *pdev = tp->pci_dev; | 4273 | struct pci_dev *pdev = tp->pci_dev; |
4148 | void __iomem *ioaddr = tp->mmio_addr; | ||
4149 | u16 pci_status, pci_cmd; | 4274 | u16 pci_status, pci_cmd; |
4150 | 4275 | ||
4151 | pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); | 4276 | pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); |
@@ -4176,13 +4301,15 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) | |||
4176 | 4301 | ||
4177 | /* The infamous DAC f*ckup only happens at boot time */ | 4302 | /* The infamous DAC f*ckup only happens at boot time */ |
4178 | if ((tp->cp_cmd & PCIDAC) && !tp->dirty_rx && !tp->cur_rx) { | 4303 | if ((tp->cp_cmd & PCIDAC) && !tp->dirty_rx && !tp->cur_rx) { |
4304 | void __iomem *ioaddr = tp->mmio_addr; | ||
4305 | |||
4179 | netif_info(tp, intr, dev, "disabling PCI DAC\n"); | 4306 | netif_info(tp, intr, dev, "disabling PCI DAC\n"); |
4180 | tp->cp_cmd &= ~PCIDAC; | 4307 | tp->cp_cmd &= ~PCIDAC; |
4181 | RTL_W16(CPlusCmd, tp->cp_cmd); | 4308 | RTL_W16(CPlusCmd, tp->cp_cmd); |
4182 | dev->features &= ~NETIF_F_HIGHDMA; | 4309 | dev->features &= ~NETIF_F_HIGHDMA; |
4183 | } | 4310 | } |
4184 | 4311 | ||
4185 | rtl8169_hw_reset(ioaddr); | 4312 | rtl8169_hw_reset(tp); |
4186 | 4313 | ||
4187 | rtl8169_schedule_work(dev, rtl8169_reinit_task); | 4314 | rtl8169_schedule_work(dev, rtl8169_reinit_task); |
4188 | } | 4315 | } |