Skip to content

Commit 66bed84

Browse files
committed
Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-queue
Jeff Kirsher says: ==================== Intel Wired LAN Driver Updates 2017-09-05 This series contains fixes for i40e only. These two patches fix an issue where our nvmupdate tool does not work on RHEL 7.4 and newer kernels, in fact, the use of the nvmupdate tool on newer kernels can cause the cards to be non-functional unless these patches are applied. Anjali reworks the locking around accessing the NVM so that NVM acquire timeouts do not occur which was causing the failed firmware updates. Jake correctly updates the wb_desc when reading the NVM through the AdminQ. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 18fb0b4 + 3c8f3e9 commit 66bed84

File tree

2 files changed

+61
-40
lines changed

2 files changed

+61
-40
lines changed

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

Lines changed: 61 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ static i40e_status i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
247247
struct i40e_asq_cmd_details cmd_details;
248248

249249
memset(&cmd_details, 0, sizeof(cmd_details));
250+
cmd_details.wb_desc = &hw->nvm_wb_desc;
250251

251252
/* Here we are checking the SR limit only for the flat memory model.
252253
* 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,
283284
* @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
284285
* @data: word read from the Shadow RAM
285286
*
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
287288
**/
288289
static i40e_status i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset,
289290
u16 *data)
@@ -297,27 +298,49 @@ static i40e_status i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset,
297298
}
298299

299300
/**
300-
* i40e_read_nvm_word - Reads Shadow RAM
301+
* __i40e_read_nvm_word - Reads nvm word, assumes called does the locking
301302
* @hw: pointer to the HW structure
302303
* @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
303304
* @data: word read from the Shadow RAM
304305
*
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.
306330
**/
307331
i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
308332
u16 *data)
309333
{
310-
enum i40e_status_code ret_code = 0;
334+
i40e_status ret_code = 0;
311335

312336
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+
321344
return ret_code;
322345
}
323346

@@ -410,31 +433,25 @@ static i40e_status i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset,
410433
}
411434

412435
/**
413-
* i40e_read_nvm_buffer - Reads Shadow RAM buffer
436+
* __i40e_read_nvm_buffer - Reads nvm buffer, caller must acquire lock
414437
* @hw: pointer to the HW structure
415438
* @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
416439
* @words: (in) number of words to read; (out) number of words actually read
417440
* @data: words read from the Shadow RAM
418441
*
419442
* 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.
422444
**/
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)
425448
{
426-
enum i40e_status_code ret_code = 0;
449+
i40e_status ret_code = 0;
427450

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
436454
ret_code = i40e_read_nvm_buffer_srctl(hw, offset, words, data);
437-
}
438455
return ret_code;
439456
}
440457

@@ -516,15 +533,15 @@ static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw,
516533
data = (u16 *)vmem.va;
517534

518535
/* 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);
520537
if (ret_code) {
521538
ret_code = I40E_ERR_NVM_CHECKSUM;
522539
goto i40e_calc_nvm_checksum_exit;
523540
}
524541

525542
/* 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);
528545
if (ret_code) {
529546
ret_code = I40E_ERR_NVM_CHECKSUM;
530547
goto i40e_calc_nvm_checksum_exit;
@@ -538,7 +555,7 @@ static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw,
538555
if ((i % I40E_SR_SECTOR_SIZE_IN_WORDS) == 0) {
539556
u16 words = I40E_SR_SECTOR_SIZE_IN_WORDS;
540557

541-
ret_code = i40e_read_nvm_buffer(hw, i, &words, data);
558+
ret_code = __i40e_read_nvm_buffer(hw, i, &words, data);
542559
if (ret_code) {
543560
ret_code = I40E_ERR_NVM_CHECKSUM;
544561
goto i40e_calc_nvm_checksum_exit;
@@ -610,14 +627,19 @@ i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
610627
u16 checksum_sr = 0;
611628
u16 checksum_local = 0;
612629

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;
613638
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);
614641
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;
621643

622644
/* Verify read checksum from EEPROM is the same as
623645
* calculated checksum
@@ -629,7 +651,6 @@ i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
629651
if (checksum)
630652
*checksum = checksum_local;
631653

632-
i40e_validate_nvm_checksum_exit:
633654
return ret_code;
634655
}
635656

@@ -1026,6 +1047,7 @@ static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
10261047
break;
10271048

10281049
case I40E_NVMUPD_CSUM_CON:
1050+
/* Assumes the caller has acquired the nvm */
10291051
status = i40e_update_nvm_checksum(hw);
10301052
if (status) {
10311053
*perrno = hw->aq.asq_last_status ?
@@ -1040,6 +1062,7 @@ static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
10401062
break;
10411063

10421064
case I40E_NVMUPD_CSUM_LCB:
1065+
/* Assumes the caller has acquired the nvm */
10431066
status = i40e_update_nvm_checksum(hw);
10441067
if (status) {
10451068
*perrno = hw->aq.asq_last_status ?

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,8 +311,6 @@ i40e_status i40e_acquire_nvm(struct i40e_hw *hw,
311311
void i40e_release_nvm(struct i40e_hw *hw);
312312
i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
313313
u16 *data);
314-
i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
315-
u16 *words, u16 *data);
316314
i40e_status i40e_update_nvm_checksum(struct i40e_hw *hw);
317315
i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
318316
u16 *checksum);

0 commit comments

Comments
 (0)