aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/r8169.c
diff options
context:
space:
mode:
authorfrançois romieu <romieu@fr.zoreil.com>2011-01-03 10:08:04 -0500
committerDavid S. Miller <davem@davemloft.net>2011-01-04 12:48:33 -0500
commitc0e45c1ca3162acb2e77b3d9e152ce6e7b6fa3f5 (patch)
treebe0c00584b165811d983920dcde77dce069e2ba9 /drivers/net/r8169.c
parent4da19633429f67c794b013488348550f457298c4 (diff)
r8169: 8168DP specific MII registers access methods.
Adapted from version 8.019.00 of Realtek's r8168 driver and amended per Hayes Wang's correction : - OCPDR_GPHY_REG_SHIFT must be 16, not 12 - the reg should be at bit 16 ~ 22, whence OCPDR_REG_MASK 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.c83
1 files changed, 81 insertions, 2 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index b5ced5ebb60..3a63363e47c 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -277,6 +277,20 @@ enum rtl8168_8101_registers {
277#define EFUSEAR_DATA_MASK 0xff 277#define EFUSEAR_DATA_MASK 0xff
278}; 278};
279 279
280enum rtl8168_registers {
281 EPHY_RXER_NUM = 0x7c,
282 OCPDR = 0xb0, /* OCP GPHY access */
283#define OCPDR_WRITE_CMD 0x80000000
284#define OCPDR_READ_CMD 0x00000000
285#define OCPDR_REG_MASK 0x7f
286#define OCPDR_GPHY_REG_SHIFT 16
287#define OCPDR_DATA_MASK 0xffff
288 OCPAR = 0xb4,
289#define OCPAR_FLAG 0x80000000
290#define OCPAR_GPHY_WRITE_CMD 0x8000f060
291#define OCPAR_GPHY_READ_CMD 0x0000f060
292};
293
280enum rtl_register_content { 294enum rtl_register_content {
281 /* InterruptStatusBits */ 295 /* InterruptStatusBits */
282 SYSErr = 0x8000, 296 SYSErr = 0x8000,
@@ -500,6 +514,12 @@ struct rtl8169_private {
500#ifdef CONFIG_R8169_VLAN 514#ifdef CONFIG_R8169_VLAN
501 struct vlan_group *vlgrp; 515 struct vlan_group *vlgrp;
502#endif 516#endif
517
518 struct mdio_ops {
519 void (*write)(void __iomem *, int, int);
520 int (*read)(void __iomem *, int);
521 } mdio_ops;
522
503 int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex); 523 int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex);
504 int (*get_settings)(struct net_device *, struct ethtool_cmd *); 524 int (*get_settings)(struct net_device *, struct ethtool_cmd *);
505 void (*phy_reset_enable)(struct rtl8169_private *tp); 525 void (*phy_reset_enable)(struct rtl8169_private *tp);
@@ -595,14 +615,55 @@ static int r8169_mdio_read(void __iomem *ioaddr, int reg_addr)
595 return value; 615 return value;
596} 616}
597 617
618static void r8168dp_1_mdio_access(void __iomem *ioaddr, int reg_addr, u32 data)
619{
620 int i;
621
622 RTL_W32(OCPDR, data |
623 ((reg_addr & OCPDR_REG_MASK) << OCPDR_GPHY_REG_SHIFT));
624 RTL_W32(OCPAR, OCPAR_GPHY_WRITE_CMD);
625 RTL_W32(EPHY_RXER_NUM, 0);
626
627 for (i = 0; i < 100; i++) {
628 mdelay(1);
629 if (!(RTL_R32(OCPAR) & OCPAR_FLAG))
630 break;
631 }
632}
633
634static void r8168dp_1_mdio_write(void __iomem *ioaddr, int reg_addr, int value)
635{
636 r8168dp_1_mdio_access(ioaddr, reg_addr, OCPDR_WRITE_CMD |
637 (value & OCPDR_DATA_MASK));
638}
639
640static int r8168dp_1_mdio_read(void __iomem *ioaddr, int reg_addr)
641{
642 int i;
643
644 r8168dp_1_mdio_access(ioaddr, reg_addr, OCPDR_READ_CMD);
645
646 mdelay(1);
647 RTL_W32(OCPAR, OCPAR_GPHY_READ_CMD);
648 RTL_W32(EPHY_RXER_NUM, 0);
649
650 for (i = 0; i < 100; i++) {
651 mdelay(1);
652 if (RTL_R32(OCPAR) & OCPAR_FLAG)
653 break;
654 }
655
656 return RTL_R32(OCPDR) & OCPDR_DATA_MASK;
657}
658
598static void rtl_writephy(struct rtl8169_private *tp, int location, u32 val) 659static void rtl_writephy(struct rtl8169_private *tp, int location, u32 val)
599{ 660{
600 r8169_mdio_write(tp->mmio_addr, location, val); 661 tp->mdio_ops.write(tp->mmio_addr, location, val);
601} 662}
602 663
603static int rtl_readphy(struct rtl8169_private *tp, int location) 664static int rtl_readphy(struct rtl8169_private *tp, int location)
604{ 665{
605 return r8169_mdio_read(tp->mmio_addr, location); 666 return tp->mdio_ops.read(tp->mmio_addr, location);
606} 667}
607 668
608static void rtl_patchphy(struct rtl8169_private *tp, int reg_addr, int value) 669static void rtl_patchphy(struct rtl8169_private *tp, int reg_addr, int value)
@@ -2474,6 +2535,22 @@ static const struct net_device_ops rtl8169_netdev_ops = {
2474 2535
2475}; 2536};
2476 2537
2538static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp)
2539{
2540 struct mdio_ops *ops = &tp->mdio_ops;
2541
2542 switch (tp->mac_version) {
2543 case RTL_GIGA_MAC_VER_27:
2544 ops->write = r8168dp_1_mdio_write;
2545 ops->read = r8168dp_1_mdio_read;
2546 break;
2547 default:
2548 ops->write = r8169_mdio_write;
2549 ops->read = r8169_mdio_read;
2550 break;
2551 }
2552}
2553
2477static int __devinit 2554static int __devinit
2478rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) 2555rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2479{ 2556{
@@ -2592,6 +2669,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2592 /* Identify chip attached to board */ 2669 /* Identify chip attached to board */
2593 rtl8169_get_mac_version(tp, ioaddr); 2670 rtl8169_get_mac_version(tp, ioaddr);
2594 2671
2672 rtl_init_mdio_ops(tp);
2673
2595 /* Use appropriate default if unknown */ 2674 /* Use appropriate default if unknown */
2596 if (tp->mac_version == RTL_GIGA_MAC_NONE) { 2675 if (tp->mac_version == RTL_GIGA_MAC_NONE) {
2597 netif_notice(tp, probe, dev, 2676 netif_notice(tp, probe, dev,