i40e/base: add wait states to NVM state machine
[dpdk.git] / drivers / net / i40e / base / 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         struct i40e_asq_cmd_details cmd_details;
404
405         DEBUGFUNC("i40e_read_nvm_aq");
406
407         memset(&cmd_details, 0, sizeof(cmd_details));
408         cmd_details.wb_desc = &hw->nvm_wb_desc;
409
410         /* Here we are checking the SR limit only for the flat memory model.
411          * We cannot do it for the module-based model, as we did not acquire
412          * the NVM resource yet (we cannot get the module pointer value).
413          * Firmware will check the module-based model.
414          */
415         if ((offset + words) > hw->nvm.sr_size)
416                 i40e_debug(hw, I40E_DEBUG_NVM,
417                            "NVM write error: offset %d beyond Shadow RAM limit %d\n",
418                            (offset + words), hw->nvm.sr_size);
419         else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS)
420                 /* We can write only up to 4KB (one sector), in one AQ write */
421                 i40e_debug(hw, I40E_DEBUG_NVM,
422                            "NVM write fail error: tried to write %d words, limit is %d.\n",
423                            words, I40E_SR_SECTOR_SIZE_IN_WORDS);
424         else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS)
425                  != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS))
426                 /* A single write cannot spread over two sectors */
427                 i40e_debug(hw, I40E_DEBUG_NVM,
428                            "NVM write error: cannot spread over two sectors in a single write offset=%d words=%d\n",
429                            offset, words);
430         else
431                 ret_code = i40e_aq_read_nvm(hw, module_pointer,
432                                             2 * offset,  /*bytes*/
433                                             2 * words,   /*bytes*/
434                                             data, last_command, &cmd_details);
435
436         return ret_code;
437 }
438
439 /**
440  * i40e_write_nvm_aq - Writes Shadow RAM.
441  * @hw: pointer to the HW structure.
442  * @module_pointer: module pointer location in words from the NVM beginning
443  * @offset: offset in words from module start
444  * @words: number of words to write
445  * @data: buffer with words to write to the Shadow RAM
446  * @last_command: tells the AdminQ that this is the last command
447  *
448  * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
449  **/
450 enum i40e_status_code i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
451                                         u32 offset, u16 words, void *data,
452                                         bool last_command)
453 {
454         enum i40e_status_code ret_code = I40E_ERR_NVM;
455         struct i40e_asq_cmd_details cmd_details;
456
457         DEBUGFUNC("i40e_write_nvm_aq");
458
459         memset(&cmd_details, 0, sizeof(cmd_details));
460         cmd_details.wb_desc = &hw->nvm_wb_desc;
461
462         /* Here we are checking the SR limit only for the flat memory model.
463          * We cannot do it for the module-based model, as we did not acquire
464          * the NVM resource yet (we cannot get the module pointer value).
465          * Firmware will check the module-based model.
466          */
467         if ((offset + words) > hw->nvm.sr_size)
468                 DEBUGOUT("NVM write error: offset beyond Shadow RAM limit.\n");
469         else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS)
470                 /* We can write only up to 4KB (one sector), in one AQ write */
471                 DEBUGOUT("NVM write fail error: cannot write more than 4KB in a single write.\n");
472         else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS)
473                  != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS))
474                 /* A single write cannot spread over two sectors */
475                 DEBUGOUT("NVM write error: cannot spread over two sectors in a single write.\n");
476         else
477                 ret_code = i40e_aq_update_nvm(hw, module_pointer,
478                                               2 * offset,  /*bytes*/
479                                               2 * words,   /*bytes*/
480                                               data, last_command, &cmd_details);
481
482         return ret_code;
483 }
484
485 /**
486  * i40e_write_nvm_word - Writes Shadow RAM word
487  * @hw: pointer to the HW structure
488  * @offset: offset of the Shadow RAM word to write
489  * @data: word to write to the Shadow RAM
490  *
491  * Writes a 16 bit word to the SR using the i40e_write_nvm_aq() method.
492  * NVM ownership have to be acquired and released (on ARQ completion event
493  * reception) by caller. To commit SR to NVM update checksum function
494  * should be called.
495  **/
496 enum i40e_status_code i40e_write_nvm_word(struct i40e_hw *hw, u32 offset,
497                                           void *data)
498 {
499         DEBUGFUNC("i40e_write_nvm_word");
500
501         *((__le16 *)data) = CPU_TO_LE16(*((u16 *)data));
502
503         /* Value 0x00 below means that we treat SR as a flat mem */
504         return i40e_write_nvm_aq(hw, 0x00, offset, 1, data, false);
505 }
506
507 /**
508  * i40e_write_nvm_buffer - Writes Shadow RAM buffer
509  * @hw: pointer to the HW structure
510  * @module_pointer: module pointer location in words from the NVM beginning
511  * @offset: offset of the Shadow RAM buffer to write
512  * @words: number of words to write
513  * @data: words to write to the Shadow RAM
514  *
515  * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
516  * NVM ownership must be acquired before calling this function and released
517  * on ARQ completion event reception by caller. To commit SR to NVM update
518  * checksum function should be called.
519  **/
520 enum i40e_status_code i40e_write_nvm_buffer(struct i40e_hw *hw,
521                                             u8 module_pointer, u32 offset,
522                                             u16 words, void *data)
523 {
524         __le16 *le_word_ptr = (__le16 *)data;
525         u16 *word_ptr = (u16 *)data;
526         u32 i = 0;
527
528         DEBUGFUNC("i40e_write_nvm_buffer");
529
530         for (i = 0; i < words; i++)
531                 le_word_ptr[i] = CPU_TO_LE16(word_ptr[i]);
532
533         /* Here we will only write one buffer as the size of the modules
534          * mirrored in the Shadow RAM is always less than 4K.
535          */
536         return i40e_write_nvm_aq(hw, module_pointer, offset, words,
537                                  data, false);
538 }
539
540 /**
541  * i40e_calc_nvm_checksum - Calculates and returns the checksum
542  * @hw: pointer to hardware structure
543  * @checksum: pointer to the checksum
544  *
545  * This function calculates SW Checksum that covers the whole 64kB shadow RAM
546  * except the VPD and PCIe ALT Auto-load modules. The structure and size of VPD
547  * is customer specific and unknown. Therefore, this function skips all maximum
548  * possible size of VPD (1kB).
549  **/
550 enum i40e_status_code i40e_calc_nvm_checksum(struct i40e_hw *hw, u16 *checksum)
551 {
552         enum i40e_status_code ret_code = I40E_SUCCESS;
553         struct i40e_virt_mem vmem;
554         u16 pcie_alt_module = 0;
555         u16 checksum_local = 0;
556         u16 vpd_module = 0;
557         u16 *data;
558         u16 i = 0;
559
560         DEBUGFUNC("i40e_calc_nvm_checksum");
561
562         ret_code = i40e_allocate_virt_mem(hw, &vmem,
563                                     I40E_SR_SECTOR_SIZE_IN_WORDS * sizeof(u16));
564         if (ret_code)
565                 goto i40e_calc_nvm_checksum_exit;
566         data = (u16 *)vmem.va;
567
568         /* read pointer to VPD area */
569         ret_code = i40e_read_nvm_word(hw, I40E_SR_VPD_PTR, &vpd_module);
570         if (ret_code != I40E_SUCCESS) {
571                 ret_code = I40E_ERR_NVM_CHECKSUM;
572                 goto i40e_calc_nvm_checksum_exit;
573         }
574
575         /* read pointer to PCIe Alt Auto-load module */
576         ret_code = i40e_read_nvm_word(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR,
577                                       &pcie_alt_module);
578         if (ret_code != I40E_SUCCESS) {
579                 ret_code = I40E_ERR_NVM_CHECKSUM;
580                 goto i40e_calc_nvm_checksum_exit;
581         }
582
583         /* Calculate SW checksum that covers the whole 64kB shadow RAM
584          * except the VPD and PCIe ALT Auto-load modules
585          */
586         for (i = 0; i < hw->nvm.sr_size; i++) {
587                 /* Read SR page */
588                 if ((i % I40E_SR_SECTOR_SIZE_IN_WORDS) == 0) {
589                         u16 words = I40E_SR_SECTOR_SIZE_IN_WORDS;
590                         ret_code = i40e_read_nvm_buffer(hw, i, &words, data);
591                         if (ret_code != I40E_SUCCESS) {
592                                 ret_code = I40E_ERR_NVM_CHECKSUM;
593                                 goto i40e_calc_nvm_checksum_exit;
594                         }
595                 }
596
597                 /* Skip Checksum word */
598                 if (i == I40E_SR_SW_CHECKSUM_WORD)
599                         continue;
600                 /* Skip VPD module (convert byte size to word count) */
601                 if ((i >= (u32)vpd_module) &&
602                     (i < ((u32)vpd_module +
603                      (I40E_SR_VPD_MODULE_MAX_SIZE / 2)))) {
604                         continue;
605                 }
606                 /* Skip PCIe ALT module (convert byte size to word count) */
607                 if ((i >= (u32)pcie_alt_module) &&
608                     (i < ((u32)pcie_alt_module +
609                      (I40E_SR_PCIE_ALT_MODULE_MAX_SIZE / 2)))) {
610                         continue;
611                 }
612
613                 checksum_local += data[i % I40E_SR_SECTOR_SIZE_IN_WORDS];
614         }
615
616         *checksum = (u16)I40E_SR_SW_CHECKSUM_BASE - checksum_local;
617
618 i40e_calc_nvm_checksum_exit:
619         i40e_free_virt_mem(hw, &vmem);
620         return ret_code;
621 }
622
623 /**
624  * i40e_update_nvm_checksum - Updates the NVM checksum
625  * @hw: pointer to hardware structure
626  *
627  * NVM ownership must be acquired before calling this function and released
628  * on ARQ completion event reception by caller.
629  * This function will commit SR to NVM.
630  **/
631 enum i40e_status_code i40e_update_nvm_checksum(struct i40e_hw *hw)
632 {
633         enum i40e_status_code ret_code = I40E_SUCCESS;
634         u16 checksum;
635
636         DEBUGFUNC("i40e_update_nvm_checksum");
637
638         ret_code = i40e_calc_nvm_checksum(hw, &checksum);
639         if (ret_code == I40E_SUCCESS)
640                 ret_code = i40e_write_nvm_aq(hw, 0x00, I40E_SR_SW_CHECKSUM_WORD,
641                                              1, &checksum, true);
642
643         return ret_code;
644 }
645
646 /**
647  * i40e_validate_nvm_checksum - Validate EEPROM checksum
648  * @hw: pointer to hardware structure
649  * @checksum: calculated checksum
650  *
651  * Performs checksum calculation and validates the NVM SW checksum. If the
652  * caller does not need checksum, the value can be NULL.
653  **/
654 enum i40e_status_code i40e_validate_nvm_checksum(struct i40e_hw *hw,
655                                                  u16 *checksum)
656 {
657         enum i40e_status_code ret_code = I40E_SUCCESS;
658         u16 checksum_sr = 0;
659         u16 checksum_local = 0;
660
661         DEBUGFUNC("i40e_validate_nvm_checksum");
662
663         ret_code = i40e_calc_nvm_checksum(hw, &checksum_local);
664         if (ret_code != I40E_SUCCESS)
665                 goto i40e_validate_nvm_checksum_exit;
666
667         /* Do not use i40e_read_nvm_word() because we do not want to take
668          * the synchronization semaphores twice here.
669          */
670         i40e_read_nvm_word(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr);
671
672         /* Verify read checksum from EEPROM is the same as
673          * calculated checksum
674          */
675         if (checksum_local != checksum_sr)
676                 ret_code = I40E_ERR_NVM_CHECKSUM;
677
678         /* If the user cares, return the calculated checksum */
679         if (checksum)
680                 *checksum = checksum_local;
681
682 i40e_validate_nvm_checksum_exit:
683         return ret_code;
684 }
685
686 STATIC enum i40e_status_code i40e_nvmupd_state_init(struct i40e_hw *hw,
687                                                     struct i40e_nvm_access *cmd,
688                                                     u8 *bytes, int *perrno);
689 STATIC enum i40e_status_code i40e_nvmupd_state_reading(struct i40e_hw *hw,
690                                                     struct i40e_nvm_access *cmd,
691                                                     u8 *bytes, int *perrno);
692 STATIC enum i40e_status_code i40e_nvmupd_state_writing(struct i40e_hw *hw,
693                                                     struct i40e_nvm_access *cmd,
694                                                     u8 *bytes, int *perrno);
695 STATIC enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
696                                                     struct i40e_nvm_access *cmd,
697                                                     int *perrno);
698 STATIC enum i40e_status_code i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
699                                                    struct i40e_nvm_access *cmd,
700                                                    int *perrno);
701 STATIC enum i40e_status_code i40e_nvmupd_nvm_write(struct i40e_hw *hw,
702                                                    struct i40e_nvm_access *cmd,
703                                                    u8 *bytes, int *perrno);
704 STATIC enum i40e_status_code i40e_nvmupd_nvm_read(struct i40e_hw *hw,
705                                                   struct i40e_nvm_access *cmd,
706                                                   u8 *bytes, int *perrno);
707 STATIC inline u8 i40e_nvmupd_get_module(u32 val)
708 {
709         return (u8)(val & I40E_NVM_MOD_PNT_MASK);
710 }
711 STATIC inline u8 i40e_nvmupd_get_transaction(u32 val)
712 {
713         return (u8)((val & I40E_NVM_TRANS_MASK) >> I40E_NVM_TRANS_SHIFT);
714 }
715
716 STATIC const char *i40e_nvm_update_state_str[] = {
717         "I40E_NVMUPD_INVALID",
718         "I40E_NVMUPD_READ_CON",
719         "I40E_NVMUPD_READ_SNT",
720         "I40E_NVMUPD_READ_LCB",
721         "I40E_NVMUPD_READ_SA",
722         "I40E_NVMUPD_WRITE_ERA",
723         "I40E_NVMUPD_WRITE_CON",
724         "I40E_NVMUPD_WRITE_SNT",
725         "I40E_NVMUPD_WRITE_LCB",
726         "I40E_NVMUPD_WRITE_SA",
727         "I40E_NVMUPD_CSUM_CON",
728         "I40E_NVMUPD_CSUM_SA",
729         "I40E_NVMUPD_CSUM_LCB",
730 };
731
732 /**
733  * i40e_nvmupd_command - Process an NVM update command
734  * @hw: pointer to hardware structure
735  * @cmd: pointer to nvm update command
736  * @bytes: pointer to the data buffer
737  * @perrno: pointer to return error code
738  *
739  * Dispatches command depending on what update state is current
740  **/
741 enum i40e_status_code i40e_nvmupd_command(struct i40e_hw *hw,
742                                           struct i40e_nvm_access *cmd,
743                                           u8 *bytes, int *perrno)
744 {
745         enum i40e_status_code status;
746
747         DEBUGFUNC("i40e_nvmupd_command");
748
749         /* assume success */
750         *perrno = 0;
751
752         switch (hw->nvmupd_state) {
753         case I40E_NVMUPD_STATE_INIT:
754                 status = i40e_nvmupd_state_init(hw, cmd, bytes, perrno);
755                 break;
756
757         case I40E_NVMUPD_STATE_READING:
758                 status = i40e_nvmupd_state_reading(hw, cmd, bytes, perrno);
759                 break;
760
761         case I40E_NVMUPD_STATE_WRITING:
762                 status = i40e_nvmupd_state_writing(hw, cmd, bytes, perrno);
763                 break;
764
765         case I40E_NVMUPD_STATE_INIT_WAIT:
766         case I40E_NVMUPD_STATE_WRITE_WAIT:
767                 status = I40E_ERR_NOT_READY;
768                 *perrno = -EBUSY;
769                 break;
770
771         default:
772                 /* invalid state, should never happen */
773                 i40e_debug(hw, I40E_DEBUG_NVM,
774                            "NVMUPD: no such state %d\n", hw->nvmupd_state);
775                 status = I40E_NOT_SUPPORTED;
776                 *perrno = -ESRCH;
777                 break;
778         }
779         return status;
780 }
781
782 /**
783  * i40e_nvmupd_state_init - Handle NVM update state Init
784  * @hw: pointer to hardware structure
785  * @cmd: pointer to nvm update command buffer
786  * @bytes: pointer to the data buffer
787  * @perrno: pointer to return error code
788  *
789  * Process legitimate commands of the Init state and conditionally set next
790  * state. Reject all other commands.
791  **/
792 STATIC enum i40e_status_code i40e_nvmupd_state_init(struct i40e_hw *hw,
793                                                     struct i40e_nvm_access *cmd,
794                                                     u8 *bytes, int *perrno)
795 {
796         enum i40e_status_code status = I40E_SUCCESS;
797         enum i40e_nvmupd_cmd upd_cmd;
798
799         DEBUGFUNC("i40e_nvmupd_state_init");
800
801         upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
802
803         switch (upd_cmd) {
804         case I40E_NVMUPD_READ_SA:
805                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
806                 if (status) {
807                         *perrno = i40e_aq_rc_to_posix(status,
808                                                      hw->aq.asq_last_status);
809                 } else {
810                         status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno);
811                         i40e_release_nvm(hw);
812                 }
813                 break;
814
815         case I40E_NVMUPD_READ_SNT:
816                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
817                 if (status) {
818                         *perrno = i40e_aq_rc_to_posix(status,
819                                                      hw->aq.asq_last_status);
820                 } else {
821                         status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno);
822                         if (status)
823                                 i40e_release_nvm(hw);
824                         else
825                                 hw->nvmupd_state = I40E_NVMUPD_STATE_READING;
826                 }
827                 break;
828
829         case I40E_NVMUPD_WRITE_ERA:
830                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
831                 if (status) {
832                         *perrno = i40e_aq_rc_to_posix(status,
833                                                      hw->aq.asq_last_status);
834                 } else {
835                         status = i40e_nvmupd_nvm_erase(hw, cmd, perrno);
836                         if (status) {
837                                 i40e_release_nvm(hw);
838                         } else {
839                                 hw->aq.nvm_release_on_done = true;
840                                 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
841                         }
842                 }
843                 break;
844
845         case I40E_NVMUPD_WRITE_SA:
846                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
847                 if (status) {
848                         *perrno = i40e_aq_rc_to_posix(status,
849                                                      hw->aq.asq_last_status);
850                 } else {
851                         status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
852                         if (status) {
853                                 i40e_release_nvm(hw);
854                         } else {
855                                 hw->aq.nvm_release_on_done = true;
856                                 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
857                         }
858                 }
859                 break;
860
861         case I40E_NVMUPD_WRITE_SNT:
862                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
863                 if (status) {
864                         *perrno = i40e_aq_rc_to_posix(status,
865                                                      hw->aq.asq_last_status);
866                 } else {
867                         status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
868                         if (status)
869                                 i40e_release_nvm(hw);
870                         else
871                                 hw->nvmupd_state = I40E_NVMUPD_STATE_WRITE_WAIT;
872                 }
873                 break;
874
875         case I40E_NVMUPD_CSUM_SA:
876                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
877                 if (status) {
878                         *perrno = i40e_aq_rc_to_posix(status,
879                                                      hw->aq.asq_last_status);
880                 } else {
881                         status = i40e_update_nvm_checksum(hw);
882                         if (status) {
883                                 *perrno = hw->aq.asq_last_status ?
884                                    i40e_aq_rc_to_posix(status,
885                                                        hw->aq.asq_last_status) :
886                                    -EIO;
887                                 i40e_release_nvm(hw);
888                         } else {
889                                 hw->aq.nvm_release_on_done = true;
890                                 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
891                         }
892                 }
893                 break;
894
895         default:
896                 i40e_debug(hw, I40E_DEBUG_NVM,
897                            "NVMUPD: bad cmd %s in init state\n",
898                            i40e_nvm_update_state_str[upd_cmd]);
899                 status = I40E_ERR_NVM;
900                 *perrno = -ESRCH;
901                 break;
902         }
903         return status;
904 }
905
906 /**
907  * i40e_nvmupd_state_reading - Handle NVM update state Reading
908  * @hw: pointer to hardware structure
909  * @cmd: pointer to nvm update command buffer
910  * @bytes: pointer to the data buffer
911  * @perrno: pointer to return error code
912  *
913  * NVM ownership is already held.  Process legitimate commands and set any
914  * change in state; reject all other commands.
915  **/
916 STATIC enum i40e_status_code i40e_nvmupd_state_reading(struct i40e_hw *hw,
917                                                     struct i40e_nvm_access *cmd,
918                                                     u8 *bytes, int *perrno)
919 {
920         enum i40e_status_code status = I40E_SUCCESS;
921         enum i40e_nvmupd_cmd upd_cmd;
922
923         DEBUGFUNC("i40e_nvmupd_state_reading");
924
925         upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
926
927         switch (upd_cmd) {
928         case I40E_NVMUPD_READ_SA:
929         case I40E_NVMUPD_READ_CON:
930                 status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno);
931                 break;
932
933         case I40E_NVMUPD_READ_LCB:
934                 status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno);
935                 i40e_release_nvm(hw);
936                 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
937                 break;
938
939         default:
940                 i40e_debug(hw, I40E_DEBUG_NVM,
941                            "NVMUPD: bad cmd %s in reading state.\n",
942                            i40e_nvm_update_state_str[upd_cmd]);
943                 status = I40E_NOT_SUPPORTED;
944                 *perrno = -ESRCH;
945                 break;
946         }
947         return status;
948 }
949
950 /**
951  * i40e_nvmupd_state_writing - Handle NVM update state Writing
952  * @hw: pointer to hardware structure
953  * @cmd: pointer to nvm update command buffer
954  * @bytes: pointer to the data buffer
955  * @perrno: pointer to return error code
956  *
957  * NVM ownership is already held.  Process legitimate commands and set any
958  * change in state; reject all other commands
959  **/
960 STATIC enum i40e_status_code i40e_nvmupd_state_writing(struct i40e_hw *hw,
961                                                     struct i40e_nvm_access *cmd,
962                                                     u8 *bytes, int *perrno)
963 {
964         enum i40e_status_code status = I40E_SUCCESS;
965         enum i40e_nvmupd_cmd upd_cmd;
966         bool retry_attempt = false;
967
968         DEBUGFUNC("i40e_nvmupd_state_writing");
969
970         upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
971
972 retry:
973         switch (upd_cmd) {
974         case I40E_NVMUPD_WRITE_CON:
975                 status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
976                 if (!status)
977                         hw->nvmupd_state = I40E_NVMUPD_STATE_WRITE_WAIT;
978                 break;
979
980         case I40E_NVMUPD_WRITE_LCB:
981                 status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
982                 if (status) {
983                         *perrno = hw->aq.asq_last_status ?
984                                    i40e_aq_rc_to_posix(status,
985                                                        hw->aq.asq_last_status) :
986                                    -EIO;
987                         hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
988                 } else {
989                         hw->aq.nvm_release_on_done = true;
990                         hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
991                 }
992                 break;
993
994         case I40E_NVMUPD_CSUM_CON:
995                 status = i40e_update_nvm_checksum(hw);
996                 if (status) {
997                         *perrno = hw->aq.asq_last_status ?
998                                    i40e_aq_rc_to_posix(status,
999                                                        hw->aq.asq_last_status) :
1000                                    -EIO;
1001                         hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
1002                 } else {
1003                         hw->nvmupd_state = I40E_NVMUPD_STATE_WRITE_WAIT;
1004                 }
1005                 break;
1006
1007         case I40E_NVMUPD_CSUM_LCB:
1008                 status = i40e_update_nvm_checksum(hw);
1009                 if (status) {
1010                         *perrno = hw->aq.asq_last_status ?
1011                                    i40e_aq_rc_to_posix(status,
1012                                                        hw->aq.asq_last_status) :
1013                                    -EIO;
1014                         hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
1015                 } else {
1016                         hw->aq.nvm_release_on_done = true;
1017                         hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
1018                 }
1019                 break;
1020
1021         default:
1022                 i40e_debug(hw, I40E_DEBUG_NVM,
1023                            "NVMUPD: bad cmd %s in writing state.\n",
1024                            i40e_nvm_update_state_str[upd_cmd]);
1025                 status = I40E_NOT_SUPPORTED;
1026                 *perrno = -ESRCH;
1027                 break;
1028         }
1029
1030         /* In some circumstances, a multi-write transaction takes longer
1031          * than the default 3 minute timeout on the write semaphore.  If
1032          * the write failed with an EBUSY status, this is likely the problem,
1033          * so here we try to reacquire the semaphore then retry the write.
1034          * We only do one retry, then give up.
1035          */
1036         if (status && (hw->aq.asq_last_status == I40E_AQ_RC_EBUSY) &&
1037             !retry_attempt) {
1038                 enum i40e_status_code old_status = status;
1039                 u32 old_asq_status = hw->aq.asq_last_status;
1040                 u32 gtime;
1041
1042                 gtime = rd32(hw, I40E_GLVFGEN_TIMER);
1043                 if (gtime >= hw->nvm.hw_semaphore_timeout) {
1044                         i40e_debug(hw, I40E_DEBUG_ALL,
1045                                    "NVMUPD: write semaphore expired (%d >= %lld), retrying\n",
1046                                    gtime, hw->nvm.hw_semaphore_timeout);
1047                         i40e_release_nvm(hw);
1048                         status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
1049                         if (status) {
1050                                 i40e_debug(hw, I40E_DEBUG_ALL,
1051                                            "NVMUPD: write semaphore reacquire failed aq_err = %d\n",
1052                                            hw->aq.asq_last_status);
1053                                 status = old_status;
1054                                 hw->aq.asq_last_status = old_asq_status;
1055                         } else {
1056                                 retry_attempt = true;
1057                                 goto retry;
1058                         }
1059                 }
1060         }
1061
1062         return status;
1063 }
1064
1065 /**
1066  * i40e_nvmupd_validate_command - Validate given command
1067  * @hw: pointer to hardware structure
1068  * @cmd: pointer to nvm update command buffer
1069  * @perrno: pointer to return error code
1070  *
1071  * Return one of the valid command types or I40E_NVMUPD_INVALID
1072  **/
1073 STATIC enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
1074                                                     struct i40e_nvm_access *cmd,
1075                                                     int *perrno)
1076 {
1077         enum i40e_nvmupd_cmd upd_cmd;
1078         u8 transaction, module;
1079
1080         DEBUGFUNC("i40e_nvmupd_validate_command\n");
1081
1082         /* anything that doesn't match a recognized case is an error */
1083         upd_cmd = I40E_NVMUPD_INVALID;
1084
1085         transaction = i40e_nvmupd_get_transaction(cmd->config);
1086         module = i40e_nvmupd_get_module(cmd->config);
1087
1088         /* limits on data size */
1089         if ((cmd->data_size < 1) ||
1090             (cmd->data_size > I40E_NVMUPD_MAX_DATA)) {
1091                 i40e_debug(hw, I40E_DEBUG_NVM,
1092                            "i40e_nvmupd_validate_command data_size %d\n",
1093                            cmd->data_size);
1094                 *perrno = -EFAULT;
1095                 return I40E_NVMUPD_INVALID;
1096         }
1097
1098         switch (cmd->command) {
1099         case I40E_NVM_READ:
1100                 switch (transaction) {
1101                 case I40E_NVM_CON:
1102                         upd_cmd = I40E_NVMUPD_READ_CON;
1103                         break;
1104                 case I40E_NVM_SNT:
1105                         upd_cmd = I40E_NVMUPD_READ_SNT;
1106                         break;
1107                 case I40E_NVM_LCB:
1108                         upd_cmd = I40E_NVMUPD_READ_LCB;
1109                         break;
1110                 case I40E_NVM_SA:
1111                         upd_cmd = I40E_NVMUPD_READ_SA;
1112                         break;
1113                 }
1114                 break;
1115
1116         case I40E_NVM_WRITE:
1117                 switch (transaction) {
1118                 case I40E_NVM_CON:
1119                         upd_cmd = I40E_NVMUPD_WRITE_CON;
1120                         break;
1121                 case I40E_NVM_SNT:
1122                         upd_cmd = I40E_NVMUPD_WRITE_SNT;
1123                         break;
1124                 case I40E_NVM_LCB:
1125                         upd_cmd = I40E_NVMUPD_WRITE_LCB;
1126                         break;
1127                 case I40E_NVM_SA:
1128                         upd_cmd = I40E_NVMUPD_WRITE_SA;
1129                         break;
1130                 case I40E_NVM_ERA:
1131                         upd_cmd = I40E_NVMUPD_WRITE_ERA;
1132                         break;
1133                 case I40E_NVM_CSUM:
1134                         upd_cmd = I40E_NVMUPD_CSUM_CON;
1135                         break;
1136                 case (I40E_NVM_CSUM|I40E_NVM_SA):
1137                         upd_cmd = I40E_NVMUPD_CSUM_SA;
1138                         break;
1139                 case (I40E_NVM_CSUM|I40E_NVM_LCB):
1140                         upd_cmd = I40E_NVMUPD_CSUM_LCB;
1141                         break;
1142                 }
1143                 break;
1144         }
1145         i40e_debug(hw, I40E_DEBUG_NVM, "%s state %d nvm_release_on_hold %d\n",
1146                    i40e_nvm_update_state_str[upd_cmd],
1147                    hw->nvmupd_state,
1148                    hw->aq.nvm_release_on_done);
1149
1150         if (upd_cmd == I40E_NVMUPD_INVALID) {
1151                 *perrno = -EFAULT;
1152                 i40e_debug(hw, I40E_DEBUG_NVM,
1153                            "i40e_nvmupd_validate_command returns %d perrno %d\n",
1154                            upd_cmd, *perrno);
1155         }
1156         return upd_cmd;
1157 }
1158
1159 /**
1160  * i40e_nvmupd_nvm_read - Read NVM
1161  * @hw: pointer to hardware structure
1162  * @cmd: pointer to nvm update command buffer
1163  * @bytes: pointer to the data buffer
1164  * @perrno: pointer to return error code
1165  *
1166  * cmd structure contains identifiers and data buffer
1167  **/
1168 STATIC enum i40e_status_code i40e_nvmupd_nvm_read(struct i40e_hw *hw,
1169                                                   struct i40e_nvm_access *cmd,
1170                                                   u8 *bytes, int *perrno)
1171 {
1172         struct i40e_asq_cmd_details cmd_details;
1173         enum i40e_status_code status;
1174         u8 module, transaction;
1175         bool last;
1176
1177         transaction = i40e_nvmupd_get_transaction(cmd->config);
1178         module = i40e_nvmupd_get_module(cmd->config);
1179         last = (transaction == I40E_NVM_LCB) || (transaction == I40E_NVM_SA);
1180
1181         memset(&cmd_details, 0, sizeof(cmd_details));
1182         cmd_details.wb_desc = &hw->nvm_wb_desc;
1183
1184         status = i40e_aq_read_nvm(hw, module, cmd->offset, (u16)cmd->data_size,
1185                                   bytes, last, &cmd_details);
1186         if (status) {
1187                 i40e_debug(hw, I40E_DEBUG_NVM,
1188                            "i40e_nvmupd_nvm_read mod 0x%x  off 0x%x  len 0x%x\n",
1189                            module, cmd->offset, cmd->data_size);
1190                 i40e_debug(hw, I40E_DEBUG_NVM,
1191                            "i40e_nvmupd_nvm_read status %d aq %d\n",
1192                            status, hw->aq.asq_last_status);
1193                 *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
1194         }
1195
1196         return status;
1197 }
1198
1199 /**
1200  * i40e_nvmupd_nvm_erase - Erase an NVM module
1201  * @hw: pointer to hardware structure
1202  * @cmd: pointer to nvm update command buffer
1203  * @perrno: pointer to return error code
1204  *
1205  * module, offset, data_size and data are in cmd structure
1206  **/
1207 STATIC enum i40e_status_code i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
1208                                                    struct i40e_nvm_access *cmd,
1209                                                    int *perrno)
1210 {
1211         enum i40e_status_code status = I40E_SUCCESS;
1212         struct i40e_asq_cmd_details cmd_details;
1213         u8 module, transaction;
1214         bool last;
1215
1216         transaction = i40e_nvmupd_get_transaction(cmd->config);
1217         module = i40e_nvmupd_get_module(cmd->config);
1218         last = (transaction & I40E_NVM_LCB);
1219
1220         memset(&cmd_details, 0, sizeof(cmd_details));
1221         cmd_details.wb_desc = &hw->nvm_wb_desc;
1222
1223         status = i40e_aq_erase_nvm(hw, module, cmd->offset, (u16)cmd->data_size,
1224                                    last, &cmd_details);
1225         if (status) {
1226                 i40e_debug(hw, I40E_DEBUG_NVM,
1227                            "i40e_nvmupd_nvm_erase mod 0x%x  off 0x%x len 0x%x\n",
1228                            module, cmd->offset, cmd->data_size);
1229                 i40e_debug(hw, I40E_DEBUG_NVM,
1230                            "i40e_nvmupd_nvm_erase status %d aq %d\n",
1231                            status, hw->aq.asq_last_status);
1232                 *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
1233         }
1234
1235         return status;
1236 }
1237
1238 /**
1239  * i40e_nvmupd_nvm_write - Write NVM
1240  * @hw: pointer to hardware structure
1241  * @cmd: pointer to nvm update command buffer
1242  * @bytes: pointer to the data buffer
1243  * @perrno: pointer to return error code
1244  *
1245  * module, offset, data_size and data are in cmd structure
1246  **/
1247 STATIC enum i40e_status_code i40e_nvmupd_nvm_write(struct i40e_hw *hw,
1248                                                    struct i40e_nvm_access *cmd,
1249                                                    u8 *bytes, int *perrno)
1250 {
1251         enum i40e_status_code status = I40E_SUCCESS;
1252         struct i40e_asq_cmd_details cmd_details;
1253         u8 module, transaction;
1254         bool last;
1255
1256         transaction = i40e_nvmupd_get_transaction(cmd->config);
1257         module = i40e_nvmupd_get_module(cmd->config);
1258         last = (transaction & I40E_NVM_LCB);
1259
1260         memset(&cmd_details, 0, sizeof(cmd_details));
1261         cmd_details.wb_desc = &hw->nvm_wb_desc;
1262
1263         status = i40e_aq_update_nvm(hw, module, cmd->offset,
1264                                     (u16)cmd->data_size, bytes, last,
1265                                     &cmd_details);
1266         if (status) {
1267                 i40e_debug(hw, I40E_DEBUG_NVM,
1268                            "i40e_nvmupd_nvm_write mod 0x%x off 0x%x len 0x%x\n",
1269                            module, cmd->offset, cmd->data_size);
1270                 i40e_debug(hw, I40E_DEBUG_NVM,
1271                            "i40e_nvmupd_nvm_write status %d aq %d\n",
1272                            status, hw->aq.asq_last_status);
1273                 *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
1274         }
1275
1276         return status;
1277 }