From: Jiawen Wu Date: Thu, 21 Oct 2021 09:50:10 +0000 (+0800) Subject: net/ngbe: support FW version query X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=506abd4a8b902ffeef5d3056f5b5cb3089c93e88;p=dpdk.git net/ngbe: support FW version query Add firmware version get operation. Signed-off-by: Jiawen Wu --- diff --git a/doc/guides/nics/features/ngbe.ini b/doc/guides/nics/features/ngbe.ini index 90e2a38bfb..85ba80a328 100644 --- a/doc/guides/nics/features/ngbe.ini +++ b/doc/guides/nics/features/ngbe.ini @@ -26,6 +26,7 @@ Packet type parsing = Y Basic stats = Y Extended stats = Y Stats per queue = Y +FW version = Y Multiprocess aware = Y Linux = Y ARMv8 = Y diff --git a/doc/guides/nics/ngbe.rst b/doc/guides/nics/ngbe.rst index 2a92f91e9f..b8211fc66e 100644 --- a/doc/guides/nics/ngbe.rst +++ b/doc/guides/nics/ngbe.rst @@ -22,6 +22,7 @@ Features - Jumbo frames - Link state information - Scattered and gather for TX and RX +- FW version Prerequisites diff --git a/drivers/net/ngbe/base/ngbe_dummy.h b/drivers/net/ngbe/base/ngbe_dummy.h index 59c8097241..aeeb46ccf9 100644 --- a/drivers/net/ngbe/base/ngbe_dummy.h +++ b/drivers/net/ngbe/base/ngbe_dummy.h @@ -33,6 +33,11 @@ static inline s32 ngbe_rom_init_params_dummy(struct ngbe_hw *TUP0) { return NGBE_ERR_OPS_DUMMY; } +static inline s32 ngbe_rom_read32_dummy(struct ngbe_hw *TUP0, u32 TUP1, + u32 *TUP2) +{ + return NGBE_ERR_OPS_DUMMY; +} static inline s32 ngbe_rom_validate_checksum_dummy(struct ngbe_hw *TUP0, u16 *TUP1) { @@ -181,6 +186,7 @@ static inline void ngbe_init_ops_dummy(struct ngbe_hw *hw) { hw->bus.set_lan_id = ngbe_bus_set_lan_id_dummy; hw->rom.init_params = ngbe_rom_init_params_dummy; + hw->rom.read32 = ngbe_rom_read32_dummy; hw->rom.validate_checksum = ngbe_rom_validate_checksum_dummy; hw->mac.init_hw = ngbe_mac_init_hw_dummy; hw->mac.reset_hw = ngbe_mac_reset_hw_dummy; diff --git a/drivers/net/ngbe/base/ngbe_eeprom.c b/drivers/net/ngbe/base/ngbe_eeprom.c index 3dcd5c2f6c..9ae2f0badb 100644 --- a/drivers/net/ngbe/base/ngbe_eeprom.c +++ b/drivers/net/ngbe/base/ngbe_eeprom.c @@ -161,6 +161,30 @@ void ngbe_release_eeprom_semaphore(struct ngbe_hw *hw) ngbe_flush(hw); } +/** + * ngbe_ee_read32 - Read EEPROM word using a host interface cmd + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to read + * @data: word read from the EEPROM + * + * Reads a 32 bit word from the EEPROM using the hostif. + **/ +s32 ngbe_ee_read32(struct ngbe_hw *hw, u32 addr, u32 *data) +{ + const u32 mask = NGBE_MNGSEM_SWMBX | NGBE_MNGSEM_SWFLASH; + int err; + + err = hw->mac.acquire_swfw_sync(hw, mask); + if (err) + return err; + + err = ngbe_hic_sr_read(hw, addr, (u8 *)data, 4); + + hw->mac.release_swfw_sync(hw, mask); + + return err; +} + /** * ngbe_validate_eeprom_checksum_em - Validate EEPROM checksum * @hw: pointer to hardware structure @@ -201,3 +225,35 @@ s32 ngbe_validate_eeprom_checksum_em(struct ngbe_hw *hw, return err; } +/** + * ngbe_save_eeprom_version + * @hw: pointer to hardware structure + * + * Save off EEPROM version number and Option Rom version which + * together make a unique identify for the eeprom + */ +s32 ngbe_save_eeprom_version(struct ngbe_hw *hw) +{ + u32 eeprom_verl = 0; + u32 etrack_id = 0; + u32 offset = (hw->rom.sw_addr + NGBE_EEPROM_VERSION_L) << 1; + + DEBUGFUNC("ngbe_save_eeprom_version"); + + if (hw->bus.lan_id == 0) { + hw->rom.read32(hw, offset, &eeprom_verl); + etrack_id = eeprom_verl; + wr32(hw, NGBE_EEPROM_VERSION_STORE_REG, etrack_id); + wr32(hw, NGBE_CALSUM_CAP_STATUS, + hw->rom.cksum_devcap | 0x10000); + } else if (hw->rom.cksum_devcap) { + etrack_id = hw->rom.saved_version; + } else { + hw->rom.read32(hw, offset, &eeprom_verl); + etrack_id = eeprom_verl; + } + + hw->eeprom_id = etrack_id; + + return 0; +} diff --git a/drivers/net/ngbe/base/ngbe_eeprom.h b/drivers/net/ngbe/base/ngbe_eeprom.h index b433077629..5f27425913 100644 --- a/drivers/net/ngbe/base/ngbe_eeprom.h +++ b/drivers/net/ngbe/base/ngbe_eeprom.h @@ -6,6 +6,8 @@ #ifndef _NGBE_EEPROM_H_ #define _NGBE_EEPROM_H_ +#define NGBE_EEPROM_VERSION_L 0x1D +#define NGBE_EEPROM_VERSION_H 0x1E #define NGBE_CALSUM_CAP_STATUS 0x10224 #define NGBE_EEPROM_VERSION_STORE_REG 0x1022C @@ -13,5 +15,8 @@ s32 ngbe_init_eeprom_params(struct ngbe_hw *hw); s32 ngbe_validate_eeprom_checksum_em(struct ngbe_hw *hw, u16 *checksum_val); s32 ngbe_get_eeprom_semaphore(struct ngbe_hw *hw); void ngbe_release_eeprom_semaphore(struct ngbe_hw *hw); +s32 ngbe_save_eeprom_version(struct ngbe_hw *hw); + +s32 ngbe_ee_read32(struct ngbe_hw *hw, u32 addr, u32 *data); #endif /* _NGBE_EEPROM_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_hw.c b/drivers/net/ngbe/base/ngbe_hw.c index c12e6e6dfd..f9fa721b67 100644 --- a/drivers/net/ngbe/base/ngbe_hw.c +++ b/drivers/net/ngbe/base/ngbe_hw.c @@ -47,6 +47,8 @@ s32 ngbe_init_hw(struct ngbe_hw *hw) DEBUGFUNC("ngbe_init_hw"); + ngbe_save_eeprom_version(hw); + /* Reset the hardware */ status = hw->mac.reset_hw(hw); if (status == 0) { @@ -1143,6 +1145,7 @@ s32 ngbe_init_ops_pf(struct ngbe_hw *hw) /* EEPROM */ rom->init_params = ngbe_init_eeprom_params; + rom->read32 = ngbe_ee_read32; rom->validate_checksum = ngbe_validate_eeprom_checksum_em; mac->mcft_size = NGBE_EM_MC_TBL_SIZE; diff --git a/drivers/net/ngbe/base/ngbe_mng.c b/drivers/net/ngbe/base/ngbe_mng.c index 6ad2838ea7..9416ea4c8d 100644 --- a/drivers/net/ngbe/base/ngbe_mng.c +++ b/drivers/net/ngbe/base/ngbe_mng.c @@ -158,6 +158,50 @@ rel_out: return err; } +/** + * ngbe_hic_sr_read - Read EEPROM word using a host interface cmd + * assuming that the semaphore is already obtained. + * @hw: pointer to hardware structure + * @offset: offset of word in the EEPROM to read + * @data: word read from the EEPROM + * + * Reads a 16 bit word from the EEPROM using the hostif. + **/ +s32 ngbe_hic_sr_read(struct ngbe_hw *hw, u32 addr, u8 *buf, int len) +{ + struct ngbe_hic_read_shadow_ram command; + u32 value; + int err, i = 0, j = 0; + + if (len > NGBE_PMMBX_DATA_SIZE) + return NGBE_ERR_HOST_INTERFACE_COMMAND; + + memset(&command, 0, sizeof(command)); + command.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD; + command.hdr.req.buf_lenh = 0; + command.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN; + command.hdr.req.checksum = FW_DEFAULT_CHECKSUM; + command.address = cpu_to_be32(addr); + command.length = cpu_to_be16(len); + + err = ngbe_hic_unlocked(hw, (u32 *)&command, + sizeof(command), NGBE_HI_COMMAND_TIMEOUT); + if (err) + return err; + + while (i < (len >> 2)) { + value = rd32a(hw, NGBE_MNGMBX, FW_NVM_DATA_OFFSET + i); + ((u32 *)buf)[i] = value; + i++; + } + + value = rd32a(hw, NGBE_MNGMBX, FW_NVM_DATA_OFFSET + i); + for (i <<= 2; i < len; i++) + ((u8 *)buf)[i] = ((u8 *)&value)[j++]; + + return 0; +} + s32 ngbe_hic_check_cap(struct ngbe_hw *hw) { struct ngbe_hic_read_shadow_ram command; diff --git a/drivers/net/ngbe/base/ngbe_mng.h b/drivers/net/ngbe/base/ngbe_mng.h index e86893101b..6f368b028f 100644 --- a/drivers/net/ngbe/base/ngbe_mng.h +++ b/drivers/net/ngbe/base/ngbe_mng.h @@ -10,12 +10,16 @@ #define NGBE_PMMBX_QSIZE 64 /* Num of dwords in range */ #define NGBE_PMMBX_BSIZE (NGBE_PMMBX_QSIZE * 4) +#define NGBE_PMMBX_DATA_SIZE (NGBE_PMMBX_BSIZE - FW_NVM_DATA_OFFSET * 4) #define NGBE_HI_COMMAND_TIMEOUT 5000 /* Process HI command limit */ /* CEM Support */ #define FW_CEM_MAX_RETRIES 3 #define FW_CEM_RESP_STATUS_SUCCESS 0x1 +#define FW_READ_SHADOW_RAM_CMD 0x31 +#define FW_READ_SHADOW_RAM_LEN 0x6 #define FW_DEFAULT_CHECKSUM 0xFF /* checksum always 0xFF */ +#define FW_NVM_DATA_OFFSET 3 #define FW_EEPROM_CHECK_STATUS 0xE9 #define FW_CHECKSUM_CAP_ST_PASS 0x80658383 @@ -61,5 +65,6 @@ struct ngbe_hic_read_shadow_ram { u16 pad3; }; +s32 ngbe_hic_sr_read(struct ngbe_hw *hw, u32 addr, u8 *buf, int len); s32 ngbe_hic_check_cap(struct ngbe_hw *hw); #endif /* _NGBE_MNG_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h index 58a5180881..5caefc99e5 100644 --- a/drivers/net/ngbe/base/ngbe_type.h +++ b/drivers/net/ngbe/base/ngbe_type.h @@ -203,6 +203,7 @@ struct ngbe_hw_stats { struct ngbe_rom_info { s32 (*init_params)(struct ngbe_hw *hw); + s32 (*read32)(struct ngbe_hw *hw, u32 addr, u32 *data); s32 (*validate_checksum)(struct ngbe_hw *hw, u16 *checksum_val); enum ngbe_eeprom_type type; @@ -313,6 +314,7 @@ struct ngbe_hw { u16 vendor_id; u16 sub_device_id; u16 sub_system_id; + u32 eeprom_id; bool adapter_stopped; uint64_t isb_dma; diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c index 0e588eecce..394b60247f 100644 --- a/drivers/net/ngbe/ngbe_ethdev.c +++ b/drivers/net/ngbe/ngbe_ethdev.c @@ -1595,6 +1595,24 @@ ngbe_dev_xstats_reset(struct rte_eth_dev *dev) return 0; } +static int +ngbe_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size) +{ + struct ngbe_hw *hw = ngbe_dev_hw(dev); + int ret; + + ret = snprintf(fw_version, fw_size, "0x%08x", hw->eeprom_id); + + if (ret < 0) + return -EINVAL; + + ret += 1; /* add the size of '\0' */ + if (fw_size < (size_t)ret) + return ret; + + return 0; +} + static int ngbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) { @@ -2240,6 +2258,7 @@ static const struct eth_dev_ops ngbe_eth_dev_ops = { .xstats_reset = ngbe_dev_xstats_reset, .xstats_get_names = ngbe_dev_xstats_get_names, .xstats_get_names_by_id = ngbe_dev_xstats_get_names_by_id, + .fw_version_get = ngbe_fw_version_get, .dev_supported_ptypes_get = ngbe_dev_supported_ptypes_get, .mtu_set = ngbe_dev_mtu_set, .vlan_filter_set = ngbe_vlan_filter_set,