diff options
author | françois romieu <romieu@fr.zoreil.com> | 2011-01-03 10:08:04 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-01-04 12:48:33 -0500 |
commit | c0e45c1ca3162acb2e77b3d9e152ce6e7b6fa3f5 (patch) | |
tree | be0c00584b165811d983920dcde77dce069e2ba9 /drivers/net/r8169.c | |
parent | 4da19633429f67c794b013488348550f457298c4 (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.c | 83 |
1 files changed, 81 insertions, 2 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index b5ced5ebb60e..3a63363e47cc 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 | ||
280 | enum 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 | |||
280 | enum rtl_register_content { | 294 | enum 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 | ||
618 | static 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 | |||
634 | static 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 | |||
640 | static 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 | |||
598 | static void rtl_writephy(struct rtl8169_private *tp, int location, u32 val) | 659 | static 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 | ||
603 | static int rtl_readphy(struct rtl8169_private *tp, int location) | 664 | static 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 | ||
608 | static void rtl_patchphy(struct rtl8169_private *tp, int reg_addr, int value) | 669 | static 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 | ||
2538 | static 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 | |||
2477 | static int __devinit | 2554 | static int __devinit |
2478 | rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 2555 | rtl8169_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, |