Skip to content

Commit e3a5d6e

Browse files
Pawel JablonskiJeff Kirsher
authored andcommitted
i40e/i40evf: Enable NVMUpdate to retrieve AdminQ and add preservation flags for NVM update
This patch adds new I40E_NVMUPD_GET_AQ_EVENT state to allow retrieval of AdminQ events as a result of AdminQ commands sent to firmware. Add preservation flags support on X722 devices for NVM update AdminQ function wrapper. Add new parameter and handling to nvmupdate admin queue function intended to allow nvmupdate tool to configure the preservation flags in the AdminQ command. This is required to implement FlatNVM on X722 devices. Signed-off-by: Pawel Jablonski <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent c13da21 commit e3a5d6e

File tree

9 files changed

+173
-59
lines changed

9 files changed

+173
-59
lines changed

drivers/net/ethernet/intel/i40e/i40e_adminq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1027,7 +1027,7 @@ i40e_status i40e_clean_arq_element(struct i40e_hw *hw,
10271027
hw->aq.arq.next_to_clean = ntc;
10281028
hw->aq.arq.next_to_use = ntu;
10291029

1030-
i40e_nvmupd_check_wait_event(hw, le16_to_cpu(e->desc.opcode));
1030+
i40e_nvmupd_check_wait_event(hw, le16_to_cpu(e->desc.opcode), &e->desc);
10311031
clean_arq_element_out:
10321032
/* Set pending if needed, unlock and return */
10331033
if (pending)

drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2231,8 +2231,12 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_phy_register_access);
22312231
*/
22322232
struct i40e_aqc_nvm_update {
22332233
u8 command_flags;
2234-
#define I40E_AQ_NVM_LAST_CMD 0x01
2235-
#define I40E_AQ_NVM_FLASH_ONLY 0x80
2234+
#define I40E_AQ_NVM_LAST_CMD 0x01
2235+
#define I40E_AQ_NVM_FLASH_ONLY 0x80
2236+
#define I40E_AQ_NVM_PRESERVATION_FLAGS_SHIFT 1
2237+
#define I40E_AQ_NVM_PRESERVATION_FLAGS_MASK 0x03
2238+
#define I40E_AQ_NVM_PRESERVATION_FLAGS_SELECTED 0x03
2239+
#define I40E_AQ_NVM_PRESERVATION_FLAGS_ALL 0x01
22362240
u8 module_pointer;
22372241
__le16 length;
22382242
__le32 offset;

drivers/net/ethernet/intel/i40e/i40e_common.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3465,13 +3465,14 @@ i40e_status i40e_aq_discover_capabilities(struct i40e_hw *hw,
34653465
* @length: length of the section to be written (in bytes from the offset)
34663466
* @data: command buffer (size [bytes] = length)
34673467
* @last_command: tells if this is the last command in a series
3468+
* @preservation_flags: Preservation mode flags
34683469
* @cmd_details: pointer to command details structure or NULL
34693470
*
34703471
* Update the NVM using the admin queue commands
34713472
**/
34723473
i40e_status i40e_aq_update_nvm(struct i40e_hw *hw, u8 module_pointer,
34733474
u32 offset, u16 length, void *data,
3474-
bool last_command,
3475+
bool last_command, u8 preservation_flags,
34753476
struct i40e_asq_cmd_details *cmd_details)
34763477
{
34773478
struct i40e_aq_desc desc;
@@ -3490,6 +3491,16 @@ i40e_status i40e_aq_update_nvm(struct i40e_hw *hw, u8 module_pointer,
34903491
/* If this is the last command in a series, set the proper flag. */
34913492
if (last_command)
34923493
cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
3494+
if (hw->mac.type == I40E_MAC_X722) {
3495+
if (preservation_flags == I40E_NVM_PRESERVATION_FLAGS_SELECTED)
3496+
cmd->command_flags |=
3497+
(I40E_AQ_NVM_PRESERVATION_FLAGS_SELECTED <<
3498+
I40E_AQ_NVM_PRESERVATION_FLAGS_SHIFT);
3499+
else if (preservation_flags == I40E_NVM_PRESERVATION_FLAGS_ALL)
3500+
cmd->command_flags |=
3501+
(I40E_AQ_NVM_PRESERVATION_FLAGS_ALL <<
3502+
I40E_AQ_NVM_PRESERVATION_FLAGS_SHIFT);
3503+
}
34933504
cmd->module_pointer = module_pointer;
34943505
cmd->offset = cpu_to_le32(offset);
34953506
cmd->length = cpu_to_le16(length);

drivers/net/ethernet/intel/i40e/i40e_main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10972,7 +10972,7 @@ i40e_status i40e_commit_partition_bw_setting(struct i40e_pf *pf)
1097210972
ret = i40e_aq_update_nvm(&pf->hw,
1097310973
I40E_SR_NVM_CONTROL_WORD,
1097410974
0x10, sizeof(nvm_word),
10975-
&nvm_word, true, NULL);
10975+
&nvm_word, true, 0, NULL);
1097610976
/* Save off last admin queue command status before releasing
1097710977
* the NVM
1097810978
*/

drivers/net/ethernet/intel/i40e/i40e_nvm.c

Lines changed: 109 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,9 @@ static i40e_status i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset,
239239
*
240240
* Writes a 16 bit words buffer to the Shadow RAM using the admin command.
241241
**/
242-
static i40e_status i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
243-
u32 offset, u16 words, void *data,
242+
static i40e_status i40e_read_nvm_aq(struct i40e_hw *hw,
243+
u8 module_pointer, u32 offset,
244+
u16 words, void *data,
244245
bool last_command)
245246
{
246247
i40e_status ret_code = I40E_ERR_NVM;
@@ -496,7 +497,8 @@ static i40e_status i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
496497
ret_code = i40e_aq_update_nvm(hw, module_pointer,
497498
2 * offset, /*bytes*/
498499
2 * words, /*bytes*/
499-
data, last_command, &cmd_details);
500+
data, last_command, 0,
501+
&cmd_details);
500502

501503
return ret_code;
502504
}
@@ -677,6 +679,9 @@ static i40e_status i40e_nvmupd_exec_aq(struct i40e_hw *hw,
677679
static i40e_status i40e_nvmupd_get_aq_result(struct i40e_hw *hw,
678680
struct i40e_nvm_access *cmd,
679681
u8 *bytes, int *perrno);
682+
static i40e_status i40e_nvmupd_get_aq_event(struct i40e_hw *hw,
683+
struct i40e_nvm_access *cmd,
684+
u8 *bytes, int *perrno);
680685
static inline u8 i40e_nvmupd_get_module(u32 val)
681686
{
682687
return (u8)(val & I40E_NVM_MOD_PNT_MASK);
@@ -686,6 +691,12 @@ static inline u8 i40e_nvmupd_get_transaction(u32 val)
686691
return (u8)((val & I40E_NVM_TRANS_MASK) >> I40E_NVM_TRANS_SHIFT);
687692
}
688693

694+
static inline u8 i40e_nvmupd_get_preservation_flags(u32 val)
695+
{
696+
return (u8)((val & I40E_NVM_PRESERVATION_FLAGS_MASK) >>
697+
I40E_NVM_PRESERVATION_FLAGS_SHIFT);
698+
}
699+
689700
static const char * const i40e_nvm_update_state_str[] = {
690701
"I40E_NVMUPD_INVALID",
691702
"I40E_NVMUPD_READ_CON",
@@ -703,6 +714,7 @@ static const char * const i40e_nvm_update_state_str[] = {
703714
"I40E_NVMUPD_STATUS",
704715
"I40E_NVMUPD_EXEC_AQ",
705716
"I40E_NVMUPD_GET_AQ_RESULT",
717+
"I40E_NVMUPD_GET_AQ_EVENT",
706718
};
707719

708720
/**
@@ -798,9 +810,9 @@ i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
798810
* the wait info and return before doing anything else
799811
*/
800812
if (cmd->offset == 0xffff) {
801-
i40e_nvmupd_check_wait_event(hw, hw->nvm_wait_opcode);
813+
i40e_nvmupd_clear_wait_state(hw);
802814
status = 0;
803-
goto exit;
815+
break;
804816
}
805817

806818
status = I40E_ERR_NOT_READY;
@@ -815,7 +827,7 @@ i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
815827
*perrno = -ESRCH;
816828
break;
817829
}
818-
exit:
830+
819831
mutex_unlock(&hw->aq.arq_mutex);
820832
return status;
821833
}
@@ -944,6 +956,10 @@ static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
944956
status = i40e_nvmupd_get_aq_result(hw, cmd, bytes, perrno);
945957
break;
946958

959+
case I40E_NVMUPD_GET_AQ_EVENT:
960+
status = i40e_nvmupd_get_aq_event(hw, cmd, bytes, perrno);
961+
break;
962+
947963
default:
948964
i40e_debug(hw, I40E_DEBUG_NVM,
949965
"NVMUPD: bad cmd %s in init state\n",
@@ -1118,38 +1134,53 @@ static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
11181134
}
11191135

11201136
/**
1121-
* i40e_nvmupd_check_wait_event - handle NVM update operation events
1137+
* i40e_nvmupd_clear_wait_state - clear wait state on hw
11221138
* @hw: pointer to the hardware structure
1123-
* @opcode: the event that just happened
11241139
**/
1125-
void i40e_nvmupd_check_wait_event(struct i40e_hw *hw, u16 opcode)
1140+
void i40e_nvmupd_clear_wait_state(struct i40e_hw *hw)
11261141
{
1127-
if (opcode == hw->nvm_wait_opcode) {
1128-
i40e_debug(hw, I40E_DEBUG_NVM,
1129-
"NVMUPD: clearing wait on opcode 0x%04x\n", opcode);
1130-
if (hw->nvm_release_on_done) {
1131-
i40e_release_nvm(hw);
1132-
hw->nvm_release_on_done = false;
1133-
}
1134-
hw->nvm_wait_opcode = 0;
1142+
i40e_debug(hw, I40E_DEBUG_NVM,
1143+
"NVMUPD: clearing wait on opcode 0x%04x\n",
1144+
hw->nvm_wait_opcode);
11351145

1136-
if (hw->aq.arq_last_status) {
1137-
hw->nvmupd_state = I40E_NVMUPD_STATE_ERROR;
1138-
return;
1139-
}
1146+
if (hw->nvm_release_on_done) {
1147+
i40e_release_nvm(hw);
1148+
hw->nvm_release_on_done = false;
1149+
}
1150+
hw->nvm_wait_opcode = 0;
11401151

1141-
switch (hw->nvmupd_state) {
1142-
case I40E_NVMUPD_STATE_INIT_WAIT:
1143-
hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
1144-
break;
1152+
if (hw->aq.arq_last_status) {
1153+
hw->nvmupd_state = I40E_NVMUPD_STATE_ERROR;
1154+
return;
1155+
}
11451156

1146-
case I40E_NVMUPD_STATE_WRITE_WAIT:
1147-
hw->nvmupd_state = I40E_NVMUPD_STATE_WRITING;
1148-
break;
1157+
switch (hw->nvmupd_state) {
1158+
case I40E_NVMUPD_STATE_INIT_WAIT:
1159+
hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
1160+
break;
11491161

1150-
default:
1151-
break;
1152-
}
1162+
case I40E_NVMUPD_STATE_WRITE_WAIT:
1163+
hw->nvmupd_state = I40E_NVMUPD_STATE_WRITING;
1164+
break;
1165+
1166+
default:
1167+
break;
1168+
}
1169+
}
1170+
1171+
/**
1172+
* i40e_nvmupd_check_wait_event - handle NVM update operation events
1173+
* @hw: pointer to the hardware structure
1174+
* @opcode: the event that just happened
1175+
**/
1176+
void i40e_nvmupd_check_wait_event(struct i40e_hw *hw, u16 opcode,
1177+
struct i40e_aq_desc *desc)
1178+
{
1179+
u32 aq_desc_len = sizeof(struct i40e_aq_desc);
1180+
1181+
if (opcode == hw->nvm_wait_opcode) {
1182+
memcpy(&hw->nvm_aq_event_desc, desc, aq_desc_len);
1183+
i40e_nvmupd_clear_wait_state(hw);
11531184
}
11541185
}
11551186

@@ -1205,6 +1236,9 @@ static enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
12051236
else if (module == 0)
12061237
upd_cmd = I40E_NVMUPD_GET_AQ_RESULT;
12071238
break;
1239+
case I40E_NVM_AQE:
1240+
upd_cmd = I40E_NVMUPD_GET_AQ_EVENT;
1241+
break;
12081242
}
12091243
break;
12101244

@@ -1267,6 +1301,9 @@ static i40e_status i40e_nvmupd_exec_aq(struct i40e_hw *hw,
12671301
u32 aq_data_len;
12681302

12691303
i40e_debug(hw, I40E_DEBUG_NVM, "NVMUPD: %s\n", __func__);
1304+
if (cmd->offset == 0xffff)
1305+
return 0;
1306+
12701307
memset(&cmd_details, 0, sizeof(cmd_details));
12711308
cmd_details.wb_desc = &hw->nvm_wb_desc;
12721309

@@ -1302,6 +1339,9 @@ static i40e_status i40e_nvmupd_exec_aq(struct i40e_hw *hw,
13021339
}
13031340
}
13041341

1342+
if (cmd->offset)
1343+
memset(&hw->nvm_aq_event_desc, 0, aq_desc_len);
1344+
13051345
/* and away we go! */
13061346
status = i40e_asq_send_command(hw, aq_desc, buff,
13071347
buff_size, &cmd_details);
@@ -1311,6 +1351,7 @@ static i40e_status i40e_nvmupd_exec_aq(struct i40e_hw *hw,
13111351
i40e_stat_str(hw, status),
13121352
i40e_aq_str(hw, hw->aq.asq_last_status));
13131353
*perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
1354+
return status;
13141355
}
13151356

13161357
/* should we wait for a followup event? */
@@ -1391,6 +1432,40 @@ static i40e_status i40e_nvmupd_get_aq_result(struct i40e_hw *hw,
13911432
return 0;
13921433
}
13931434

1435+
/**
1436+
* i40e_nvmupd_get_aq_event - Get the Admin Queue event from previous exec_aq
1437+
* @hw: pointer to hardware structure
1438+
* @cmd: pointer to nvm update command buffer
1439+
* @bytes: pointer to the data buffer
1440+
* @perrno: pointer to return error code
1441+
*
1442+
* cmd structure contains identifiers and data buffer
1443+
**/
1444+
static i40e_status i40e_nvmupd_get_aq_event(struct i40e_hw *hw,
1445+
struct i40e_nvm_access *cmd,
1446+
u8 *bytes, int *perrno)
1447+
{
1448+
u32 aq_total_len;
1449+
u32 aq_desc_len;
1450+
1451+
i40e_debug(hw, I40E_DEBUG_NVM, "NVMUPD: %s\n", __func__);
1452+
1453+
aq_desc_len = sizeof(struct i40e_aq_desc);
1454+
aq_total_len = aq_desc_len + le16_to_cpu(hw->nvm_aq_event_desc.datalen);
1455+
1456+
/* check copylength range */
1457+
if (cmd->data_size > aq_total_len) {
1458+
i40e_debug(hw, I40E_DEBUG_NVM,
1459+
"%s: copy length %d too big, trimming to %d\n",
1460+
__func__, cmd->data_size, aq_total_len);
1461+
cmd->data_size = aq_total_len;
1462+
}
1463+
1464+
memcpy(bytes, &hw->nvm_aq_event_desc, cmd->data_size);
1465+
1466+
return 0;
1467+
}
1468+
13941469
/**
13951470
* i40e_nvmupd_nvm_read - Read NVM
13961471
* @hw: pointer to hardware structure
@@ -1486,18 +1561,20 @@ static i40e_status i40e_nvmupd_nvm_write(struct i40e_hw *hw,
14861561
i40e_status status = 0;
14871562
struct i40e_asq_cmd_details cmd_details;
14881563
u8 module, transaction;
1564+
u8 preservation_flags;
14891565
bool last;
14901566

14911567
transaction = i40e_nvmupd_get_transaction(cmd->config);
14921568
module = i40e_nvmupd_get_module(cmd->config);
14931569
last = (transaction & I40E_NVM_LCB);
1570+
preservation_flags = i40e_nvmupd_get_preservation_flags(cmd->config);
14941571

14951572
memset(&cmd_details, 0, sizeof(cmd_details));
14961573
cmd_details.wb_desc = &hw->nvm_wb_desc;
14971574

14981575
status = i40e_aq_update_nvm(hw, module, cmd->offset,
14991576
(u16)cmd->data_size, bytes, last,
1500-
&cmd_details);
1577+
preservation_flags, &cmd_details);
15011578
if (status) {
15021579
i40e_debug(hw, I40E_DEBUG_NVM,
15031580
"i40e_nvmupd_nvm_write mod 0x%x off 0x%x len 0x%x\n",

drivers/net/ethernet/intel/i40e/i40e_prototype.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ i40e_status i40e_aq_discover_capabilities(struct i40e_hw *hw,
214214
struct i40e_asq_cmd_details *cmd_details);
215215
i40e_status i40e_aq_update_nvm(struct i40e_hw *hw, u8 module_pointer,
216216
u32 offset, u16 length, void *data,
217-
bool last_command,
217+
bool last_command, u8 preservation_flags,
218218
struct i40e_asq_cmd_details *cmd_details);
219219
i40e_status i40e_aq_get_lldp_mib(struct i40e_hw *hw, u8 bridge_type,
220220
u8 mib_type, void *buff, u16 buff_size,
@@ -333,7 +333,9 @@ i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
333333
i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
334334
struct i40e_nvm_access *cmd,
335335
u8 *bytes, int *);
336-
void i40e_nvmupd_check_wait_event(struct i40e_hw *hw, u16 opcode);
336+
void i40e_nvmupd_check_wait_event(struct i40e_hw *hw, u16 opcode,
337+
struct i40e_aq_desc *desc);
338+
void i40e_nvmupd_clear_wait_state(struct i40e_hw *hw);
337339
void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status);
338340

339341
extern struct i40e_rx_ptype_decoded i40e_ptype_lookup[];

drivers/net/ethernet/intel/i40e/i40e_type.h

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ enum i40e_nvmupd_cmd {
402402
I40E_NVMUPD_STATUS,
403403
I40E_NVMUPD_EXEC_AQ,
404404
I40E_NVMUPD_GET_AQ_RESULT,
405+
I40E_NVMUPD_GET_AQ_EVENT,
405406
};
406407

407408
enum i40e_nvmupd_state {
@@ -421,15 +422,21 @@ enum i40e_nvmupd_state {
421422

422423
#define I40E_NVM_MOD_PNT_MASK 0xFF
423424

424-
#define I40E_NVM_TRANS_SHIFT 8
425-
#define I40E_NVM_TRANS_MASK (0xf << I40E_NVM_TRANS_SHIFT)
426-
#define I40E_NVM_CON 0x0
427-
#define I40E_NVM_SNT 0x1
428-
#define I40E_NVM_LCB 0x2
429-
#define I40E_NVM_SA (I40E_NVM_SNT | I40E_NVM_LCB)
430-
#define I40E_NVM_ERA 0x4
431-
#define I40E_NVM_CSUM 0x8
432-
#define I40E_NVM_EXEC 0xf
425+
#define I40E_NVM_TRANS_SHIFT 8
426+
#define I40E_NVM_TRANS_MASK (0xf << I40E_NVM_TRANS_SHIFT)
427+
#define I40E_NVM_PRESERVATION_FLAGS_SHIFT 12
428+
#define I40E_NVM_PRESERVATION_FLAGS_MASK \
429+
(0x3 << I40E_NVM_PRESERVATION_FLAGS_SHIFT)
430+
#define I40E_NVM_PRESERVATION_FLAGS_SELECTED 0x01
431+
#define I40E_NVM_PRESERVATION_FLAGS_ALL 0x02
432+
#define I40E_NVM_CON 0x0
433+
#define I40E_NVM_SNT 0x1
434+
#define I40E_NVM_LCB 0x2
435+
#define I40E_NVM_SA (I40E_NVM_SNT | I40E_NVM_LCB)
436+
#define I40E_NVM_ERA 0x4
437+
#define I40E_NVM_CSUM 0x8
438+
#define I40E_NVM_AQE 0xe
439+
#define I40E_NVM_EXEC 0xf
433440

434441
#define I40E_NVM_ADAPT_SHIFT 16
435442
#define I40E_NVM_ADAPT_MASK (0xffff << I40E_NVM_ADAPT_SHIFT)
@@ -611,6 +618,7 @@ struct i40e_hw {
611618
/* state of nvm update process */
612619
enum i40e_nvmupd_state nvmupd_state;
613620
struct i40e_aq_desc nvm_wb_desc;
621+
struct i40e_aq_desc nvm_aq_event_desc;
614622
struct i40e_virt_mem nvm_buff;
615623
bool nvm_release_on_done;
616624
u16 nvm_wait_opcode;

0 commit comments

Comments
 (0)