ixgbe: read the netlist version information

Add functions reading the netlist version info and use them
as a part of the setting NVM info procedure.

Reviewed-by: Mateusz Polchlopek <mateusz.polchlopek@intel.com>
Tested-by: Bharath R <bharath.r@intel.com>
Signed-off-by: Slawomir Mrozowicz <slawomirx.mrozowicz@intel.com>
Co-developed-by: Piotr Kwapulinski <piotr.kwapulinski@intel.com>
Signed-off-by: Piotr Kwapulinski <piotr.kwapulinski@intel.com>
Signed-off-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
Slawomir Mrozowicz 2025-04-10 15:00:00 +02:00 committed by Tony Nguyen
parent 70db0788a2
commit 904c2b4c0b
2 changed files with 145 additions and 0 deletions

View File

@ -2585,6 +2585,33 @@ static int ixgbe_read_nvm_module(struct ixgbe_hw *hw,
return err;
}
/**
* ixgbe_read_netlist_module - Read data from the netlist module area
* @hw: pointer to the HW structure
* @bank: whether to read from the active or inactive module
* @offset: offset into the netlist to read from
* @data: storage for returned word value
*
* Read a word from the specified netlist bank.
*
* Return: the exit code of the operation.
*/
static int ixgbe_read_netlist_module(struct ixgbe_hw *hw,
enum ixgbe_bank_select bank,
u32 offset, u16 *data)
{
__le16 data_local;
int err;
err = ixgbe_read_flash_module(hw, bank, IXGBE_E610_SR_NETLIST_BANK_PTR,
offset * sizeof(data_local),
(u8 *)&data_local, sizeof(data_local));
if (!err)
*data = le16_to_cpu(data_local);
return err;
}
/**
* ixgbe_read_orom_module - Read from the active Option ROM module
* @hw: pointer to the HW structure
@ -2888,6 +2915,86 @@ static int ixgbe_get_nvm_ver_info(struct ixgbe_hw *hw,
return 0;
}
/**
* ixgbe_get_netlist_info - Read the netlist version information
* @hw: pointer to the HW struct
* @bank: whether to read from the active or inactive flash bank
* @netlist: pointer to netlist version info structure
*
* Get the netlist version information from the requested bank. Reads the Link
* Topology section to find the Netlist ID block and extract the relevant
* information into the netlist version structure.
*
* Return: the exit code of the operation.
*/
static int ixgbe_get_netlist_info(struct ixgbe_hw *hw,
enum ixgbe_bank_select bank,
struct ixgbe_netlist_info *netlist)
{
u16 module_id, length, node_count, i;
u16 *id_blk;
int err;
err = ixgbe_read_netlist_module(hw, bank, IXGBE_NETLIST_TYPE_OFFSET,
&module_id);
if (err)
return err;
if (module_id != IXGBE_NETLIST_LINK_TOPO_MOD_ID)
return -EIO;
err = ixgbe_read_netlist_module(hw, bank, IXGBE_LINK_TOPO_MODULE_LEN,
&length);
if (err)
return err;
/* Sanity check that we have at least enough words to store the
* netlist ID block.
*/
if (length < IXGBE_NETLIST_ID_BLK_SIZE)
return -EIO;
err = ixgbe_read_netlist_module(hw, bank, IXGBE_LINK_TOPO_NODE_COUNT,
&node_count);
if (err)
return err;
node_count &= IXGBE_LINK_TOPO_NODE_COUNT_M;
id_blk = kcalloc(IXGBE_NETLIST_ID_BLK_SIZE, sizeof(*id_blk), GFP_KERNEL);
if (!id_blk)
return -ENOMEM;
/* Read out the entire Netlist ID Block at once. */
err = ixgbe_read_flash_module(hw, bank, IXGBE_E610_SR_NETLIST_BANK_PTR,
IXGBE_NETLIST_ID_BLK_OFFSET(node_count) *
sizeof(*id_blk), (u8 *)id_blk,
IXGBE_NETLIST_ID_BLK_SIZE *
sizeof(*id_blk));
if (err)
goto free_id_blk;
for (i = 0; i < IXGBE_NETLIST_ID_BLK_SIZE; i++)
id_blk[i] = le16_to_cpu(((__le16 *)id_blk)[i]);
netlist->major = id_blk[IXGBE_NETLIST_ID_BLK_MAJOR_VER_HIGH] << 16 |
id_blk[IXGBE_NETLIST_ID_BLK_MAJOR_VER_LOW];
netlist->minor = id_blk[IXGBE_NETLIST_ID_BLK_MINOR_VER_HIGH] << 16 |
id_blk[IXGBE_NETLIST_ID_BLK_MINOR_VER_LOW];
netlist->type = id_blk[IXGBE_NETLIST_ID_BLK_TYPE_HIGH] << 16 |
id_blk[IXGBE_NETLIST_ID_BLK_TYPE_LOW];
netlist->rev = id_blk[IXGBE_NETLIST_ID_BLK_REV_HIGH] << 16 |
id_blk[IXGBE_NETLIST_ID_BLK_REV_LOW];
netlist->cust_ver = id_blk[IXGBE_NETLIST_ID_BLK_CUST_VER];
/* Read the left most 4 bytes of SHA */
netlist->hash = id_blk[IXGBE_NETLIST_ID_BLK_SHA_HASH_WORD(15)] << 16 |
id_blk[IXGBE_NETLIST_ID_BLK_SHA_HASH_WORD(14)];
free_id_blk:
kfree(id_blk);
return err;
}
/**
* ixgbe_get_flash_data - get flash data
* @hw: pointer to the HW struct
@ -2937,6 +3044,11 @@ int ixgbe_get_flash_data(struct ixgbe_hw *hw)
err = ixgbe_get_orom_ver_info(hw, IXGBE_ACTIVE_FLASH_BANK,
&flash->orom);
if (err)
return err;
err = ixgbe_get_netlist_info(hw, IXGBE_ACTIVE_FLASH_BANK,
&flash->netlist);
return err;
}

View File

@ -45,6 +45,39 @@
/* Shadow RAM related */
#define IXGBE_SR_WORDS_IN_1KB 512
/* The Netlist ID Block is located after all of the Link Topology nodes. */
#define IXGBE_NETLIST_ID_BLK_SIZE 0x30
#define IXGBE_NETLIST_ID_BLK_OFFSET(n) IXGBE_NETLIST_LINK_TOPO_OFFSET(0x0004 + 2 * (n))
/* netlist ID block field offsets (word offsets) */
#define IXGBE_NETLIST_ID_BLK_MAJOR_VER_LOW 0x02
#define IXGBE_NETLIST_ID_BLK_MAJOR_VER_HIGH 0x03
#define IXGBE_NETLIST_ID_BLK_MINOR_VER_LOW 0x04
#define IXGBE_NETLIST_ID_BLK_MINOR_VER_HIGH 0x05
#define IXGBE_NETLIST_ID_BLK_TYPE_LOW 0x06
#define IXGBE_NETLIST_ID_BLK_TYPE_HIGH 0x07
#define IXGBE_NETLIST_ID_BLK_REV_LOW 0x08
#define IXGBE_NETLIST_ID_BLK_REV_HIGH 0x09
#define IXGBE_NETLIST_ID_BLK_SHA_HASH_WORD(n) (0x0A + (n))
#define IXGBE_NETLIST_ID_BLK_CUST_VER 0x2F
/* The Link Topology Netlist section is stored as a series of words. It is
* stored in the NVM as a TLV, with the first two words containing the type
* and length.
*/
#define IXGBE_NETLIST_LINK_TOPO_MOD_ID 0x011B
#define IXGBE_NETLIST_TYPE_OFFSET 0x0000
#define IXGBE_NETLIST_LEN_OFFSET 0x0001
/* The Link Topology section follows the TLV header. When reading the netlist
* using ixgbe_read_netlist_module, we need to account for the 2-word TLV
* header.
*/
#define IXGBE_NETLIST_LINK_TOPO_OFFSET(n) ((n) + 2)
#define IXGBE_LINK_TOPO_MODULE_LEN IXGBE_NETLIST_LINK_TOPO_OFFSET(0x0000)
#define IXGBE_LINK_TOPO_NODE_COUNT IXGBE_NETLIST_LINK_TOPO_OFFSET(0x0001)
#define IXGBE_LINK_TOPO_NODE_COUNT_M GENMASK_ULL(9, 0)
/* Firmware Status Register (GL_FWSTS) */
#define GL_FWSTS 0x00083048 /* Reset Source: POR */
#define GL_FWSTS_EP_PF0 BIT(24)