ixgbe/base: use a semaphore to serialize X550 IOSF accesses
authorWenzhuo Lu <wenzhuo.lu@intel.com>
Wed, 24 Jun 2015 03:26:06 +0000 (11:26 +0800)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Fri, 26 Jun 2015 10:58:05 +0000 (12:58 +0200)
Because each IOSF access requires the use of multiple registers,
use a semaphore to serialize those accesses.

Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
drivers/net/ixgbe/base/ixgbe_x550.c

index de97768..845cdac 100644 (file)
@@ -758,13 +758,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));
 
@@ -781,9 +786,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;
 }
 
@@ -798,13 +805,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));
 
@@ -818,15 +830,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;
 }
 
 /**