From d66791389c473a2c1008222f56c85e5ae002af1e Mon Sep 17 00:00:00 2001 From: Ouyang Changchun Date: Mon, 29 Sep 2014 15:16:21 +0800 Subject: [PATCH] ixgbe/base: rework semaphore - Store lan_id and physical semaphore mask into hardware physical information, and use them to control read and write physical registers in IXGBE base code. - Extend mask from 16 bits to 32 bits for releasing or acquiring SWFW semaphore in IXGBE base code. It is used in reading and writing I2C byte. Signed-off-by: Changchun Ouyang [Thomas: merge dependent patches] --- lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.c | 4 +- lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.h | 4 +- lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.c | 4 +- lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.h | 4 +- lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.c | 55 ++++------- lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h | 9 +- lib/librte_pmd_ixgbe/ixgbe/ixgbe_x540.c | 108 ++++++++++++++-------- lib/librte_pmd_ixgbe/ixgbe/ixgbe_x540.h | 4 +- 8 files changed, 104 insertions(+), 88 deletions(-) diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.c b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.c index 7e6b092349..378304f517 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.c +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.c @@ -1178,7 +1178,7 @@ s32 ixgbe_enable_sec_rx_path(struct ixgbe_hw *hw) * Acquires the SWFW semaphore through SW_FW_SYNC register for the specified * function (CSR, PHY0, PHY1, EEPROM, Flash) **/ -s32 ixgbe_acquire_swfw_semaphore(struct ixgbe_hw *hw, u16 mask) +s32 ixgbe_acquire_swfw_semaphore(struct ixgbe_hw *hw, u32 mask) { return ixgbe_call_func(hw, hw->mac.ops.acquire_swfw_sync, (hw, mask), IXGBE_NOT_IMPLEMENTED); @@ -1192,7 +1192,7 @@ s32 ixgbe_acquire_swfw_semaphore(struct ixgbe_hw *hw, u16 mask) * Releases the SWFW semaphore through SW_FW_SYNC register for the specified * function (CSR, PHY0, PHY1, EEPROM, Flash) **/ -void ixgbe_release_swfw_semaphore(struct ixgbe_hw *hw, u16 mask) +void ixgbe_release_swfw_semaphore(struct ixgbe_hw *hw, u32 mask) { if (hw->mac.ops.release_swfw_sync) hw->mac.ops.release_swfw_sync(hw, mask); diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.h b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.h index da41d95c6e..88a31e8dc4 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.h +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_api.h @@ -172,8 +172,8 @@ s32 ixgbe_write_i2c_eeprom(struct ixgbe_hw *hw, u8 byte_offset, u8 eeprom_data); s32 ixgbe_get_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr); s32 ixgbe_set_san_mac_addr(struct ixgbe_hw *hw, u8 *san_mac_addr); s32 ixgbe_get_device_caps(struct ixgbe_hw *hw, u16 *device_caps); -s32 ixgbe_acquire_swfw_semaphore(struct ixgbe_hw *hw, u16 mask); -void ixgbe_release_swfw_semaphore(struct ixgbe_hw *hw, u16 mask); +s32 ixgbe_acquire_swfw_semaphore(struct ixgbe_hw *hw, u32 mask); +void ixgbe_release_swfw_semaphore(struct ixgbe_hw *hw, u32 mask); s32 ixgbe_get_wwn_prefix(struct ixgbe_hw *hw, u16 *wwnn_prefix, u16 *wwpn_prefix); s32 ixgbe_get_fcoe_boot_status(struct ixgbe_hw *hw, u16 *bs); diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.c b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.c index e017822e72..f2acf6348b 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.c +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.c @@ -3169,7 +3169,7 @@ out: * Acquires the SWFW semaphore through the GSSR register for the specified * function (CSR, PHY0, PHY1, EEPROM, Flash) **/ -s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) +s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u32 mask) { u32 gssr = 0; u32 swmask = mask; @@ -3216,7 +3216,7 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) * Releases the SWFW semaphore through the GSSR register for the specified * function (CSR, PHY0, PHY1, EEPROM, Flash) **/ -void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask) +void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u32 mask) { u32 gssr; u32 swmask = mask; diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.h b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.h index 8b8bd0be42..14f1fec28c 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.h +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_common.h @@ -114,8 +114,8 @@ bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw); void ixgbe_fc_autoneg(struct ixgbe_hw *hw); s32 ixgbe_validate_mac_addr(u8 *mac_addr); -s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask); -void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask); +s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u32 mask); +void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u32 mask); s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw); s32 prot_autoc_read_generic(struct ixgbe_hw *hw, bool *, u32 *reg_val); diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.c b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.c index 3ba6be52db..7969812e5e 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.c +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.c @@ -99,6 +99,15 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) DEBUGFUNC("ixgbe_identify_phy_generic"); + if (!hw->phy.phy_semaphore_mask) { + hw->phy.lan_id = IXGBE_READ_REG(hw, IXGBE_STATUS) & + IXGBE_STATUS_LAN_ID_1; + if (hw->phy.lan_id) + hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY1_SM; + else + hw->phy.phy_semaphore_mask = IXGBE_GSSR_PHY0_SM; + } + if (hw->phy.type == ixgbe_phy_unknown) { for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { if (ixgbe_validate_phy_addr(hw, phy_addr)) { @@ -403,15 +412,10 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, u16 *phy_data) { s32 status; - u16 gssr; + u32 gssr = hw->phy.phy_semaphore_mask; DEBUGFUNC("ixgbe_read_phy_reg_generic"); - if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1) - gssr = IXGBE_GSSR_PHY1_SM; - else - gssr = IXGBE_GSSR_PHY0_SM; - if (hw->mac.ops.acquire_swfw_sync(hw, gssr) == IXGBE_SUCCESS) { status = ixgbe_read_phy_reg_mdi(hw, reg_addr, device_type, phy_data); @@ -509,15 +513,10 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, u16 phy_data) { s32 status; - u16 gssr; + u32 gssr = hw->phy.phy_semaphore_mask; DEBUGFUNC("ixgbe_write_phy_reg_generic"); - if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1) - gssr = IXGBE_GSSR_PHY1_SM; - else - gssr = IXGBE_GSSR_PHY0_SM; - if (hw->mac.ops.acquire_swfw_sync(hw, gssr) == IXGBE_SUCCESS) { status = ixgbe_write_phy_reg_mdi(hw, reg_addr, device_type, phy_data); @@ -1469,26 +1468,18 @@ s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset, s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, u8 *data) { - s32 status = IXGBE_SUCCESS; + s32 status; u32 max_retry = 10; u32 retry = 0; - u16 swfw_mask = 0; + u32 swfw_mask = hw->phy.phy_semaphore_mask; bool nack = 1; *data = 0; DEBUGFUNC("ixgbe_read_i2c_byte_generic"); - if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1) - swfw_mask = IXGBE_GSSR_PHY1_SM; - else - swfw_mask = IXGBE_GSSR_PHY0_SM; - do { - if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) - != IXGBE_SUCCESS) { - status = IXGBE_ERR_SWFW_SYNC; - goto read_byte_out; - } + if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)) + return IXGBE_ERR_SWFW_SYNC; ixgbe_i2c_start(hw); @@ -1529,7 +1520,8 @@ s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, goto fail; ixgbe_i2c_stop(hw); - break; + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + return IXGBE_SUCCESS; fail: ixgbe_i2c_bus_clear(hw); @@ -1543,9 +1535,6 @@ fail: } while (retry < max_retry); - hw->mac.ops.release_swfw_sync(hw, swfw_mask); - -read_byte_out: return status; } @@ -1564,15 +1553,10 @@ s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, s32 status = IXGBE_SUCCESS; u32 max_retry = 1; u32 retry = 0; - u16 swfw_mask = 0; + u32 swfw_mask = hw->phy.phy_semaphore_mask; DEBUGFUNC("ixgbe_write_i2c_byte_generic"); - if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1) - swfw_mask = IXGBE_GSSR_PHY1_SM; - else - swfw_mask = IXGBE_GSSR_PHY0_SM; - if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != IXGBE_SUCCESS) { status = IXGBE_ERR_SWFW_SYNC; goto write_byte_out; @@ -1606,7 +1590,8 @@ s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, goto fail; ixgbe_i2c_stop(hw); - break; + hw->mac.ops.release_swfw_sync(hw, swfw_mask); + return IXGBE_SUCCESS; fail: ixgbe_i2c_bus_clear(hw); diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h index d597993667..29cf5725b9 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h @@ -1815,6 +1815,9 @@ enum { #define IXGBE_GSSR_MAC_CSR_SM 0x0008 #define IXGBE_GSSR_FLASH_SM 0x0010 #define IXGBE_GSSR_SW_MNG_SM 0x0400 +#define IXGBE_GSSR_SHARED_I2C_SM 0x1806 /* Wait for both phys and both I2Cs */ +#define IXGBE_GSSR_I2C_MASK 0x1800 +#define IXGBE_GSSR_NVM_PHY_MASK 0xF /* FW Status register bitmask */ #define IXGBE_FWSTS_FWRI 0x00000200 /* Firmware Reset Indication */ @@ -3091,8 +3094,8 @@ struct ixgbe_mac_operations { s32 (*enable_rx_dma)(struct ixgbe_hw *, u32); s32 (*disable_sec_rx_path)(struct ixgbe_hw *); s32 (*enable_sec_rx_path)(struct ixgbe_hw *); - s32 (*acquire_swfw_sync)(struct ixgbe_hw *, u16); - void (*release_swfw_sync)(struct ixgbe_hw *, u16); + s32 (*acquire_swfw_sync)(struct ixgbe_hw *, u32); + void (*release_swfw_sync)(struct ixgbe_hw *, u32); s32 (*prot_autoc_read)(struct ixgbe_hw *, bool *, u32 *); s32 (*prot_autoc_write)(struct ixgbe_hw *, u32, bool); @@ -3225,6 +3228,8 @@ struct ixgbe_phy_info { bool sfp_setup_needed; u32 revision; enum ixgbe_media_type media_type; + u32 phy_semaphore_mask; + u8 lan_id; bool reset_disable; ixgbe_autoneg_advertised autoneg_advertised; enum ixgbe_smart_speed smart_speed; diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x540.c b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x540.c index 990b676271..ab384502ae 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x540.c +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x540.c @@ -736,6 +736,26 @@ STATIC s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw) return status; } +/** + * ixgbe_set_mux - Set mux for port 1 access with CS4227 + * @hw: pointer to hardware structure + * @state: set mux if 1, clear if 0 + */ +STATIC void ixgbe_set_mux(struct ixgbe_hw *hw, u8 state) +{ + u32 esdp; + + if (!hw->phy.lan_id) + return; + esdp = IXGBE_READ_REG(hw, IXGBE_ESDP); + if (state) + esdp |= IXGBE_ESDP_SDP1; + else + esdp &= ~IXGBE_ESDP_SDP1; + IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp); + IXGBE_WRITE_FLUSH(hw); +} + /** * ixgbe_acquire_swfw_sync_X540 - Acquire SWFW semaphore * @hw: pointer to hardware structure @@ -744,34 +764,33 @@ STATIC s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw) * Acquires the SWFW semaphore thought the SW_FW_SYNC register for * the specified function (CSR, PHY0, PHY1, NVM, Flash) **/ -s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask) +s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask) { - u32 swfw_sync; - u32 swmask = mask; - u32 fwmask = mask << 5; - u32 hwmask = 0; + u32 swmask = mask & IXGBE_GSSR_NVM_PHY_MASK; + u32 fwmask = swmask << 5; + u32 swi2c_mask = mask & IXGBE_GSSR_I2C_MASK; u32 timeout = 200; + u32 hwmask = 0; + u32 swfw_sync; u32 i; - s32 ret_val = IXGBE_SUCCESS; DEBUGFUNC("ixgbe_acquire_swfw_sync_X540"); - if (swmask == IXGBE_GSSR_EEP_SM) - hwmask = IXGBE_GSSR_FLASH_SM; + if (swmask & IXGBE_GSSR_EEP_SM) + hwmask |= IXGBE_GSSR_FLASH_SM; /* SW only mask doesn't have FW bit pair */ - if (swmask == IXGBE_GSSR_SW_MNG_SM) - fwmask = 0; + if (mask & IXGBE_GSSR_SW_MNG_SM) + swmask |= IXGBE_GSSR_SW_MNG_SM; + swmask |= swi2c_mask; + fwmask |= swi2c_mask << 2; for (i = 0; i < timeout; i++) { - /* - * SW NVM semaphore bit is used for access to all + /* SW NVM semaphore bit is used for access to all * SW_FW_SYNC bits (not just NVM) */ - if (ixgbe_get_swfw_sync_semaphore(hw)) { - ret_val = IXGBE_ERR_SWFW_SYNC; - goto out; - } + if (ixgbe_get_swfw_sync_semaphore(hw)) + return IXGBE_ERR_SWFW_SYNC; swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); if (!(swfw_sync & (fwmask | swmask | hwmask))) { @@ -779,24 +798,23 @@ s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask) IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync); ixgbe_release_swfw_sync_semaphore(hw); msec_delay(5); - goto out; - } else { - /* - * Firmware currently using resource (fwmask), hardware - * currently using resource (hwmask), or other software - * thread currently using resource (swmask) - */ - ixgbe_release_swfw_sync_semaphore(hw); - msec_delay(5); + if (swi2c_mask) + ixgbe_set_mux(hw, 1); + return IXGBE_SUCCESS; } + /* Firmware currently using resource (fwmask), hardware + * currently using resource (hwmask), or other software + * thread currently using resource (swmask) + */ + ixgbe_release_swfw_sync_semaphore(hw); + msec_delay(5); } /* Failed to get SW only semaphore */ if (swmask == IXGBE_GSSR_SW_MNG_SM) { - ret_val = IXGBE_ERR_SWFW_SYNC; ERROR_REPORT1(IXGBE_ERROR_POLLING, "Failed to get SW only semaphore"); - goto out; + return IXGBE_ERR_SWFW_SYNC; } /* If the resource is not released by the FW/HW the SW can assume that @@ -804,32 +822,36 @@ s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask) * of the requested resource(s) while ignoring the corresponding FW/HW * bits in the SW_FW_SYNC register. */ + if (ixgbe_get_swfw_sync_semaphore(hw)) + return IXGBE_ERR_SWFW_SYNC; swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); if (swfw_sync & (fwmask | hwmask)) { - if (ixgbe_get_swfw_sync_semaphore(hw)) { - ret_val = IXGBE_ERR_SWFW_SYNC; - goto out; - } - swfw_sync |= swmask; IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync); ixgbe_release_swfw_sync_semaphore(hw); msec_delay(5); + if (swi2c_mask) + ixgbe_set_mux(hw, 1); + return IXGBE_SUCCESS; } /* If the resource is not released by other SW the SW can assume that * the other SW malfunctions. In that case the SW should clear all SW * flags that it does not own and then repeat the whole process once * again. */ - else if (swfw_sync & swmask) { - ixgbe_release_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM | - IXGBE_GSSR_PHY0_SM | IXGBE_GSSR_PHY1_SM | - IXGBE_GSSR_MAC_CSR_SM); - ret_val = IXGBE_ERR_SWFW_SYNC; + if (swfw_sync & swmask) { + u32 rmask = IXGBE_GSSR_EEP_SM | IXGBE_GSSR_PHY0_SM | + IXGBE_GSSR_PHY1_SM | IXGBE_GSSR_MAC_CSR_SM; + + if (swi2c_mask) + rmask |= IXGBE_GSSR_I2C_MASK; + ixgbe_release_swfw_sync_X540(hw, rmask); + ixgbe_release_swfw_sync_semaphore(hw); + return IXGBE_ERR_SWFW_SYNC; } + ixgbe_release_swfw_sync_semaphore(hw); -out: - return ret_val; + return IXGBE_ERR_SWFW_SYNC; } /** @@ -840,13 +862,17 @@ out: * Releases the SWFW semaphore through the SW_FW_SYNC register * for the specified function (CSR, PHY0, PHY1, EVM, Flash) **/ -void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask) +void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask) { + u32 swmask = mask & (IXGBE_GSSR_NVM_PHY_MASK | IXGBE_GSSR_SW_MNG_SM); u32 swfw_sync; - u32 swmask = mask; DEBUGFUNC("ixgbe_release_swfw_sync_X540"); + if (mask & IXGBE_GSSR_I2C_MASK) { + swmask |= mask & IXGBE_GSSR_I2C_MASK; + ixgbe_set_mux(hw, 0); + } ixgbe_get_swfw_sync_semaphore(hw); swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC); diff --git a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x540.h b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x540.h index 86158e67d8..338c0e6e91 100644 --- a/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x540.h +++ b/lib/librte_pmd_ixgbe/ixgbe/ixgbe_x540.h @@ -58,8 +58,8 @@ s32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw, u16 *checksum_val); s32 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw); s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw); -s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask); -void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u16 mask); +s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask); +void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask); s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index); s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index); -- 2.20.1