Because each IOSF access requires the use of multiple registers,
use a semaphore to serialize those accesses.

Signed-off-by: Wenzhuo Lu <wenzhuo.lu at intel.com>
---
 drivers/net/ixgbe/base/ixgbe_x550.c | 30 +++++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ixgbe/base/ixgbe_x550.c 
b/drivers/net/ixgbe/base/ixgbe_x550.c
index 0109938..3e8ea74 100644
--- a/drivers/net/ixgbe/base/ixgbe_x550.c
+++ b/drivers/net/ixgbe/base/ixgbe_x550.c
@@ -766,13 +766,18 @@ STATIC s32 ixgbe_iosf_wait(struct ixgbe_hw *hw, u32 *ctrl)
 s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
                            u32 device_type, u32 data)
 {
+       u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
        u32 command, error;
        s32 ret;

-       ret = ixgbe_iosf_wait(hw, NULL);
+       ret = ixgbe_acquire_swfw_semaphore(hw, gssr);
        if (ret != IXGBE_SUCCESS)
                return ret;

+       ret = ixgbe_iosf_wait(hw, NULL);
+       if (ret != IXGBE_SUCCESS)
+               goto out;
+
        command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
                   (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));

@@ -789,9 +794,11 @@ s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 
reg_addr,
                         IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
                ERROR_REPORT2(IXGBE_ERROR_POLLING,
                              "Failed to write, error %x\n", error);
-               return IXGBE_ERR_PHY;
+               ret = IXGBE_ERR_PHY;
        }

+out:
+       ixgbe_release_swfw_semaphore(hw, gssr);
        return ret;
 }

@@ -806,13 +813,18 @@ s32 ixgbe_write_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 
reg_addr,
 s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
                           u32 device_type, u32 *data)
 {
+       u32 gssr = IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_PHY0_SM;
        u32 command, error;
        s32 ret;

-       ret = ixgbe_iosf_wait(hw, NULL);
+       ret = ixgbe_acquire_swfw_semaphore(hw, gssr);
        if (ret != IXGBE_SUCCESS)
                return ret;

+       ret = ixgbe_iosf_wait(hw, NULL);
+       if (ret != IXGBE_SUCCESS)
+               goto out;
+
        command = ((reg_addr << IXGBE_SB_IOSF_CTRL_ADDR_SHIFT) |
                   (device_type << IXGBE_SB_IOSF_CTRL_TARGET_SELECT_SHIFT));

@@ -826,15 +838,15 @@ s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 
reg_addr,
                         IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT;
                ERROR_REPORT2(IXGBE_ERROR_POLLING,
                                "Failed to read, error %x\n", error);
-               return IXGBE_ERR_PHY;
+               ret = IXGBE_ERR_PHY;
        }

-       if (ret != IXGBE_SUCCESS)
-               return ret;
+       if (ret == IXGBE_SUCCESS)
+               *data = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA);

-       *data = IXGBE_READ_REG(hw, IXGBE_SB_IOSF_INDIRECT_DATA);
-
-       return IXGBE_SUCCESS;
+out:
+       ixgbe_release_swfw_semaphore(hw, gssr);
+       return ret;
 }

 /**
-- 
1.9.3

Reply via email to