|
@@ -920,6 +920,70 @@ i40e_status i40e_init_dcb(struct i40e_hw *hw)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * _i40e_read_lldp_cfg - generic read of LLDP Configuration data from NVM
|
|
|
+ * @hw: pointer to the HW structure
|
|
|
+ * @lldp_cfg: pointer to hold lldp configuration variables
|
|
|
+ * @module: address of the module pointer
|
|
|
+ * @word_offset: offset of LLDP configuration
|
|
|
+ *
|
|
|
+ * Reads the LLDP configuration data from NVM using passed addresses
|
|
|
+ **/
|
|
|
+static i40e_status _i40e_read_lldp_cfg(struct i40e_hw *hw,
|
|
|
+ struct i40e_lldp_variables *lldp_cfg,
|
|
|
+ u8 module, u32 word_offset)
|
|
|
+{
|
|
|
+ u32 address, offset = (2 * word_offset);
|
|
|
+ i40e_status ret;
|
|
|
+ __le16 raw_mem;
|
|
|
+ u16 mem;
|
|
|
+
|
|
|
+ ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ ret = i40e_aq_read_nvm(hw, 0x0, module * 2, sizeof(raw_mem), &raw_mem,
|
|
|
+ true, NULL);
|
|
|
+ i40e_release_nvm(hw);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ mem = le16_to_cpu(raw_mem);
|
|
|
+ /* Check if this pointer needs to be read in word size or 4K sector
|
|
|
+ * units.
|
|
|
+ */
|
|
|
+ if (mem & I40E_PTR_TYPE)
|
|
|
+ address = (0x7FFF & mem) * 4096;
|
|
|
+ else
|
|
|
+ address = (0x7FFF & mem) * 2;
|
|
|
+
|
|
|
+ ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
|
|
|
+ if (ret)
|
|
|
+ goto err_lldp_cfg;
|
|
|
+
|
|
|
+ ret = i40e_aq_read_nvm(hw, module, offset, sizeof(raw_mem), &raw_mem,
|
|
|
+ true, NULL);
|
|
|
+ i40e_release_nvm(hw);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ mem = le16_to_cpu(raw_mem);
|
|
|
+ offset = mem + word_offset;
|
|
|
+ offset *= 2;
|
|
|
+
|
|
|
+ ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
|
|
|
+ if (ret)
|
|
|
+ goto err_lldp_cfg;
|
|
|
+
|
|
|
+ ret = i40e_aq_read_nvm(hw, 0, address + offset,
|
|
|
+ sizeof(struct i40e_lldp_variables), lldp_cfg,
|
|
|
+ true, NULL);
|
|
|
+ i40e_release_nvm(hw);
|
|
|
+
|
|
|
+err_lldp_cfg:
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* i40e_read_lldp_cfg - read LLDP Configuration data from NVM
|
|
|
* @hw: pointer to the HW structure
|
|
@@ -931,21 +995,34 @@ i40e_status i40e_read_lldp_cfg(struct i40e_hw *hw,
|
|
|
struct i40e_lldp_variables *lldp_cfg)
|
|
|
{
|
|
|
i40e_status ret = 0;
|
|
|
- u32 offset = (2 * I40E_NVM_LLDP_CFG_PTR);
|
|
|
+ u32 mem;
|
|
|
|
|
|
if (!lldp_cfg)
|
|
|
return I40E_ERR_PARAM;
|
|
|
|
|
|
ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
|
|
|
if (ret)
|
|
|
- goto err_lldp_cfg;
|
|
|
+ return ret;
|
|
|
|
|
|
- ret = i40e_aq_read_nvm(hw, I40E_SR_EMP_MODULE_PTR, offset,
|
|
|
- sizeof(struct i40e_lldp_variables),
|
|
|
- (u8 *)lldp_cfg,
|
|
|
- true, NULL);
|
|
|
+ ret = i40e_aq_read_nvm(hw, I40E_SR_NVM_CONTROL_WORD, 0, sizeof(mem),
|
|
|
+ &mem, true, NULL);
|
|
|
i40e_release_nvm(hw);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ /* Read a bit that holds information whether we are running flat or
|
|
|
+ * structured NVM image. Flat image has LLDP configuration in shadow
|
|
|
+ * ram, so there is a need to pass different addresses for both cases.
|
|
|
+ */
|
|
|
+ if (mem & I40E_SR_NVM_MAP_STRUCTURE_TYPE) {
|
|
|
+ /* Flat NVM case */
|
|
|
+ ret = _i40e_read_lldp_cfg(hw, lldp_cfg, I40E_SR_EMP_MODULE_PTR,
|
|
|
+ I40E_SR_LLDP_CFG_PTR);
|
|
|
+ } else {
|
|
|
+ /* Good old structured NVM image */
|
|
|
+ ret = _i40e_read_lldp_cfg(hw, lldp_cfg, I40E_EMP_MODULE_PTR,
|
|
|
+ I40E_NVM_LLDP_CFG_PTR);
|
|
|
+ }
|
|
|
|
|
|
-err_lldp_cfg:
|
|
|
return ret;
|
|
|
}
|