From 8bdbca1345503ef93f1fcfed2896b9eaef25a75d Mon Sep 17 00:00:00 2001 From: Wenzhuo Lu Date: Wed, 24 Jun 2015 11:26:06 +0800 Subject: [PATCH] ixgbe/base: use a semaphore to serialize X550 IOSF accesses Because each IOSF access requires the use of multiple registers, use a semaphore to serialize those accesses. Signed-off-by: Wenzhuo Lu Acked-by: Helin Zhang --- 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 de97768e80..845cdac968 100644 --- a/drivers/net/ixgbe/base/ixgbe_x550.c +++ b/drivers/net/ixgbe/base/ixgbe_x550.c @@ -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; } /** -- 2.20.1