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 | |
| 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>
| -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, |
