@@ -239,8 +239,9 @@ static i40e_status i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset,
239
239
*
240
240
* Writes a 16 bit words buffer to the Shadow RAM using the admin command.
241
241
**/
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 ,
244
245
bool last_command )
245
246
{
246
247
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,
496
497
ret_code = i40e_aq_update_nvm (hw , module_pointer ,
497
498
2 * offset , /*bytes*/
498
499
2 * words , /*bytes*/
499
- data , last_command , & cmd_details );
500
+ data , last_command , 0 ,
501
+ & cmd_details );
500
502
501
503
return ret_code ;
502
504
}
@@ -677,6 +679,9 @@ static i40e_status i40e_nvmupd_exec_aq(struct i40e_hw *hw,
677
679
static i40e_status i40e_nvmupd_get_aq_result (struct i40e_hw * hw ,
678
680
struct i40e_nvm_access * cmd ,
679
681
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 );
680
685
static inline u8 i40e_nvmupd_get_module (u32 val )
681
686
{
682
687
return (u8 )(val & I40E_NVM_MOD_PNT_MASK );
@@ -686,6 +691,12 @@ static inline u8 i40e_nvmupd_get_transaction(u32 val)
686
691
return (u8 )((val & I40E_NVM_TRANS_MASK ) >> I40E_NVM_TRANS_SHIFT );
687
692
}
688
693
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
+
689
700
static const char * const i40e_nvm_update_state_str [] = {
690
701
"I40E_NVMUPD_INVALID" ,
691
702
"I40E_NVMUPD_READ_CON" ,
@@ -703,6 +714,7 @@ static const char * const i40e_nvm_update_state_str[] = {
703
714
"I40E_NVMUPD_STATUS" ,
704
715
"I40E_NVMUPD_EXEC_AQ" ,
705
716
"I40E_NVMUPD_GET_AQ_RESULT" ,
717
+ "I40E_NVMUPD_GET_AQ_EVENT" ,
706
718
};
707
719
708
720
/**
@@ -798,9 +810,9 @@ i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
798
810
* the wait info and return before doing anything else
799
811
*/
800
812
if (cmd -> offset == 0xffff ) {
801
- i40e_nvmupd_check_wait_event (hw , hw -> nvm_wait_opcode );
813
+ i40e_nvmupd_clear_wait_state (hw );
802
814
status = 0 ;
803
- goto exit ;
815
+ break ;
804
816
}
805
817
806
818
status = I40E_ERR_NOT_READY ;
@@ -815,7 +827,7 @@ i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
815
827
* perrno = - ESRCH ;
816
828
break ;
817
829
}
818
- exit :
830
+
819
831
mutex_unlock (& hw -> aq .arq_mutex );
820
832
return status ;
821
833
}
@@ -944,6 +956,10 @@ static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
944
956
status = i40e_nvmupd_get_aq_result (hw , cmd , bytes , perrno );
945
957
break ;
946
958
959
+ case I40E_NVMUPD_GET_AQ_EVENT :
960
+ status = i40e_nvmupd_get_aq_event (hw , cmd , bytes , perrno );
961
+ break ;
962
+
947
963
default :
948
964
i40e_debug (hw , I40E_DEBUG_NVM ,
949
965
"NVMUPD: bad cmd %s in init state\n" ,
@@ -1118,38 +1134,53 @@ static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
1118
1134
}
1119
1135
1120
1136
/**
1121
- * i40e_nvmupd_check_wait_event - handle NVM update operation events
1137
+ * i40e_nvmupd_clear_wait_state - clear wait state on hw
1122
1138
* @hw: pointer to the hardware structure
1123
- * @opcode: the event that just happened
1124
1139
**/
1125
- void i40e_nvmupd_check_wait_event (struct i40e_hw * hw , u16 opcode )
1140
+ void i40e_nvmupd_clear_wait_state (struct i40e_hw * hw )
1126
1141
{
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 );
1135
1145
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 ;
1140
1151
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
+ }
1145
1156
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 ;
1149
1161
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 );
1153
1184
}
1154
1185
}
1155
1186
@@ -1205,6 +1236,9 @@ static enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
1205
1236
else if (module == 0 )
1206
1237
upd_cmd = I40E_NVMUPD_GET_AQ_RESULT ;
1207
1238
break ;
1239
+ case I40E_NVM_AQE :
1240
+ upd_cmd = I40E_NVMUPD_GET_AQ_EVENT ;
1241
+ break ;
1208
1242
}
1209
1243
break ;
1210
1244
@@ -1267,6 +1301,9 @@ static i40e_status i40e_nvmupd_exec_aq(struct i40e_hw *hw,
1267
1301
u32 aq_data_len ;
1268
1302
1269
1303
i40e_debug (hw , I40E_DEBUG_NVM , "NVMUPD: %s\n" , __func__ );
1304
+ if (cmd -> offset == 0xffff )
1305
+ return 0 ;
1306
+
1270
1307
memset (& cmd_details , 0 , sizeof (cmd_details ));
1271
1308
cmd_details .wb_desc = & hw -> nvm_wb_desc ;
1272
1309
@@ -1302,6 +1339,9 @@ static i40e_status i40e_nvmupd_exec_aq(struct i40e_hw *hw,
1302
1339
}
1303
1340
}
1304
1341
1342
+ if (cmd -> offset )
1343
+ memset (& hw -> nvm_aq_event_desc , 0 , aq_desc_len );
1344
+
1305
1345
/* and away we go! */
1306
1346
status = i40e_asq_send_command (hw , aq_desc , buff ,
1307
1347
buff_size , & cmd_details );
@@ -1311,6 +1351,7 @@ static i40e_status i40e_nvmupd_exec_aq(struct i40e_hw *hw,
1311
1351
i40e_stat_str (hw , status ),
1312
1352
i40e_aq_str (hw , hw -> aq .asq_last_status ));
1313
1353
* perrno = i40e_aq_rc_to_posix (status , hw -> aq .asq_last_status );
1354
+ return status ;
1314
1355
}
1315
1356
1316
1357
/* should we wait for a followup event? */
@@ -1391,6 +1432,40 @@ static i40e_status i40e_nvmupd_get_aq_result(struct i40e_hw *hw,
1391
1432
return 0 ;
1392
1433
}
1393
1434
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
+
1394
1469
/**
1395
1470
* i40e_nvmupd_nvm_read - Read NVM
1396
1471
* @hw: pointer to hardware structure
@@ -1486,18 +1561,20 @@ static i40e_status i40e_nvmupd_nvm_write(struct i40e_hw *hw,
1486
1561
i40e_status status = 0 ;
1487
1562
struct i40e_asq_cmd_details cmd_details ;
1488
1563
u8 module , transaction ;
1564
+ u8 preservation_flags ;
1489
1565
bool last ;
1490
1566
1491
1567
transaction = i40e_nvmupd_get_transaction (cmd -> config );
1492
1568
module = i40e_nvmupd_get_module (cmd -> config );
1493
1569
last = (transaction & I40E_NVM_LCB );
1570
+ preservation_flags = i40e_nvmupd_get_preservation_flags (cmd -> config );
1494
1571
1495
1572
memset (& cmd_details , 0 , sizeof (cmd_details ));
1496
1573
cmd_details .wb_desc = & hw -> nvm_wb_desc ;
1497
1574
1498
1575
status = i40e_aq_update_nvm (hw , module , cmd -> offset ,
1499
1576
(u16 )cmd -> data_size , bytes , last ,
1500
- & cmd_details );
1577
+ preservation_flags , & cmd_details );
1501
1578
if (status ) {
1502
1579
i40e_debug (hw , I40E_DEBUG_NVM ,
1503
1580
"i40e_nvmupd_nvm_write mod 0x%x off 0x%x len 0x%x\n" ,
0 commit comments