ice: add board identifier info to devlink .info_get
Export a unique board identifier using "board.id" for devlink's .info_get command. Obtain this by reading the NVM for the PBA identification string. Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Reviewed-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Acked-by: Jakub Kicinski <kuba@kernel.org> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
ff2e5c700e
commit
e961b679fb
|
@ -19,6 +19,10 @@ The ``ice`` driver reports the following versions
|
|||
- Type
|
||||
- Example
|
||||
- Description
|
||||
* - ``board.id``
|
||||
- fixed
|
||||
- K65390-000
|
||||
- The Product Board Assembly (PBA) identifier of the board.
|
||||
* - ``fw.mgmt``
|
||||
- running
|
||||
- 2.1.7
|
||||
|
|
|
@ -934,72 +934,6 @@ enum ice_status ice_reset(struct ice_hw *hw, enum ice_reset_req req)
|
|||
return ice_check_reset(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_get_pfa_module_tlv - Reads sub module TLV from NVM PFA
|
||||
* @hw: pointer to hardware structure
|
||||
* @module_tlv: pointer to module TLV to return
|
||||
* @module_tlv_len: pointer to module TLV length to return
|
||||
* @module_type: module type requested
|
||||
*
|
||||
* Finds the requested sub module TLV type from the Preserved Field
|
||||
* Area (PFA) and returns the TLV pointer and length. The caller can
|
||||
* use these to read the variable length TLV value.
|
||||
*/
|
||||
enum ice_status
|
||||
ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len,
|
||||
u16 module_type)
|
||||
{
|
||||
enum ice_status status;
|
||||
u16 pfa_len, pfa_ptr;
|
||||
u16 next_tlv;
|
||||
|
||||
status = ice_read_sr_word(hw, ICE_SR_PFA_PTR, &pfa_ptr);
|
||||
if (status) {
|
||||
ice_debug(hw, ICE_DBG_INIT, "Preserved Field Array pointer.\n");
|
||||
return status;
|
||||
}
|
||||
status = ice_read_sr_word(hw, pfa_ptr, &pfa_len);
|
||||
if (status) {
|
||||
ice_debug(hw, ICE_DBG_INIT, "Failed to read PFA length.\n");
|
||||
return status;
|
||||
}
|
||||
/* Starting with first TLV after PFA length, iterate through the list
|
||||
* of TLVs to find the requested one.
|
||||
*/
|
||||
next_tlv = pfa_ptr + 1;
|
||||
while (next_tlv < pfa_ptr + pfa_len) {
|
||||
u16 tlv_sub_module_type;
|
||||
u16 tlv_len;
|
||||
|
||||
/* Read TLV type */
|
||||
status = ice_read_sr_word(hw, next_tlv, &tlv_sub_module_type);
|
||||
if (status) {
|
||||
ice_debug(hw, ICE_DBG_INIT, "Failed to read TLV type.\n");
|
||||
break;
|
||||
}
|
||||
/* Read TLV length */
|
||||
status = ice_read_sr_word(hw, next_tlv + 1, &tlv_len);
|
||||
if (status) {
|
||||
ice_debug(hw, ICE_DBG_INIT, "Failed to read TLV length.\n");
|
||||
break;
|
||||
}
|
||||
if (tlv_sub_module_type == module_type) {
|
||||
if (tlv_len) {
|
||||
*module_tlv = next_tlv;
|
||||
*module_tlv_len = tlv_len;
|
||||
return 0;
|
||||
}
|
||||
return ICE_ERR_INVAL_SIZE;
|
||||
}
|
||||
/* Check next TLV, i.e. current TLV pointer + length + 2 words
|
||||
* (for current TLV's type and length)
|
||||
*/
|
||||
next_tlv = next_tlv + tlv_len + 2;
|
||||
}
|
||||
/* Module does not exist */
|
||||
return ICE_ERR_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_copy_rxq_ctx_to_hw
|
||||
* @hw: pointer to the hardware structure
|
||||
|
|
|
@ -15,9 +15,6 @@ enum ice_status ice_nvm_validate_checksum(struct ice_hw *hw);
|
|||
|
||||
enum ice_status ice_init_hw(struct ice_hw *hw);
|
||||
void ice_deinit_hw(struct ice_hw *hw);
|
||||
enum ice_status
|
||||
ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len,
|
||||
u16 module_type);
|
||||
enum ice_status ice_check_reset(struct ice_hw *hw);
|
||||
enum ice_status ice_reset(struct ice_hw *hw, enum ice_reset_req req);
|
||||
enum ice_status ice_create_all_ctrlq(struct ice_hw *hw);
|
||||
|
|
|
@ -19,6 +19,18 @@ static int ice_info_get_dsn(struct ice_pf *pf, char *buf, size_t len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ice_info_pba(struct ice_pf *pf, char *buf, size_t len)
|
||||
{
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
enum ice_status status;
|
||||
|
||||
status = ice_read_pba_string(hw, (u8 *)buf, len);
|
||||
if (status)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ice_info_fw_mgmt(struct ice_pf *pf, char *buf, size_t len)
|
||||
{
|
||||
struct ice_hw *hw = &pf->hw;
|
||||
|
@ -93,6 +105,7 @@ static int ice_info_ddp_pkg_version(struct ice_pf *pf, char *buf, size_t len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define fixed(key, getter) { ICE_VERSION_FIXED, key, getter }
|
||||
#define running(key, getter) { ICE_VERSION_RUNNING, key, getter }
|
||||
|
||||
enum ice_version_type {
|
||||
|
@ -106,6 +119,7 @@ static const struct ice_devlink_version {
|
|||
const char *key;
|
||||
int (*getter)(struct ice_pf *pf, char *buf, size_t len);
|
||||
} ice_devlink_versions[] = {
|
||||
fixed(DEVLINK_INFO_VERSION_GENERIC_BOARD_ID, ice_info_pba),
|
||||
running(DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, ice_info_fw_mgmt),
|
||||
running("fw.mgmt.api", ice_info_fw_api),
|
||||
running("fw.mgmt.build", ice_info_fw_build),
|
||||
|
@ -125,7 +139,7 @@ static const struct ice_devlink_version {
|
|||
* Callback for the devlink .info_get operation. Reports information about the
|
||||
* device.
|
||||
*
|
||||
* @returns zero on success or an error code on failure.
|
||||
* Return: zero on success or an error code on failure.
|
||||
*/
|
||||
static int ice_devlink_info_get(struct devlink *devlink,
|
||||
struct devlink_info_req *req,
|
||||
|
|
|
@ -185,6 +185,131 @@ enum ice_status ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data)
|
|||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_get_pfa_module_tlv - Reads sub module TLV from NVM PFA
|
||||
* @hw: pointer to hardware structure
|
||||
* @module_tlv: pointer to module TLV to return
|
||||
* @module_tlv_len: pointer to module TLV length to return
|
||||
* @module_type: module type requested
|
||||
*
|
||||
* Finds the requested sub module TLV type from the Preserved Field
|
||||
* Area (PFA) and returns the TLV pointer and length. The caller can
|
||||
* use these to read the variable length TLV value.
|
||||
*/
|
||||
enum ice_status
|
||||
ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len,
|
||||
u16 module_type)
|
||||
{
|
||||
enum ice_status status;
|
||||
u16 pfa_len, pfa_ptr;
|
||||
u16 next_tlv;
|
||||
|
||||
status = ice_read_sr_word(hw, ICE_SR_PFA_PTR, &pfa_ptr);
|
||||
if (status) {
|
||||
ice_debug(hw, ICE_DBG_INIT, "Preserved Field Array pointer.\n");
|
||||
return status;
|
||||
}
|
||||
status = ice_read_sr_word(hw, pfa_ptr, &pfa_len);
|
||||
if (status) {
|
||||
ice_debug(hw, ICE_DBG_INIT, "Failed to read PFA length.\n");
|
||||
return status;
|
||||
}
|
||||
/* Starting with first TLV after PFA length, iterate through the list
|
||||
* of TLVs to find the requested one.
|
||||
*/
|
||||
next_tlv = pfa_ptr + 1;
|
||||
while (next_tlv < pfa_ptr + pfa_len) {
|
||||
u16 tlv_sub_module_type;
|
||||
u16 tlv_len;
|
||||
|
||||
/* Read TLV type */
|
||||
status = ice_read_sr_word(hw, next_tlv, &tlv_sub_module_type);
|
||||
if (status) {
|
||||
ice_debug(hw, ICE_DBG_INIT, "Failed to read TLV type.\n");
|
||||
break;
|
||||
}
|
||||
/* Read TLV length */
|
||||
status = ice_read_sr_word(hw, next_tlv + 1, &tlv_len);
|
||||
if (status) {
|
||||
ice_debug(hw, ICE_DBG_INIT, "Failed to read TLV length.\n");
|
||||
break;
|
||||
}
|
||||
if (tlv_sub_module_type == module_type) {
|
||||
if (tlv_len) {
|
||||
*module_tlv = next_tlv;
|
||||
*module_tlv_len = tlv_len;
|
||||
return 0;
|
||||
}
|
||||
return ICE_ERR_INVAL_SIZE;
|
||||
}
|
||||
/* Check next TLV, i.e. current TLV pointer + length + 2 words
|
||||
* (for current TLV's type and length)
|
||||
*/
|
||||
next_tlv = next_tlv + tlv_len + 2;
|
||||
}
|
||||
/* Module does not exist */
|
||||
return ICE_ERR_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_read_pba_string - Reads part number string from NVM
|
||||
* @hw: pointer to hardware structure
|
||||
* @pba_num: stores the part number string from the NVM
|
||||
* @pba_num_size: part number string buffer length
|
||||
*
|
||||
* Reads the part number string from the NVM.
|
||||
*/
|
||||
enum ice_status
|
||||
ice_read_pba_string(struct ice_hw *hw, u8 *pba_num, u32 pba_num_size)
|
||||
{
|
||||
u16 pba_tlv, pba_tlv_len;
|
||||
enum ice_status status;
|
||||
u16 pba_word, pba_size;
|
||||
u16 i;
|
||||
|
||||
status = ice_get_pfa_module_tlv(hw, &pba_tlv, &pba_tlv_len,
|
||||
ICE_SR_PBA_BLOCK_PTR);
|
||||
if (status) {
|
||||
ice_debug(hw, ICE_DBG_INIT, "Failed to read PBA Block TLV.\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
/* pba_size is the next word */
|
||||
status = ice_read_sr_word(hw, (pba_tlv + 2), &pba_size);
|
||||
if (status) {
|
||||
ice_debug(hw, ICE_DBG_INIT, "Failed to read PBA Section size.\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
if (pba_tlv_len < pba_size) {
|
||||
ice_debug(hw, ICE_DBG_INIT, "Invalid PBA Block TLV size.\n");
|
||||
return ICE_ERR_INVAL_SIZE;
|
||||
}
|
||||
|
||||
/* Subtract one to get PBA word count (PBA Size word is included in
|
||||
* total size)
|
||||
*/
|
||||
pba_size--;
|
||||
if (pba_num_size < (((u32)pba_size * 2) + 1)) {
|
||||
ice_debug(hw, ICE_DBG_INIT, "Buffer too small for PBA data.\n");
|
||||
return ICE_ERR_PARAM;
|
||||
}
|
||||
|
||||
for (i = 0; i < pba_size; i++) {
|
||||
status = ice_read_sr_word(hw, (pba_tlv + 2 + 1) + i, &pba_word);
|
||||
if (status) {
|
||||
ice_debug(hw, ICE_DBG_INIT, "Failed to read PBA Block word %d.\n", i);
|
||||
return status;
|
||||
}
|
||||
|
||||
pba_num[(i * 2)] = (pba_word >> 8) & 0xFF;
|
||||
pba_num[(i * 2) + 1] = pba_word & 0xFF;
|
||||
}
|
||||
pba_num[(pba_size * 2)] = '\0';
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_get_orom_ver_info - Read Option ROM version information
|
||||
* @hw: pointer to the HW struct
|
||||
|
|
|
@ -10,6 +10,11 @@ void ice_release_nvm(struct ice_hw *hw);
|
|||
enum ice_status
|
||||
ice_read_flat_nvm(struct ice_hw *hw, u32 offset, u32 *length, u8 *data,
|
||||
bool read_shadow_ram);
|
||||
enum ice_status
|
||||
ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len,
|
||||
u16 module_type);
|
||||
enum ice_status
|
||||
ice_read_pba_string(struct ice_hw *hw, u8 *pba_num, u32 pba_num_size);
|
||||
enum ice_status ice_init_nvm(struct ice_hw *hw);
|
||||
enum ice_status ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data);
|
||||
#endif /* _ICE_NVM_H_ */
|
||||
|
|
|
@ -636,6 +636,7 @@ struct ice_hw_port_stats {
|
|||
/* Checksum and Shadow RAM pointers */
|
||||
#define ICE_SR_BOOT_CFG_PTR 0x132
|
||||
#define ICE_NVM_OROM_VER_OFF 0x02
|
||||
#define ICE_SR_PBA_BLOCK_PTR 0x16
|
||||
#define ICE_SR_NVM_DEV_STARTER_VER 0x18
|
||||
#define ICE_SR_NVM_EETRACK_LO 0x2D
|
||||
#define ICE_SR_NVM_EETRACK_HI 0x2E
|
||||
|
|
Loading…
Reference in New Issue