From da431fd14d00af94deab1e1c078f8417a3732e1f Mon Sep 17 00:00:00 2001 From: Wenzhuo Lu Date: Wed, 24 Jun 2015 11:26:24 +0800 Subject: [PATCH] ixgbe/base: fix X550em CS4227 speed mode According to the hardware, the LINE side of the cs4227 needs to be set to 10 Gbps SR mode regardless of the configuration of the link. Signed-off-by: Wenzhuo Lu Acked-by: Helin Zhang --- drivers/net/ixgbe/base/ixgbe_phy.h | 2 + drivers/net/ixgbe/base/ixgbe_x550.c | 143 +++++++++++++++------------- 2 files changed, 81 insertions(+), 64 deletions(-) diff --git a/drivers/net/ixgbe/base/ixgbe_phy.h b/drivers/net/ixgbe/base/ixgbe_phy.h index e3cf7ff6c8..1f07c1e94d 100644 --- a/drivers/net/ixgbe/base/ixgbe_phy.h +++ b/drivers/net/ixgbe/base/ixgbe_phy.h @@ -97,6 +97,8 @@ POSSIBILITY OF SUCH DAMAGE. #define IXGBE_CS4227_LINE_SPARE24_LSB 0x12B0 /* Reg to program EDC */ #define IXGBE_CS4227_HOST_SPARE22_MSB 0x1AAD /* Reg to program speed */ #define IXGBE_CS4227_HOST_SPARE24_LSB 0x1AB0 /* Reg to program EDC */ +#define IXGBE_CS4227_SPEED_1G 0x8000 +#define IXGBE_CS4227_SPEED_10G 0 #define IXGBE_CS4227_EDC_MODE_CX1 0x0002 #define IXGBE_CS4227_EDC_MODE_SR 0x0004 #define IXGBE_CS4227_RESET_HOLD 500 /* microseconds */ diff --git a/drivers/net/ixgbe/base/ixgbe_x550.c b/drivers/net/ixgbe/base/ixgbe_x550.c index 9a3f48875c..48077aec24 100644 --- a/drivers/net/ixgbe/base/ixgbe_x550.c +++ b/drivers/net/ixgbe/base/ixgbe_x550.c @@ -117,7 +117,9 @@ STATIC s32 ixgbe_write_cs4227(struct ixgbe_hw *hw, u16 reg, u16 value) * ixgbe_get_cs4227_status - Return CS4227 status * @hw: pointer to hardware structure * - * Returns error if CS4227 not successfully initialized + * Performs a diagnostic on the CS4227 chip. Returns an error if it is + * not operating correctly. + * This function assumes that the caller has acquired the proper semaphore. **/ STATIC s32 ixgbe_get_cs4227_status(struct ixgbe_hw *hw) { @@ -126,6 +128,7 @@ STATIC s32 ixgbe_get_cs4227_status(struct ixgbe_hw *hw) u16 reg_slice, reg_val; u8 retry; + /* Check register reads. */ for (retry = 0; retry < IXGBE_CS4227_RETRIES; ++retry) { status = ixgbe_read_cs4227(hw, IXGBE_CS4227_GLOBAL_ID_LSB, &value); @@ -146,8 +149,16 @@ STATIC s32 ixgbe_get_cs4227_status(struct ixgbe_hw *hw) * Otherwise, this will disrupt link on all ports. Because we * can only do this the first time, we must check all ports, * not just our own. + * While we are at it, set the LINE side to 10G SR, which is + * what it needs to be regardless of the actual link. */ if (value != IXGBE_CS4227_SCRATCH_VALUE) { + reg_slice = IXGBE_CS4227_LINE_SPARE22_MSB; + reg_val = IXGBE_CS4227_SPEED_10G; + status = ixgbe_write_cs4227(hw, reg_slice, reg_val); + if (status != IXGBE_SUCCESS) + return status; + reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB; reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1; status = ixgbe_write_cs4227(hw, reg_slice, reg_val); @@ -160,6 +171,12 @@ STATIC s32 ixgbe_get_cs4227_status(struct ixgbe_hw *hw) if (status != IXGBE_SUCCESS) return status; + reg_slice = IXGBE_CS4227_LINE_SPARE22_MSB + (1 << 12); + reg_val = IXGBE_CS4227_SPEED_10G; + status = ixgbe_write_cs4227(hw, reg_slice, reg_val); + if (status != IXGBE_SUCCESS) + return status; + reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + (1 << 12); reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1; status = ixgbe_write_cs4227(hw, reg_slice, reg_val); @@ -1764,6 +1781,67 @@ s32 ixgbe_setup_kx4_x550em(struct ixgbe_hw *hw) return status; } +/** + * ixgbe_setup_mac_link_sfp_x550em - Setup internal/external the PHY for SFP + * @hw: pointer to hardware structure + * + * Configure the external PHY and the integrated KR PHY for SFP support. + **/ +s32 ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg_wait_to_complete) +{ + s32 ret_val; + u16 reg_slice, reg_val; + bool setup_linear = false; + UNREFERENCED_1PARAMETER(autoneg_wait_to_complete); + + /* Check if SFP module is supported and linear */ + ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear); + + /* If no SFP module present, then return success. Return success since + * there is no reason to configure CS4227 and SFP not present error is + * not excepted in the setup MAC link flow. + */ + if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT) + return IXGBE_SUCCESS; + + if (ret_val != IXGBE_SUCCESS) + return ret_val; + + /* Configure CS4227 LINE side to 10G SR. */ + reg_slice = IXGBE_CS4227_LINE_SPARE22_MSB + (hw->bus.lan_id << 12); + reg_val = IXGBE_CS4227_SPEED_10G; + ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice, + reg_val); + + reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + (hw->bus.lan_id << 12); + reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1; + ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice, + reg_val); + + /* Configure CS4227 for HOST connection rate then type. */ + reg_slice = IXGBE_CS4227_HOST_SPARE22_MSB + (hw->bus.lan_id << 12); + reg_val = (speed & IXGBE_LINK_SPEED_10GB_FULL) ? + IXGBE_CS4227_SPEED_10G : IXGBE_CS4227_SPEED_1G; + ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice, + reg_val); + + reg_slice = IXGBE_CS4227_HOST_SPARE24_LSB + (hw->bus.lan_id << 12); + if (setup_linear) + reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1; + else + reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1; + ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice, + reg_val); + + /* If internal link mode is XFI, then setup XFI internal link. */ + if (!(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) + ret_val = ixgbe_setup_ixfi_x550em(hw, &speed); + + return ret_val; +} + /** * ixgbe_setup_ixfi_x550em - Configure the KR PHY for iXFI mode. * @hw: pointer to hardware structure @@ -1909,69 +1987,6 @@ STATIC s32 ixgbe_ext_phy_t_x550em_get_link(struct ixgbe_hw *hw, bool *link_up) return IXGBE_SUCCESS; } -/** - * ixgbe_setup_mac_link_sfp_x550em - Setup internal/external the PHY for SFP - * @hw: pointer to hardware structure - * - * Configure the external PHY and the integrated KR PHY for SFP support. - **/ -s32 ixgbe_setup_mac_link_sfp_x550em(struct ixgbe_hw *hw, - ixgbe_link_speed speed, - bool autoneg_wait_to_complete) -{ - s32 ret_val; - u16 reg_slice, reg_val; - bool setup_linear = false; - UNREFERENCED_1PARAMETER(autoneg_wait_to_complete); - - /* Check if SFP module is supported and linear */ - ret_val = ixgbe_supported_sfp_modules_X550em(hw, &setup_linear); - - /* If no SFP module present, then return success. Return success since - * there is no reason to configure CS4227 and SFP not present error is - * not excepted in the setup MAC link flow. - */ - if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT) - return IXGBE_SUCCESS; - - if (ret_val != IXGBE_SUCCESS) - return ret_val; - - /* Configure CS4227 for LINE connection rate then type. */ - reg_slice = IXGBE_CS4227_LINE_SPARE22_MSB + (hw->bus.lan_id << 12); - reg_val = (speed & IXGBE_LINK_SPEED_10GB_FULL) ? 0 : 0x8000; - ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice, - reg_val); - - reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + (hw->bus.lan_id << 12); - if (setup_linear) - reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1; - else - reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1; - ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice, - reg_val); - - /* Configure CS4227 for HOST connection rate then type. */ - reg_slice = IXGBE_CS4227_HOST_SPARE22_MSB + (hw->bus.lan_id << 12); - reg_val = (speed & IXGBE_LINK_SPEED_10GB_FULL) ? 0 : 0x8000; - ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice, - reg_val); - - reg_slice = IXGBE_CS4227_HOST_SPARE24_LSB + (hw->bus.lan_id << 12); - if (setup_linear) - reg_val = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1; - else - reg_val = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1; - ret_val = ixgbe_write_i2c_combined(hw, IXGBE_CS4227, reg_slice, - reg_val); - - /* If internal link mode is XFI, then setup XFI internal link. */ - if (!(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) - ret_val = ixgbe_setup_ixfi_x550em(hw, &speed); - - return ret_val; -} - /** * ixgbe_setup_internal_phy_t_x550em - Configure KR PHY to X557 link * @hw: point to hardware structure