ixgbe: Acquire PHY semaphore before device reset
authorPaul Greenwalt <paul.greenwalt@intel.com>
Mon, 13 Mar 2017 09:47:56 +0000 (05:47 -0400)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Sat, 29 Apr 2017 02:02:31 +0000 (19:02 -0700)
A recent firmware change fixed an issue to acquire the PHY semaphore before
accessing PHY registers. This led to a case where  SW can issue a device
reset clearing the MDIO registers. This patch makes SW acquire the PHY
semaphore before issuing a device reset.

Signed-off-by: Paul Greenwalt <paul.greenwalt@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c
drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c

index 84a467a8ed3d5f1aaab77b53dc158d3feba95c98..6ea0d6a5fb90c53df768d3532bd07691f8e48ca0 100644 (file)
@@ -95,6 +95,7 @@ s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw)
 {
        s32 status;
        u32 ctrl, i;
+       u32 swfw_mask = hw->phy.phy_semaphore_mask;
 
        /* Call adapter stop to disable tx/rx and clear interrupts */
        status = hw->mac.ops.stop_adapter(hw);
@@ -105,10 +106,17 @@ s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw)
        ixgbe_clear_tx_pending(hw);
 
 mac_reset_top:
+       status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
+       if (status) {
+               hw_dbg(hw, "semaphore failed with %d", status);
+               return IXGBE_ERR_SWFW_SYNC;
+       }
+
        ctrl = IXGBE_CTRL_RST;
        ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
        IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
        IXGBE_WRITE_FLUSH(hw);
+       hw->mac.ops.release_swfw_sync(hw, swfw_mask);
        usleep_range(1000, 1200);
 
        /* Poll for reset bit to self-clear indicating reset is complete */
index 2658394599e44259ec41915b31d589f131c94bca..58d3bcaca2b9a9e89508a2f5f41521d6c385c1c6 100644 (file)
@@ -3318,6 +3318,7 @@ static s32 ixgbe_reset_hw_X550em(struct ixgbe_hw *hw)
        u32 ctrl = 0;
        u32 i;
        bool link_up = false;
+       u32 swfw_mask = hw->phy.phy_semaphore_mask;
 
        /* Call adapter stop to disable Tx/Rx and clear interrupts */
        status = hw->mac.ops.stop_adapter(hw);
@@ -3363,9 +3364,16 @@ mac_reset_top:
                        ctrl = IXGBE_CTRL_RST;
        }
 
+       status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask);
+       if (status) {
+               hw_dbg(hw, "semaphore failed with %d", status);
+               return IXGBE_ERR_SWFW_SYNC;
+       }
+
        ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
        IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
        IXGBE_WRITE_FLUSH(hw);
+       hw->mac.ops.release_swfw_sync(hw, swfw_mask);
        usleep_range(1000, 1200);
 
        /* Poll for reset bit to self-clear meaning reset is complete */