r8169: modify the flow of the hw reset.
[cascardo/linux.git] / drivers / net / r8169.c
index 05d8178..604f946 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
 #include <linux/pm_runtime.h>
 #include <linux/firmware.h>
@@ -69,8 +70,6 @@ static const int multicast_filter_limit = 32;
 #define MAC_ADDR_LEN   6
 
 #define MAX_READ_REQUEST_SHIFT 12
-#define RX_FIFO_THRESH 7       /* 7 means NO threshold, Rx buffer level before first PCI xfer. */
-#define RX_DMA_BURST   6       /* Maximum PCI burst, '6' is 1024 */
 #define TX_DMA_BURST   6       /* Maximum PCI burst, '6' is 1024 */
 #define SafeMtu                0x1c20  /* ... actually life sucks beyond ~7k */
 #define InterFrameGap  0x03    /* 3 means InterFrameGap = the shortest one */
@@ -269,9 +268,20 @@ enum rtl_registers {
        TxPoll          = 0x38,
        IntrMask        = 0x3c,
        IntrStatus      = 0x3e,
+
        TxConfig        = 0x40,
-       RxConfig        = 0x44,
+#define        TXCFG_AUTO_FIFO                 (1 << 7)        /* 8111e-vl */
+#define        TXCFG_EMPTY                     (1 << 11)       /* 8111e-vl */
 
+       RxConfig        = 0x44,
+#define        RX128_INT_EN                    (1 << 15)       /* 8111c and later */
+#define        RX_MULTI_EN                     (1 << 14)       /* 8111c only */
+#define        RXCFG_FIFO_SHIFT                13
+                                       /* No threshold before first PCI xfer */
+#define        RX_FIFO_THRESH                  (7 << RXCFG_FIFO_SHIFT)
+#define        RXCFG_DMA_SHIFT                 8
+                                       /* Unlimited maximum PCI burst. */
+#define        RX_DMA_BURST                    (7 << RXCFG_DMA_SHIFT)
 #define RTL_RX_CONFIG_MASK             0xff7e1880u
 
        RxMissed        = 0x4c,
@@ -326,12 +336,13 @@ enum rtl8168_8101_registers {
 #define        EPHYAR_REG_SHIFT                16
 #define        EPHYAR_DATA_MASK                0xffff
        DLLPR                   = 0xd0,
-#define        PM_SWITCH                       (1 << 6)
+#define        PFM_EN                          (1 << 6)
        DBG_REG                 = 0xd1,
 #define        FIX_NAK_1                       (1 << 4)
 #define        FIX_NAK_2                       (1 << 3)
        TWSI                    = 0xd2,
        MCU                     = 0xd3,
+#define        NOW_IS_OOB                      (1 << 7)
 #define        EN_NDP                          (1 << 3)
 #define        EN_OOB_RESET                    (1 << 2)
        EFUSEAR                 = 0xdc,
@@ -344,18 +355,22 @@ enum rtl8168_8101_registers {
 };
 
 enum rtl8168_registers {
+       LED_FREQ                = 0x1a,
+       EEE_LED                 = 0x1b,
        ERIDR                   = 0x70,
        ERIAR                   = 0x74,
 #define ERIAR_FLAG                     0x80000000
 #define ERIAR_WRITE_CMD                        0x80000000
 #define ERIAR_READ_CMD                 0x00000000
 #define ERIAR_ADDR_BYTE_ALIGN          4
-#define ERIAR_EXGMAC                   0
-#define ERIAR_MSIX                     1
-#define ERIAR_ASF                      2
 #define ERIAR_TYPE_SHIFT               16
-#define ERIAR_BYTEEN                   0x0f
-#define ERIAR_BYTEEN_SHIFT             12
+#define ERIAR_EXGMAC                   (0x00 << ERIAR_TYPE_SHIFT)
+#define ERIAR_MSIX                     (0x01 << ERIAR_TYPE_SHIFT)
+#define ERIAR_ASF                      (0x02 << ERIAR_TYPE_SHIFT)
+#define ERIAR_MASK_SHIFT               12
+#define ERIAR_MASK_0001                        (0x1 << ERIAR_MASK_SHIFT)
+#define ERIAR_MASK_0011                        (0x3 << ERIAR_MASK_SHIFT)
+#define ERIAR_MASK_1111                        (0xf << ERIAR_MASK_SHIFT)
        EPHY_RXER_NUM           = 0x7c,
        OCPDR                   = 0xb0, /* OCP GPHY access */
 #define OCPDR_WRITE_CMD                        0x80000000
@@ -370,6 +385,7 @@ enum rtl8168_registers {
        RDSAR1                  = 0xd0, /* 8168c only. Undocumented on 8168dp */
        MISC                    = 0xf0, /* 8168e only. */
 #define TXPLA_RST                      (1 << 29)
+#define PWM_EN                         (1 << 22)
 };
 
 enum rtl_register_content {
@@ -394,6 +410,7 @@ enum rtl_register_content {
        RxCRC   = (1 << 19),
 
        /* ChipCmdBits */
+       StopReq         = 0x80,
        CmdReset        = 0x10,
        CmdRxEnb        = 0x08,
        CmdTxEnb        = 0x04,
@@ -416,10 +433,6 @@ enum rtl_register_content {
        AcceptMyPhys    = 0x02,
        AcceptAllPhys   = 0x01,
 
-       /* RxConfigBits */
-       RxCfgFIFOShift  = 13,
-       RxCfgDMAShift   =  8,
-
        /* TxConfigBits */
        TxInterFrameGapShift = 24,
        TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
@@ -658,7 +671,6 @@ struct rtl8169_private {
        unsigned int (*phy_reset_pending)(struct rtl8169_private *tp);
        unsigned int (*link_ok)(void __iomem *);
        int (*do_ioctl)(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd);
-       int pcie_cap;
        struct delayed_work task;
        unsigned features;
 
@@ -666,7 +678,18 @@ struct rtl8169_private {
        struct rtl8169_counters counters;
        u32 saved_wolopts;
 
-       const struct firmware *fw;
+       struct rtl_fw {
+               const struct firmware *fw;
+
+#define RTL_VER_SIZE           32
+
+               char version[RTL_VER_SIZE];
+
+               struct rtl_fw_phy_action {
+                       __le32 *code;
+                       size_t size;
+               } phy_action;
+       } *rtl_fw;
 #define RTL_FIRMWARE_UNKNOWN   ERR_PTR(-EAGAIN);
 };
 
@@ -701,8 +724,7 @@ static void rtl8169_down(struct net_device *dev);
 static void rtl8169_rx_clear(struct rtl8169_private *tp);
 static int rtl8169_poll(struct napi_struct *napi, int budget);
 
-static const unsigned int rtl8169_rx_config =
-       (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
+static const unsigned int rtl8169_rx_config = RX_FIFO_THRESH | RX_DMA_BURST;
 
 static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg)
 {
@@ -742,7 +764,7 @@ static void rtl8168_oob_notify(struct rtl8169_private *tp, u8 cmd)
        msleep(2);
        for (i = 0; i < 5; i++) {
                udelay(100);
-               if (!(RTL_R32(ERIDR) & ERIAR_FLAG))
+               if (!(RTL_R32(ERIAR) & ERIAR_FLAG))
                        break;
        }
 
@@ -1049,13 +1071,6 @@ static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
        RTL_W16(IntrStatus, 0xffff);
 }
 
-static void rtl8169_asic_down(void __iomem *ioaddr)
-{
-       RTL_W8(ChipCmd, 0x00);
-       rtl8169_irq_mask_and_ack(ioaddr);
-       RTL_R16(CPlusCmd);
-}
-
 static unsigned int rtl8169_tbi_reset_pending(struct rtl8169_private *tp)
 {
        void __iomem *ioaddr = tp->mmio_addr;
@@ -1221,12 +1236,14 @@ static void rtl8169_get_drvinfo(struct net_device *dev,
                                struct ethtool_drvinfo *info)
 {
        struct rtl8169_private *tp = netdev_priv(dev);
+       struct rtl_fw *rtl_fw = tp->rtl_fw;
 
        strcpy(info->driver, MODULENAME);
        strcpy(info->version, RTL8169_VERSION);
        strcpy(info->bus_info, pci_name(tp->pci_dev));
-       strncpy(info->fw_version, IS_ERR_OR_NULL(tp->fw) ? "N/A" :
-               rtl_lookup_firmware_name(tp), sizeof(info->fw_version) - 1);
+       BUILD_BUG_ON(sizeof(info->fw_version) < sizeof(rtl_fw->version));
+       strcpy(info->fw_version, IS_ERR_OR_NULL(rtl_fw) ? "N/A" :
+              rtl_fw->version);
 }
 
 static int rtl8169_get_regs_len(struct net_device *dev)
@@ -1741,21 +1758,75 @@ static void rtl_writephy_batch(struct rtl8169_private *tp,
 #define PHY_DELAY_MS           0xe0000000
 #define PHY_WRITE_ERI_WORD     0xf0000000
 
-static void
-rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)
+struct fw_info {
+       u32     magic;
+       char    version[RTL_VER_SIZE];
+       __le32  fw_start;
+       __le32  fw_len;
+       u8      chksum;
+} __packed;
+
+#define FW_OPCODE_SIZE sizeof(typeof(*((struct rtl_fw_phy_action *)0)->code))
+
+static bool rtl_fw_format_ok(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
 {
-       __le32 *phytable = (__le32 *)fw->data;
-       struct net_device *dev = tp->dev;
-       size_t index, fw_size = fw->size / sizeof(*phytable);
-       u32 predata, count;
+       const struct firmware *fw = rtl_fw->fw;
+       struct fw_info *fw_info = (struct fw_info *)fw->data;
+       struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
+       char *version = rtl_fw->version;
+       bool rc = false;
 
-       if (fw->size % sizeof(*phytable)) {
-               netif_err(tp, probe, dev, "odd sized firmware %zd\n", fw->size);
-               return;
+       if (fw->size < FW_OPCODE_SIZE)
+               goto out;
+
+       if (!fw_info->magic) {
+               size_t i, size, start;
+               u8 checksum = 0;
+
+               if (fw->size < sizeof(*fw_info))
+                       goto out;
+
+               for (i = 0; i < fw->size; i++)
+                       checksum += fw->data[i];
+               if (checksum != 0)
+                       goto out;
+
+               start = le32_to_cpu(fw_info->fw_start);
+               if (start > fw->size)
+                       goto out;
+
+               size = le32_to_cpu(fw_info->fw_len);
+               if (size > (fw->size - start) / FW_OPCODE_SIZE)
+                       goto out;
+
+               memcpy(version, fw_info->version, RTL_VER_SIZE);
+
+               pa->code = (__le32 *)(fw->data + start);
+               pa->size = size;
+       } else {
+               if (fw->size % FW_OPCODE_SIZE)
+                       goto out;
+
+               strlcpy(version, rtl_lookup_firmware_name(tp), RTL_VER_SIZE);
+
+               pa->code = (__le32 *)fw->data;
+               pa->size = fw->size / FW_OPCODE_SIZE;
        }
+       version[RTL_VER_SIZE - 1] = 0;
+
+       rc = true;
+out:
+       return rc;
+}
+
+static bool rtl_fw_data_ok(struct rtl8169_private *tp, struct net_device *dev,
+                          struct rtl_fw_phy_action *pa)
+{
+       bool rc = false;
+       size_t index;
 
-       for (index = 0; index < fw_size; index++) {
-               u32 action = le32_to_cpu(phytable[index]);
+       for (index = 0; index < pa->size; index++) {
+               u32 action = le32_to_cpu(pa->code[index]);
                u32 regno = (action & 0x0fff0000) >> 16;
 
                switch(action & 0xf0000000) {
@@ -1771,25 +1842,25 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)
 
                case PHY_BJMPN:
                        if (regno > index) {
-                               netif_err(tp, probe, tp->dev,
+                               netif_err(tp, ifup, tp->dev,
                                          "Out of range of firmware\n");
-                               return;
+                               goto out;
                        }
                        break;
                case PHY_READCOUNT_EQ_SKIP:
-                       if (index + 2 >= fw_size) {
-                               netif_err(tp, probe, tp->dev,
+                       if (index + 2 >= pa->size) {
+                               netif_err(tp, ifup, tp->dev,
                                          "Out of range of firmware\n");
-                               return;
+                               goto out;
                        }
                        break;
                case PHY_COMP_EQ_SKIPN:
                case PHY_COMP_NEQ_SKIPN:
                case PHY_SKIPN:
-                       if (index + 1 + regno >= fw_size) {
-                               netif_err(tp, probe, tp->dev,
+                       if (index + 1 + regno >= pa->size) {
+                               netif_err(tp, ifup, tp->dev,
                                          "Out of range of firmware\n");
-                               return;
+                               goto out;
                        }
                        break;
 
@@ -1797,17 +1868,42 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)
                case PHY_WRITE_MAC_BYTE:
                case PHY_WRITE_ERI_WORD:
                default:
-                       netif_err(tp, probe, tp->dev,
+                       netif_err(tp, ifup, tp->dev,
                                  "Invalid action 0x%08x\n", action);
-                       return;
+                       goto out;
                }
        }
+       rc = true;
+out:
+       return rc;
+}
+
+static int rtl_check_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
+{
+       struct net_device *dev = tp->dev;
+       int rc = -EINVAL;
+
+       if (!rtl_fw_format_ok(tp, rtl_fw)) {
+               netif_err(tp, ifup, dev, "invalid firwmare\n");
+               goto out;
+       }
+
+       if (rtl_fw_data_ok(tp, dev, &rtl_fw->phy_action))
+               rc = 0;
+out:
+       return rc;
+}
 
-       predata = 0;
-       count = 0;
+static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
+{
+       struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
+       u32 predata, count;
+       size_t index;
 
-       for (index = 0; index < fw_size; ) {
-               u32 action = le32_to_cpu(phytable[index]);
+       predata = count = 0;
+
+       for (index = 0; index < pa->size; ) {
+               u32 action = le32_to_cpu(pa->code[index]);
                u32 data = action & 0x0000ffff;
                u32 regno = (action & 0x0fff0000) >> 16;
 
@@ -1879,18 +1975,20 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)
 
 static void rtl_release_firmware(struct rtl8169_private *tp)
 {
-       if (!IS_ERR_OR_NULL(tp->fw))
-               release_firmware(tp->fw);
-       tp->fw = RTL_FIRMWARE_UNKNOWN;
+       if (!IS_ERR_OR_NULL(tp->rtl_fw)) {
+               release_firmware(tp->rtl_fw->fw);
+               kfree(tp->rtl_fw);
+       }
+       tp->rtl_fw = RTL_FIRMWARE_UNKNOWN;
 }
 
 static void rtl_apply_firmware(struct rtl8169_private *tp)
 {
-       const struct firmware *fw = tp->fw;
+       struct rtl_fw *rtl_fw = tp->rtl_fw;
 
        /* TODO: release firmware once rtl_phy_write_fw signals failures. */
-       if (!IS_ERR_OR_NULL(fw))
-               rtl_phy_write_fw(tp, fw);
+       if (!IS_ERR_OR_NULL(rtl_fw))
+               rtl_phy_write_fw(tp, rtl_fw);
 }
 
 static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val)
@@ -3232,6 +3330,11 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp)
        }
 }
 
+static void rtl8169_init_ring_indexes(struct rtl8169_private *tp)
+{
+       tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0;
+}
+
 static void rtl_hw_reset(struct rtl8169_private *tp)
 {
        void __iomem *ioaddr = tp->mmio_addr;
@@ -3244,8 +3347,10 @@ static void rtl_hw_reset(struct rtl8169_private *tp)
        for (i = 0; i < 100; i++) {
                if ((RTL_R8(ChipCmd) & CmdReset) == 0)
                        break;
-               msleep_interruptible(1);
+               udelay(100);
        }
+
+       rtl8169_init_ring_indexes(tp);
 }
 
 static int __devinit
@@ -3349,9 +3454,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        }
        tp->mmio_addr = ioaddr;
 
-       tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
-       if (!tp->pcie_cap)
-               netif_info(tp, probe, dev, "no PCI Express capability\n");
+       if (!pci_is_pcie(pdev))
+               netif_info(tp, probe, dev, "not PCI Express\n");
 
        RTL_W16(IntrMask, 0x0000);
 
@@ -3443,7 +3547,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        tp->timer.data = (unsigned long) dev;
        tp->timer.function = rtl8169_phy_timer;
 
-       tp->fw = RTL_FIRMWARE_UNKNOWN;
+       tp->rtl_fw = RTL_FIRMWARE_UNKNOWN;
 
        rc = register_netdev(dev);
        if (rc < 0)
@@ -3512,25 +3616,48 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
        pci_set_drvdata(pdev, NULL);
 }
 
-static void rtl_request_firmware(struct rtl8169_private *tp)
+static void rtl_request_uncached_firmware(struct rtl8169_private *tp)
 {
-       /* Return early if the firmware is already loaded / cached. */
-       if (IS_ERR(tp->fw)) {
-               const char *name;
+       struct rtl_fw *rtl_fw;
+       const char *name;
+       int rc = -ENOMEM;
 
-               name = rtl_lookup_firmware_name(tp);
-               if (name) {
-                       int rc;
+       name = rtl_lookup_firmware_name(tp);
+       if (!name)
+               goto out_no_firmware;
 
-                       rc = request_firmware(&tp->fw, name, &tp->pci_dev->dev);
-                       if (rc >= 0)
-                               return;
+       rtl_fw = kzalloc(sizeof(*rtl_fw), GFP_KERNEL);
+       if (!rtl_fw)
+               goto err_warn;
 
-                       netif_warn(tp, ifup, tp->dev, "unable to load "
-                               "firmware patch %s (%d)\n", name, rc);
-               }
-               tp->fw = NULL;
-       }
+       rc = request_firmware(&rtl_fw->fw, name, &tp->pci_dev->dev);
+       if (rc < 0)
+               goto err_free;
+
+       rc = rtl_check_firmware(tp, rtl_fw);
+       if (rc < 0)
+               goto err_release_firmware;
+
+       tp->rtl_fw = rtl_fw;
+out:
+       return;
+
+err_release_firmware:
+       release_firmware(rtl_fw->fw);
+err_free:
+       kfree(rtl_fw);
+err_warn:
+       netif_warn(tp, ifup, tp->dev, "unable to load firmware patch %s (%d)\n",
+                  name, rc);
+out_no_firmware:
+       tp->rtl_fw = NULL;
+       goto out;
+}
+
+static void rtl_request_firmware(struct rtl8169_private *tp)
+{
+       if (IS_ERR(tp->rtl_fw))
+               rtl_request_uncached_firmware(tp);
 }
 
 static int rtl8169_open(struct net_device *dev)
@@ -3605,6 +3732,16 @@ err_pm_runtime_put:
        goto out;
 }
 
+static void rtl_rx_close(struct rtl8169_private *tp)
+{
+       void __iomem *ioaddr = tp->mmio_addr;
+       u32 rxcfg = RTL_R32(RxConfig);
+
+       rxcfg &= ~(AcceptErr | AcceptRunt | AcceptBroadcast | AcceptMulticast |
+                  AcceptMyPhys | AcceptAllPhys);
+       RTL_W32(RxConfig, rxcfg);
+}
+
 static void rtl8169_hw_reset(struct rtl8169_private *tp)
 {
        void __iomem *ioaddr = tp->mmio_addr;
@@ -3612,19 +3749,19 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp)
        /* Disable interrupts */
        rtl8169_irq_mask_and_ack(ioaddr);
 
+       rtl_rx_close(tp);
+
        if (tp->mac_version == RTL_GIGA_MAC_VER_27 ||
            tp->mac_version == RTL_GIGA_MAC_VER_28 ||
            tp->mac_version == RTL_GIGA_MAC_VER_31) {
                while (RTL_R8(TxPoll) & NPQ)
                        udelay(20);
-
+       } else {
+               RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq);
+               udelay(100);
        }
 
-       /* Reset the chipset */
-       RTL_W8(ChipCmd, CmdReset);
-
-       /* PCI commit */
-       RTL_R8(ChipCmd);
+       rtl_hw_reset(tp);
 }
 
 static void rtl_set_rx_tx_config_registers(struct rtl8169_private *tp)
@@ -3644,8 +3781,6 @@ static void rtl_hw_start(struct net_device *dev)
 {
        struct rtl8169_private *tp = netdev_priv(dev);
 
-       rtl_hw_reset(tp);
-
        tp->hw_start(dev);
 
        netif_start_queue(dev);
@@ -3780,9 +3915,7 @@ static void rtl_hw_start_8169(struct net_device *dev)
 
 static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force)
 {
-       struct net_device *dev = pci_get_drvdata(pdev);
-       struct rtl8169_private *tp = netdev_priv(dev);
-       int cap = tp->pcie_cap;
+       int cap = pci_pcie_cap(pdev);
 
        if (cap) {
                u16 ctl;
@@ -3830,9 +3963,7 @@ static void rtl_ephy_init(void __iomem *ioaddr, const struct ephy_info *e, int l
 
 static void rtl_disable_clock_request(struct pci_dev *pdev)
 {
-       struct net_device *dev = pci_get_drvdata(pdev);
-       struct rtl8169_private *tp = netdev_priv(dev);
-       int cap = tp->pcie_cap;
+       int cap = pci_pcie_cap(pdev);
 
        if (cap) {
                u16 ctl;
@@ -3845,9 +3976,7 @@ static void rtl_disable_clock_request(struct pci_dev *pdev)
 
 static void rtl_enable_clock_request(struct pci_dev *pdev)
 {
-       struct net_device *dev = pci_get_drvdata(pdev);
-       struct rtl8169_private *tp = netdev_priv(dev);
-       int cap = tp->pcie_cap;
+       int cap = pci_pcie_cap(pdev);
 
        if (cap) {
                u16 ctl;
@@ -4258,7 +4387,7 @@ static void rtl_hw_start_8105e_1(void __iomem *ioaddr, struct pci_dev *pdev)
        RTL_W32(FuncEvent, RTL_R32(FuncEvent) & ~0x010000);
 
        RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET);
-       RTL_W8(DLLPR, RTL_R8(DLLPR) | PM_SWITCH);
+       RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN);
 
        rtl_ephy_init(ioaddr, e_info_8105e_1, ARRAY_SIZE(e_info_8105e_1));
 }
@@ -4277,7 +4406,7 @@ static void rtl_hw_start_8101(struct net_device *dev)
 
        if (tp->mac_version == RTL_GIGA_MAC_VER_13 ||
            tp->mac_version == RTL_GIGA_MAC_VER_16) {
-               int cap = tp->pcie_cap;
+               int cap = pci_pcie_cap(pdev);
 
                if (cap) {
                        pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL,
@@ -4460,11 +4589,6 @@ err_out:
        return -ENOMEM;
 }
 
-static void rtl8169_init_ring_indexes(struct rtl8169_private *tp)
-{
-       tp->dirty_tx = tp->dirty_rx = tp->cur_tx = tp->cur_rx = 0;
-}
-
 static int rtl8169_init_ring(struct net_device *dev)
 {
        struct rtl8169_private *tp = netdev_priv(dev);
@@ -4592,7 +4716,7 @@ static void rtl8169_reset_task(struct work_struct *work)
 
        rtl8169_tx_clear(tp);
 
-       rtl8169_init_ring_indexes(tp);
+       rtl8169_hw_reset(tp);
        rtl_hw_start(dev);
        netif_wake_queue(dev);
        rtl8169_check_link_status(dev, tp, tp->mmio_addr);
@@ -5006,7 +5130,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
                 * the chip, so just exit the loop.
                 */
                if (unlikely(!netif_running(dev))) {
-                       rtl8169_asic_down(ioaddr);
+                       rtl8169_hw_reset(tp);
                        break;
                }
 
@@ -5129,7 +5253,7 @@ static void rtl8169_down(struct net_device *dev)
 
        spin_lock_irq(&tp->lock);
 
-       rtl8169_asic_down(ioaddr);
+       rtl8169_hw_reset(tp);
        /*
         * At this point device interrupts can not be enabled in any function,
         * as netif_running is not true (rtl8169_interrupt, rtl8169_reset_task,
@@ -5383,7 +5507,7 @@ static void rtl_shutdown(struct pci_dev *pdev)
 
        spin_lock_irq(&tp->lock);
 
-       rtl8169_asic_down(ioaddr);
+       rtl8169_hw_reset(tp);
 
        spin_unlock_irq(&tp->lock);