igc: Add PHY power management control
authorSasha Neftin <sasha.neftin@intel.com>
Wed, 8 Jan 2020 08:19:24 +0000 (10:19 +0200)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Fri, 17 Jan 2020 17:55:34 +0000 (09:55 -0800)
PHY power management control should provide a reliable and accurate
indication of PHY reset completion and decrease the delay time
after a PHY reset

Signed-off-by: Sasha Neftin <sasha.neftin@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/igc/igc_defines.h
drivers/net/ethernet/intel/igc/igc_phy.c
drivers/net/ethernet/intel/igc/igc_regs.h

index 9e34b0969322ceb43ffbcd7b2c43744cb5aabc65..58efa7a02c68459dceee71b260e78ee8774950f6 100644 (file)
 /* PHY Status Register */
 #define MII_SR_LINK_STATUS     0x0004 /* Link Status 1 = link */
 #define MII_SR_AUTONEG_COMPLETE        0x0020 /* Auto Neg Complete */
+#define IGC_PHY_RST_COMP       0x0100 /* Internal PHY reset completion */
 
 /* PHY 1000 MII Register/Bit Definitions */
 /* PHY Registers defined by IEEE */
index f4b05af0dd2f6f0e39e620a76909ed5998d7da44..8e1799508edc42438a128c38be2f62cf8eeae083 100644 (file)
@@ -173,6 +173,7 @@ s32 igc_check_downshift(struct igc_hw *hw)
 s32 igc_phy_hw_reset(struct igc_hw *hw)
 {
        struct igc_phy_info *phy = &hw->phy;
+       u32 phpm = 0, timeout = 10000;
        s32  ret_val;
        u32 ctrl;
 
@@ -186,6 +187,8 @@ s32 igc_phy_hw_reset(struct igc_hw *hw)
        if (ret_val)
                goto out;
 
+       phpm = rd32(IGC_I225_PHPM);
+
        ctrl = rd32(IGC_CTRL);
        wr32(IGC_CTRL, ctrl | IGC_CTRL_PHY_RST);
        wrfl();
@@ -195,7 +198,18 @@ s32 igc_phy_hw_reset(struct igc_hw *hw)
        wr32(IGC_CTRL, ctrl);
        wrfl();
 
-       usleep_range(1500, 2000);
+       /* SW should guarantee 100us for the completion of the PHY reset */
+       usleep_range(100, 150);
+       do {
+               phpm = rd32(IGC_I225_PHPM);
+               timeout--;
+               udelay(1);
+       } while (!(phpm & IGC_PHY_RST_COMP) && timeout);
+
+       if (!timeout)
+               hw_dbg("Timeout is expired after a phy reset\n");
+
+       usleep_range(100, 150);
 
        phy->ops.release(hw);
 
index c82111051898c45a886ba28572d670fcfa36ea53..c9029b549b908480caf3df4726fec55a4439132d 100644 (file)
@@ -12,6 +12,7 @@
 #define IGC_MDIC               0x00020  /* MDI Control - RW */
 #define IGC_MDICNFG            0x00E04  /* MDC/MDIO Configuration - RW */
 #define IGC_CONNSW             0x00034  /* Copper/Fiber switch control - RW */
+#define IGC_I225_PHPM          0x00E14  /* I225 PHY Power Management */
 
 /* Internal Packet Buffer Size Registers */
 #define IGC_RXPBS              0x02404  /* Rx Packet Buffer Size - RW */