aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/r8169.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/r8169.c')
-rw-r--r--drivers/net/r8169.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 0ec47f463157..a73dd287fdba 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -278,6 +278,18 @@ enum rtl8168_8101_registers {
278}; 278};
279 279
280enum rtl8168_registers { 280enum rtl8168_registers {
281 ERIDR = 0x70,
282 ERIAR = 0x74,
283#define ERIAR_FLAG 0x80000000
284#define ERIAR_WRITE_CMD 0x80000000
285#define ERIAR_READ_CMD 0x00000000
286#define ERIAR_ADDR_BYTE_ALIGN 4
287#define ERIAR_EXGMAC 0
288#define ERIAR_MSIX 1
289#define ERIAR_ASF 2
290#define ERIAR_TYPE_SHIFT 16
291#define ERIAR_BYTEEN 0x0f
292#define ERIAR_BYTEEN_SHIFT 12
281 EPHY_RXER_NUM = 0x7c, 293 EPHY_RXER_NUM = 0x7c,
282 OCPDR = 0xb0, /* OCP GPHY access */ 294 OCPDR = 0xb0, /* OCP GPHY access */
283#define OCPDR_WRITE_CMD 0x80000000 295#define OCPDR_WRITE_CMD 0x80000000
@@ -572,6 +584,81 @@ static int rtl8169_poll(struct napi_struct *napi, int budget);
572static const unsigned int rtl8169_rx_config = 584static const unsigned int rtl8169_rx_config =
573 (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); 585 (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
574 586
587static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg)
588{
589 void __iomem *ioaddr = tp->mmio_addr;
590 int i;
591
592 RTL_W32(OCPAR, ((u32)mask & 0x0f) << 12 | (reg & 0x0fff));
593 for (i = 0; i < 20; i++) {
594 udelay(100);
595 if (RTL_R32(OCPAR) & OCPAR_FLAG)
596 break;
597 }
598 return RTL_R32(OCPDR);
599}
600
601static void ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg, u32 data)
602{
603 void __iomem *ioaddr = tp->mmio_addr;
604 int i;
605
606 RTL_W32(OCPDR, data);
607 RTL_W32(OCPAR, OCPAR_FLAG | ((u32)mask & 0x0f) << 12 | (reg & 0x0fff));
608 for (i = 0; i < 20; i++) {
609 udelay(100);
610 if ((RTL_R32(OCPAR) & OCPAR_FLAG) == 0)
611 break;
612 }
613}
614
615static void rtl8168_oob_notify(void __iomem *ioaddr, u8 cmd)
616{
617 int i;
618
619 RTL_W8(ERIDR, cmd);
620 RTL_W32(ERIAR, 0x800010e8);
621 msleep(2);
622 for (i = 0; i < 5; i++) {
623 udelay(100);
624 if (!(RTL_R32(ERIDR) & ERIAR_FLAG))
625 break;
626 }
627
628 ocp_write(ioaddr, 0x1, 0x30, 0x00000001);
629}
630
631#define OOB_CMD_RESET 0x00
632#define OOB_CMD_DRIVER_START 0x05
633#define OOB_CMD_DRIVER_STOP 0x06
634
635static void rtl8168_driver_start(struct rtl8169_private *tp)
636{
637 int i;
638
639 rtl8168_oob_notify(tp, OOB_CMD_DRIVER_START);
640
641 for (i = 0; i < 10; i++) {
642 msleep(10);
643 if (ocp_read(tp, 0x0f, 0x0010) & 0x00000800)
644 break;
645 }
646}
647
648static void rtl8168_driver_stop(struct rtl8169_private *tp)
649{
650 int i;
651
652 rtl8168_oob_notify(tp, OOB_CMD_DRIVER_STOP);
653
654 for (i = 0; i < 10; i++) {
655 msleep(10);
656 if ((ocp_read(tp, 0x0f, 0x0010) & 0x00000800) == 0)
657 break;
658 }
659}
660
661
575static void r8169_mdio_write(void __iomem *ioaddr, int reg_addr, int value) 662static void r8169_mdio_write(void __iomem *ioaddr, int reg_addr, int value)
576{ 663{
577 int i; 664 int i;
@@ -2913,6 +3000,9 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
2913 dev->base_addr, dev->dev_addr, 3000 dev->base_addr, dev->dev_addr,
2914 (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), dev->irq); 3001 (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), dev->irq);
2915 3002
3003 if (tp->mac_version == RTL_GIGA_MAC_VER_27)
3004 rtl8168_driver_start(tp);
3005
2916 rtl8169_init_phy(dev, tp); 3006 rtl8169_init_phy(dev, tp);
2917 3007
2918 /* 3008 /*
@@ -2948,6 +3038,9 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
2948 struct net_device *dev = pci_get_drvdata(pdev); 3038 struct net_device *dev = pci_get_drvdata(pdev);
2949 struct rtl8169_private *tp = netdev_priv(dev); 3039 struct rtl8169_private *tp = netdev_priv(dev);
2950 3040
3041 if (tp->mac_version == RTL_GIGA_MAC_VER_27)
3042 rtl8168_driver_stop(tp);
3043
2951 cancel_delayed_work_sync(&tp->task); 3044 cancel_delayed_work_sync(&tp->task);
2952 3045
2953 unregister_netdev(dev); 3046 unregister_netdev(dev);