i40e/base: enhance polling of NVM semaphore
[dpdk.git] / lib / librte_pmd_i40e / i40e / i40e_nvm.c
1 /*******************************************************************************
2
3 Copyright (c) 2013 - 2015, Intel Corporation
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8
9  1. Redistributions of source code must retain the above copyright notice,
10     this list of conditions and the following disclaimer.
11
12  2. Redistributions in binary form must reproduce the above copyright
13     notice, this list of conditions and the following disclaimer in the
14     documentation and/or other materials provided with the distribution.
15
16  3. Neither the name of the Intel Corporation nor the names of its
17     contributors may be used to endorse or promote products derived from
18     this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE.
31
32 ***************************************************************************/
33
34 #include "i40e_prototype.h"
35
36 enum i40e_status_code i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset,
37                                                u16 *data);
38 enum i40e_status_code i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset,
39                                             u16 *data);
40 enum i40e_status_code i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
41                                                  u16 *words, u16 *data);
42 enum i40e_status_code i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset,
43                                               u16 *words, u16 *data);
44 enum i40e_status_code i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
45                                        u32 offset, u16 words, void *data,
46                                        bool last_command);
47
48 /**
49  * i40e_init_nvm_ops - Initialize NVM function pointers
50  * @hw: pointer to the HW structure
51  *
52  * Setup the function pointers and the NVM info structure. Should be called
53  * once per NVM initialization, e.g. inside the i40e_init_shared_code().
54  * Please notice that the NVM term is used here (& in all methods covered
55  * in this file) as an equivalent of the FLASH part mapped into the SR.
56  * We are accessing FLASH always thru the Shadow RAM.
57  **/
58 enum i40e_status_code i40e_init_nvm(struct i40e_hw *hw)
59 {
60         struct i40e_nvm_info *nvm = &hw->nvm;
61         enum i40e_status_code ret_code = I40E_SUCCESS;
62         u32 fla, gens;
63         u8 sr_size;
64
65         DEBUGFUNC("i40e_init_nvm");
66
67         /* The SR size is stored regardless of the nvm programming mode
68          * as the blank mode may be used in the factory line.
69          */
70         gens = rd32(hw, I40E_GLNVM_GENS);
71         sr_size = ((gens & I40E_GLNVM_GENS_SR_SIZE_MASK) >>
72                            I40E_GLNVM_GENS_SR_SIZE_SHIFT);
73         /* Switching to words (sr_size contains power of 2KB) */
74         nvm->sr_size = (1 << sr_size) * I40E_SR_WORDS_IN_1KB;
75
76         /* Check if we are in the normal or blank NVM programming mode */
77         fla = rd32(hw, I40E_GLNVM_FLA);
78         if (fla & I40E_GLNVM_FLA_LOCKED_MASK) { /* Normal programming mode */
79                 /* Max NVM timeout */
80                 nvm->timeout = I40E_MAX_NVM_TIMEOUT;
81                 nvm->blank_nvm_mode = false;
82         } else { /* Blank programming mode */
83                 nvm->blank_nvm_mode = true;
84                 ret_code = I40E_ERR_NVM_BLANK_MODE;
85                 i40e_debug(hw, I40E_DEBUG_NVM, "NVM init error: unsupported blank mode.\n");
86         }
87
88         return ret_code;
89 }
90
91 /**
92  * i40e_acquire_nvm - Generic request for acquiring the NVM ownership
93  * @hw: pointer to the HW structure
94  * @access: NVM access type (read or write)
95  *
96  * This function will request NVM ownership for reading
97  * via the proper Admin Command.
98  **/
99 enum i40e_status_code i40e_acquire_nvm(struct i40e_hw *hw,
100                                        enum i40e_aq_resource_access_type access)
101 {
102         enum i40e_status_code ret_code = I40E_SUCCESS;
103         u64 gtime, timeout;
104         u64 time_left = 0;
105
106         DEBUGFUNC("i40e_acquire_nvm");
107
108         if (hw->nvm.blank_nvm_mode)
109                 goto i40e_i40e_acquire_nvm_exit;
110
111         ret_code = i40e_aq_request_resource(hw, I40E_NVM_RESOURCE_ID, access,
112                                             0, &time_left, NULL);
113         /* Reading the Global Device Timer */
114         gtime = rd32(hw, I40E_GLVFGEN_TIMER);
115
116         /* Store the timeout */
117         hw->nvm.hw_semaphore_timeout = I40E_MS_TO_GTIME(time_left) + gtime;
118
119         if (ret_code)
120                 i40e_debug(hw, I40E_DEBUG_NVM,
121                            "NVM acquire type %d failed time_left=%llu ret=%d aq_err=%d\n",
122                            access, time_left, ret_code, hw->aq.asq_last_status);
123
124         if (ret_code && time_left) {
125                 /* Poll until the current NVM owner timeouts */
126                 timeout = I40E_MS_TO_GTIME(I40E_MAX_NVM_TIMEOUT) + gtime;
127                 while ((gtime < timeout) && time_left) {
128                         i40e_msec_delay(10);
129                         gtime = rd32(hw, I40E_GLVFGEN_TIMER);
130                         ret_code = i40e_aq_request_resource(hw,
131                                                         I40E_NVM_RESOURCE_ID,
132                                                         access, 0, &time_left,
133                                                         NULL);
134                         if (ret_code == I40E_SUCCESS) {
135                                 hw->nvm.hw_semaphore_timeout =
136                                             I40E_MS_TO_GTIME(time_left) + gtime;
137                                 break;
138                         }
139                 }
140                 if (ret_code != I40E_SUCCESS) {
141                         hw->nvm.hw_semaphore_timeout = 0;
142                         i40e_debug(hw, I40E_DEBUG_NVM,
143                                    "NVM acquire timed out, wait %llu ms before trying again. status=%d aq_err=%d\n",
144                                    time_left, ret_code, hw->aq.asq_last_status);
145                 }
146         }
147
148 i40e_i40e_acquire_nvm_exit:
149         return ret_code;
150 }
151
152 /**
153  * i40e_release_nvm - Generic request for releasing the NVM ownership
154  * @hw: pointer to the HW structure
155  *
156  * This function will release NVM resource via the proper Admin Command.
157  **/
158 void i40e_release_nvm(struct i40e_hw *hw)
159 {
160         DEBUGFUNC("i40e_release_nvm");
161
162         if (!hw->nvm.blank_nvm_mode)
163                 i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL);
164 }
165
166 /**
167  * i40e_poll_sr_srctl_done_bit - Polls the GLNVM_SRCTL done bit
168  * @hw: pointer to the HW structure
169  *
170  * Polls the SRCTL Shadow RAM register done bit.
171  **/
172 static enum i40e_status_code i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw)
173 {
174         enum i40e_status_code ret_code = I40E_ERR_TIMEOUT;
175         u32 srctl, wait_cnt;
176
177         DEBUGFUNC("i40e_poll_sr_srctl_done_bit");
178
179         /* Poll the I40E_GLNVM_SRCTL until the done bit is set */
180         for (wait_cnt = 0; wait_cnt < I40E_SRRD_SRCTL_ATTEMPTS; wait_cnt++) {
181                 srctl = rd32(hw, I40E_GLNVM_SRCTL);
182                 if (srctl & I40E_GLNVM_SRCTL_DONE_MASK) {
183                         ret_code = I40E_SUCCESS;
184                         break;
185                 }
186                 i40e_usec_delay(5);
187         }
188         if (ret_code == I40E_ERR_TIMEOUT)
189                 i40e_debug(hw, I40E_DEBUG_NVM, "Done bit in GLNVM_SRCTL not set");
190         return ret_code;
191 }
192
193 /**
194  * i40e_read_nvm_word - Reads Shadow RAM
195  * @hw: pointer to the HW structure
196  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
197  * @data: word read from the Shadow RAM
198  *
199  * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
200  **/
201 enum i40e_status_code i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
202                                          u16 *data)
203 {
204         return i40e_read_nvm_word_srctl(hw, offset, data);
205 }
206
207 /**
208  * i40e_read_nvm_word_srctl - Reads Shadow RAM via SRCTL register
209  * @hw: pointer to the HW structure
210  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
211  * @data: word read from the Shadow RAM
212  *
213  * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
214  **/
215 enum i40e_status_code i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset,
216                                                u16 *data)
217 {
218         enum i40e_status_code ret_code = I40E_ERR_TIMEOUT;
219         u32 sr_reg;
220
221         DEBUGFUNC("i40e_read_nvm_word_srctl");
222
223         if (offset >= hw->nvm.sr_size) {
224                 i40e_debug(hw, I40E_DEBUG_NVM,
225                            "NVM read error: Offset %d beyond Shadow RAM limit %d\n",
226                            offset, hw->nvm.sr_size);
227                 ret_code = I40E_ERR_PARAM;
228                 goto read_nvm_exit;
229         }
230
231         /* Poll the done bit first */
232         ret_code = i40e_poll_sr_srctl_done_bit(hw);
233         if (ret_code == I40E_SUCCESS) {
234                 /* Write the address and start reading */
235                 sr_reg = (u32)(offset << I40E_GLNVM_SRCTL_ADDR_SHIFT) |
236                          (1 << I40E_GLNVM_SRCTL_START_SHIFT);
237                 wr32(hw, I40E_GLNVM_SRCTL, sr_reg);
238
239                 /* Poll I40E_GLNVM_SRCTL until the done bit is set */
240                 ret_code = i40e_poll_sr_srctl_done_bit(hw);
241                 if (ret_code == I40E_SUCCESS) {
242                         sr_reg = rd32(hw, I40E_GLNVM_SRDATA);
243                         *data = (u16)((sr_reg &
244                                        I40E_GLNVM_SRDATA_RDDATA_MASK)
245                                     >> I40E_GLNVM_SRDATA_RDDATA_SHIFT);
246                 }
247         }
248         if (ret_code != I40E_SUCCESS)
249                 i40e_debug(hw, I40E_DEBUG_NVM,
250                            "NVM read error: Couldn't access Shadow RAM address: 0x%x\n",
251                            offset);
252
253 read_nvm_exit:
254         return ret_code;
255 }
256
257 /**
258  * i40e_read_nvm_word_aq - Reads Shadow RAM via AQ
259  * @hw: pointer to the HW structure
260  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
261  * @data: word read from the Shadow RAM
262  *
263  * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
264  **/
265 enum i40e_status_code i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset,
266                                             u16 *data)
267 {
268         enum i40e_status_code ret_code = I40E_ERR_TIMEOUT;
269
270         DEBUGFUNC("i40e_read_nvm_word_aq");
271
272         ret_code = i40e_read_nvm_aq(hw, 0x0, offset, 1, data, true);
273         *data = LE16_TO_CPU(*(__le16 *)data);
274
275         return ret_code;
276 }
277
278 /**
279  * i40e_read_nvm_buffer - Reads Shadow RAM buffer
280  * @hw: pointer to the HW structure
281  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
282  * @words: (in) number of words to read; (out) number of words actually read
283  * @data: words read from the Shadow RAM
284  *
285  * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd()
286  * method. The buffer read is preceded by the NVM ownership take
287  * and followed by the release.
288  **/
289 enum i40e_status_code i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
290                                            u16 *words, u16 *data)
291 {
292         return i40e_read_nvm_buffer_srctl(hw, offset, words, data);
293 }
294
295 /**
296  * i40e_read_nvm_buffer_srctl - Reads Shadow RAM buffer via SRCTL register
297  * @hw: pointer to the HW structure
298  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
299  * @words: (in) number of words to read; (out) number of words actually read
300  * @data: words read from the Shadow RAM
301  *
302  * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd()
303  * method. The buffer read is preceded by the NVM ownership take
304  * and followed by the release.
305  **/
306 enum i40e_status_code i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
307                                                  u16 *words, u16 *data)
308 {
309         enum i40e_status_code ret_code = I40E_SUCCESS;
310         u16 index, word;
311
312         DEBUGFUNC("i40e_read_nvm_buffer_srctl");
313
314         /* Loop thru the selected region */
315         for (word = 0; word < *words; word++) {
316                 index = offset + word;
317                 ret_code = i40e_read_nvm_word_srctl(hw, index, &data[word]);
318                 if (ret_code != I40E_SUCCESS)
319                         break;
320         }
321
322         /* Update the number of words read from the Shadow RAM */
323         *words = word;
324
325         return ret_code;
326 }
327
328 /**
329  * i40e_read_nvm_buffer_aq - Reads Shadow RAM buffer via AQ
330  * @hw: pointer to the HW structure
331  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
332  * @words: (in) number of words to read; (out) number of words actually read
333  * @data: words read from the Shadow RAM
334  *
335  * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_aq()
336  * method. The buffer read is preceded by the NVM ownership take
337  * and followed by the release.
338  **/
339 enum i40e_status_code i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset,
340                                               u16 *words, u16 *data)
341 {
342         enum i40e_status_code ret_code;
343         u16 read_size = *words;
344         bool last_cmd = false;
345         u16 words_read = 0;
346         u16 i = 0;
347
348         DEBUGFUNC("i40e_read_nvm_buffer_aq");
349
350         do {
351                 /* Calculate number of bytes we should read in this step.
352                  * FVL AQ do not allow to read more than one page at a time or
353                  * to cross page boundaries.
354                  */
355                 if (offset % I40E_SR_SECTOR_SIZE_IN_WORDS)
356                         read_size = min(*words,
357                                         (u16)(I40E_SR_SECTOR_SIZE_IN_WORDS -
358                                       (offset % I40E_SR_SECTOR_SIZE_IN_WORDS)));
359                 else
360                         read_size = min((*words - words_read),
361                                         I40E_SR_SECTOR_SIZE_IN_WORDS);
362
363                 /* Check if this is last command, if so set proper flag */
364                 if ((words_read + read_size) >= *words)
365                         last_cmd = true;
366
367                 ret_code = i40e_read_nvm_aq(hw, 0x0, offset, read_size,
368                                             data + words_read, last_cmd);
369                 if (ret_code != I40E_SUCCESS)
370                         goto read_nvm_buffer_aq_exit;
371
372                 /* Increment counter for words already read and move offset to
373                  * new read location
374                  */
375                 words_read += read_size;
376                 offset += read_size;
377         } while (words_read < *words);
378
379         for (i = 0; i < *words; i++)
380                 data[i] = LE16_TO_CPU(((__le16 *)data)[i]);
381
382 read_nvm_buffer_aq_exit:
383         *words = words_read;
384         return ret_code;
385 }
386
387 /**
388  * i40e_read_nvm_aq - Read Shadow RAM.
389  * @hw: pointer to the HW structure.
390  * @module_pointer: module pointer location in words from the NVM beginning
391  * @offset: offset in words from module start
392  * @words: number of words to write
393  * @data: buffer with words to write to the Shadow RAM
394  * @last_command: tells the AdminQ that this is the last command
395  *
396  * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
397  **/
398 enum i40e_status_code i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
399                                        u32 offset, u16 words, void *data,
400                                        bool last_command)
401 {
402         enum i40e_status_code ret_code = I40E_ERR_NVM;
403
404         DEBUGFUNC("i40e_read_nvm_aq");
405
406         /* Here we are checking the SR limit only for the flat memory model.
407          * We cannot do it for the module-based model, as we did not acquire
408          * the NVM resource yet (we cannot get the module pointer value).
409          * Firmware will check the module-based model.
410          */
411         if ((offset + words) > hw->nvm.sr_size)
412                 i40e_debug(hw, I40E_DEBUG_NVM,
413                            "NVM write error: offset %d beyond Shadow RAM limit %d\n",
414                            (offset + words), hw->nvm.sr_size);
415         else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS)
416                 /* We can write only up to 4KB (one sector), in one AQ write */
417                 i40e_debug(hw, I40E_DEBUG_NVM,
418                            "NVM write fail error: tried to write %d words, limit is %d.\n",
419                            words, I40E_SR_SECTOR_SIZE_IN_WORDS);
420         else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS)
421                  != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS))
422                 /* A single write cannot spread over two sectors */
423                 i40e_debug(hw, I40E_DEBUG_NVM,
424                            "NVM write error: cannot spread over two sectors in a single write offset=%d words=%d\n",
425                            offset, words);
426         else
427                 ret_code = i40e_aq_read_nvm(hw, module_pointer,
428                                             2 * offset,  /*bytes*/
429                                             2 * words,   /*bytes*/
430                                             data, last_command, NULL);
431
432         return ret_code;
433 }
434
435 /**
436  * i40e_write_nvm_aq - Writes Shadow RAM.
437  * @hw: pointer to the HW structure.
438  * @module_pointer: module pointer location in words from the NVM beginning
439  * @offset: offset in words from module start
440  * @words: number of words to write
441  * @data: buffer with words to write to the Shadow RAM
442  * @last_command: tells the AdminQ that this is the last command
443  *
444  * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
445  **/
446 enum i40e_status_code i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
447                                         u32 offset, u16 words, void *data,
448                                         bool last_command)
449 {
450         enum i40e_status_code ret_code = I40E_ERR_NVM;
451
452         DEBUGFUNC("i40e_write_nvm_aq");
453
454         /* Here we are checking the SR limit only for the flat memory model.
455          * We cannot do it for the module-based model, as we did not acquire
456          * the NVM resource yet (we cannot get the module pointer value).
457          * Firmware will check the module-based model.
458          */
459         if ((offset + words) > hw->nvm.sr_size)
460                 DEBUGOUT("NVM write error: offset beyond Shadow RAM limit.\n");
461         else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS)
462                 /* We can write only up to 4KB (one sector), in one AQ write */
463                 DEBUGOUT("NVM write fail error: cannot write more than 4KB in a single write.\n");
464         else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS)
465                  != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS))
466                 /* A single write cannot spread over two sectors */
467                 DEBUGOUT("NVM write error: cannot spread over two sectors in a single write.\n");
468         else
469                 ret_code = i40e_aq_update_nvm(hw, module_pointer,
470                                               2 * offset,  /*bytes*/
471                                               2 * words,   /*bytes*/
472                                               data, last_command, NULL);
473
474         return ret_code;
475 }
476
477 /**
478  * i40e_write_nvm_word - Writes Shadow RAM word
479  * @hw: pointer to the HW structure
480  * @offset: offset of the Shadow RAM word to write
481  * @data: word to write to the Shadow RAM
482  *
483  * Writes a 16 bit word to the SR using the i40e_write_nvm_aq() method.
484  * NVM ownership have to be acquired and released (on ARQ completion event
485  * reception) by caller. To commit SR to NVM update checksum function
486  * should be called.
487  **/
488 enum i40e_status_code i40e_write_nvm_word(struct i40e_hw *hw, u32 offset,
489                                           void *data)
490 {
491         DEBUGFUNC("i40e_write_nvm_word");
492
493         *((__le16 *)data) = CPU_TO_LE16(*((u16 *)data));
494
495         /* Value 0x00 below means that we treat SR as a flat mem */
496         return i40e_write_nvm_aq(hw, 0x00, offset, 1, data, false);
497 }
498
499 /**
500  * i40e_write_nvm_buffer - Writes Shadow RAM buffer
501  * @hw: pointer to the HW structure
502  * @module_pointer: module pointer location in words from the NVM beginning
503  * @offset: offset of the Shadow RAM buffer to write
504  * @words: number of words to write
505  * @data: words to write to the Shadow RAM
506  *
507  * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
508  * NVM ownership must be acquired before calling this function and released
509  * on ARQ completion event reception by caller. To commit SR to NVM update
510  * checksum function should be called.
511  **/
512 enum i40e_status_code i40e_write_nvm_buffer(struct i40e_hw *hw,
513                                             u8 module_pointer, u32 offset,
514                                             u16 words, void *data)
515 {
516         __le16 *le_word_ptr = (__le16 *)data;
517         u16 *word_ptr = (u16 *)data;
518         u32 i = 0;
519
520         DEBUGFUNC("i40e_write_nvm_buffer");
521
522         for (i = 0; i < words; i++)
523                 le_word_ptr[i] = CPU_TO_LE16(word_ptr[i]);
524
525         /* Here we will only write one buffer as the size of the modules
526          * mirrored in the Shadow RAM is always less than 4K.
527          */
528         return i40e_write_nvm_aq(hw, module_pointer, offset, words,
529                                  data, false);
530 }
531
532 /**
533  * i40e_calc_nvm_checksum - Calculates and returns the checksum
534  * @hw: pointer to hardware structure
535  * @checksum: pointer to the checksum
536  *
537  * This function calculates SW Checksum that covers the whole 64kB shadow RAM
538  * except the VPD and PCIe ALT Auto-load modules. The structure and size of VPD
539  * is customer specific and unknown. Therefore, this function skips all maximum
540  * possible size of VPD (1kB).
541  **/
542 enum i40e_status_code i40e_calc_nvm_checksum(struct i40e_hw *hw, u16 *checksum)
543 {
544         enum i40e_status_code ret_code = I40E_SUCCESS;
545         u16 pcie_alt_module = 0;
546         u16 checksum_local = 0;
547         u16 vpd_module = 0;
548         u16 word = 0;
549         u32 i = 0;
550
551         DEBUGFUNC("i40e_calc_nvm_checksum");
552
553         /* read pointer to VPD area */
554         ret_code = i40e_read_nvm_word(hw, I40E_SR_VPD_PTR, &vpd_module);
555         if (ret_code != I40E_SUCCESS) {
556                 ret_code = I40E_ERR_NVM_CHECKSUM;
557                 goto i40e_calc_nvm_checksum_exit;
558         }
559
560         /* read pointer to PCIe Alt Auto-load module */
561         ret_code = i40e_read_nvm_word(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR,
562                                        &pcie_alt_module);
563         if (ret_code != I40E_SUCCESS) {
564                 ret_code = I40E_ERR_NVM_CHECKSUM;
565                 goto i40e_calc_nvm_checksum_exit;
566         }
567
568         /* Calculate SW checksum that covers the whole 64kB shadow RAM
569          * except the VPD and PCIe ALT Auto-load modules
570          */
571         for (i = 0; i < hw->nvm.sr_size; i++) {
572                 /* Skip Checksum word */
573                 if (i == I40E_SR_SW_CHECKSUM_WORD)
574                         i++;
575                 /* Skip VPD module (convert byte size to word count) */
576                 if (i == (u32)vpd_module) {
577                         i += (I40E_SR_VPD_MODULE_MAX_SIZE / 2);
578                         if (i >= hw->nvm.sr_size)
579                                 break;
580                 }
581                 /* Skip PCIe ALT module (convert byte size to word count) */
582                 if (i == (u32)pcie_alt_module) {
583                         i += (I40E_SR_PCIE_ALT_MODULE_MAX_SIZE / 2);
584                         if (i >= hw->nvm.sr_size)
585                                 break;
586                 }
587
588                 ret_code = i40e_read_nvm_word(hw, (u16)i, &word);
589                 if (ret_code != I40E_SUCCESS) {
590                         ret_code = I40E_ERR_NVM_CHECKSUM;
591                         goto i40e_calc_nvm_checksum_exit;
592                 }
593                 checksum_local += word;
594         }
595
596         *checksum = (u16)I40E_SR_SW_CHECKSUM_BASE - checksum_local;
597
598 i40e_calc_nvm_checksum_exit:
599         return ret_code;
600 }
601
602 /**
603  * i40e_update_nvm_checksum - Updates the NVM checksum
604  * @hw: pointer to hardware structure
605  *
606  * NVM ownership must be acquired before calling this function and released
607  * on ARQ completion event reception by caller.
608  * This function will commit SR to NVM.
609  **/
610 enum i40e_status_code i40e_update_nvm_checksum(struct i40e_hw *hw)
611 {
612         enum i40e_status_code ret_code = I40E_SUCCESS;
613         u16 checksum;
614
615         DEBUGFUNC("i40e_update_nvm_checksum");
616
617         ret_code = i40e_calc_nvm_checksum(hw, &checksum);
618         if (ret_code == I40E_SUCCESS)
619                 ret_code = i40e_write_nvm_aq(hw, 0x00, I40E_SR_SW_CHECKSUM_WORD,
620                                              1, &checksum, true);
621
622         return ret_code;
623 }
624
625 /**
626  * i40e_validate_nvm_checksum - Validate EEPROM checksum
627  * @hw: pointer to hardware structure
628  * @checksum: calculated checksum
629  *
630  * Performs checksum calculation and validates the NVM SW checksum. If the
631  * caller does not need checksum, the value can be NULL.
632  **/
633 enum i40e_status_code i40e_validate_nvm_checksum(struct i40e_hw *hw,
634                                                  u16 *checksum)
635 {
636         enum i40e_status_code ret_code = I40E_SUCCESS;
637         u16 checksum_sr = 0;
638         u16 checksum_local = 0;
639
640         DEBUGFUNC("i40e_validate_nvm_checksum");
641
642         ret_code = i40e_calc_nvm_checksum(hw, &checksum_local);
643         if (ret_code != I40E_SUCCESS)
644                 goto i40e_validate_nvm_checksum_exit;
645
646         /* Do not use i40e_read_nvm_word() because we do not want to take
647          * the synchronization semaphores twice here.
648          */
649         i40e_read_nvm_word(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr);
650
651         /* Verify read checksum from EEPROM is the same as
652          * calculated checksum
653          */
654         if (checksum_local != checksum_sr)
655                 ret_code = I40E_ERR_NVM_CHECKSUM;
656
657         /* If the user cares, return the calculated checksum */
658         if (checksum)
659                 *checksum = checksum_local;
660
661 i40e_validate_nvm_checksum_exit:
662         return ret_code;
663 }
664
665 STATIC enum i40e_status_code i40e_nvmupd_state_init(struct i40e_hw *hw,
666                                                     struct i40e_nvm_access *cmd,
667                                                     u8 *bytes, int *perrno);
668 STATIC enum i40e_status_code i40e_nvmupd_state_reading(struct i40e_hw *hw,
669                                                     struct i40e_nvm_access *cmd,
670                                                     u8 *bytes, int *perrno);
671 STATIC enum i40e_status_code i40e_nvmupd_state_writing(struct i40e_hw *hw,
672                                                     struct i40e_nvm_access *cmd,
673                                                     u8 *bytes, int *perrno);
674 STATIC enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
675                                                     struct i40e_nvm_access *cmd,
676                                                     int *perrno);
677 STATIC enum i40e_status_code i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
678                                                    struct i40e_nvm_access *cmd,
679                                                    int *perrno);
680 STATIC enum i40e_status_code i40e_nvmupd_nvm_write(struct i40e_hw *hw,
681                                                    struct i40e_nvm_access *cmd,
682                                                    u8 *bytes, int *perrno);
683 STATIC enum i40e_status_code i40e_nvmupd_nvm_read(struct i40e_hw *hw,
684                                                   struct i40e_nvm_access *cmd,
685                                                   u8 *bytes, int *perrno);
686 STATIC inline u8 i40e_nvmupd_get_module(u32 val)
687 {
688         return (u8)(val & I40E_NVM_MOD_PNT_MASK);
689 }
690 STATIC inline u8 i40e_nvmupd_get_transaction(u32 val)
691 {
692         return (u8)((val & I40E_NVM_TRANS_MASK) >> I40E_NVM_TRANS_SHIFT);
693 }
694
695 STATIC const char *i40e_nvm_update_state_str[] = {
696         "I40E_NVMUPD_INVALID",
697         "I40E_NVMUPD_READ_CON",
698         "I40E_NVMUPD_READ_SNT",
699         "I40E_NVMUPD_READ_LCB",
700         "I40E_NVMUPD_READ_SA",
701         "I40E_NVMUPD_WRITE_ERA",
702         "I40E_NVMUPD_WRITE_CON",
703         "I40E_NVMUPD_WRITE_SNT",
704         "I40E_NVMUPD_WRITE_LCB",
705         "I40E_NVMUPD_WRITE_SA",
706         "I40E_NVMUPD_CSUM_CON",
707         "I40E_NVMUPD_CSUM_SA",
708         "I40E_NVMUPD_CSUM_LCB",
709 };
710
711 /**
712  * i40e_nvmupd_command - Process an NVM update command
713  * @hw: pointer to hardware structure
714  * @cmd: pointer to nvm update command
715  * @bytes: pointer to the data buffer
716  * @perrno: pointer to return error code
717  *
718  * Dispatches command depending on what update state is current
719  **/
720 enum i40e_status_code i40e_nvmupd_command(struct i40e_hw *hw,
721                                           struct i40e_nvm_access *cmd,
722                                           u8 *bytes, int *perrno)
723 {
724         enum i40e_status_code status;
725
726         DEBUGFUNC("i40e_nvmupd_command");
727
728         /* assume success */
729         *perrno = 0;
730
731         switch (hw->nvmupd_state) {
732         case I40E_NVMUPD_STATE_INIT:
733                 status = i40e_nvmupd_state_init(hw, cmd, bytes, perrno);
734                 break;
735
736         case I40E_NVMUPD_STATE_READING:
737                 status = i40e_nvmupd_state_reading(hw, cmd, bytes, perrno);
738                 break;
739
740         case I40E_NVMUPD_STATE_WRITING:
741                 status = i40e_nvmupd_state_writing(hw, cmd, bytes, perrno);
742                 break;
743
744         default:
745                 /* invalid state, should never happen */
746                 i40e_debug(hw, I40E_DEBUG_NVM,
747                            "NVMUPD: no such state %d\n", hw->nvmupd_state);
748                 status = I40E_NOT_SUPPORTED;
749                 *perrno = -ESRCH;
750                 break;
751         }
752         return status;
753 }
754
755 /**
756  * i40e_nvmupd_state_init - Handle NVM update state Init
757  * @hw: pointer to hardware structure
758  * @cmd: pointer to nvm update command buffer
759  * @bytes: pointer to the data buffer
760  * @perrno: pointer to return error code
761  *
762  * Process legitimate commands of the Init state and conditionally set next
763  * state. Reject all other commands.
764  **/
765 STATIC enum i40e_status_code i40e_nvmupd_state_init(struct i40e_hw *hw,
766                                                     struct i40e_nvm_access *cmd,
767                                                     u8 *bytes, int *perrno)
768 {
769         enum i40e_status_code status = I40E_SUCCESS;
770         enum i40e_nvmupd_cmd upd_cmd;
771
772         DEBUGFUNC("i40e_nvmupd_state_init");
773
774         upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
775
776         switch (upd_cmd) {
777         case I40E_NVMUPD_READ_SA:
778                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
779                 if (status) {
780                         *perrno = i40e_aq_rc_to_posix(status,
781                                                      hw->aq.asq_last_status);
782                 } else {
783                         status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno);
784                         i40e_release_nvm(hw);
785                 }
786                 break;
787
788         case I40E_NVMUPD_READ_SNT:
789                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
790                 if (status) {
791                         *perrno = i40e_aq_rc_to_posix(status,
792                                                      hw->aq.asq_last_status);
793                 } else {
794                         status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno);
795                         if (status)
796                                 i40e_release_nvm(hw);
797                         else
798                                 hw->nvmupd_state = I40E_NVMUPD_STATE_READING;
799                 }
800                 break;
801
802         case I40E_NVMUPD_WRITE_ERA:
803                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
804                 if (status) {
805                         *perrno = i40e_aq_rc_to_posix(status,
806                                                      hw->aq.asq_last_status);
807                 } else {
808                         status = i40e_nvmupd_nvm_erase(hw, cmd, perrno);
809                         if (status)
810                                 i40e_release_nvm(hw);
811                         else
812                                 hw->aq.nvm_release_on_done = true;
813                 }
814                 break;
815
816         case I40E_NVMUPD_WRITE_SA:
817                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
818                 if (status) {
819                         *perrno = i40e_aq_rc_to_posix(status,
820                                                      hw->aq.asq_last_status);
821                 } else {
822                         status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
823                         if (status)
824                                 i40e_release_nvm(hw);
825                         else
826                                 hw->aq.nvm_release_on_done = true;
827                 }
828                 break;
829
830         case I40E_NVMUPD_WRITE_SNT:
831                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
832                 if (status) {
833                         *perrno = i40e_aq_rc_to_posix(status,
834                                                      hw->aq.asq_last_status);
835                 } else {
836                         status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
837                         if (status)
838                                 i40e_release_nvm(hw);
839                         else
840                                 hw->nvmupd_state = I40E_NVMUPD_STATE_WRITING;
841                 }
842                 break;
843
844         case I40E_NVMUPD_CSUM_SA:
845                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
846                 if (status) {
847                         *perrno = i40e_aq_rc_to_posix(status,
848                                                      hw->aq.asq_last_status);
849                 } else {
850                         status = i40e_update_nvm_checksum(hw);
851                         if (status) {
852                                 *perrno = hw->aq.asq_last_status ?
853                                    i40e_aq_rc_to_posix(status,
854                                                        hw->aq.asq_last_status) :
855                                    -EIO;
856                                 i40e_release_nvm(hw);
857                         } else {
858                                 hw->aq.nvm_release_on_done = true;
859                         }
860                 }
861                 break;
862
863         default:
864                 i40e_debug(hw, I40E_DEBUG_NVM,
865                            "NVMUPD: bad cmd %s in init state\n",
866                            i40e_nvm_update_state_str[upd_cmd]);
867                 status = I40E_ERR_NVM;
868                 *perrno = -ESRCH;
869                 break;
870         }
871         return status;
872 }
873
874 /**
875  * i40e_nvmupd_state_reading - Handle NVM update state Reading
876  * @hw: pointer to hardware structure
877  * @cmd: pointer to nvm update command buffer
878  * @bytes: pointer to the data buffer
879  * @perrno: pointer to return error code
880  *
881  * NVM ownership is already held.  Process legitimate commands and set any
882  * change in state; reject all other commands.
883  **/
884 STATIC enum i40e_status_code i40e_nvmupd_state_reading(struct i40e_hw *hw,
885                                                     struct i40e_nvm_access *cmd,
886                                                     u8 *bytes, int *perrno)
887 {
888         enum i40e_status_code status;
889         enum i40e_nvmupd_cmd upd_cmd;
890
891         DEBUGFUNC("i40e_nvmupd_state_reading");
892
893         upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
894
895         switch (upd_cmd) {
896         case I40E_NVMUPD_READ_SA:
897         case I40E_NVMUPD_READ_CON:
898                 status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno);
899                 break;
900
901         case I40E_NVMUPD_READ_LCB:
902                 status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno);
903                 i40e_release_nvm(hw);
904                 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
905                 break;
906
907         default:
908                 i40e_debug(hw, I40E_DEBUG_NVM,
909                            "NVMUPD: bad cmd %s in reading state.\n",
910                            i40e_nvm_update_state_str[upd_cmd]);
911                 status = I40E_NOT_SUPPORTED;
912                 *perrno = -ESRCH;
913                 break;
914         }
915         return status;
916 }
917
918 /**
919  * i40e_nvmupd_state_writing - Handle NVM update state Writing
920  * @hw: pointer to hardware structure
921  * @cmd: pointer to nvm update command buffer
922  * @bytes: pointer to the data buffer
923  * @perrno: pointer to return error code
924  *
925  * NVM ownership is already held.  Process legitimate commands and set any
926  * change in state; reject all other commands
927  **/
928 STATIC enum i40e_status_code i40e_nvmupd_state_writing(struct i40e_hw *hw,
929                                                     struct i40e_nvm_access *cmd,
930                                                     u8 *bytes, int *perrno)
931 {
932         enum i40e_status_code status;
933         enum i40e_nvmupd_cmd upd_cmd;
934         bool retry_attempt = false;
935
936         DEBUGFUNC("i40e_nvmupd_state_writing");
937
938         upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
939
940 retry:
941         switch (upd_cmd) {
942         case I40E_NVMUPD_WRITE_CON:
943                 status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
944                 break;
945
946         case I40E_NVMUPD_WRITE_LCB:
947                 status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
948                 if (!status)
949                         hw->aq.nvm_release_on_done = true;
950                 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
951                 break;
952
953         case I40E_NVMUPD_CSUM_CON:
954                 status = i40e_update_nvm_checksum(hw);
955                 if (status) {
956                         *perrno = hw->aq.asq_last_status ?
957                                    i40e_aq_rc_to_posix(status,
958                                                        hw->aq.asq_last_status) :
959                                    -EIO;
960                         hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
961                 }
962                 break;
963
964         case I40E_NVMUPD_CSUM_LCB:
965                 status = i40e_update_nvm_checksum(hw);
966                 if (status)
967                         *perrno = hw->aq.asq_last_status ?
968                                    i40e_aq_rc_to_posix(status,
969                                                        hw->aq.asq_last_status) :
970                                    -EIO;
971                 else
972                         hw->aq.nvm_release_on_done = true;
973                 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
974                 break;
975
976         default:
977                 i40e_debug(hw, I40E_DEBUG_NVM,
978                            "NVMUPD: bad cmd %s in writing state.\n",
979                            i40e_nvm_update_state_str[upd_cmd]);
980                 status = I40E_NOT_SUPPORTED;
981                 *perrno = -ESRCH;
982                 break;
983         }
984
985         /* In some circumstances, a multi-write transaction takes longer
986          * than the default 3 minute timeout on the write semaphore.  If
987          * the write failed with an EBUSY status, this is likely the problem,
988          * so here we try to reacquire the semaphore then retry the write.
989          * We only do one retry, then give up.
990          */
991         if (status && (hw->aq.asq_last_status == I40E_AQ_RC_EBUSY) &&
992             !retry_attempt) {
993                 enum i40e_status_code old_status = status;
994                 u32 old_asq_status = hw->aq.asq_last_status;
995                 u32 gtime;
996
997                 gtime = rd32(hw, I40E_GLVFGEN_TIMER);
998                 if (gtime >= hw->nvm.hw_semaphore_timeout) {
999                         i40e_debug(hw, I40E_DEBUG_ALL,
1000                                    "NVMUPD: write semaphore expired (%d >= %lld), retrying\n",
1001                                    gtime, hw->nvm.hw_semaphore_timeout);
1002                         i40e_release_nvm(hw);
1003                         status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
1004                         if (status) {
1005                                 i40e_debug(hw, I40E_DEBUG_ALL,
1006                                            "NVMUPD: write semaphore reacquire failed aq_err = %d\n",
1007                                            hw->aq.asq_last_status);
1008                                 status = old_status;
1009                                 hw->aq.asq_last_status = old_asq_status;
1010                         } else {
1011                                 retry_attempt = true;
1012                                 goto retry;
1013                         }
1014                 }
1015         }
1016
1017         return status;
1018 }
1019
1020 /**
1021  * i40e_nvmupd_validate_command - Validate given command
1022  * @hw: pointer to hardware structure
1023  * @cmd: pointer to nvm update command buffer
1024  * @perrno: pointer to return error code
1025  *
1026  * Return one of the valid command types or I40E_NVMUPD_INVALID
1027  **/
1028 STATIC enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
1029                                                     struct i40e_nvm_access *cmd,
1030                                                     int *perrno)
1031 {
1032         enum i40e_nvmupd_cmd upd_cmd;
1033         u8 transaction, module;
1034
1035         DEBUGFUNC("i40e_nvmupd_validate_command\n");
1036
1037         /* anything that doesn't match a recognized case is an error */
1038         upd_cmd = I40E_NVMUPD_INVALID;
1039
1040         transaction = i40e_nvmupd_get_transaction(cmd->config);
1041         module = i40e_nvmupd_get_module(cmd->config);
1042
1043         /* limits on data size */
1044         if ((cmd->data_size < 1) ||
1045             (cmd->data_size > I40E_NVMUPD_MAX_DATA)) {
1046                 i40e_debug(hw, I40E_DEBUG_NVM,
1047                            "i40e_nvmupd_validate_command data_size %d\n",
1048                            cmd->data_size);
1049                 *perrno = -EFAULT;
1050                 return I40E_NVMUPD_INVALID;
1051         }
1052
1053         switch (cmd->command) {
1054         case I40E_NVM_READ:
1055                 switch (transaction) {
1056                 case I40E_NVM_CON:
1057                         upd_cmd = I40E_NVMUPD_READ_CON;
1058                         break;
1059                 case I40E_NVM_SNT:
1060                         upd_cmd = I40E_NVMUPD_READ_SNT;
1061                         break;
1062                 case I40E_NVM_LCB:
1063                         upd_cmd = I40E_NVMUPD_READ_LCB;
1064                         break;
1065                 case I40E_NVM_SA:
1066                         upd_cmd = I40E_NVMUPD_READ_SA;
1067                         break;
1068                 }
1069                 break;
1070
1071         case I40E_NVM_WRITE:
1072                 switch (transaction) {
1073                 case I40E_NVM_CON:
1074                         upd_cmd = I40E_NVMUPD_WRITE_CON;
1075                         break;
1076                 case I40E_NVM_SNT:
1077                         upd_cmd = I40E_NVMUPD_WRITE_SNT;
1078                         break;
1079                 case I40E_NVM_LCB:
1080                         upd_cmd = I40E_NVMUPD_WRITE_LCB;
1081                         break;
1082                 case I40E_NVM_SA:
1083                         upd_cmd = I40E_NVMUPD_WRITE_SA;
1084                         break;
1085                 case I40E_NVM_ERA:
1086                         upd_cmd = I40E_NVMUPD_WRITE_ERA;
1087                         break;
1088                 case I40E_NVM_CSUM:
1089                         upd_cmd = I40E_NVMUPD_CSUM_CON;
1090                         break;
1091                 case (I40E_NVM_CSUM|I40E_NVM_SA):
1092                         upd_cmd = I40E_NVMUPD_CSUM_SA;
1093                         break;
1094                 case (I40E_NVM_CSUM|I40E_NVM_LCB):
1095                         upd_cmd = I40E_NVMUPD_CSUM_LCB;
1096                         break;
1097                 }
1098                 break;
1099         }
1100         i40e_debug(hw, I40E_DEBUG_NVM, "%s state %d nvm_release_on_hold %d\n",
1101                    i40e_nvm_update_state_str[upd_cmd],
1102                    hw->nvmupd_state,
1103                    hw->aq.nvm_release_on_done);
1104
1105         if (upd_cmd == I40E_NVMUPD_INVALID) {
1106                 *perrno = -EFAULT;
1107                 i40e_debug(hw, I40E_DEBUG_NVM,
1108                            "i40e_nvmupd_validate_command returns %d perrno %d\n",
1109                            upd_cmd, *perrno);
1110         }
1111         return upd_cmd;
1112 }
1113
1114 /**
1115  * i40e_nvmupd_nvm_read - Read NVM
1116  * @hw: pointer to hardware structure
1117  * @cmd: pointer to nvm update command buffer
1118  * @bytes: pointer to the data buffer
1119  * @perrno: pointer to return error code
1120  *
1121  * cmd structure contains identifiers and data buffer
1122  **/
1123 STATIC enum i40e_status_code i40e_nvmupd_nvm_read(struct i40e_hw *hw,
1124                                                   struct i40e_nvm_access *cmd,
1125                                                   u8 *bytes, int *perrno)
1126 {
1127         enum i40e_status_code status;
1128         u8 module, transaction;
1129         bool last;
1130
1131         transaction = i40e_nvmupd_get_transaction(cmd->config);
1132         module = i40e_nvmupd_get_module(cmd->config);
1133         last = (transaction == I40E_NVM_LCB) || (transaction == I40E_NVM_SA);
1134
1135         status = i40e_aq_read_nvm(hw, module, cmd->offset, (u16)cmd->data_size,
1136                                   bytes, last, NULL);
1137         if (status) {
1138                 i40e_debug(hw, I40E_DEBUG_NVM,
1139                            "i40e_nvmupd_nvm_read mod 0x%x  off 0x%x  len 0x%x\n",
1140                            module, cmd->offset, cmd->data_size);
1141                 i40e_debug(hw, I40E_DEBUG_NVM,
1142                            "i40e_nvmupd_nvm_read status %d aq %d\n",
1143                            status, hw->aq.asq_last_status);
1144                 *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
1145         }
1146
1147         return status;
1148 }
1149
1150 /**
1151  * i40e_nvmupd_nvm_erase - Erase an NVM module
1152  * @hw: pointer to hardware structure
1153  * @cmd: pointer to nvm update command buffer
1154  * @perrno: pointer to return error code
1155  *
1156  * module, offset, data_size and data are in cmd structure
1157  **/
1158 STATIC enum i40e_status_code i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
1159                                                    struct i40e_nvm_access *cmd,
1160                                                    int *perrno)
1161 {
1162         enum i40e_status_code status = I40E_SUCCESS;
1163         u8 module, transaction;
1164         bool last;
1165
1166         transaction = i40e_nvmupd_get_transaction(cmd->config);
1167         module = i40e_nvmupd_get_module(cmd->config);
1168         last = (transaction & I40E_NVM_LCB);
1169         status = i40e_aq_erase_nvm(hw, module, cmd->offset, (u16)cmd->data_size,
1170                                    last, NULL);
1171         if (status) {
1172                 i40e_debug(hw, I40E_DEBUG_NVM,
1173                            "i40e_nvmupd_nvm_erase mod 0x%x  off 0x%x len 0x%x\n",
1174                            module, cmd->offset, cmd->data_size);
1175                 i40e_debug(hw, I40E_DEBUG_NVM,
1176                            "i40e_nvmupd_nvm_erase status %d aq %d\n",
1177                            status, hw->aq.asq_last_status);
1178                 *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
1179         }
1180
1181         return status;
1182 }
1183
1184 /**
1185  * i40e_nvmupd_nvm_write - Write NVM
1186  * @hw: pointer to hardware structure
1187  * @cmd: pointer to nvm update command buffer
1188  * @bytes: pointer to the data buffer
1189  * @perrno: pointer to return error code
1190  *
1191  * module, offset, data_size and data are in cmd structure
1192  **/
1193 STATIC enum i40e_status_code i40e_nvmupd_nvm_write(struct i40e_hw *hw,
1194                                                    struct i40e_nvm_access *cmd,
1195                                                    u8 *bytes, int *perrno)
1196 {
1197         enum i40e_status_code status = I40E_SUCCESS;
1198         u8 module, transaction;
1199         bool last;
1200
1201         transaction = i40e_nvmupd_get_transaction(cmd->config);
1202         module = i40e_nvmupd_get_module(cmd->config);
1203         last = (transaction & I40E_NVM_LCB);
1204
1205         status = i40e_aq_update_nvm(hw, module, cmd->offset,
1206                                     (u16)cmd->data_size, bytes, last, NULL);
1207         if (status) {
1208                 i40e_debug(hw, I40E_DEBUG_NVM,
1209                            "i40e_nvmupd_nvm_write mod 0x%x off 0x%x len 0x%x\n",
1210                            module, cmd->offset, cmd->data_size);
1211                 i40e_debug(hw, I40E_DEBUG_NVM,
1212                            "i40e_nvmupd_nvm_write status %d aq %d\n",
1213                            status, hw->aq.asq_last_status);
1214                 *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
1215         }
1216
1217         return status;
1218 }