Skip to content

Commit

Permalink
i40e/i40evf: add exec_aq command to nvmupdate utility
Browse files Browse the repository at this point in the history
Add a facility to run AQ commands through the nvmupdate utility in order
to allow the update tools to interact with the FW and do special
commands needed for updates and configuration changes.

Change-ID: I5c41523e4055b37f8e4ee479f7a0574368f4a588
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
  • Loading branch information
Shannon Nelson authored and Jeff Kirsher committed Sep 18, 2015
1 parent 2f1b5bc commit e4c83c2
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 0 deletions.
3 changes: 3 additions & 0 deletions drivers/net/ethernet/intel/i40e/i40e_adminq.c
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,9 @@ i40e_status i40e_shutdown_adminq(struct i40e_hw *hw)

/* destroy the locks */

if (hw->nvm_buff.va)
i40e_free_virt_mem(hw, &hw->nvm_buff);

return ret_code;
}

Expand Down
83 changes: 83 additions & 0 deletions drivers/net/ethernet/intel/i40e/i40e_nvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,9 @@ static i40e_status i40e_nvmupd_nvm_write(struct i40e_hw *hw,
static i40e_status i40e_nvmupd_nvm_read(struct i40e_hw *hw,
struct i40e_nvm_access *cmd,
u8 *bytes, int *perrno);
static i40e_status i40e_nvmupd_exec_aq(struct i40e_hw *hw,
struct i40e_nvm_access *cmd,
u8 *bytes, int *perrno);
static inline u8 i40e_nvmupd_get_module(u32 val)
{
return (u8)(val & I40E_NVM_MOD_PNT_MASK);
Expand All @@ -639,6 +642,7 @@ static char *i40e_nvm_update_state_str[] = {
"I40E_NVMUPD_CSUM_SA",
"I40E_NVMUPD_CSUM_LCB",
"I40E_NVMUPD_STATUS",
"I40E_NVMUPD_EXEC_AQ",
};

/**
Expand Down Expand Up @@ -824,6 +828,10 @@ static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
}
break;

case I40E_NVMUPD_EXEC_AQ:
status = i40e_nvmupd_exec_aq(hw, cmd, bytes, perrno);
break;

default:
i40e_debug(hw, I40E_DEBUG_NVM,
"NVMUPD: bad cmd %s in init state\n",
Expand Down Expand Up @@ -1069,13 +1077,88 @@ static enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
case (I40E_NVM_CSUM|I40E_NVM_LCB):
upd_cmd = I40E_NVMUPD_CSUM_LCB;
break;
case I40E_NVM_EXEC:
if (module == 0)
upd_cmd = I40E_NVMUPD_EXEC_AQ;
break;
}
break;
}

return upd_cmd;
}

/**
* i40e_nvmupd_exec_aq - Run an AQ command
* @hw: pointer to hardware structure
* @cmd: pointer to nvm update command buffer
* @bytes: pointer to the data buffer
* @perrno: pointer to return error code
*
* cmd structure contains identifiers and data buffer
**/
static i40e_status i40e_nvmupd_exec_aq(struct i40e_hw *hw,
struct i40e_nvm_access *cmd,
u8 *bytes, int *perrno)
{
struct i40e_asq_cmd_details cmd_details;
i40e_status status;
struct i40e_aq_desc *aq_desc;
u32 buff_size = 0;
u8 *buff = NULL;
u32 aq_desc_len;
u32 aq_data_len;

i40e_debug(hw, I40E_DEBUG_NVM, "NVMUPD: %s\n", __func__);
memset(&cmd_details, 0, sizeof(cmd_details));
cmd_details.wb_desc = &hw->nvm_wb_desc;

aq_desc_len = sizeof(struct i40e_aq_desc);
memset(&hw->nvm_wb_desc, 0, aq_desc_len);

/* get the aq descriptor */
if (cmd->data_size < aq_desc_len) {
i40e_debug(hw, I40E_DEBUG_NVM,
"NVMUPD: not enough aq desc bytes for exec, size %d < %d\n",
cmd->data_size, aq_desc_len);
*perrno = -EINVAL;
return I40E_ERR_PARAM;
}
aq_desc = (struct i40e_aq_desc *)bytes;

/* if data buffer needed, make sure it's ready */
aq_data_len = cmd->data_size - aq_desc_len;
buff_size = max_t(u32, aq_data_len, le16_to_cpu(aq_desc->datalen));
if (buff_size) {
if (!hw->nvm_buff.va) {
status = i40e_allocate_virt_mem(hw, &hw->nvm_buff,
hw->aq.asq_buf_size);
if (status)
i40e_debug(hw, I40E_DEBUG_NVM,
"NVMUPD: i40e_allocate_virt_mem for exec buff failed, %d\n",
status);
}

if (hw->nvm_buff.va) {
buff = hw->nvm_buff.va;
memcpy(buff, &bytes[aq_desc_len], aq_data_len);
}
}

/* and away we go! */
status = i40e_asq_send_command(hw, aq_desc, buff,
buff_size, &cmd_details);
if (status) {
i40e_debug(hw, I40E_DEBUG_NVM,
"i40e_nvmupd_exec_aq err %s aq_err %s\n",
i40e_stat_str(hw, status),
i40e_aq_str(hw, hw->aq.asq_last_status));
*perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
}

return status;
}

/**
* i40e_nvmupd_nvm_read - Read NVM
* @hw: pointer to hardware structure
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/intel/i40e/i40e_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ enum i40e_nvmupd_cmd {
I40E_NVMUPD_CSUM_SA,
I40E_NVMUPD_CSUM_LCB,
I40E_NVMUPD_STATUS,
I40E_NVMUPD_EXEC_AQ,
};

enum i40e_nvmupd_state {
Expand Down Expand Up @@ -497,6 +498,7 @@ struct i40e_hw {
/* state of nvm update process */
enum i40e_nvmupd_state nvmupd_state;
struct i40e_aq_desc nvm_wb_desc;
struct i40e_virt_mem nvm_buff;

/* HMC info */
struct i40e_hmc_info hmc; /* HMC info struct */
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/intel/i40evf/i40e_adminq.c
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,9 @@ i40e_status i40evf_shutdown_adminq(struct i40e_hw *hw)

/* destroy the locks */

if (hw->nvm_buff.va)
i40e_free_virt_mem(hw, &hw->nvm_buff);

return ret_code;
}

Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/intel/i40evf/i40e_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ enum i40e_nvmupd_cmd {
I40E_NVMUPD_CSUM_SA,
I40E_NVMUPD_CSUM_LCB,
I40E_NVMUPD_STATUS,
I40E_NVMUPD_EXEC_AQ,
};

enum i40e_nvmupd_state {
Expand Down Expand Up @@ -491,6 +492,7 @@ struct i40e_hw {
/* state of nvm update process */
enum i40e_nvmupd_state nvmupd_state;
struct i40e_aq_desc nvm_wb_desc;
struct i40e_virt_mem nvm_buff;

/* HMC info */
struct i40e_hmc_info hmc; /* HMC info struct */
Expand Down

0 comments on commit e4c83c2

Please sign in to comment.