1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2001-2020 Intel Corporation
5 #include "i40e_prototype.h"
8 * i40e_init_nvm_ops - Initialize NVM function pointers
9 * @hw: pointer to the HW structure
11 * Setup the function pointers and the NVM info structure. Should be called
12 * once per NVM initialization, e.g. inside the i40e_init_shared_code().
13 * Please notice that the NVM term is used here (& in all methods covered
14 * in this file) as an equivalent of the FLASH part mapped into the SR.
15 * We are accessing FLASH always through the Shadow RAM.
17 enum i40e_status_code i40e_init_nvm(struct i40e_hw *hw)
19 struct i40e_nvm_info *nvm = &hw->nvm;
20 enum i40e_status_code ret_code = I40E_SUCCESS;
24 DEBUGFUNC("i40e_init_nvm");
26 /* The SR size is stored regardless of the nvm programming mode
27 * as the blank mode may be used in the factory line.
29 gens = rd32(hw, I40E_GLNVM_GENS);
30 sr_size = ((gens & I40E_GLNVM_GENS_SR_SIZE_MASK) >>
31 I40E_GLNVM_GENS_SR_SIZE_SHIFT);
32 /* Switching to words (sr_size contains power of 2KB) */
33 nvm->sr_size = BIT(sr_size) * I40E_SR_WORDS_IN_1KB;
35 /* Check if we are in the normal or blank NVM programming mode */
36 fla = rd32(hw, I40E_GLNVM_FLA);
37 if (fla & I40E_GLNVM_FLA_LOCKED_MASK) { /* Normal programming mode */
39 nvm->timeout = I40E_MAX_NVM_TIMEOUT;
40 nvm->blank_nvm_mode = false;
41 } else { /* Blank programming mode */
42 nvm->blank_nvm_mode = true;
43 ret_code = I40E_ERR_NVM_BLANK_MODE;
44 i40e_debug(hw, I40E_DEBUG_NVM, "NVM init error: unsupported blank mode.\n");
51 * i40e_acquire_nvm - Generic request for acquiring the NVM ownership
52 * @hw: pointer to the HW structure
53 * @access: NVM access type (read or write)
55 * This function will request NVM ownership for reading
56 * via the proper Admin Command.
58 enum i40e_status_code i40e_acquire_nvm(struct i40e_hw *hw,
59 enum i40e_aq_resource_access_type access)
61 enum i40e_status_code ret_code = I40E_SUCCESS;
65 DEBUGFUNC("i40e_acquire_nvm");
67 if (hw->nvm.blank_nvm_mode)
68 goto i40e_i40e_acquire_nvm_exit;
70 ret_code = i40e_aq_request_resource(hw, I40E_NVM_RESOURCE_ID, access,
72 /* Reading the Global Device Timer */
73 gtime = rd32(hw, I40E_GLVFGEN_TIMER);
75 /* Store the timeout */
76 hw->nvm.hw_semaphore_timeout = I40E_MS_TO_GTIME(time_left) + gtime;
79 i40e_debug(hw, I40E_DEBUG_NVM,
80 "NVM acquire type %d failed time_left=%llu ret=%d aq_err=%d\n",
81 access, time_left, ret_code, hw->aq.asq_last_status);
83 if (ret_code && time_left) {
84 /* Poll until the current NVM owner timeouts */
85 timeout = I40E_MS_TO_GTIME(I40E_MAX_NVM_TIMEOUT) + gtime;
86 while ((gtime < timeout) && time_left) {
88 gtime = rd32(hw, I40E_GLVFGEN_TIMER);
89 ret_code = i40e_aq_request_resource(hw,
91 access, 0, &time_left,
93 if (ret_code == I40E_SUCCESS) {
94 hw->nvm.hw_semaphore_timeout =
95 I40E_MS_TO_GTIME(time_left) + gtime;
99 if (ret_code != I40E_SUCCESS) {
100 hw->nvm.hw_semaphore_timeout = 0;
101 i40e_debug(hw, I40E_DEBUG_NVM,
102 "NVM acquire timed out, wait %llu ms before trying again. status=%d aq_err=%d\n",
103 time_left, ret_code, hw->aq.asq_last_status);
107 i40e_i40e_acquire_nvm_exit:
112 * i40e_release_nvm - Generic request for releasing the NVM ownership
113 * @hw: pointer to the HW structure
115 * This function will release NVM resource via the proper Admin Command.
117 void i40e_release_nvm(struct i40e_hw *hw)
119 enum i40e_status_code ret_code = I40E_SUCCESS;
122 DEBUGFUNC("i40e_release_nvm");
124 if (hw->nvm.blank_nvm_mode)
127 ret_code = i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL);
129 /* there are some rare cases when trying to release the resource
130 * results in an admin Q timeout, so handle them correctly
132 while ((ret_code == I40E_ERR_ADMIN_QUEUE_TIMEOUT) &&
133 (total_delay < hw->aq.asq_cmd_timeout)) {
135 ret_code = i40e_aq_release_resource(hw,
136 I40E_NVM_RESOURCE_ID, 0, NULL);
142 * i40e_poll_sr_srctl_done_bit - Polls the GLNVM_SRCTL done bit
143 * @hw: pointer to the HW structure
145 * Polls the SRCTL Shadow RAM register done bit.
147 static enum i40e_status_code i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw)
149 enum i40e_status_code ret_code = I40E_ERR_TIMEOUT;
152 DEBUGFUNC("i40e_poll_sr_srctl_done_bit");
154 /* Poll the I40E_GLNVM_SRCTL until the done bit is set */
155 for (wait_cnt = 0; wait_cnt < I40E_SRRD_SRCTL_ATTEMPTS; wait_cnt++) {
156 srctl = rd32(hw, I40E_GLNVM_SRCTL);
157 if (srctl & I40E_GLNVM_SRCTL_DONE_MASK) {
158 ret_code = I40E_SUCCESS;
163 if (ret_code == I40E_ERR_TIMEOUT)
164 i40e_debug(hw, I40E_DEBUG_NVM, "Done bit in GLNVM_SRCTL not set");
169 * i40e_read_nvm_word_srctl - Reads Shadow RAM via SRCTL register
170 * @hw: pointer to the HW structure
171 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
172 * @data: word read from the Shadow RAM
174 * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
176 STATIC enum i40e_status_code i40e_read_nvm_word_srctl(struct i40e_hw *hw,
180 enum i40e_status_code ret_code = I40E_ERR_TIMEOUT;
183 DEBUGFUNC("i40e_read_nvm_word_srctl");
185 if (offset >= hw->nvm.sr_size) {
186 i40e_debug(hw, I40E_DEBUG_NVM,
187 "NVM read error: Offset %d beyond Shadow RAM limit %d\n",
188 offset, hw->nvm.sr_size);
189 ret_code = I40E_ERR_PARAM;
193 /* Poll the done bit first */
194 ret_code = i40e_poll_sr_srctl_done_bit(hw);
195 if (ret_code == I40E_SUCCESS) {
196 /* Write the address and start reading */
197 sr_reg = ((u32)offset << I40E_GLNVM_SRCTL_ADDR_SHIFT) |
198 BIT(I40E_GLNVM_SRCTL_START_SHIFT);
199 wr32(hw, I40E_GLNVM_SRCTL, sr_reg);
201 /* Poll I40E_GLNVM_SRCTL until the done bit is set */
202 ret_code = i40e_poll_sr_srctl_done_bit(hw);
203 if (ret_code == I40E_SUCCESS) {
204 sr_reg = rd32(hw, I40E_GLNVM_SRDATA);
205 *data = (u16)((sr_reg &
206 I40E_GLNVM_SRDATA_RDDATA_MASK)
207 >> I40E_GLNVM_SRDATA_RDDATA_SHIFT);
210 if (ret_code != I40E_SUCCESS)
211 i40e_debug(hw, I40E_DEBUG_NVM,
212 "NVM read error: Couldn't access Shadow RAM address: 0x%x\n",
220 * i40e_read_nvm_aq - Read Shadow RAM.
221 * @hw: pointer to the HW structure.
222 * @module_pointer: module pointer location in words from the NVM beginning
223 * @offset: offset in words from module start
224 * @words: number of words to write
225 * @data: buffer with words to write to the Shadow RAM
226 * @last_command: tells the AdminQ that this is the last command
228 * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
230 STATIC enum i40e_status_code i40e_read_nvm_aq(struct i40e_hw *hw,
231 u8 module_pointer, u32 offset,
232 u16 words, void *data,
235 enum i40e_status_code ret_code = I40E_ERR_NVM;
236 struct i40e_asq_cmd_details cmd_details;
238 DEBUGFUNC("i40e_read_nvm_aq");
240 memset(&cmd_details, 0, sizeof(cmd_details));
241 cmd_details.wb_desc = &hw->nvm_wb_desc;
243 /* Here we are checking the SR limit only for the flat memory model.
244 * We cannot do it for the module-based model, as we did not acquire
245 * the NVM resource yet (we cannot get the module pointer value).
246 * Firmware will check the module-based model.
248 if ((offset + words) > hw->nvm.sr_size)
249 i40e_debug(hw, I40E_DEBUG_NVM,
250 "NVM write error: offset %d beyond Shadow RAM limit %d\n",
251 (offset + words), hw->nvm.sr_size);
252 else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS)
253 /* We can write only up to 4KB (one sector), in one AQ write */
254 i40e_debug(hw, I40E_DEBUG_NVM,
255 "NVM write fail error: tried to write %d words, limit is %d.\n",
256 words, I40E_SR_SECTOR_SIZE_IN_WORDS);
257 else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS)
258 != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS))
259 /* A single write cannot spread over two sectors */
260 i40e_debug(hw, I40E_DEBUG_NVM,
261 "NVM write error: cannot spread over two sectors in a single write offset=%d words=%d\n",
264 ret_code = i40e_aq_read_nvm(hw, module_pointer,
265 2 * offset, /*bytes*/
267 data, last_command, &cmd_details);
273 * i40e_read_nvm_word_aq - Reads Shadow RAM via AQ
274 * @hw: pointer to the HW structure
275 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
276 * @data: word read from the Shadow RAM
278 * Reads one 16 bit word from the Shadow RAM using the AdminQ
280 STATIC enum i40e_status_code i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset,
283 enum i40e_status_code ret_code = I40E_ERR_TIMEOUT;
285 DEBUGFUNC("i40e_read_nvm_word_aq");
287 ret_code = i40e_read_nvm_aq(hw, 0x0, offset, 1, data, true);
288 *data = LE16_TO_CPU(*(__le16 *)data);
294 * __i40e_read_nvm_word - Reads NVM word, assumes caller does the locking
295 * @hw: pointer to the HW structure
296 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
297 * @data: word read from the Shadow RAM
299 * Reads one 16 bit word from the Shadow RAM.
301 * Do not use this function except in cases where the nvm lock is already
302 * taken via i40e_acquire_nvm().
304 enum i40e_status_code __i40e_read_nvm_word(struct i40e_hw *hw,
309 if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE)
310 return i40e_read_nvm_word_aq(hw, offset, data);
312 return i40e_read_nvm_word_srctl(hw, offset, data);
316 * i40e_read_nvm_word - Reads NVM word, acquires lock if necessary
317 * @hw: pointer to the HW structure
318 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
319 * @data: word read from the Shadow RAM
321 * Reads one 16 bit word from the Shadow RAM.
323 enum i40e_status_code i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
326 enum i40e_status_code ret_code = I40E_SUCCESS;
328 if (hw->flags & I40E_HW_FLAG_NVM_READ_REQUIRES_LOCK)
329 ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
333 ret_code = __i40e_read_nvm_word(hw, offset, data);
335 if (hw->flags & I40E_HW_FLAG_NVM_READ_REQUIRES_LOCK)
336 i40e_release_nvm(hw);
341 * i40e_read_nvm_module_data - Reads NVM Buffer to specified memory location
342 * @hw: Pointer to the HW structure
343 * @module_ptr: Pointer to module in words with respect to NVM beginning
344 * @module_offset: Offset in words from module start
345 * @data_offset: Offset in words from reading data area start
346 * @words_data_size: Words to read from NVM
347 * @data_ptr: Pointer to memory location where resulting buffer will be stored
349 enum i40e_status_code
350 i40e_read_nvm_module_data(struct i40e_hw *hw, u8 module_ptr, u16 module_offset,
351 u16 data_offset, u16 words_data_size, u16 *data_ptr)
353 enum i40e_status_code status;
354 u16 specific_ptr = 0;
358 if (module_ptr != 0) {
359 status = i40e_read_nvm_word(hw, module_ptr, &ptr_value);
360 if (status != I40E_SUCCESS) {
361 i40e_debug(hw, I40E_DEBUG_ALL,
362 "Reading nvm word failed.Error code: %d.\n",
367 #define I40E_NVM_INVALID_PTR_VAL 0x7FFF
368 #define I40E_NVM_INVALID_VAL 0xFFFF
370 /* Pointer not initialized */
371 if (ptr_value == I40E_NVM_INVALID_PTR_VAL ||
372 ptr_value == I40E_NVM_INVALID_VAL) {
373 i40e_debug(hw, I40E_DEBUG_ALL, "Pointer not initialized.\n");
374 return I40E_ERR_BAD_PTR;
377 /* Check whether the module is in SR mapped area or outside */
378 if (ptr_value & I40E_PTR_TYPE) {
379 /* Pointer points outside of the Shared RAM mapped area */
380 i40e_debug(hw, I40E_DEBUG_ALL,
381 "Reading nvm data failed. Pointer points outside of the Shared RAM mapped area.\n");
383 return I40E_ERR_PARAM;
385 /* Read from the Shadow RAM */
387 status = i40e_read_nvm_word(hw, ptr_value + module_offset,
389 if (status != I40E_SUCCESS) {
390 i40e_debug(hw, I40E_DEBUG_ALL,
391 "Reading nvm word failed.Error code: %d.\n",
396 offset = ptr_value + module_offset + specific_ptr +
399 status = i40e_read_nvm_buffer(hw, offset, &words_data_size,
401 if (status != I40E_SUCCESS) {
402 i40e_debug(hw, I40E_DEBUG_ALL,
403 "Reading nvm buffer failed.Error code: %d.\n",
412 * i40e_read_nvm_buffer_srctl - Reads Shadow RAM buffer via SRCTL register
413 * @hw: pointer to the HW structure
414 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
415 * @words: (in) number of words to read; (out) number of words actually read
416 * @data: words read from the Shadow RAM
418 * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd()
419 * method. The buffer read is preceded by the NVM ownership take
420 * and followed by the release.
422 STATIC enum i40e_status_code i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
423 u16 *words, u16 *data)
425 enum i40e_status_code ret_code = I40E_SUCCESS;
428 DEBUGFUNC("i40e_read_nvm_buffer_srctl");
430 /* Loop through the selected region */
431 for (word = 0; word < *words; word++) {
432 index = offset + word;
433 ret_code = i40e_read_nvm_word_srctl(hw, index, &data[word]);
434 if (ret_code != I40E_SUCCESS)
438 /* Update the number of words read from the Shadow RAM */
445 * i40e_read_nvm_buffer_aq - Reads Shadow RAM buffer via AQ
446 * @hw: pointer to the HW structure
447 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
448 * @words: (in) number of words to read; (out) number of words actually read
449 * @data: words read from the Shadow RAM
451 * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_aq()
452 * method. The buffer read is preceded by the NVM ownership take
453 * and followed by the release.
455 STATIC enum i40e_status_code i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset,
456 u16 *words, u16 *data)
458 enum i40e_status_code ret_code;
459 u16 read_size = *words;
460 bool last_cmd = false;
464 DEBUGFUNC("i40e_read_nvm_buffer_aq");
467 /* Calculate number of bytes we should read in this step.
468 * FVL AQ do not allow to read more than one page at a time or
469 * to cross page boundaries.
471 if (offset % I40E_SR_SECTOR_SIZE_IN_WORDS)
472 read_size = min(*words,
473 (u16)(I40E_SR_SECTOR_SIZE_IN_WORDS -
474 (offset % I40E_SR_SECTOR_SIZE_IN_WORDS)));
476 read_size = min((*words - words_read),
477 I40E_SR_SECTOR_SIZE_IN_WORDS);
479 /* Check if this is last command, if so set proper flag */
480 if ((words_read + read_size) >= *words)
483 ret_code = i40e_read_nvm_aq(hw, 0x0, offset, read_size,
484 data + words_read, last_cmd);
485 if (ret_code != I40E_SUCCESS)
486 goto read_nvm_buffer_aq_exit;
488 /* Increment counter for words already read and move offset to
491 words_read += read_size;
493 } while (words_read < *words);
495 for (i = 0; i < *words; i++)
496 data[i] = LE16_TO_CPU(((__le16 *)data)[i]);
498 read_nvm_buffer_aq_exit:
504 * __i40e_read_nvm_buffer - Reads NVM buffer, caller must acquire lock
505 * @hw: pointer to the HW structure
506 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
507 * @words: (in) number of words to read; (out) number of words actually read
508 * @data: words read from the Shadow RAM
510 * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd()
513 enum i40e_status_code __i40e_read_nvm_buffer(struct i40e_hw *hw,
515 u16 *words, u16 *data)
517 if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE)
518 return i40e_read_nvm_buffer_aq(hw, offset, words, data);
520 return i40e_read_nvm_buffer_srctl(hw, offset, words, data);
524 * i40e_read_nvm_buffer - Reads Shadow RAM buffer and acquire lock if necessary
525 * @hw: pointer to the HW structure
526 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
527 * @words: (in) number of words to read; (out) number of words actually read
528 * @data: words read from the Shadow RAM
530 * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd()
531 * method. The buffer read is preceded by the NVM ownership take
532 * and followed by the release.
534 enum i40e_status_code i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
535 u16 *words, u16 *data)
537 enum i40e_status_code ret_code = I40E_SUCCESS;
539 if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE) {
540 ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
542 ret_code = i40e_read_nvm_buffer_aq(hw, offset, words,
544 i40e_release_nvm(hw);
547 ret_code = i40e_read_nvm_buffer_srctl(hw, offset, words, data);
554 * i40e_write_nvm_aq - Writes Shadow RAM.
555 * @hw: pointer to the HW structure.
556 * @module_pointer: module pointer location in words from the NVM beginning
557 * @offset: offset in words from module start
558 * @words: number of words to write
559 * @data: buffer with words to write to the Shadow RAM
560 * @last_command: tells the AdminQ that this is the last command
562 * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
564 enum i40e_status_code i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
565 u32 offset, u16 words, void *data,
568 enum i40e_status_code ret_code = I40E_ERR_NVM;
569 struct i40e_asq_cmd_details cmd_details;
571 DEBUGFUNC("i40e_write_nvm_aq");
573 memset(&cmd_details, 0, sizeof(cmd_details));
574 cmd_details.wb_desc = &hw->nvm_wb_desc;
576 /* Here we are checking the SR limit only for the flat memory model.
577 * We cannot do it for the module-based model, as we did not acquire
578 * the NVM resource yet (we cannot get the module pointer value).
579 * Firmware will check the module-based model.
581 if ((offset + words) > hw->nvm.sr_size)
582 DEBUGOUT("NVM write error: offset beyond Shadow RAM limit.\n");
583 else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS)
584 /* We can write only up to 4KB (one sector), in one AQ write */
585 DEBUGOUT("NVM write fail error: cannot write more than 4KB in a single write.\n");
586 else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS)
587 != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS))
588 /* A single write cannot spread over two sectors */
589 DEBUGOUT("NVM write error: cannot spread over two sectors in a single write.\n");
591 ret_code = i40e_aq_update_nvm(hw, module_pointer,
592 2 * offset, /*bytes*/
594 data, last_command, 0,
601 * __i40e_write_nvm_word - Writes Shadow RAM word
602 * @hw: pointer to the HW structure
603 * @offset: offset of the Shadow RAM word to write
604 * @data: word to write to the Shadow RAM
606 * Writes a 16 bit word to the SR using the i40e_write_nvm_aq() method.
607 * NVM ownership have to be acquired and released (on ARQ completion event
608 * reception) by caller. To commit SR to NVM update checksum function
611 enum i40e_status_code __i40e_write_nvm_word(struct i40e_hw *hw, u32 offset,
614 DEBUGFUNC("i40e_write_nvm_word");
616 *((__le16 *)data) = CPU_TO_LE16(*((u16 *)data));
618 /* Value 0x00 below means that we treat SR as a flat mem */
619 return i40e_write_nvm_aq(hw, 0x00, offset, 1, data, false);
623 * __i40e_write_nvm_buffer - Writes Shadow RAM buffer
624 * @hw: pointer to the HW structure
625 * @module_pointer: module pointer location in words from the NVM beginning
626 * @offset: offset of the Shadow RAM buffer to write
627 * @words: number of words to write
628 * @data: words to write to the Shadow RAM
630 * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
631 * NVM ownership must be acquired before calling this function and released
632 * on ARQ completion event reception by caller. To commit SR to NVM update
633 * checksum function should be called.
635 enum i40e_status_code __i40e_write_nvm_buffer(struct i40e_hw *hw,
636 u8 module_pointer, u32 offset,
637 u16 words, void *data)
639 __le16 *le_word_ptr = (__le16 *)data;
640 u16 *word_ptr = (u16 *)data;
643 DEBUGFUNC("i40e_write_nvm_buffer");
645 for (i = 0; i < words; i++)
646 le_word_ptr[i] = CPU_TO_LE16(word_ptr[i]);
648 /* Here we will only write one buffer as the size of the modules
649 * mirrored in the Shadow RAM is always less than 4K.
651 return i40e_write_nvm_aq(hw, module_pointer, offset, words,
656 * i40e_calc_nvm_checksum - Calculates and returns the checksum
657 * @hw: pointer to hardware structure
658 * @checksum: pointer to the checksum
660 * This function calculates SW Checksum that covers the whole 64kB shadow RAM
661 * except the VPD and PCIe ALT Auto-load modules. The structure and size of VPD
662 * is customer specific and unknown. Therefore, this function skips all maximum
663 * possible size of VPD (1kB).
665 enum i40e_status_code i40e_calc_nvm_checksum(struct i40e_hw *hw, u16 *checksum)
667 enum i40e_status_code ret_code = I40E_SUCCESS;
668 struct i40e_virt_mem vmem;
669 u16 pcie_alt_module = 0;
670 u16 checksum_local = 0;
675 DEBUGFUNC("i40e_calc_nvm_checksum");
677 ret_code = i40e_allocate_virt_mem(hw, &vmem,
678 I40E_SR_SECTOR_SIZE_IN_WORDS * sizeof(u16));
680 goto i40e_calc_nvm_checksum_exit;
681 data = (u16 *)vmem.va;
683 /* read pointer to VPD area */
684 ret_code = __i40e_read_nvm_word(hw, I40E_SR_VPD_PTR, &vpd_module);
685 if (ret_code != I40E_SUCCESS) {
686 ret_code = I40E_ERR_NVM_CHECKSUM;
687 goto i40e_calc_nvm_checksum_exit;
690 /* read pointer to PCIe Alt Auto-load module */
691 ret_code = __i40e_read_nvm_word(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR,
693 if (ret_code != I40E_SUCCESS) {
694 ret_code = I40E_ERR_NVM_CHECKSUM;
695 goto i40e_calc_nvm_checksum_exit;
698 /* Calculate SW checksum that covers the whole 64kB shadow RAM
699 * except the VPD and PCIe ALT Auto-load modules
701 for (i = 0; i < hw->nvm.sr_size; i++) {
703 if ((i % I40E_SR_SECTOR_SIZE_IN_WORDS) == 0) {
704 u16 words = I40E_SR_SECTOR_SIZE_IN_WORDS;
706 ret_code = __i40e_read_nvm_buffer(hw, i, &words, data);
707 if (ret_code != I40E_SUCCESS) {
708 ret_code = I40E_ERR_NVM_CHECKSUM;
709 goto i40e_calc_nvm_checksum_exit;
713 /* Skip Checksum word */
714 if (i == I40E_SR_SW_CHECKSUM_WORD)
716 /* Skip VPD module (convert byte size to word count) */
717 if ((i >= (u32)vpd_module) &&
718 (i < ((u32)vpd_module +
719 (I40E_SR_VPD_MODULE_MAX_SIZE / 2)))) {
722 /* Skip PCIe ALT module (convert byte size to word count) */
723 if ((i >= (u32)pcie_alt_module) &&
724 (i < ((u32)pcie_alt_module +
725 (I40E_SR_PCIE_ALT_MODULE_MAX_SIZE / 2)))) {
729 checksum_local += data[i % I40E_SR_SECTOR_SIZE_IN_WORDS];
732 *checksum = (u16)I40E_SR_SW_CHECKSUM_BASE - checksum_local;
734 i40e_calc_nvm_checksum_exit:
735 i40e_free_virt_mem(hw, &vmem);
740 * i40e_update_nvm_checksum - Updates the NVM checksum
741 * @hw: pointer to hardware structure
743 * NVM ownership must be acquired before calling this function and released
744 * on ARQ completion event reception by caller.
745 * This function will commit SR to NVM.
747 enum i40e_status_code i40e_update_nvm_checksum(struct i40e_hw *hw)
749 enum i40e_status_code ret_code = I40E_SUCCESS;
753 DEBUGFUNC("i40e_update_nvm_checksum");
755 ret_code = i40e_calc_nvm_checksum(hw, &checksum);
756 le_sum = CPU_TO_LE16(checksum);
757 if (ret_code == I40E_SUCCESS)
758 ret_code = i40e_write_nvm_aq(hw, 0x00, I40E_SR_SW_CHECKSUM_WORD,
765 * i40e_validate_nvm_checksum - Validate EEPROM checksum
766 * @hw: pointer to hardware structure
767 * @checksum: calculated checksum
769 * Performs checksum calculation and validates the NVM SW checksum. If the
770 * caller does not need checksum, the value can be NULL.
772 enum i40e_status_code i40e_validate_nvm_checksum(struct i40e_hw *hw,
775 enum i40e_status_code ret_code = I40E_SUCCESS;
777 u16 checksum_local = 0;
779 DEBUGFUNC("i40e_validate_nvm_checksum");
781 /* We must acquire the NVM lock in order to correctly synchronize the
782 * NVM accesses across multiple PFs. Without doing so it is possible
783 * for one of the PFs to read invalid data potentially indicating that
784 * the checksum is invalid.
786 ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
789 ret_code = i40e_calc_nvm_checksum(hw, &checksum_local);
790 __i40e_read_nvm_word(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr);
791 i40e_release_nvm(hw);
795 /* Verify read checksum from EEPROM is the same as
796 * calculated checksum
798 if (checksum_local != checksum_sr)
799 ret_code = I40E_ERR_NVM_CHECKSUM;
801 /* If the user cares, return the calculated checksum */
803 *checksum = checksum_local;
808 STATIC enum i40e_status_code i40e_nvmupd_state_init(struct i40e_hw *hw,
809 struct i40e_nvm_access *cmd,
810 u8 *bytes, int *perrno);
811 STATIC enum i40e_status_code i40e_nvmupd_state_reading(struct i40e_hw *hw,
812 struct i40e_nvm_access *cmd,
813 u8 *bytes, int *perrno);
814 STATIC enum i40e_status_code i40e_nvmupd_state_writing(struct i40e_hw *hw,
815 struct i40e_nvm_access *cmd,
816 u8 *bytes, int *perrno);
817 STATIC enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
818 struct i40e_nvm_access *cmd,
820 STATIC enum i40e_status_code i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
821 struct i40e_nvm_access *cmd,
823 STATIC enum i40e_status_code i40e_nvmupd_nvm_write(struct i40e_hw *hw,
824 struct i40e_nvm_access *cmd,
825 u8 *bytes, int *perrno);
826 STATIC enum i40e_status_code i40e_nvmupd_nvm_read(struct i40e_hw *hw,
827 struct i40e_nvm_access *cmd,
828 u8 *bytes, int *perrno);
829 STATIC enum i40e_status_code i40e_nvmupd_exec_aq(struct i40e_hw *hw,
830 struct i40e_nvm_access *cmd,
831 u8 *bytes, int *perrno);
832 STATIC enum i40e_status_code i40e_nvmupd_get_aq_result(struct i40e_hw *hw,
833 struct i40e_nvm_access *cmd,
834 u8 *bytes, int *perrno);
835 STATIC enum i40e_status_code i40e_nvmupd_get_aq_event(struct i40e_hw *hw,
836 struct i40e_nvm_access *cmd,
837 u8 *bytes, int *perrno);
838 STATIC INLINE u8 i40e_nvmupd_get_module(u32 val)
840 return (u8)(val & I40E_NVM_MOD_PNT_MASK);
842 STATIC INLINE u8 i40e_nvmupd_get_transaction(u32 val)
844 return (u8)((val & I40E_NVM_TRANS_MASK) >> I40E_NVM_TRANS_SHIFT);
847 STATIC INLINE u8 i40e_nvmupd_get_preservation_flags(u32 val)
849 return (u8)((val & I40E_NVM_PRESERVATION_FLAGS_MASK) >>
850 I40E_NVM_PRESERVATION_FLAGS_SHIFT);
853 STATIC const char *i40e_nvm_update_state_str[] = {
854 "I40E_NVMUPD_INVALID",
855 "I40E_NVMUPD_READ_CON",
856 "I40E_NVMUPD_READ_SNT",
857 "I40E_NVMUPD_READ_LCB",
858 "I40E_NVMUPD_READ_SA",
859 "I40E_NVMUPD_WRITE_ERA",
860 "I40E_NVMUPD_WRITE_CON",
861 "I40E_NVMUPD_WRITE_SNT",
862 "I40E_NVMUPD_WRITE_LCB",
863 "I40E_NVMUPD_WRITE_SA",
864 "I40E_NVMUPD_CSUM_CON",
865 "I40E_NVMUPD_CSUM_SA",
866 "I40E_NVMUPD_CSUM_LCB",
867 "I40E_NVMUPD_STATUS",
868 "I40E_NVMUPD_EXEC_AQ",
869 "I40E_NVMUPD_GET_AQ_RESULT",
870 "I40E_NVMUPD_GET_AQ_EVENT",
871 "I40E_NVMUPD_GET_FEATURES",
875 * i40e_nvmupd_command - Process an NVM update command
876 * @hw: pointer to hardware structure
877 * @cmd: pointer to nvm update command
878 * @bytes: pointer to the data buffer
879 * @perrno: pointer to return error code
881 * Dispatches command depending on what update state is current
883 enum i40e_status_code i40e_nvmupd_command(struct i40e_hw *hw,
884 struct i40e_nvm_access *cmd,
885 u8 *bytes, int *perrno)
887 enum i40e_status_code status;
888 enum i40e_nvmupd_cmd upd_cmd;
890 DEBUGFUNC("i40e_nvmupd_command");
895 /* early check for status command and debug msgs */
896 upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
898 i40e_debug(hw, I40E_DEBUG_NVM, "%s state %d nvm_release_on_hold %d opc 0x%04x cmd 0x%08x config 0x%08x offset 0x%08x data_size 0x%08x\n",
899 i40e_nvm_update_state_str[upd_cmd],
901 hw->nvm_release_on_done, hw->nvm_wait_opcode,
902 cmd->command, cmd->config, cmd->offset, cmd->data_size);
904 if (upd_cmd == I40E_NVMUPD_INVALID) {
906 i40e_debug(hw, I40E_DEBUG_NVM,
907 "i40e_nvmupd_validate_command returns %d errno %d\n",
911 /* a status request returns immediately rather than
912 * going into the state machine
914 if (upd_cmd == I40E_NVMUPD_STATUS) {
915 if (!cmd->data_size) {
917 return I40E_ERR_BUF_TOO_SHORT;
920 bytes[0] = hw->nvmupd_state;
922 if (cmd->data_size >= 4) {
924 *((u16 *)&bytes[2]) = hw->nvm_wait_opcode;
927 /* Clear error status on read */
928 if (hw->nvmupd_state == I40E_NVMUPD_STATE_ERROR)
929 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
935 * A supported features request returns immediately
936 * rather than going into state machine
938 if (upd_cmd == I40E_NVMUPD_FEATURES) {
939 if (cmd->data_size < hw->nvmupd_features.size) {
941 return I40E_ERR_BUF_TOO_SHORT;
945 * If buffer is bigger than i40e_nvmupd_features structure,
946 * make sure the trailing bytes are set to 0x0.
948 if (cmd->data_size > hw->nvmupd_features.size)
949 i40e_memset(bytes + hw->nvmupd_features.size, 0x0,
950 cmd->data_size - hw->nvmupd_features.size,
953 i40e_memcpy(bytes, &hw->nvmupd_features,
954 hw->nvmupd_features.size, I40E_NONDMA_MEM);
959 /* Clear status even it is not read and log */
960 if (hw->nvmupd_state == I40E_NVMUPD_STATE_ERROR) {
961 i40e_debug(hw, I40E_DEBUG_NVM,
962 "Clearing I40E_NVMUPD_STATE_ERROR state without reading\n");
963 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
966 /* Acquire lock to prevent race condition where adminq_task
967 * can execute after i40e_nvmupd_nvm_read/write but before state
968 * variables (nvm_wait_opcode, nvm_release_on_done) are updated.
970 * During NVMUpdate, it is observed that lock could be held for
971 * ~5ms for most commands. However lock is held for ~60ms for
972 * NVMUPD_CSUM_LCB command.
974 i40e_acquire_spinlock(&hw->aq.arq_spinlock);
975 switch (hw->nvmupd_state) {
976 case I40E_NVMUPD_STATE_INIT:
977 status = i40e_nvmupd_state_init(hw, cmd, bytes, perrno);
980 case I40E_NVMUPD_STATE_READING:
981 status = i40e_nvmupd_state_reading(hw, cmd, bytes, perrno);
984 case I40E_NVMUPD_STATE_WRITING:
985 status = i40e_nvmupd_state_writing(hw, cmd, bytes, perrno);
988 case I40E_NVMUPD_STATE_INIT_WAIT:
989 case I40E_NVMUPD_STATE_WRITE_WAIT:
990 /* if we need to stop waiting for an event, clear
991 * the wait info and return before doing anything else
993 if (cmd->offset == 0xffff) {
994 i40e_nvmupd_clear_wait_state(hw);
995 status = I40E_SUCCESS;
999 status = I40E_ERR_NOT_READY;
1004 /* invalid state, should never happen */
1005 i40e_debug(hw, I40E_DEBUG_NVM,
1006 "NVMUPD: no such state %d\n", hw->nvmupd_state);
1007 status = I40E_NOT_SUPPORTED;
1012 i40e_release_spinlock(&hw->aq.arq_spinlock);
1017 * i40e_nvmupd_state_init - Handle NVM update state Init
1018 * @hw: pointer to hardware structure
1019 * @cmd: pointer to nvm update command buffer
1020 * @bytes: pointer to the data buffer
1021 * @perrno: pointer to return error code
1023 * Process legitimate commands of the Init state and conditionally set next
1024 * state. Reject all other commands.
1026 STATIC enum i40e_status_code i40e_nvmupd_state_init(struct i40e_hw *hw,
1027 struct i40e_nvm_access *cmd,
1028 u8 *bytes, int *perrno)
1030 enum i40e_status_code status = I40E_SUCCESS;
1031 enum i40e_nvmupd_cmd upd_cmd;
1033 DEBUGFUNC("i40e_nvmupd_state_init");
1035 upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
1038 case I40E_NVMUPD_READ_SA:
1039 status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
1041 *perrno = i40e_aq_rc_to_posix(status,
1042 hw->aq.asq_last_status);
1044 status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno);
1045 i40e_release_nvm(hw);
1049 case I40E_NVMUPD_READ_SNT:
1050 status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
1052 *perrno = i40e_aq_rc_to_posix(status,
1053 hw->aq.asq_last_status);
1055 status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno);
1057 i40e_release_nvm(hw);
1059 hw->nvmupd_state = I40E_NVMUPD_STATE_READING;
1063 case I40E_NVMUPD_WRITE_ERA:
1064 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
1066 *perrno = i40e_aq_rc_to_posix(status,
1067 hw->aq.asq_last_status);
1069 status = i40e_nvmupd_nvm_erase(hw, cmd, perrno);
1071 i40e_release_nvm(hw);
1073 hw->nvm_release_on_done = true;
1074 hw->nvm_wait_opcode = i40e_aqc_opc_nvm_erase;
1075 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
1080 case I40E_NVMUPD_WRITE_SA:
1081 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
1083 *perrno = i40e_aq_rc_to_posix(status,
1084 hw->aq.asq_last_status);
1086 status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
1088 i40e_release_nvm(hw);
1090 hw->nvm_release_on_done = true;
1091 hw->nvm_wait_opcode = i40e_aqc_opc_nvm_update;
1092 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
1097 case I40E_NVMUPD_WRITE_SNT:
1098 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
1100 *perrno = i40e_aq_rc_to_posix(status,
1101 hw->aq.asq_last_status);
1103 status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
1105 i40e_release_nvm(hw);
1107 hw->nvm_wait_opcode = i40e_aqc_opc_nvm_update;
1108 hw->nvmupd_state = I40E_NVMUPD_STATE_WRITE_WAIT;
1113 case I40E_NVMUPD_CSUM_SA:
1114 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
1116 *perrno = i40e_aq_rc_to_posix(status,
1117 hw->aq.asq_last_status);
1119 status = i40e_update_nvm_checksum(hw);
1121 *perrno = hw->aq.asq_last_status ?
1122 i40e_aq_rc_to_posix(status,
1123 hw->aq.asq_last_status) :
1125 i40e_release_nvm(hw);
1127 hw->nvm_release_on_done = true;
1128 hw->nvm_wait_opcode = i40e_aqc_opc_nvm_update;
1129 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
1134 case I40E_NVMUPD_EXEC_AQ:
1135 status = i40e_nvmupd_exec_aq(hw, cmd, bytes, perrno);
1138 case I40E_NVMUPD_GET_AQ_RESULT:
1139 status = i40e_nvmupd_get_aq_result(hw, cmd, bytes, perrno);
1142 case I40E_NVMUPD_GET_AQ_EVENT:
1143 status = i40e_nvmupd_get_aq_event(hw, cmd, bytes, perrno);
1147 i40e_debug(hw, I40E_DEBUG_NVM,
1148 "NVMUPD: bad cmd %s in init state\n",
1149 i40e_nvm_update_state_str[upd_cmd]);
1150 status = I40E_ERR_NVM;
1158 * i40e_nvmupd_state_reading - Handle NVM update state Reading
1159 * @hw: pointer to hardware structure
1160 * @cmd: pointer to nvm update command buffer
1161 * @bytes: pointer to the data buffer
1162 * @perrno: pointer to return error code
1164 * NVM ownership is already held. Process legitimate commands and set any
1165 * change in state; reject all other commands.
1167 STATIC enum i40e_status_code i40e_nvmupd_state_reading(struct i40e_hw *hw,
1168 struct i40e_nvm_access *cmd,
1169 u8 *bytes, int *perrno)
1171 enum i40e_status_code status = I40E_SUCCESS;
1172 enum i40e_nvmupd_cmd upd_cmd;
1174 DEBUGFUNC("i40e_nvmupd_state_reading");
1176 upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
1179 case I40E_NVMUPD_READ_SA:
1180 case I40E_NVMUPD_READ_CON:
1181 status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno);
1184 case I40E_NVMUPD_READ_LCB:
1185 status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno);
1186 i40e_release_nvm(hw);
1187 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
1191 i40e_debug(hw, I40E_DEBUG_NVM,
1192 "NVMUPD: bad cmd %s in reading state.\n",
1193 i40e_nvm_update_state_str[upd_cmd]);
1194 status = I40E_NOT_SUPPORTED;
1202 * i40e_nvmupd_state_writing - Handle NVM update state Writing
1203 * @hw: pointer to hardware structure
1204 * @cmd: pointer to nvm update command buffer
1205 * @bytes: pointer to the data buffer
1206 * @perrno: pointer to return error code
1208 * NVM ownership is already held. Process legitimate commands and set any
1209 * change in state; reject all other commands
1211 STATIC enum i40e_status_code i40e_nvmupd_state_writing(struct i40e_hw *hw,
1212 struct i40e_nvm_access *cmd,
1213 u8 *bytes, int *perrno)
1215 enum i40e_status_code status = I40E_SUCCESS;
1216 enum i40e_nvmupd_cmd upd_cmd;
1217 bool retry_attempt = false;
1219 DEBUGFUNC("i40e_nvmupd_state_writing");
1221 upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
1225 case I40E_NVMUPD_WRITE_CON:
1226 status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
1228 hw->nvm_wait_opcode = i40e_aqc_opc_nvm_update;
1229 hw->nvmupd_state = I40E_NVMUPD_STATE_WRITE_WAIT;
1233 case I40E_NVMUPD_WRITE_LCB:
1234 status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
1236 *perrno = hw->aq.asq_last_status ?
1237 i40e_aq_rc_to_posix(status,
1238 hw->aq.asq_last_status) :
1240 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
1242 hw->nvm_release_on_done = true;
1243 hw->nvm_wait_opcode = i40e_aqc_opc_nvm_update;
1244 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
1248 case I40E_NVMUPD_CSUM_CON:
1249 /* Assumes the caller has acquired the nvm */
1250 status = i40e_update_nvm_checksum(hw);
1252 *perrno = hw->aq.asq_last_status ?
1253 i40e_aq_rc_to_posix(status,
1254 hw->aq.asq_last_status) :
1256 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
1258 hw->nvm_wait_opcode = i40e_aqc_opc_nvm_update;
1259 hw->nvmupd_state = I40E_NVMUPD_STATE_WRITE_WAIT;
1263 case I40E_NVMUPD_CSUM_LCB:
1264 /* Assumes the caller has acquired the nvm */
1265 status = i40e_update_nvm_checksum(hw);
1267 *perrno = hw->aq.asq_last_status ?
1268 i40e_aq_rc_to_posix(status,
1269 hw->aq.asq_last_status) :
1271 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
1273 hw->nvm_release_on_done = true;
1274 hw->nvm_wait_opcode = i40e_aqc_opc_nvm_update;
1275 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
1280 i40e_debug(hw, I40E_DEBUG_NVM,
1281 "NVMUPD: bad cmd %s in writing state.\n",
1282 i40e_nvm_update_state_str[upd_cmd]);
1283 status = I40E_NOT_SUPPORTED;
1288 /* In some circumstances, a multi-write transaction takes longer
1289 * than the default 3 minute timeout on the write semaphore. If
1290 * the write failed with an EBUSY status, this is likely the problem,
1291 * so here we try to reacquire the semaphore then retry the write.
1292 * We only do one retry, then give up.
1294 if (status && (hw->aq.asq_last_status == I40E_AQ_RC_EBUSY) &&
1296 enum i40e_status_code old_status = status;
1297 u32 old_asq_status = hw->aq.asq_last_status;
1300 gtime = rd32(hw, I40E_GLVFGEN_TIMER);
1301 if (gtime >= hw->nvm.hw_semaphore_timeout) {
1302 i40e_debug(hw, I40E_DEBUG_ALL,
1303 "NVMUPD: write semaphore expired (%d >= %lld), retrying\n",
1304 gtime, hw->nvm.hw_semaphore_timeout);
1305 i40e_release_nvm(hw);
1306 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
1308 i40e_debug(hw, I40E_DEBUG_ALL,
1309 "NVMUPD: write semaphore reacquire failed aq_err = %d\n",
1310 hw->aq.asq_last_status);
1311 status = old_status;
1312 hw->aq.asq_last_status = old_asq_status;
1314 retry_attempt = true;
1324 * i40e_nvmupd_clear_wait_state - clear wait state on hw
1325 * @hw: pointer to the hardware structure
1327 void i40e_nvmupd_clear_wait_state(struct i40e_hw *hw)
1329 i40e_debug(hw, I40E_DEBUG_NVM,
1330 "NVMUPD: clearing wait on opcode 0x%04x\n",
1331 hw->nvm_wait_opcode);
1333 if (hw->nvm_release_on_done) {
1334 i40e_release_nvm(hw);
1335 hw->nvm_release_on_done = false;
1337 hw->nvm_wait_opcode = 0;
1339 if (hw->aq.arq_last_status) {
1340 hw->nvmupd_state = I40E_NVMUPD_STATE_ERROR;
1344 switch (hw->nvmupd_state) {
1345 case I40E_NVMUPD_STATE_INIT_WAIT:
1346 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
1349 case I40E_NVMUPD_STATE_WRITE_WAIT:
1350 hw->nvmupd_state = I40E_NVMUPD_STATE_WRITING;
1359 * i40e_nvmupd_check_wait_event - handle NVM update operation events
1360 * @hw: pointer to the hardware structure
1361 * @opcode: the event that just happened
1362 * @desc: AdminQ descriptor
1364 void i40e_nvmupd_check_wait_event(struct i40e_hw *hw, u16 opcode,
1365 struct i40e_aq_desc *desc)
1367 u32 aq_desc_len = sizeof(struct i40e_aq_desc);
1369 if (opcode == hw->nvm_wait_opcode) {
1370 i40e_memcpy(&hw->nvm_aq_event_desc, desc,
1371 aq_desc_len, I40E_NONDMA_TO_NONDMA);
1372 i40e_nvmupd_clear_wait_state(hw);
1377 * i40e_nvmupd_validate_command - Validate given command
1378 * @hw: pointer to hardware structure
1379 * @cmd: pointer to nvm update command buffer
1380 * @perrno: pointer to return error code
1382 * Return one of the valid command types or I40E_NVMUPD_INVALID
1384 STATIC enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
1385 struct i40e_nvm_access *cmd,
1388 enum i40e_nvmupd_cmd upd_cmd;
1389 u8 module, transaction;
1391 DEBUGFUNC("i40e_nvmupd_validate_command\n");
1393 /* anything that doesn't match a recognized case is an error */
1394 upd_cmd = I40E_NVMUPD_INVALID;
1396 transaction = i40e_nvmupd_get_transaction(cmd->config);
1397 module = i40e_nvmupd_get_module(cmd->config);
1399 /* limits on data size */
1400 if ((cmd->data_size < 1) ||
1401 (cmd->data_size > I40E_NVMUPD_MAX_DATA)) {
1402 i40e_debug(hw, I40E_DEBUG_NVM,
1403 "i40e_nvmupd_validate_command data_size %d\n",
1406 return I40E_NVMUPD_INVALID;
1409 switch (cmd->command) {
1411 switch (transaction) {
1413 upd_cmd = I40E_NVMUPD_READ_CON;
1416 upd_cmd = I40E_NVMUPD_READ_SNT;
1419 upd_cmd = I40E_NVMUPD_READ_LCB;
1422 upd_cmd = I40E_NVMUPD_READ_SA;
1426 case I40E_NVM_EXEC_GET_AQ_RESULT:
1427 upd_cmd = I40E_NVMUPD_GET_AQ_RESULT;
1429 case I40E_NVM_EXEC_FEATURES:
1430 upd_cmd = I40E_NVMUPD_FEATURES;
1432 case I40E_NVM_EXEC_STATUS:
1433 upd_cmd = I40E_NVMUPD_STATUS;
1437 return I40E_NVMUPD_INVALID;
1441 upd_cmd = I40E_NVMUPD_GET_AQ_EVENT;
1446 case I40E_NVM_WRITE:
1447 switch (transaction) {
1449 upd_cmd = I40E_NVMUPD_WRITE_CON;
1452 upd_cmd = I40E_NVMUPD_WRITE_SNT;
1455 upd_cmd = I40E_NVMUPD_WRITE_LCB;
1458 upd_cmd = I40E_NVMUPD_WRITE_SA;
1461 upd_cmd = I40E_NVMUPD_WRITE_ERA;
1464 upd_cmd = I40E_NVMUPD_CSUM_CON;
1466 case (I40E_NVM_CSUM|I40E_NVM_SA):
1467 upd_cmd = I40E_NVMUPD_CSUM_SA;
1469 case (I40E_NVM_CSUM|I40E_NVM_LCB):
1470 upd_cmd = I40E_NVMUPD_CSUM_LCB;
1474 upd_cmd = I40E_NVMUPD_EXEC_AQ;
1484 * i40e_nvmupd_exec_aq - Run an AQ command
1485 * @hw: pointer to hardware structure
1486 * @cmd: pointer to nvm update command buffer
1487 * @bytes: pointer to the data buffer
1488 * @perrno: pointer to return error code
1490 * cmd structure contains identifiers and data buffer
1492 STATIC enum i40e_status_code i40e_nvmupd_exec_aq(struct i40e_hw *hw,
1493 struct i40e_nvm_access *cmd,
1494 u8 *bytes, int *perrno)
1496 struct i40e_asq_cmd_details cmd_details;
1497 enum i40e_status_code status;
1498 struct i40e_aq_desc *aq_desc;
1504 i40e_debug(hw, I40E_DEBUG_NVM, "NVMUPD: %s\n", __func__);
1505 if (cmd->offset == 0xffff)
1506 return I40E_SUCCESS;
1508 memset(&cmd_details, 0, sizeof(cmd_details));
1509 cmd_details.wb_desc = &hw->nvm_wb_desc;
1511 aq_desc_len = sizeof(struct i40e_aq_desc);
1512 memset(&hw->nvm_wb_desc, 0, aq_desc_len);
1514 /* get the aq descriptor */
1515 if (cmd->data_size < aq_desc_len) {
1516 i40e_debug(hw, I40E_DEBUG_NVM,
1517 "NVMUPD: not enough aq desc bytes for exec, size %d < %d\n",
1518 cmd->data_size, aq_desc_len);
1520 return I40E_ERR_PARAM;
1522 aq_desc = (struct i40e_aq_desc *)bytes;
1524 /* if data buffer needed, make sure it's ready */
1525 aq_data_len = cmd->data_size - aq_desc_len;
1526 buff_size = max(aq_data_len, (u32)LE16_TO_CPU(aq_desc->datalen));
1528 if (!hw->nvm_buff.va) {
1529 status = i40e_allocate_virt_mem(hw, &hw->nvm_buff,
1530 hw->aq.asq_buf_size);
1532 i40e_debug(hw, I40E_DEBUG_NVM,
1533 "NVMUPD: i40e_allocate_virt_mem for exec buff failed, %d\n",
1537 if (hw->nvm_buff.va) {
1538 buff = hw->nvm_buff.va;
1539 i40e_memcpy(buff, &bytes[aq_desc_len], aq_data_len,
1540 I40E_NONDMA_TO_NONDMA);
1545 memset(&hw->nvm_aq_event_desc, 0, aq_desc_len);
1547 /* and away we go! */
1548 status = i40e_asq_send_command(hw, aq_desc, buff,
1549 buff_size, &cmd_details);
1551 i40e_debug(hw, I40E_DEBUG_NVM,
1552 "i40e_nvmupd_exec_aq err %s aq_err %s\n",
1553 i40e_stat_str(hw, status),
1554 i40e_aq_str(hw, hw->aq.asq_last_status));
1555 *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
1559 /* should we wait for a followup event? */
1561 hw->nvm_wait_opcode = cmd->offset;
1562 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
1569 * i40e_nvmupd_get_aq_result - Get the results from the previous exec_aq
1570 * @hw: pointer to hardware structure
1571 * @cmd: pointer to nvm update command buffer
1572 * @bytes: pointer to the data buffer
1573 * @perrno: pointer to return error code
1575 * cmd structure contains identifiers and data buffer
1577 STATIC enum i40e_status_code i40e_nvmupd_get_aq_result(struct i40e_hw *hw,
1578 struct i40e_nvm_access *cmd,
1579 u8 *bytes, int *perrno)
1586 i40e_debug(hw, I40E_DEBUG_NVM, "NVMUPD: %s\n", __func__);
1588 aq_desc_len = sizeof(struct i40e_aq_desc);
1589 aq_total_len = aq_desc_len + LE16_TO_CPU(hw->nvm_wb_desc.datalen);
1591 /* check offset range */
1592 if (cmd->offset > aq_total_len) {
1593 i40e_debug(hw, I40E_DEBUG_NVM, "%s: offset too big %d > %d\n",
1594 __func__, cmd->offset, aq_total_len);
1596 return I40E_ERR_PARAM;
1599 /* check copylength range */
1600 if (cmd->data_size > (aq_total_len - cmd->offset)) {
1601 int new_len = aq_total_len - cmd->offset;
1603 i40e_debug(hw, I40E_DEBUG_NVM, "%s: copy length %d too big, trimming to %d\n",
1604 __func__, cmd->data_size, new_len);
1605 cmd->data_size = new_len;
1608 remainder = cmd->data_size;
1609 if (cmd->offset < aq_desc_len) {
1610 u32 len = aq_desc_len - cmd->offset;
1612 len = min(len, cmd->data_size);
1613 i40e_debug(hw, I40E_DEBUG_NVM, "%s: aq_desc bytes %d to %d\n",
1614 __func__, cmd->offset, cmd->offset + len);
1616 buff = ((u8 *)&hw->nvm_wb_desc) + cmd->offset;
1617 i40e_memcpy(bytes, buff, len, I40E_NONDMA_TO_NONDMA);
1621 buff = hw->nvm_buff.va;
1623 buff = (u8 *)hw->nvm_buff.va + (cmd->offset - aq_desc_len);
1626 if (remainder > 0) {
1627 int start_byte = buff - (u8 *)hw->nvm_buff.va;
1629 i40e_debug(hw, I40E_DEBUG_NVM, "%s: databuf bytes %d to %d\n",
1630 __func__, start_byte, start_byte + remainder);
1631 i40e_memcpy(bytes, buff, remainder, I40E_NONDMA_TO_NONDMA);
1634 return I40E_SUCCESS;
1638 * i40e_nvmupd_get_aq_event - Get the Admin Queue event from previous exec_aq
1639 * @hw: pointer to hardware structure
1640 * @cmd: pointer to nvm update command buffer
1641 * @bytes: pointer to the data buffer
1642 * @perrno: pointer to return error code
1644 * cmd structure contains identifiers and data buffer
1646 STATIC enum i40e_status_code i40e_nvmupd_get_aq_event(struct i40e_hw *hw,
1647 struct i40e_nvm_access *cmd,
1648 u8 *bytes, int *perrno)
1653 i40e_debug(hw, I40E_DEBUG_NVM, "NVMUPD: %s\n", __func__);
1655 aq_desc_len = sizeof(struct i40e_aq_desc);
1656 aq_total_len = aq_desc_len + LE16_TO_CPU(hw->nvm_aq_event_desc.datalen);
1658 /* check copylength range */
1659 if (cmd->data_size > aq_total_len) {
1660 i40e_debug(hw, I40E_DEBUG_NVM,
1661 "%s: copy length %d too big, trimming to %d\n",
1662 __func__, cmd->data_size, aq_total_len);
1663 cmd->data_size = aq_total_len;
1666 i40e_memcpy(bytes, &hw->nvm_aq_event_desc, cmd->data_size,
1667 I40E_NONDMA_TO_NONDMA);
1669 return I40E_SUCCESS;
1673 * i40e_nvmupd_nvm_read - Read NVM
1674 * @hw: pointer to hardware structure
1675 * @cmd: pointer to nvm update command buffer
1676 * @bytes: pointer to the data buffer
1677 * @perrno: pointer to return error code
1679 * cmd structure contains identifiers and data buffer
1681 STATIC enum i40e_status_code i40e_nvmupd_nvm_read(struct i40e_hw *hw,
1682 struct i40e_nvm_access *cmd,
1683 u8 *bytes, int *perrno)
1685 struct i40e_asq_cmd_details cmd_details;
1686 enum i40e_status_code status;
1687 u8 module, transaction;
1690 transaction = i40e_nvmupd_get_transaction(cmd->config);
1691 module = i40e_nvmupd_get_module(cmd->config);
1692 last = (transaction == I40E_NVM_LCB) || (transaction == I40E_NVM_SA);
1694 memset(&cmd_details, 0, sizeof(cmd_details));
1695 cmd_details.wb_desc = &hw->nvm_wb_desc;
1697 status = i40e_aq_read_nvm(hw, module, cmd->offset, (u16)cmd->data_size,
1698 bytes, last, &cmd_details);
1700 i40e_debug(hw, I40E_DEBUG_NVM,
1701 "i40e_nvmupd_nvm_read mod 0x%x off 0x%x len 0x%x\n",
1702 module, cmd->offset, cmd->data_size);
1703 i40e_debug(hw, I40E_DEBUG_NVM,
1704 "i40e_nvmupd_nvm_read status %d aq %d\n",
1705 status, hw->aq.asq_last_status);
1706 *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
1713 * i40e_nvmupd_nvm_erase - Erase an NVM module
1714 * @hw: pointer to hardware structure
1715 * @cmd: pointer to nvm update command buffer
1716 * @perrno: pointer to return error code
1718 * module, offset, data_size and data are in cmd structure
1720 STATIC enum i40e_status_code i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
1721 struct i40e_nvm_access *cmd,
1724 enum i40e_status_code status = I40E_SUCCESS;
1725 struct i40e_asq_cmd_details cmd_details;
1726 u8 module, transaction;
1729 transaction = i40e_nvmupd_get_transaction(cmd->config);
1730 module = i40e_nvmupd_get_module(cmd->config);
1731 last = (transaction & I40E_NVM_LCB);
1733 memset(&cmd_details, 0, sizeof(cmd_details));
1734 cmd_details.wb_desc = &hw->nvm_wb_desc;
1736 status = i40e_aq_erase_nvm(hw, module, cmd->offset, (u16)cmd->data_size,
1737 last, &cmd_details);
1739 i40e_debug(hw, I40E_DEBUG_NVM,
1740 "i40e_nvmupd_nvm_erase mod 0x%x off 0x%x len 0x%x\n",
1741 module, cmd->offset, cmd->data_size);
1742 i40e_debug(hw, I40E_DEBUG_NVM,
1743 "i40e_nvmupd_nvm_erase status %d aq %d\n",
1744 status, hw->aq.asq_last_status);
1745 *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
1752 * i40e_nvmupd_nvm_write - Write NVM
1753 * @hw: pointer to hardware structure
1754 * @cmd: pointer to nvm update command buffer
1755 * @bytes: pointer to the data buffer
1756 * @perrno: pointer to return error code
1758 * module, offset, data_size and data are in cmd structure
1760 STATIC enum i40e_status_code i40e_nvmupd_nvm_write(struct i40e_hw *hw,
1761 struct i40e_nvm_access *cmd,
1762 u8 *bytes, int *perrno)
1764 enum i40e_status_code status = I40E_SUCCESS;
1765 struct i40e_asq_cmd_details cmd_details;
1766 u8 module, transaction;
1767 u8 preservation_flags;
1770 transaction = i40e_nvmupd_get_transaction(cmd->config);
1771 module = i40e_nvmupd_get_module(cmd->config);
1772 last = (transaction & I40E_NVM_LCB);
1773 preservation_flags = i40e_nvmupd_get_preservation_flags(cmd->config);
1775 memset(&cmd_details, 0, sizeof(cmd_details));
1776 cmd_details.wb_desc = &hw->nvm_wb_desc;
1778 status = i40e_aq_update_nvm(hw, module, cmd->offset,
1779 (u16)cmd->data_size, bytes, last,
1780 preservation_flags, &cmd_details);
1782 i40e_debug(hw, I40E_DEBUG_NVM,
1783 "i40e_nvmupd_nvm_write mod 0x%x off 0x%x len 0x%x\n",
1784 module, cmd->offset, cmd->data_size);
1785 i40e_debug(hw, I40E_DEBUG_NVM,
1786 "i40e_nvmupd_nvm_write status %d aq %d\n",
1787 status, hw->aq.asq_last_status);
1788 *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);