|
@@ -240,6 +240,46 @@ i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
|
|
|
return ret_code;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * i40e_write_nvm_aq - Writes Shadow RAM.
|
|
|
+ * @hw: pointer to the HW structure.
|
|
|
+ * @module_pointer: module pointer location in words from the NVM beginning
|
|
|
+ * @offset: offset in words from module start
|
|
|
+ * @words: number of words to write
|
|
|
+ * @data: buffer with words to write to the Shadow RAM
|
|
|
+ * @last_command: tells the AdminQ that this is the last command
|
|
|
+ *
|
|
|
+ * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
|
|
|
+ **/
|
|
|
+i40e_status i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
|
|
|
+ u32 offset, u16 words, void *data,
|
|
|
+ bool last_command)
|
|
|
+{
|
|
|
+ i40e_status ret_code = I40E_ERR_NVM;
|
|
|
+
|
|
|
+ /* Here we are checking the SR limit only for the flat memory model.
|
|
|
+ * We cannot do it for the module-based model, as we did not acquire
|
|
|
+ * the NVM resource yet (we cannot get the module pointer value).
|
|
|
+ * Firmware will check the module-based model.
|
|
|
+ */
|
|
|
+ if ((offset + words) > hw->nvm.sr_size)
|
|
|
+ hw_dbg(hw, "NVM write error: offset beyond Shadow RAM limit.\n");
|
|
|
+ else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS)
|
|
|
+ /* We can write only up to 4KB (one sector), in one AQ write */
|
|
|
+ hw_dbg(hw, "NVM write fail error: cannot write more than 4KB in a single write.\n");
|
|
|
+ else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS)
|
|
|
+ != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS))
|
|
|
+ /* A single write cannot spread over two sectors */
|
|
|
+ hw_dbg(hw, "NVM write error: cannot spread over two sectors in a single write.\n");
|
|
|
+ else
|
|
|
+ ret_code = i40e_aq_update_nvm(hw, module_pointer,
|
|
|
+ 2 * offset, /*bytes*/
|
|
|
+ 2 * words, /*bytes*/
|
|
|
+ data, last_command, NULL);
|
|
|
+
|
|
|
+ return ret_code;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* i40e_calc_nvm_checksum - Calculates and returns the checksum
|
|
|
* @hw: pointer to hardware structure
|
|
@@ -309,6 +349,27 @@ i40e_calc_nvm_checksum_exit:
|
|
|
return ret_code;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * i40e_update_nvm_checksum - Updates the NVM checksum
|
|
|
+ * @hw: pointer to hardware structure
|
|
|
+ *
|
|
|
+ * NVM ownership must be acquired before calling this function and released
|
|
|
+ * on ARQ completion event reception by caller.
|
|
|
+ * This function will commit SR to NVM.
|
|
|
+ **/
|
|
|
+i40e_status i40e_update_nvm_checksum(struct i40e_hw *hw)
|
|
|
+{
|
|
|
+ i40e_status ret_code = 0;
|
|
|
+ u16 checksum;
|
|
|
+
|
|
|
+ ret_code = i40e_calc_nvm_checksum(hw, &checksum);
|
|
|
+ if (!ret_code)
|
|
|
+ ret_code = i40e_write_nvm_aq(hw, 0x00, I40E_SR_SW_CHECKSUM_WORD,
|
|
|
+ 1, &checksum, true);
|
|
|
+
|
|
|
+ return ret_code;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* i40e_validate_nvm_checksum - Validate EEPROM checksum
|
|
|
* @hw: pointer to hardware structure
|
|
@@ -346,3 +407,453 @@ i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
|
|
|
i40e_validate_nvm_checksum_exit:
|
|
|
return ret_code;
|
|
|
}
|
|
|
+
|
|
|
+static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
|
|
|
+ struct i40e_nvm_access *cmd,
|
|
|
+ u8 *bytes, int *errno);
|
|
|
+static i40e_status i40e_nvmupd_state_reading(struct i40e_hw *hw,
|
|
|
+ struct i40e_nvm_access *cmd,
|
|
|
+ u8 *bytes, int *errno);
|
|
|
+static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
|
|
|
+ struct i40e_nvm_access *cmd,
|
|
|
+ u8 *bytes, int *errno);
|
|
|
+static enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
|
|
|
+ struct i40e_nvm_access *cmd,
|
|
|
+ int *errno);
|
|
|
+static i40e_status i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
|
|
|
+ struct i40e_nvm_access *cmd,
|
|
|
+ int *errno);
|
|
|
+static i40e_status i40e_nvmupd_nvm_write(struct i40e_hw *hw,
|
|
|
+ struct i40e_nvm_access *cmd,
|
|
|
+ u8 *bytes, int *errno);
|
|
|
+static i40e_status i40e_nvmupd_nvm_read(struct i40e_hw *hw,
|
|
|
+ struct i40e_nvm_access *cmd,
|
|
|
+ u8 *bytes, int *errno);
|
|
|
+static inline u8 i40e_nvmupd_get_module(u32 val)
|
|
|
+{
|
|
|
+ return (u8)(val & I40E_NVM_MOD_PNT_MASK);
|
|
|
+}
|
|
|
+static inline u8 i40e_nvmupd_get_transaction(u32 val)
|
|
|
+{
|
|
|
+ return (u8)((val & I40E_NVM_TRANS_MASK) >> I40E_NVM_TRANS_SHIFT);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * i40e_nvmupd_command - Process an NVM update command
|
|
|
+ * @hw: pointer to hardware structure
|
|
|
+ * @cmd: pointer to nvm update command
|
|
|
+ * @bytes: pointer to the data buffer
|
|
|
+ * @errno: pointer to return error code
|
|
|
+ *
|
|
|
+ * Dispatches command depending on what update state is current
|
|
|
+ **/
|
|
|
+i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
|
|
|
+ struct i40e_nvm_access *cmd,
|
|
|
+ u8 *bytes, int *errno)
|
|
|
+{
|
|
|
+ i40e_status status;
|
|
|
+
|
|
|
+ /* assume success */
|
|
|
+ *errno = 0;
|
|
|
+
|
|
|
+ switch (hw->nvmupd_state) {
|
|
|
+ case I40E_NVMUPD_STATE_INIT:
|
|
|
+ status = i40e_nvmupd_state_init(hw, cmd, bytes, errno);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case I40E_NVMUPD_STATE_READING:
|
|
|
+ status = i40e_nvmupd_state_reading(hw, cmd, bytes, errno);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case I40E_NVMUPD_STATE_WRITING:
|
|
|
+ status = i40e_nvmupd_state_writing(hw, cmd, bytes, errno);
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ /* invalid state, should never happen */
|
|
|
+ status = I40E_NOT_SUPPORTED;
|
|
|
+ *errno = -ESRCH;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * i40e_nvmupd_state_init - Handle NVM update state Init
|
|
|
+ * @hw: pointer to hardware structure
|
|
|
+ * @cmd: pointer to nvm update command buffer
|
|
|
+ * @bytes: pointer to the data buffer
|
|
|
+ * @errno: pointer to return error code
|
|
|
+ *
|
|
|
+ * Process legitimate commands of the Init state and conditionally set next
|
|
|
+ * state. Reject all other commands.
|
|
|
+ **/
|
|
|
+static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
|
|
|
+ struct i40e_nvm_access *cmd,
|
|
|
+ u8 *bytes, int *errno)
|
|
|
+{
|
|
|
+ i40e_status status = 0;
|
|
|
+ enum i40e_nvmupd_cmd upd_cmd;
|
|
|
+
|
|
|
+ upd_cmd = i40e_nvmupd_validate_command(hw, cmd, errno);
|
|
|
+
|
|
|
+ switch (upd_cmd) {
|
|
|
+ case I40E_NVMUPD_READ_SA:
|
|
|
+ status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
|
|
|
+ if (status) {
|
|
|
+ *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
|
|
|
+ } else {
|
|
|
+ status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno);
|
|
|
+ i40e_release_nvm(hw);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case I40E_NVMUPD_READ_SNT:
|
|
|
+ status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
|
|
|
+ if (status) {
|
|
|
+ *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
|
|
|
+ } else {
|
|
|
+ status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno);
|
|
|
+ hw->nvmupd_state = I40E_NVMUPD_STATE_READING;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case I40E_NVMUPD_WRITE_ERA:
|
|
|
+ status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
|
|
|
+ if (status) {
|
|
|
+ *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
|
|
|
+ } else {
|
|
|
+ status = i40e_nvmupd_nvm_erase(hw, cmd, errno);
|
|
|
+ if (status)
|
|
|
+ i40e_release_nvm(hw);
|
|
|
+ else
|
|
|
+ hw->aq.nvm_release_on_done = true;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case I40E_NVMUPD_WRITE_SA:
|
|
|
+ status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
|
|
|
+ if (status) {
|
|
|
+ *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
|
|
|
+ } else {
|
|
|
+ status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno);
|
|
|
+ if (status)
|
|
|
+ i40e_release_nvm(hw);
|
|
|
+ else
|
|
|
+ hw->aq.nvm_release_on_done = true;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case I40E_NVMUPD_WRITE_SNT:
|
|
|
+ status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
|
|
|
+ if (status) {
|
|
|
+ *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
|
|
|
+ } else {
|
|
|
+ status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno);
|
|
|
+ hw->nvmupd_state = I40E_NVMUPD_STATE_WRITING;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case I40E_NVMUPD_CSUM_SA:
|
|
|
+ status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
|
|
|
+ if (status) {
|
|
|
+ *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
|
|
|
+ } else {
|
|
|
+ status = i40e_update_nvm_checksum(hw);
|
|
|
+ if (status) {
|
|
|
+ *errno = hw->aq.asq_last_status ?
|
|
|
+ i40e_aq_rc_to_posix(hw->aq.asq_last_status) :
|
|
|
+ -EIO;
|
|
|
+ i40e_release_nvm(hw);
|
|
|
+ } else {
|
|
|
+ hw->aq.nvm_release_on_done = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ status = I40E_ERR_NVM;
|
|
|
+ *errno = -ESRCH;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * i40e_nvmupd_state_reading - Handle NVM update state Reading
|
|
|
+ * @hw: pointer to hardware structure
|
|
|
+ * @cmd: pointer to nvm update command buffer
|
|
|
+ * @bytes: pointer to the data buffer
|
|
|
+ * @errno: pointer to return error code
|
|
|
+ *
|
|
|
+ * NVM ownership is already held. Process legitimate commands and set any
|
|
|
+ * change in state; reject all other commands.
|
|
|
+ **/
|
|
|
+static i40e_status i40e_nvmupd_state_reading(struct i40e_hw *hw,
|
|
|
+ struct i40e_nvm_access *cmd,
|
|
|
+ u8 *bytes, int *errno)
|
|
|
+{
|
|
|
+ i40e_status status;
|
|
|
+ enum i40e_nvmupd_cmd upd_cmd;
|
|
|
+
|
|
|
+ upd_cmd = i40e_nvmupd_validate_command(hw, cmd, errno);
|
|
|
+
|
|
|
+ switch (upd_cmd) {
|
|
|
+ case I40E_NVMUPD_READ_SA:
|
|
|
+ case I40E_NVMUPD_READ_CON:
|
|
|
+ status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case I40E_NVMUPD_READ_LCB:
|
|
|
+ status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno);
|
|
|
+ i40e_release_nvm(hw);
|
|
|
+ hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ status = I40E_NOT_SUPPORTED;
|
|
|
+ *errno = -ESRCH;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * i40e_nvmupd_state_writing - Handle NVM update state Writing
|
|
|
+ * @hw: pointer to hardware structure
|
|
|
+ * @cmd: pointer to nvm update command buffer
|
|
|
+ * @bytes: pointer to the data buffer
|
|
|
+ * @errno: pointer to return error code
|
|
|
+ *
|
|
|
+ * NVM ownership is already held. Process legitimate commands and set any
|
|
|
+ * change in state; reject all other commands
|
|
|
+ **/
|
|
|
+static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
|
|
|
+ struct i40e_nvm_access *cmd,
|
|
|
+ u8 *bytes, int *errno)
|
|
|
+{
|
|
|
+ i40e_status status;
|
|
|
+ enum i40e_nvmupd_cmd upd_cmd;
|
|
|
+
|
|
|
+ upd_cmd = i40e_nvmupd_validate_command(hw, cmd, errno);
|
|
|
+
|
|
|
+ switch (upd_cmd) {
|
|
|
+ case I40E_NVMUPD_WRITE_CON:
|
|
|
+ status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case I40E_NVMUPD_WRITE_LCB:
|
|
|
+ status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno);
|
|
|
+ if (!status) {
|
|
|
+ hw->aq.nvm_release_on_done = true;
|
|
|
+ hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case I40E_NVMUPD_CSUM_CON:
|
|
|
+ status = i40e_update_nvm_checksum(hw);
|
|
|
+ if (status)
|
|
|
+ *errno = hw->aq.asq_last_status ?
|
|
|
+ i40e_aq_rc_to_posix(hw->aq.asq_last_status) :
|
|
|
+ -EIO;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case I40E_NVMUPD_CSUM_LCB:
|
|
|
+ status = i40e_update_nvm_checksum(hw);
|
|
|
+ if (status) {
|
|
|
+ *errno = hw->aq.asq_last_status ?
|
|
|
+ i40e_aq_rc_to_posix(hw->aq.asq_last_status) :
|
|
|
+ -EIO;
|
|
|
+ } else {
|
|
|
+ hw->aq.nvm_release_on_done = true;
|
|
|
+ hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ status = I40E_NOT_SUPPORTED;
|
|
|
+ *errno = -ESRCH;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * i40e_nvmupd_validate_command - Validate given command
|
|
|
+ * @hw: pointer to hardware structure
|
|
|
+ * @cmd: pointer to nvm update command buffer
|
|
|
+ * @errno: pointer to return error code
|
|
|
+ *
|
|
|
+ * Return one of the valid command types or I40E_NVMUPD_INVALID
|
|
|
+ **/
|
|
|
+static enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
|
|
|
+ struct i40e_nvm_access *cmd,
|
|
|
+ int *errno)
|
|
|
+{
|
|
|
+ enum i40e_nvmupd_cmd upd_cmd;
|
|
|
+ u8 transaction, module;
|
|
|
+
|
|
|
+ /* anything that doesn't match a recognized case is an error */
|
|
|
+ upd_cmd = I40E_NVMUPD_INVALID;
|
|
|
+
|
|
|
+ transaction = i40e_nvmupd_get_transaction(cmd->config);
|
|
|
+ module = i40e_nvmupd_get_module(cmd->config);
|
|
|
+
|
|
|
+ /* limits on data size */
|
|
|
+ if ((cmd->data_size < 1) ||
|
|
|
+ (cmd->data_size > I40E_NVMUPD_MAX_DATA)) {
|
|
|
+ hw_dbg(hw, "i40e_nvmupd_validate_command data_size %d\n",
|
|
|
+ cmd->data_size);
|
|
|
+ *errno = -EFAULT;
|
|
|
+ return I40E_NVMUPD_INVALID;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (cmd->command) {
|
|
|
+ case I40E_NVM_READ:
|
|
|
+ switch (transaction) {
|
|
|
+ case I40E_NVM_CON:
|
|
|
+ upd_cmd = I40E_NVMUPD_READ_CON;
|
|
|
+ break;
|
|
|
+ case I40E_NVM_SNT:
|
|
|
+ upd_cmd = I40E_NVMUPD_READ_SNT;
|
|
|
+ break;
|
|
|
+ case I40E_NVM_LCB:
|
|
|
+ upd_cmd = I40E_NVMUPD_READ_LCB;
|
|
|
+ break;
|
|
|
+ case I40E_NVM_SA:
|
|
|
+ upd_cmd = I40E_NVMUPD_READ_SA;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case I40E_NVM_WRITE:
|
|
|
+ switch (transaction) {
|
|
|
+ case I40E_NVM_CON:
|
|
|
+ upd_cmd = I40E_NVMUPD_WRITE_CON;
|
|
|
+ break;
|
|
|
+ case I40E_NVM_SNT:
|
|
|
+ upd_cmd = I40E_NVMUPD_WRITE_SNT;
|
|
|
+ break;
|
|
|
+ case I40E_NVM_LCB:
|
|
|
+ upd_cmd = I40E_NVMUPD_WRITE_LCB;
|
|
|
+ break;
|
|
|
+ case I40E_NVM_SA:
|
|
|
+ upd_cmd = I40E_NVMUPD_WRITE_SA;
|
|
|
+ break;
|
|
|
+ case I40E_NVM_ERA:
|
|
|
+ upd_cmd = I40E_NVMUPD_WRITE_ERA;
|
|
|
+ break;
|
|
|
+ case I40E_NVM_CSUM:
|
|
|
+ upd_cmd = I40E_NVMUPD_CSUM_CON;
|
|
|
+ break;
|
|
|
+ case (I40E_NVM_CSUM|I40E_NVM_SA):
|
|
|
+ upd_cmd = I40E_NVMUPD_CSUM_SA;
|
|
|
+ break;
|
|
|
+ case (I40E_NVM_CSUM|I40E_NVM_LCB):
|
|
|
+ upd_cmd = I40E_NVMUPD_CSUM_LCB;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (upd_cmd == I40E_NVMUPD_INVALID) {
|
|
|
+ *errno = -EFAULT;
|
|
|
+ hw_dbg(hw,
|
|
|
+ "i40e_nvmupd_validate_command returns %d errno: %d\n",
|
|
|
+ upd_cmd, *errno);
|
|
|
+ }
|
|
|
+ return upd_cmd;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * i40e_nvmupd_nvm_read - Read NVM
|
|
|
+ * @hw: pointer to hardware structure
|
|
|
+ * @cmd: pointer to nvm update command buffer
|
|
|
+ * @bytes: pointer to the data buffer
|
|
|
+ * @errno: pointer to return error code
|
|
|
+ *
|
|
|
+ * cmd structure contains identifiers and data buffer
|
|
|
+ **/
|
|
|
+static i40e_status i40e_nvmupd_nvm_read(struct i40e_hw *hw,
|
|
|
+ struct i40e_nvm_access *cmd,
|
|
|
+ u8 *bytes, int *errno)
|
|
|
+{
|
|
|
+ i40e_status status;
|
|
|
+ u8 module, transaction;
|
|
|
+ bool last;
|
|
|
+
|
|
|
+ transaction = i40e_nvmupd_get_transaction(cmd->config);
|
|
|
+ module = i40e_nvmupd_get_module(cmd->config);
|
|
|
+ last = (transaction == I40E_NVM_LCB) || (transaction == I40E_NVM_SA);
|
|
|
+ hw_dbg(hw, "i40e_nvmupd_nvm_read mod 0x%x off 0x%x len 0x%x\n",
|
|
|
+ module, cmd->offset, cmd->data_size);
|
|
|
+
|
|
|
+ status = i40e_aq_read_nvm(hw, module, cmd->offset, (u16)cmd->data_size,
|
|
|
+ bytes, last, NULL);
|
|
|
+ hw_dbg(hw, "i40e_nvmupd_nvm_read status %d\n", status);
|
|
|
+ if (status)
|
|
|
+ *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * i40e_nvmupd_nvm_erase - Erase an NVM module
|
|
|
+ * @hw: pointer to hardware structure
|
|
|
+ * @cmd: pointer to nvm update command buffer
|
|
|
+ * @errno: pointer to return error code
|
|
|
+ *
|
|
|
+ * module, offset, data_size and data are in cmd structure
|
|
|
+ **/
|
|
|
+static i40e_status i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
|
|
|
+ struct i40e_nvm_access *cmd,
|
|
|
+ int *errno)
|
|
|
+{
|
|
|
+ i40e_status status = 0;
|
|
|
+ u8 module, transaction;
|
|
|
+ bool last;
|
|
|
+
|
|
|
+ transaction = i40e_nvmupd_get_transaction(cmd->config);
|
|
|
+ module = i40e_nvmupd_get_module(cmd->config);
|
|
|
+ last = (transaction & I40E_NVM_LCB);
|
|
|
+ hw_dbg(hw, "i40e_nvmupd_nvm_erase mod 0x%x off 0x%x len 0x%x\n",
|
|
|
+ module, cmd->offset, cmd->data_size);
|
|
|
+ status = i40e_aq_erase_nvm(hw, module, cmd->offset, (u16)cmd->data_size,
|
|
|
+ last, NULL);
|
|
|
+ hw_dbg(hw, "i40e_nvmupd_nvm_erase status %d\n", status);
|
|
|
+ if (status)
|
|
|
+ *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * i40e_nvmupd_nvm_write - Write NVM
|
|
|
+ * @hw: pointer to hardware structure
|
|
|
+ * @cmd: pointer to nvm update command buffer
|
|
|
+ * @bytes: pointer to the data buffer
|
|
|
+ * @errno: pointer to return error code
|
|
|
+ *
|
|
|
+ * module, offset, data_size and data are in cmd structure
|
|
|
+ **/
|
|
|
+static i40e_status i40e_nvmupd_nvm_write(struct i40e_hw *hw,
|
|
|
+ struct i40e_nvm_access *cmd,
|
|
|
+ u8 *bytes, int *errno)
|
|
|
+{
|
|
|
+ i40e_status status = 0;
|
|
|
+ u8 module, transaction;
|
|
|
+ bool last;
|
|
|
+
|
|
|
+ transaction = i40e_nvmupd_get_transaction(cmd->config);
|
|
|
+ module = i40e_nvmupd_get_module(cmd->config);
|
|
|
+ last = (transaction & I40E_NVM_LCB);
|
|
|
+ hw_dbg(hw, "i40e_nvmupd_nvm_write mod 0x%x off 0x%x len 0x%x\n",
|
|
|
+ module, cmd->offset, cmd->data_size);
|
|
|
+ status = i40e_aq_update_nvm(hw, module, cmd->offset,
|
|
|
+ (u16)cmd->data_size, bytes, last, NULL);
|
|
|
+ hw_dbg(hw, "i40e_nvmupd_nvm_write status %d\n", status);
|
|
|
+ if (status)
|
|
|
+ *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|