@@ -247,6 +247,7 @@ static i40e_status i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
247
247
struct i40e_asq_cmd_details cmd_details ;
248
248
249
249
memset (& cmd_details , 0 , sizeof (cmd_details ));
250
+ cmd_details .wb_desc = & hw -> nvm_wb_desc ;
250
251
251
252
/* Here we are checking the SR limit only for the flat memory model.
252
253
* We cannot do it for the module-based model, as we did not acquire
@@ -283,7 +284,7 @@ static i40e_status i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
283
284
* @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
284
285
* @data: word read from the Shadow RAM
285
286
*
286
- * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
287
+ * Reads one 16 bit word from the Shadow RAM using the AdminQ
287
288
**/
288
289
static i40e_status i40e_read_nvm_word_aq (struct i40e_hw * hw , u16 offset ,
289
290
u16 * data )
@@ -297,27 +298,49 @@ static i40e_status i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset,
297
298
}
298
299
299
300
/**
300
- * i40e_read_nvm_word - Reads Shadow RAM
301
+ * __i40e_read_nvm_word - Reads nvm word, assumes called does the locking
301
302
* @hw: pointer to the HW structure
302
303
* @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
303
304
* @data: word read from the Shadow RAM
304
305
*
305
- * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
306
+ * Reads one 16 bit word from the Shadow RAM.
307
+ *
308
+ * Do not use this function except in cases where the nvm lock is already
309
+ * taken via i40e_acquire_nvm().
310
+ **/
311
+ static i40e_status __i40e_read_nvm_word (struct i40e_hw * hw ,
312
+ u16 offset , u16 * data )
313
+ {
314
+ i40e_status ret_code = 0 ;
315
+
316
+ if (hw -> flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE )
317
+ ret_code = i40e_read_nvm_word_aq (hw , offset , data );
318
+ else
319
+ ret_code = i40e_read_nvm_word_srctl (hw , offset , data );
320
+ return ret_code ;
321
+ }
322
+
323
+ /**
324
+ * i40e_read_nvm_word - Reads nvm word and acquire lock if necessary
325
+ * @hw: pointer to the HW structure
326
+ * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
327
+ * @data: word read from the Shadow RAM
328
+ *
329
+ * Reads one 16 bit word from the Shadow RAM.
306
330
**/
307
331
i40e_status i40e_read_nvm_word (struct i40e_hw * hw , u16 offset ,
308
332
u16 * data )
309
333
{
310
- enum i40e_status_code ret_code = 0 ;
334
+ i40e_status ret_code = 0 ;
311
335
312
336
ret_code = i40e_acquire_nvm (hw , I40E_RESOURCE_READ );
313
- if (!ret_code ) {
314
- if (hw -> flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE ) {
315
- ret_code = i40e_read_nvm_word_aq (hw , offset , data );
316
- } else {
317
- ret_code = i40e_read_nvm_word_srctl (hw , offset , data );
318
- }
319
- i40e_release_nvm (hw );
320
- }
337
+ if (ret_code )
338
+ return ret_code ;
339
+
340
+ ret_code = __i40e_read_nvm_word (hw , offset , data );
341
+
342
+ i40e_release_nvm (hw );
343
+
321
344
return ret_code ;
322
345
}
323
346
@@ -410,31 +433,25 @@ static i40e_status i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset,
410
433
}
411
434
412
435
/**
413
- * i40e_read_nvm_buffer - Reads Shadow RAM buffer
436
+ * __i40e_read_nvm_buffer - Reads nvm buffer, caller must acquire lock
414
437
* @hw: pointer to the HW structure
415
438
* @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
416
439
* @words: (in) number of words to read; (out) number of words actually read
417
440
* @data: words read from the Shadow RAM
418
441
*
419
442
* Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd()
420
- * method. The buffer read is preceded by the NVM ownership take
421
- * and followed by the release.
443
+ * method.
422
444
**/
423
- i40e_status i40e_read_nvm_buffer (struct i40e_hw * hw , u16 offset ,
424
- u16 * words , u16 * data )
445
+ static i40e_status __i40e_read_nvm_buffer (struct i40e_hw * hw ,
446
+ u16 offset , u16 * words ,
447
+ u16 * data )
425
448
{
426
- enum i40e_status_code ret_code = 0 ;
449
+ i40e_status ret_code = 0 ;
427
450
428
- if (hw -> flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE ) {
429
- ret_code = i40e_acquire_nvm (hw , I40E_RESOURCE_READ );
430
- if (!ret_code ) {
431
- ret_code = i40e_read_nvm_buffer_aq (hw , offset , words ,
432
- data );
433
- i40e_release_nvm (hw );
434
- }
435
- } else {
451
+ if (hw -> flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE )
452
+ ret_code = i40e_read_nvm_buffer_aq (hw , offset , words , data );
453
+ else
436
454
ret_code = i40e_read_nvm_buffer_srctl (hw , offset , words , data );
437
- }
438
455
return ret_code ;
439
456
}
440
457
@@ -516,15 +533,15 @@ static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw,
516
533
data = (u16 * )vmem .va ;
517
534
518
535
/* read pointer to VPD area */
519
- ret_code = i40e_read_nvm_word (hw , I40E_SR_VPD_PTR , & vpd_module );
536
+ ret_code = __i40e_read_nvm_word (hw , I40E_SR_VPD_PTR , & vpd_module );
520
537
if (ret_code ) {
521
538
ret_code = I40E_ERR_NVM_CHECKSUM ;
522
539
goto i40e_calc_nvm_checksum_exit ;
523
540
}
524
541
525
542
/* read pointer to PCIe Alt Auto-load module */
526
- ret_code = i40e_read_nvm_word (hw , I40E_SR_PCIE_ALT_AUTO_LOAD_PTR ,
527
- & pcie_alt_module );
543
+ ret_code = __i40e_read_nvm_word (hw , I40E_SR_PCIE_ALT_AUTO_LOAD_PTR ,
544
+ & pcie_alt_module );
528
545
if (ret_code ) {
529
546
ret_code = I40E_ERR_NVM_CHECKSUM ;
530
547
goto i40e_calc_nvm_checksum_exit ;
@@ -538,7 +555,7 @@ static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw,
538
555
if ((i % I40E_SR_SECTOR_SIZE_IN_WORDS ) == 0 ) {
539
556
u16 words = I40E_SR_SECTOR_SIZE_IN_WORDS ;
540
557
541
- ret_code = i40e_read_nvm_buffer (hw , i , & words , data );
558
+ ret_code = __i40e_read_nvm_buffer (hw , i , & words , data );
542
559
if (ret_code ) {
543
560
ret_code = I40E_ERR_NVM_CHECKSUM ;
544
561
goto i40e_calc_nvm_checksum_exit ;
@@ -610,14 +627,19 @@ i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
610
627
u16 checksum_sr = 0 ;
611
628
u16 checksum_local = 0 ;
612
629
630
+ /* We must acquire the NVM lock in order to correctly synchronize the
631
+ * NVM accesses across multiple PFs. Without doing so it is possible
632
+ * for one of the PFs to read invalid data potentially indicating that
633
+ * the checksum is invalid.
634
+ */
635
+ ret_code = i40e_acquire_nvm (hw , I40E_RESOURCE_READ );
636
+ if (ret_code )
637
+ return ret_code ;
613
638
ret_code = i40e_calc_nvm_checksum (hw , & checksum_local );
639
+ __i40e_read_nvm_word (hw , I40E_SR_SW_CHECKSUM_WORD , & checksum_sr );
640
+ i40e_release_nvm (hw );
614
641
if (ret_code )
615
- goto i40e_validate_nvm_checksum_exit ;
616
-
617
- /* Do not use i40e_read_nvm_word() because we do not want to take
618
- * the synchronization semaphores twice here.
619
- */
620
- i40e_read_nvm_word (hw , I40E_SR_SW_CHECKSUM_WORD , & checksum_sr );
642
+ return ret_code ;
621
643
622
644
/* Verify read checksum from EEPROM is the same as
623
645
* calculated checksum
@@ -629,7 +651,6 @@ i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
629
651
if (checksum )
630
652
* checksum = checksum_local ;
631
653
632
- i40e_validate_nvm_checksum_exit :
633
654
return ret_code ;
634
655
}
635
656
@@ -1026,6 +1047,7 @@ static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
1026
1047
break ;
1027
1048
1028
1049
case I40E_NVMUPD_CSUM_CON :
1050
+ /* Assumes the caller has acquired the nvm */
1029
1051
status = i40e_update_nvm_checksum (hw );
1030
1052
if (status ) {
1031
1053
* perrno = hw -> aq .asq_last_status ?
@@ -1040,6 +1062,7 @@ static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
1040
1062
break ;
1041
1063
1042
1064
case I40E_NVMUPD_CSUM_LCB :
1065
+ /* Assumes the caller has acquired the nvm */
1043
1066
status = i40e_update_nvm_checksum (hw );
1044
1067
if (status ) {
1045
1068
* perrno = hw -> aq .asq_last_status ?
0 commit comments