i40e/base: minor clean up
[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 = BIT(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         enum i40e_status_code ret_code = I40E_SUCCESS;
161         u32 total_delay = 0;
162
163         DEBUGFUNC("i40e_release_nvm");
164
165         if (hw->nvm.blank_nvm_mode)
166                 return;
167
168         ret_code = i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL);
169
170         /* there are some rare cases when trying to release the resource
171          * results in an admin Q timeout, so handle them correctly
172          */
173         while ((ret_code == I40E_ERR_ADMIN_QUEUE_TIMEOUT) &&
174                (total_delay < hw->aq.asq_cmd_timeout)) {
175                         i40e_msec_delay(1);
176                         ret_code = i40e_aq_release_resource(hw,
177                                                 I40E_NVM_RESOURCE_ID, 0, NULL);
178                         total_delay++;
179         }
180 }
181
182 /**
183  * i40e_poll_sr_srctl_done_bit - Polls the GLNVM_SRCTL done bit
184  * @hw: pointer to the HW structure
185  *
186  * Polls the SRCTL Shadow RAM register done bit.
187  **/
188 static enum i40e_status_code i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw)
189 {
190         enum i40e_status_code ret_code = I40E_ERR_TIMEOUT;
191         u32 srctl, wait_cnt;
192
193         DEBUGFUNC("i40e_poll_sr_srctl_done_bit");
194
195         /* Poll the I40E_GLNVM_SRCTL until the done bit is set */
196         for (wait_cnt = 0; wait_cnt < I40E_SRRD_SRCTL_ATTEMPTS; wait_cnt++) {
197                 srctl = rd32(hw, I40E_GLNVM_SRCTL);
198                 if (srctl & I40E_GLNVM_SRCTL_DONE_MASK) {
199                         ret_code = I40E_SUCCESS;
200                         break;
201                 }
202                 i40e_usec_delay(5);
203         }
204         if (ret_code == I40E_ERR_TIMEOUT)
205                 i40e_debug(hw, I40E_DEBUG_NVM, "Done bit in GLNVM_SRCTL not set");
206         return ret_code;
207 }
208
209 /**
210  * i40e_read_nvm_word - Reads Shadow RAM
211  * @hw: pointer to the HW structure
212  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
213  * @data: word read from the Shadow RAM
214  *
215  * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
216  **/
217 enum i40e_status_code i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
218                                          u16 *data)
219 {
220         return i40e_read_nvm_word_srctl(hw, offset, data);
221 }
222
223 /**
224  * i40e_read_nvm_word_srctl - Reads Shadow RAM via SRCTL register
225  * @hw: pointer to the HW structure
226  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
227  * @data: word read from the Shadow RAM
228  *
229  * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
230  **/
231 enum i40e_status_code i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset,
232                                                u16 *data)
233 {
234         enum i40e_status_code ret_code = I40E_ERR_TIMEOUT;
235         u32 sr_reg;
236
237         DEBUGFUNC("i40e_read_nvm_word_srctl");
238
239         if (offset >= hw->nvm.sr_size) {
240                 i40e_debug(hw, I40E_DEBUG_NVM,
241                            "NVM read error: Offset %d beyond Shadow RAM limit %d\n",
242                            offset, hw->nvm.sr_size);
243                 ret_code = I40E_ERR_PARAM;
244                 goto read_nvm_exit;
245         }
246
247         /* Poll the done bit first */
248         ret_code = i40e_poll_sr_srctl_done_bit(hw);
249         if (ret_code == I40E_SUCCESS) {
250                 /* Write the address and start reading */
251                 sr_reg = ((u32)offset << I40E_GLNVM_SRCTL_ADDR_SHIFT) |
252                          BIT(I40E_GLNVM_SRCTL_START_SHIFT);
253                 wr32(hw, I40E_GLNVM_SRCTL, sr_reg);
254
255                 /* Poll I40E_GLNVM_SRCTL until the done bit is set */
256                 ret_code = i40e_poll_sr_srctl_done_bit(hw);
257                 if (ret_code == I40E_SUCCESS) {
258                         sr_reg = rd32(hw, I40E_GLNVM_SRDATA);
259                         *data = (u16)((sr_reg &
260                                        I40E_GLNVM_SRDATA_RDDATA_MASK)
261                                     >> I40E_GLNVM_SRDATA_RDDATA_SHIFT);
262                 }
263         }
264         if (ret_code != I40E_SUCCESS)
265                 i40e_debug(hw, I40E_DEBUG_NVM,
266                            "NVM read error: Couldn't access Shadow RAM address: 0x%x\n",
267                            offset);
268
269 read_nvm_exit:
270         return ret_code;
271 }
272
273 /**
274  * i40e_read_nvm_word_aq - Reads Shadow RAM via AQ
275  * @hw: pointer to the HW structure
276  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
277  * @data: word read from the Shadow RAM
278  *
279  * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
280  **/
281 enum i40e_status_code i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset,
282                                             u16 *data)
283 {
284         enum i40e_status_code ret_code = I40E_ERR_TIMEOUT;
285
286         DEBUGFUNC("i40e_read_nvm_word_aq");
287
288         ret_code = i40e_read_nvm_aq(hw, 0x0, offset, 1, data, true);
289         *data = LE16_TO_CPU(*(__le16 *)data);
290
291         return ret_code;
292 }
293
294 /**
295  * i40e_read_nvm_buffer - Reads Shadow RAM buffer
296  * @hw: pointer to the HW structure
297  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
298  * @words: (in) number of words to read; (out) number of words actually read
299  * @data: words read from the Shadow RAM
300  *
301  * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd()
302  * method. The buffer read is preceded by the NVM ownership take
303  * and followed by the release.
304  **/
305 enum i40e_status_code i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
306                                            u16 *words, u16 *data)
307 {
308         return i40e_read_nvm_buffer_srctl(hw, offset, words, data);
309 }
310
311 /**
312  * i40e_read_nvm_buffer_srctl - Reads Shadow RAM buffer via SRCTL register
313  * @hw: pointer to the HW structure
314  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
315  * @words: (in) number of words to read; (out) number of words actually read
316  * @data: words read from the Shadow RAM
317  *
318  * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd()
319  * method. The buffer read is preceded by the NVM ownership take
320  * and followed by the release.
321  **/
322 enum i40e_status_code i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
323                                                  u16 *words, u16 *data)
324 {
325         enum i40e_status_code ret_code = I40E_SUCCESS;
326         u16 index, word;
327
328         DEBUGFUNC("i40e_read_nvm_buffer_srctl");
329
330         /* Loop thru the selected region */
331         for (word = 0; word < *words; word++) {
332                 index = offset + word;
333                 ret_code = i40e_read_nvm_word_srctl(hw, index, &data[word]);
334                 if (ret_code != I40E_SUCCESS)
335                         break;
336         }
337
338         /* Update the number of words read from the Shadow RAM */
339         *words = word;
340
341         return ret_code;
342 }
343
344 /**
345  * i40e_read_nvm_buffer_aq - Reads Shadow RAM buffer via AQ
346  * @hw: pointer to the HW structure
347  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
348  * @words: (in) number of words to read; (out) number of words actually read
349  * @data: words read from the Shadow RAM
350  *
351  * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_aq()
352  * method. The buffer read is preceded by the NVM ownership take
353  * and followed by the release.
354  **/
355 enum i40e_status_code i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset,
356                                               u16 *words, u16 *data)
357 {
358         enum i40e_status_code ret_code;
359         u16 read_size = *words;
360         bool last_cmd = false;
361         u16 words_read = 0;
362         u16 i = 0;
363
364         DEBUGFUNC("i40e_read_nvm_buffer_aq");
365
366         do {
367                 /* Calculate number of bytes we should read in this step.
368                  * FVL AQ do not allow to read more than one page at a time or
369                  * to cross page boundaries.
370                  */
371                 if (offset % I40E_SR_SECTOR_SIZE_IN_WORDS)
372                         read_size = min(*words,
373                                         (u16)(I40E_SR_SECTOR_SIZE_IN_WORDS -
374                                       (offset % I40E_SR_SECTOR_SIZE_IN_WORDS)));
375                 else
376                         read_size = min((*words - words_read),
377                                         I40E_SR_SECTOR_SIZE_IN_WORDS);
378
379                 /* Check if this is last command, if so set proper flag */
380                 if ((words_read + read_size) >= *words)
381                         last_cmd = true;
382
383                 ret_code = i40e_read_nvm_aq(hw, 0x0, offset, read_size,
384                                             data + words_read, last_cmd);
385                 if (ret_code != I40E_SUCCESS)
386                         goto read_nvm_buffer_aq_exit;
387
388                 /* Increment counter for words already read and move offset to
389                  * new read location
390                  */
391                 words_read += read_size;
392                 offset += read_size;
393         } while (words_read < *words);
394
395         for (i = 0; i < *words; i++)
396                 data[i] = LE16_TO_CPU(((__le16 *)data)[i]);
397
398 read_nvm_buffer_aq_exit:
399         *words = words_read;
400         return ret_code;
401 }
402
403 /**
404  * i40e_read_nvm_aq - Read Shadow RAM.
405  * @hw: pointer to the HW structure.
406  * @module_pointer: module pointer location in words from the NVM beginning
407  * @offset: offset in words from module start
408  * @words: number of words to write
409  * @data: buffer with words to write to the Shadow RAM
410  * @last_command: tells the AdminQ that this is the last command
411  *
412  * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
413  **/
414 enum i40e_status_code i40e_read_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
415                                        u32 offset, u16 words, void *data,
416                                        bool last_command)
417 {
418         enum i40e_status_code ret_code = I40E_ERR_NVM;
419         struct i40e_asq_cmd_details cmd_details;
420
421         DEBUGFUNC("i40e_read_nvm_aq");
422
423         memset(&cmd_details, 0, sizeof(cmd_details));
424         cmd_details.wb_desc = &hw->nvm_wb_desc;
425
426         /* Here we are checking the SR limit only for the flat memory model.
427          * We cannot do it for the module-based model, as we did not acquire
428          * the NVM resource yet (we cannot get the module pointer value).
429          * Firmware will check the module-based model.
430          */
431         if ((offset + words) > hw->nvm.sr_size)
432                 i40e_debug(hw, I40E_DEBUG_NVM,
433                            "NVM write error: offset %d beyond Shadow RAM limit %d\n",
434                            (offset + words), hw->nvm.sr_size);
435         else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS)
436                 /* We can write only up to 4KB (one sector), in one AQ write */
437                 i40e_debug(hw, I40E_DEBUG_NVM,
438                            "NVM write fail error: tried to write %d words, limit is %d.\n",
439                            words, I40E_SR_SECTOR_SIZE_IN_WORDS);
440         else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS)
441                  != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS))
442                 /* A single write cannot spread over two sectors */
443                 i40e_debug(hw, I40E_DEBUG_NVM,
444                            "NVM write error: cannot spread over two sectors in a single write offset=%d words=%d\n",
445                            offset, words);
446         else
447                 ret_code = i40e_aq_read_nvm(hw, module_pointer,
448                                             2 * offset,  /*bytes*/
449                                             2 * words,   /*bytes*/
450                                             data, last_command, &cmd_details);
451
452         return ret_code;
453 }
454
455 /**
456  * i40e_write_nvm_aq - Writes Shadow RAM.
457  * @hw: pointer to the HW structure.
458  * @module_pointer: module pointer location in words from the NVM beginning
459  * @offset: offset in words from module start
460  * @words: number of words to write
461  * @data: buffer with words to write to the Shadow RAM
462  * @last_command: tells the AdminQ that this is the last command
463  *
464  * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
465  **/
466 enum i40e_status_code i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
467                                         u32 offset, u16 words, void *data,
468                                         bool last_command)
469 {
470         enum i40e_status_code ret_code = I40E_ERR_NVM;
471         struct i40e_asq_cmd_details cmd_details;
472
473         DEBUGFUNC("i40e_write_nvm_aq");
474
475         memset(&cmd_details, 0, sizeof(cmd_details));
476         cmd_details.wb_desc = &hw->nvm_wb_desc;
477
478         /* Here we are checking the SR limit only for the flat memory model.
479          * We cannot do it for the module-based model, as we did not acquire
480          * the NVM resource yet (we cannot get the module pointer value).
481          * Firmware will check the module-based model.
482          */
483         if ((offset + words) > hw->nvm.sr_size)
484                 DEBUGOUT("NVM write error: offset beyond Shadow RAM limit.\n");
485         else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS)
486                 /* We can write only up to 4KB (one sector), in one AQ write */
487                 DEBUGOUT("NVM write fail error: cannot write more than 4KB in a single write.\n");
488         else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS)
489                  != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS))
490                 /* A single write cannot spread over two sectors */
491                 DEBUGOUT("NVM write error: cannot spread over two sectors in a single write.\n");
492         else
493                 ret_code = i40e_aq_update_nvm(hw, module_pointer,
494                                               2 * offset,  /*bytes*/
495                                               2 * words,   /*bytes*/
496                                               data, last_command, &cmd_details);
497
498         return ret_code;
499 }
500
501 /**
502  * i40e_write_nvm_word - Writes Shadow RAM word
503  * @hw: pointer to the HW structure
504  * @offset: offset of the Shadow RAM word to write
505  * @data: word to write to the Shadow RAM
506  *
507  * Writes a 16 bit word to the SR using the i40e_write_nvm_aq() method.
508  * NVM ownership have to be acquired and released (on ARQ completion event
509  * reception) by caller. To commit SR to NVM update checksum function
510  * should be called.
511  **/
512 enum i40e_status_code i40e_write_nvm_word(struct i40e_hw *hw, u32 offset,
513                                           void *data)
514 {
515         DEBUGFUNC("i40e_write_nvm_word");
516
517         *((__le16 *)data) = CPU_TO_LE16(*((u16 *)data));
518
519         /* Value 0x00 below means that we treat SR as a flat mem */
520         return i40e_write_nvm_aq(hw, 0x00, offset, 1, data, false);
521 }
522
523 /**
524  * i40e_write_nvm_buffer - Writes Shadow RAM buffer
525  * @hw: pointer to the HW structure
526  * @module_pointer: module pointer location in words from the NVM beginning
527  * @offset: offset of the Shadow RAM buffer to write
528  * @words: number of words to write
529  * @data: words to write to the Shadow RAM
530  *
531  * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
532  * NVM ownership must be acquired before calling this function and released
533  * on ARQ completion event reception by caller. To commit SR to NVM update
534  * checksum function should be called.
535  **/
536 enum i40e_status_code i40e_write_nvm_buffer(struct i40e_hw *hw,
537                                             u8 module_pointer, u32 offset,
538                                             u16 words, void *data)
539 {
540         __le16 *le_word_ptr = (__le16 *)data;
541         u16 *word_ptr = (u16 *)data;
542         u32 i = 0;
543
544         DEBUGFUNC("i40e_write_nvm_buffer");
545
546         for (i = 0; i < words; i++)
547                 le_word_ptr[i] = CPU_TO_LE16(word_ptr[i]);
548
549         /* Here we will only write one buffer as the size of the modules
550          * mirrored in the Shadow RAM is always less than 4K.
551          */
552         return i40e_write_nvm_aq(hw, module_pointer, offset, words,
553                                  data, false);
554 }
555
556 /**
557  * i40e_calc_nvm_checksum - Calculates and returns the checksum
558  * @hw: pointer to hardware structure
559  * @checksum: pointer to the checksum
560  *
561  * This function calculates SW Checksum that covers the whole 64kB shadow RAM
562  * except the VPD and PCIe ALT Auto-load modules. The structure and size of VPD
563  * is customer specific and unknown. Therefore, this function skips all maximum
564  * possible size of VPD (1kB).
565  **/
566 enum i40e_status_code i40e_calc_nvm_checksum(struct i40e_hw *hw, u16 *checksum)
567 {
568         enum i40e_status_code ret_code = I40E_SUCCESS;
569         struct i40e_virt_mem vmem;
570         u16 pcie_alt_module = 0;
571         u16 checksum_local = 0;
572         u16 vpd_module = 0;
573         u16 *data;
574         u16 i = 0;
575
576         DEBUGFUNC("i40e_calc_nvm_checksum");
577
578         ret_code = i40e_allocate_virt_mem(hw, &vmem,
579                                     I40E_SR_SECTOR_SIZE_IN_WORDS * sizeof(u16));
580         if (ret_code)
581                 goto i40e_calc_nvm_checksum_exit;
582         data = (u16 *)vmem.va;
583
584         /* read pointer to VPD area */
585         ret_code = i40e_read_nvm_word(hw, I40E_SR_VPD_PTR, &vpd_module);
586         if (ret_code != I40E_SUCCESS) {
587                 ret_code = I40E_ERR_NVM_CHECKSUM;
588                 goto i40e_calc_nvm_checksum_exit;
589         }
590
591         /* read pointer to PCIe Alt Auto-load module */
592         ret_code = i40e_read_nvm_word(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR,
593                                       &pcie_alt_module);
594         if (ret_code != I40E_SUCCESS) {
595                 ret_code = I40E_ERR_NVM_CHECKSUM;
596                 goto i40e_calc_nvm_checksum_exit;
597         }
598
599         /* Calculate SW checksum that covers the whole 64kB shadow RAM
600          * except the VPD and PCIe ALT Auto-load modules
601          */
602         for (i = 0; i < hw->nvm.sr_size; i++) {
603                 /* Read SR page */
604                 if ((i % I40E_SR_SECTOR_SIZE_IN_WORDS) == 0) {
605                         u16 words = I40E_SR_SECTOR_SIZE_IN_WORDS;
606
607                         ret_code = i40e_read_nvm_buffer(hw, i, &words, data);
608                         if (ret_code != I40E_SUCCESS) {
609                                 ret_code = I40E_ERR_NVM_CHECKSUM;
610                                 goto i40e_calc_nvm_checksum_exit;
611                         }
612                 }
613
614                 /* Skip Checksum word */
615                 if (i == I40E_SR_SW_CHECKSUM_WORD)
616                         continue;
617                 /* Skip VPD module (convert byte size to word count) */
618                 if ((i >= (u32)vpd_module) &&
619                     (i < ((u32)vpd_module +
620                      (I40E_SR_VPD_MODULE_MAX_SIZE / 2)))) {
621                         continue;
622                 }
623                 /* Skip PCIe ALT module (convert byte size to word count) */
624                 if ((i >= (u32)pcie_alt_module) &&
625                     (i < ((u32)pcie_alt_module +
626                      (I40E_SR_PCIE_ALT_MODULE_MAX_SIZE / 2)))) {
627                         continue;
628                 }
629
630                 checksum_local += data[i % I40E_SR_SECTOR_SIZE_IN_WORDS];
631         }
632
633         *checksum = (u16)I40E_SR_SW_CHECKSUM_BASE - checksum_local;
634
635 i40e_calc_nvm_checksum_exit:
636         i40e_free_virt_mem(hw, &vmem);
637         return ret_code;
638 }
639
640 /**
641  * i40e_update_nvm_checksum - Updates the NVM checksum
642  * @hw: pointer to hardware structure
643  *
644  * NVM ownership must be acquired before calling this function and released
645  * on ARQ completion event reception by caller.
646  * This function will commit SR to NVM.
647  **/
648 enum i40e_status_code i40e_update_nvm_checksum(struct i40e_hw *hw)
649 {
650         enum i40e_status_code ret_code = I40E_SUCCESS;
651         u16 checksum;
652         __le16 le_sum;
653
654         DEBUGFUNC("i40e_update_nvm_checksum");
655
656         ret_code = i40e_calc_nvm_checksum(hw, &checksum);
657         le_sum = CPU_TO_LE16(checksum);
658         if (ret_code == I40E_SUCCESS)
659                 ret_code = i40e_write_nvm_aq(hw, 0x00, I40E_SR_SW_CHECKSUM_WORD,
660                                              1, &le_sum, true);
661
662         return ret_code;
663 }
664
665 /**
666  * i40e_validate_nvm_checksum - Validate EEPROM checksum
667  * @hw: pointer to hardware structure
668  * @checksum: calculated checksum
669  *
670  * Performs checksum calculation and validates the NVM SW checksum. If the
671  * caller does not need checksum, the value can be NULL.
672  **/
673 enum i40e_status_code i40e_validate_nvm_checksum(struct i40e_hw *hw,
674                                                  u16 *checksum)
675 {
676         enum i40e_status_code ret_code = I40E_SUCCESS;
677         u16 checksum_sr = 0;
678         u16 checksum_local = 0;
679
680         DEBUGFUNC("i40e_validate_nvm_checksum");
681
682         ret_code = i40e_calc_nvm_checksum(hw, &checksum_local);
683         if (ret_code != I40E_SUCCESS)
684                 goto i40e_validate_nvm_checksum_exit;
685
686         /* Do not use i40e_read_nvm_word() because we do not want to take
687          * the synchronization semaphores twice here.
688          */
689         i40e_read_nvm_word(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr);
690
691         /* Verify read checksum from EEPROM is the same as
692          * calculated checksum
693          */
694         if (checksum_local != checksum_sr)
695                 ret_code = I40E_ERR_NVM_CHECKSUM;
696
697         /* If the user cares, return the calculated checksum */
698         if (checksum)
699                 *checksum = checksum_local;
700
701 i40e_validate_nvm_checksum_exit:
702         return ret_code;
703 }
704
705 STATIC enum i40e_status_code i40e_nvmupd_state_init(struct i40e_hw *hw,
706                                                     struct i40e_nvm_access *cmd,
707                                                     u8 *bytes, int *perrno);
708 STATIC enum i40e_status_code i40e_nvmupd_state_reading(struct i40e_hw *hw,
709                                                     struct i40e_nvm_access *cmd,
710                                                     u8 *bytes, int *perrno);
711 STATIC enum i40e_status_code i40e_nvmupd_state_writing(struct i40e_hw *hw,
712                                                     struct i40e_nvm_access *cmd,
713                                                     u8 *bytes, int *perrno);
714 STATIC enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
715                                                     struct i40e_nvm_access *cmd,
716                                                     int *perrno);
717 STATIC enum i40e_status_code i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
718                                                    struct i40e_nvm_access *cmd,
719                                                    int *perrno);
720 STATIC enum i40e_status_code i40e_nvmupd_nvm_write(struct i40e_hw *hw,
721                                                    struct i40e_nvm_access *cmd,
722                                                    u8 *bytes, int *perrno);
723 STATIC enum i40e_status_code i40e_nvmupd_nvm_read(struct i40e_hw *hw,
724                                                   struct i40e_nvm_access *cmd,
725                                                   u8 *bytes, int *perrno);
726 STATIC enum i40e_status_code i40e_nvmupd_exec_aq(struct i40e_hw *hw,
727                                                  struct i40e_nvm_access *cmd,
728                                                  u8 *bytes, int *perrno);
729 STATIC enum i40e_status_code i40e_nvmupd_get_aq_result(struct i40e_hw *hw,
730                                                     struct i40e_nvm_access *cmd,
731                                                     u8 *bytes, int *perrno);
732 STATIC INLINE u8 i40e_nvmupd_get_module(u32 val)
733 {
734         return (u8)(val & I40E_NVM_MOD_PNT_MASK);
735 }
736 STATIC INLINE u8 i40e_nvmupd_get_transaction(u32 val)
737 {
738         return (u8)((val & I40E_NVM_TRANS_MASK) >> I40E_NVM_TRANS_SHIFT);
739 }
740
741 STATIC const char *i40e_nvm_update_state_str[] = {
742         "I40E_NVMUPD_INVALID",
743         "I40E_NVMUPD_READ_CON",
744         "I40E_NVMUPD_READ_SNT",
745         "I40E_NVMUPD_READ_LCB",
746         "I40E_NVMUPD_READ_SA",
747         "I40E_NVMUPD_WRITE_ERA",
748         "I40E_NVMUPD_WRITE_CON",
749         "I40E_NVMUPD_WRITE_SNT",
750         "I40E_NVMUPD_WRITE_LCB",
751         "I40E_NVMUPD_WRITE_SA",
752         "I40E_NVMUPD_CSUM_CON",
753         "I40E_NVMUPD_CSUM_SA",
754         "I40E_NVMUPD_CSUM_LCB",
755         "I40E_NVMUPD_STATUS",
756         "I40E_NVMUPD_EXEC_AQ",
757         "I40E_NVMUPD_GET_AQ_RESULT",
758 };
759
760 /**
761  * i40e_nvmupd_command - Process an NVM update command
762  * @hw: pointer to hardware structure
763  * @cmd: pointer to nvm update command
764  * @bytes: pointer to the data buffer
765  * @perrno: pointer to return error code
766  *
767  * Dispatches command depending on what update state is current
768  **/
769 enum i40e_status_code i40e_nvmupd_command(struct i40e_hw *hw,
770                                           struct i40e_nvm_access *cmd,
771                                           u8 *bytes, int *perrno)
772 {
773         enum i40e_status_code status;
774         enum i40e_nvmupd_cmd upd_cmd;
775
776         DEBUGFUNC("i40e_nvmupd_command");
777
778         /* assume success */
779         *perrno = 0;
780
781         /* early check for status command and debug msgs */
782         upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
783
784         i40e_debug(hw, I40E_DEBUG_NVM, "%s state %d nvm_release_on_hold %d\n",
785                    i40e_nvm_update_state_str[upd_cmd],
786                    hw->nvmupd_state,
787                    hw->aq.nvm_release_on_done);
788
789         if (upd_cmd == I40E_NVMUPD_INVALID) {
790                 *perrno = -EFAULT;
791                 i40e_debug(hw, I40E_DEBUG_NVM,
792                            "i40e_nvmupd_validate_command returns %d errno %d\n",
793                            upd_cmd, *perrno);
794         }
795
796         /* a status request returns immediately rather than
797          * going into the state machine
798          */
799         if (upd_cmd == I40E_NVMUPD_STATUS) {
800                 bytes[0] = hw->nvmupd_state;
801                 return I40E_SUCCESS;
802         }
803
804         switch (hw->nvmupd_state) {
805         case I40E_NVMUPD_STATE_INIT:
806                 status = i40e_nvmupd_state_init(hw, cmd, bytes, perrno);
807                 break;
808
809         case I40E_NVMUPD_STATE_READING:
810                 status = i40e_nvmupd_state_reading(hw, cmd, bytes, perrno);
811                 break;
812
813         case I40E_NVMUPD_STATE_WRITING:
814                 status = i40e_nvmupd_state_writing(hw, cmd, bytes, perrno);
815                 break;
816
817         case I40E_NVMUPD_STATE_INIT_WAIT:
818         case I40E_NVMUPD_STATE_WRITE_WAIT:
819                 status = I40E_ERR_NOT_READY;
820                 *perrno = -EBUSY;
821                 break;
822
823         default:
824                 /* invalid state, should never happen */
825                 i40e_debug(hw, I40E_DEBUG_NVM,
826                            "NVMUPD: no such state %d\n", hw->nvmupd_state);
827                 status = I40E_NOT_SUPPORTED;
828                 *perrno = -ESRCH;
829                 break;
830         }
831         return status;
832 }
833
834 /**
835  * i40e_nvmupd_state_init - Handle NVM update state Init
836  * @hw: pointer to hardware structure
837  * @cmd: pointer to nvm update command buffer
838  * @bytes: pointer to the data buffer
839  * @perrno: pointer to return error code
840  *
841  * Process legitimate commands of the Init state and conditionally set next
842  * state. Reject all other commands.
843  **/
844 STATIC enum i40e_status_code i40e_nvmupd_state_init(struct i40e_hw *hw,
845                                                     struct i40e_nvm_access *cmd,
846                                                     u8 *bytes, int *perrno)
847 {
848         enum i40e_status_code status = I40E_SUCCESS;
849         enum i40e_nvmupd_cmd upd_cmd;
850
851         DEBUGFUNC("i40e_nvmupd_state_init");
852
853         upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
854
855         switch (upd_cmd) {
856         case I40E_NVMUPD_READ_SA:
857                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
858                 if (status) {
859                         *perrno = i40e_aq_rc_to_posix(status,
860                                                      hw->aq.asq_last_status);
861                 } else {
862                         status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno);
863                         i40e_release_nvm(hw);
864                 }
865                 break;
866
867         case I40E_NVMUPD_READ_SNT:
868                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
869                 if (status) {
870                         *perrno = i40e_aq_rc_to_posix(status,
871                                                      hw->aq.asq_last_status);
872                 } else {
873                         status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno);
874                         if (status)
875                                 i40e_release_nvm(hw);
876                         else
877                                 hw->nvmupd_state = I40E_NVMUPD_STATE_READING;
878                 }
879                 break;
880
881         case I40E_NVMUPD_WRITE_ERA:
882                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
883                 if (status) {
884                         *perrno = i40e_aq_rc_to_posix(status,
885                                                      hw->aq.asq_last_status);
886                 } else {
887                         status = i40e_nvmupd_nvm_erase(hw, cmd, perrno);
888                         if (status) {
889                                 i40e_release_nvm(hw);
890                         } else {
891                                 hw->aq.nvm_release_on_done = true;
892                                 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
893                         }
894                 }
895                 break;
896
897         case I40E_NVMUPD_WRITE_SA:
898                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
899                 if (status) {
900                         *perrno = i40e_aq_rc_to_posix(status,
901                                                      hw->aq.asq_last_status);
902                 } else {
903                         status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
904                         if (status) {
905                                 i40e_release_nvm(hw);
906                         } else {
907                                 hw->aq.nvm_release_on_done = true;
908                                 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
909                         }
910                 }
911                 break;
912
913         case I40E_NVMUPD_WRITE_SNT:
914                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
915                 if (status) {
916                         *perrno = i40e_aq_rc_to_posix(status,
917                                                      hw->aq.asq_last_status);
918                 } else {
919                         status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
920                         if (status)
921                                 i40e_release_nvm(hw);
922                         else
923                                 hw->nvmupd_state = I40E_NVMUPD_STATE_WRITE_WAIT;
924                 }
925                 break;
926
927         case I40E_NVMUPD_CSUM_SA:
928                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
929                 if (status) {
930                         *perrno = i40e_aq_rc_to_posix(status,
931                                                      hw->aq.asq_last_status);
932                 } else {
933                         status = i40e_update_nvm_checksum(hw);
934                         if (status) {
935                                 *perrno = hw->aq.asq_last_status ?
936                                    i40e_aq_rc_to_posix(status,
937                                                        hw->aq.asq_last_status) :
938                                    -EIO;
939                                 i40e_release_nvm(hw);
940                         } else {
941                                 hw->aq.nvm_release_on_done = true;
942                                 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
943                         }
944                 }
945                 break;
946
947         case I40E_NVMUPD_EXEC_AQ:
948                 status = i40e_nvmupd_exec_aq(hw, cmd, bytes, perrno);
949                 break;
950
951         case I40E_NVMUPD_GET_AQ_RESULT:
952                 status = i40e_nvmupd_get_aq_result(hw, cmd, bytes, perrno);
953                 break;
954
955         default:
956                 i40e_debug(hw, I40E_DEBUG_NVM,
957                            "NVMUPD: bad cmd %s in init state\n",
958                            i40e_nvm_update_state_str[upd_cmd]);
959                 status = I40E_ERR_NVM;
960                 *perrno = -ESRCH;
961                 break;
962         }
963         return status;
964 }
965
966 /**
967  * i40e_nvmupd_state_reading - Handle NVM update state Reading
968  * @hw: pointer to hardware structure
969  * @cmd: pointer to nvm update command buffer
970  * @bytes: pointer to the data buffer
971  * @perrno: pointer to return error code
972  *
973  * NVM ownership is already held.  Process legitimate commands and set any
974  * change in state; reject all other commands.
975  **/
976 STATIC enum i40e_status_code i40e_nvmupd_state_reading(struct i40e_hw *hw,
977                                                     struct i40e_nvm_access *cmd,
978                                                     u8 *bytes, int *perrno)
979 {
980         enum i40e_status_code status = I40E_SUCCESS;
981         enum i40e_nvmupd_cmd upd_cmd;
982
983         DEBUGFUNC("i40e_nvmupd_state_reading");
984
985         upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
986
987         switch (upd_cmd) {
988         case I40E_NVMUPD_READ_SA:
989         case I40E_NVMUPD_READ_CON:
990                 status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno);
991                 break;
992
993         case I40E_NVMUPD_READ_LCB:
994                 status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno);
995                 i40e_release_nvm(hw);
996                 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
997                 break;
998
999         default:
1000                 i40e_debug(hw, I40E_DEBUG_NVM,
1001                            "NVMUPD: bad cmd %s in reading state.\n",
1002                            i40e_nvm_update_state_str[upd_cmd]);
1003                 status = I40E_NOT_SUPPORTED;
1004                 *perrno = -ESRCH;
1005                 break;
1006         }
1007         return status;
1008 }
1009
1010 /**
1011  * i40e_nvmupd_state_writing - Handle NVM update state Writing
1012  * @hw: pointer to hardware structure
1013  * @cmd: pointer to nvm update command buffer
1014  * @bytes: pointer to the data buffer
1015  * @perrno: pointer to return error code
1016  *
1017  * NVM ownership is already held.  Process legitimate commands and set any
1018  * change in state; reject all other commands
1019  **/
1020 STATIC enum i40e_status_code i40e_nvmupd_state_writing(struct i40e_hw *hw,
1021                                                     struct i40e_nvm_access *cmd,
1022                                                     u8 *bytes, int *perrno)
1023 {
1024         enum i40e_status_code status = I40E_SUCCESS;
1025         enum i40e_nvmupd_cmd upd_cmd;
1026         bool retry_attempt = false;
1027
1028         DEBUGFUNC("i40e_nvmupd_state_writing");
1029
1030         upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
1031
1032 retry:
1033         switch (upd_cmd) {
1034         case I40E_NVMUPD_WRITE_CON:
1035                 status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
1036                 if (!status)
1037                         hw->nvmupd_state = I40E_NVMUPD_STATE_WRITE_WAIT;
1038                 break;
1039
1040         case I40E_NVMUPD_WRITE_LCB:
1041                 status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
1042                 if (status) {
1043                         *perrno = hw->aq.asq_last_status ?
1044                                    i40e_aq_rc_to_posix(status,
1045                                                        hw->aq.asq_last_status) :
1046                                    -EIO;
1047                         hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
1048                 } else {
1049                         hw->aq.nvm_release_on_done = true;
1050                         hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
1051                 }
1052                 break;
1053
1054         case I40E_NVMUPD_CSUM_CON:
1055                 status = i40e_update_nvm_checksum(hw);
1056                 if (status) {
1057                         *perrno = hw->aq.asq_last_status ?
1058                                    i40e_aq_rc_to_posix(status,
1059                                                        hw->aq.asq_last_status) :
1060                                    -EIO;
1061                         hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
1062                 } else {
1063                         hw->nvmupd_state = I40E_NVMUPD_STATE_WRITE_WAIT;
1064                 }
1065                 break;
1066
1067         case I40E_NVMUPD_CSUM_LCB:
1068                 status = i40e_update_nvm_checksum(hw);
1069                 if (status) {
1070                         *perrno = hw->aq.asq_last_status ?
1071                                    i40e_aq_rc_to_posix(status,
1072                                                        hw->aq.asq_last_status) :
1073                                    -EIO;
1074                         hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
1075                 } else {
1076                         hw->aq.nvm_release_on_done = true;
1077                         hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
1078                 }
1079                 break;
1080
1081         default:
1082                 i40e_debug(hw, I40E_DEBUG_NVM,
1083                            "NVMUPD: bad cmd %s in writing state.\n",
1084                            i40e_nvm_update_state_str[upd_cmd]);
1085                 status = I40E_NOT_SUPPORTED;
1086                 *perrno = -ESRCH;
1087                 break;
1088         }
1089
1090         /* In some circumstances, a multi-write transaction takes longer
1091          * than the default 3 minute timeout on the write semaphore.  If
1092          * the write failed with an EBUSY status, this is likely the problem,
1093          * so here we try to reacquire the semaphore then retry the write.
1094          * We only do one retry, then give up.
1095          */
1096         if (status && (hw->aq.asq_last_status == I40E_AQ_RC_EBUSY) &&
1097             !retry_attempt) {
1098                 enum i40e_status_code old_status = status;
1099                 u32 old_asq_status = hw->aq.asq_last_status;
1100                 u32 gtime;
1101
1102                 gtime = rd32(hw, I40E_GLVFGEN_TIMER);
1103                 if (gtime >= hw->nvm.hw_semaphore_timeout) {
1104                         i40e_debug(hw, I40E_DEBUG_ALL,
1105                                    "NVMUPD: write semaphore expired (%d >= %lld), retrying\n",
1106                                    gtime, hw->nvm.hw_semaphore_timeout);
1107                         i40e_release_nvm(hw);
1108                         status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
1109                         if (status) {
1110                                 i40e_debug(hw, I40E_DEBUG_ALL,
1111                                            "NVMUPD: write semaphore reacquire failed aq_err = %d\n",
1112                                            hw->aq.asq_last_status);
1113                                 status = old_status;
1114                                 hw->aq.asq_last_status = old_asq_status;
1115                         } else {
1116                                 retry_attempt = true;
1117                                 goto retry;
1118                         }
1119                 }
1120         }
1121
1122         return status;
1123 }
1124
1125 /**
1126  * i40e_nvmupd_validate_command - Validate given command
1127  * @hw: pointer to hardware structure
1128  * @cmd: pointer to nvm update command buffer
1129  * @perrno: pointer to return error code
1130  *
1131  * Return one of the valid command types or I40E_NVMUPD_INVALID
1132  **/
1133 STATIC enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
1134                                                     struct i40e_nvm_access *cmd,
1135                                                     int *perrno)
1136 {
1137         enum i40e_nvmupd_cmd upd_cmd;
1138         u8 module, transaction;
1139
1140         DEBUGFUNC("i40e_nvmupd_validate_command\n");
1141
1142         /* anything that doesn't match a recognized case is an error */
1143         upd_cmd = I40E_NVMUPD_INVALID;
1144
1145         transaction = i40e_nvmupd_get_transaction(cmd->config);
1146         module = i40e_nvmupd_get_module(cmd->config);
1147
1148         /* limits on data size */
1149         if ((cmd->data_size < 1) ||
1150             (cmd->data_size > I40E_NVMUPD_MAX_DATA)) {
1151                 i40e_debug(hw, I40E_DEBUG_NVM,
1152                            "i40e_nvmupd_validate_command data_size %d\n",
1153                            cmd->data_size);
1154                 *perrno = -EFAULT;
1155                 return I40E_NVMUPD_INVALID;
1156         }
1157
1158         switch (cmd->command) {
1159         case I40E_NVM_READ:
1160                 switch (transaction) {
1161                 case I40E_NVM_CON:
1162                         upd_cmd = I40E_NVMUPD_READ_CON;
1163                         break;
1164                 case I40E_NVM_SNT:
1165                         upd_cmd = I40E_NVMUPD_READ_SNT;
1166                         break;
1167                 case I40E_NVM_LCB:
1168                         upd_cmd = I40E_NVMUPD_READ_LCB;
1169                         break;
1170                 case I40E_NVM_SA:
1171                         upd_cmd = I40E_NVMUPD_READ_SA;
1172                         break;
1173                 case I40E_NVM_EXEC:
1174                         if (module == 0xf)
1175                                 upd_cmd = I40E_NVMUPD_STATUS;
1176                         else if (module == 0)
1177                                 upd_cmd = I40E_NVMUPD_GET_AQ_RESULT;
1178                         break;
1179                 }
1180                 break;
1181
1182         case I40E_NVM_WRITE:
1183                 switch (transaction) {
1184                 case I40E_NVM_CON:
1185                         upd_cmd = I40E_NVMUPD_WRITE_CON;
1186                         break;
1187                 case I40E_NVM_SNT:
1188                         upd_cmd = I40E_NVMUPD_WRITE_SNT;
1189                         break;
1190                 case I40E_NVM_LCB:
1191                         upd_cmd = I40E_NVMUPD_WRITE_LCB;
1192                         break;
1193                 case I40E_NVM_SA:
1194                         upd_cmd = I40E_NVMUPD_WRITE_SA;
1195                         break;
1196                 case I40E_NVM_ERA:
1197                         upd_cmd = I40E_NVMUPD_WRITE_ERA;
1198                         break;
1199                 case I40E_NVM_CSUM:
1200                         upd_cmd = I40E_NVMUPD_CSUM_CON;
1201                         break;
1202                 case (I40E_NVM_CSUM|I40E_NVM_SA):
1203                         upd_cmd = I40E_NVMUPD_CSUM_SA;
1204                         break;
1205                 case (I40E_NVM_CSUM|I40E_NVM_LCB):
1206                         upd_cmd = I40E_NVMUPD_CSUM_LCB;
1207                         break;
1208                 case I40E_NVM_EXEC:
1209                         if (module == 0)
1210                                 upd_cmd = I40E_NVMUPD_EXEC_AQ;
1211                         break;
1212                 }
1213                 break;
1214         }
1215
1216         return upd_cmd;
1217 }
1218
1219 /**
1220  * i40e_nvmupd_exec_aq - Run an AQ command
1221  * @hw: pointer to hardware structure
1222  * @cmd: pointer to nvm update command buffer
1223  * @bytes: pointer to the data buffer
1224  * @perrno: pointer to return error code
1225  *
1226  * cmd structure contains identifiers and data buffer
1227  **/
1228 STATIC enum i40e_status_code i40e_nvmupd_exec_aq(struct i40e_hw *hw,
1229                                                  struct i40e_nvm_access *cmd,
1230                                                  u8 *bytes, int *perrno)
1231 {
1232         struct i40e_asq_cmd_details cmd_details;
1233         enum i40e_status_code status;
1234         struct i40e_aq_desc *aq_desc;
1235         u32 buff_size = 0;
1236         u8 *buff = NULL;
1237         u32 aq_desc_len;
1238         u32 aq_data_len;
1239
1240         i40e_debug(hw, I40E_DEBUG_NVM, "NVMUPD: %s\n", __func__);
1241         memset(&cmd_details, 0, sizeof(cmd_details));
1242         cmd_details.wb_desc = &hw->nvm_wb_desc;
1243
1244         aq_desc_len = sizeof(struct i40e_aq_desc);
1245         memset(&hw->nvm_wb_desc, 0, aq_desc_len);
1246
1247         /* get the aq descriptor */
1248         if (cmd->data_size < aq_desc_len) {
1249                 i40e_debug(hw, I40E_DEBUG_NVM,
1250                            "NVMUPD: not enough aq desc bytes for exec, size %d < %d\n",
1251                            cmd->data_size, aq_desc_len);
1252                 *perrno = -EINVAL;
1253                 return I40E_ERR_PARAM;
1254         }
1255         aq_desc = (struct i40e_aq_desc *)bytes;
1256
1257         /* if data buffer needed, make sure it's ready */
1258         aq_data_len = cmd->data_size - aq_desc_len;
1259         buff_size = max(aq_data_len, (u32)LE16_TO_CPU(aq_desc->datalen));
1260         if (buff_size) {
1261                 if (!hw->nvm_buff.va) {
1262                         status = i40e_allocate_virt_mem(hw, &hw->nvm_buff,
1263                                                         hw->aq.asq_buf_size);
1264                         if (status)
1265                                 i40e_debug(hw, I40E_DEBUG_NVM,
1266                                            "NVMUPD: i40e_allocate_virt_mem for exec buff failed, %d\n",
1267                                            status);
1268                 }
1269
1270                 if (hw->nvm_buff.va) {
1271                         buff = hw->nvm_buff.va;
1272                         memcpy(buff, &bytes[aq_desc_len], aq_data_len);
1273                 }
1274         }
1275
1276         /* and away we go! */
1277         status = i40e_asq_send_command(hw, aq_desc, buff,
1278                                        buff_size, &cmd_details);
1279         if (status) {
1280                 i40e_debug(hw, I40E_DEBUG_NVM,
1281                            "i40e_nvmupd_exec_aq err %s aq_err %s\n",
1282                            i40e_stat_str(hw, status),
1283                            i40e_aq_str(hw, hw->aq.asq_last_status));
1284                 *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
1285         }
1286
1287         return status;
1288 }
1289
1290 /**
1291  * i40e_nvmupd_get_aq_result - Get the results from the previous exec_aq
1292  * @hw: pointer to hardware structure
1293  * @cmd: pointer to nvm update command buffer
1294  * @bytes: pointer to the data buffer
1295  * @perrno: pointer to return error code
1296  *
1297  * cmd structure contains identifiers and data buffer
1298  **/
1299 STATIC enum i40e_status_code i40e_nvmupd_get_aq_result(struct i40e_hw *hw,
1300                                                     struct i40e_nvm_access *cmd,
1301                                                     u8 *bytes, int *perrno)
1302 {
1303         u32 aq_total_len;
1304         u32 aq_desc_len;
1305         int remainder;
1306         u8 *buff;
1307
1308         i40e_debug(hw, I40E_DEBUG_NVM, "NVMUPD: %s\n", __func__);
1309
1310         aq_desc_len = sizeof(struct i40e_aq_desc);
1311         aq_total_len = aq_desc_len + LE16_TO_CPU(hw->nvm_wb_desc.datalen);
1312
1313         /* check offset range */
1314         if (cmd->offset > aq_total_len) {
1315                 i40e_debug(hw, I40E_DEBUG_NVM, "%s: offset too big %d > %d\n",
1316                            __func__, cmd->offset, aq_total_len);
1317                 *perrno = -EINVAL;
1318                 return I40E_ERR_PARAM;
1319         }
1320
1321         /* check copylength range */
1322         if (cmd->data_size > (aq_total_len - cmd->offset)) {
1323                 int new_len = aq_total_len - cmd->offset;
1324
1325                 i40e_debug(hw, I40E_DEBUG_NVM, "%s: copy length %d too big, trimming to %d\n",
1326                            __func__, cmd->data_size, new_len);
1327                 cmd->data_size = new_len;
1328         }
1329
1330         remainder = cmd->data_size;
1331         if (cmd->offset < aq_desc_len) {
1332                 u32 len = aq_desc_len - cmd->offset;
1333
1334                 len = min(len, cmd->data_size);
1335                 i40e_debug(hw, I40E_DEBUG_NVM, "%s: aq_desc bytes %d to %d\n",
1336                            __func__, cmd->offset, cmd->offset + len);
1337
1338                 buff = ((u8 *)&hw->nvm_wb_desc) + cmd->offset;
1339                 memcpy(bytes, buff, len);
1340
1341                 bytes += len;
1342                 remainder -= len;
1343                 buff = hw->nvm_buff.va;
1344         } else {
1345                 buff = (u8 *)hw->nvm_buff.va + (cmd->offset - aq_desc_len);
1346         }
1347
1348         if (remainder > 0) {
1349                 int start_byte = buff - (u8 *)hw->nvm_buff.va;
1350
1351                 i40e_debug(hw, I40E_DEBUG_NVM, "%s: databuf bytes %d to %d\n",
1352                            __func__, start_byte, start_byte + remainder);
1353                 memcpy(bytes, buff, remainder);
1354         }
1355
1356         return I40E_SUCCESS;
1357 }
1358
1359 /**
1360  * i40e_nvmupd_nvm_read - Read NVM
1361  * @hw: pointer to hardware structure
1362  * @cmd: pointer to nvm update command buffer
1363  * @bytes: pointer to the data buffer
1364  * @perrno: pointer to return error code
1365  *
1366  * cmd structure contains identifiers and data buffer
1367  **/
1368 STATIC enum i40e_status_code i40e_nvmupd_nvm_read(struct i40e_hw *hw,
1369                                                   struct i40e_nvm_access *cmd,
1370                                                   u8 *bytes, int *perrno)
1371 {
1372         struct i40e_asq_cmd_details cmd_details;
1373         enum i40e_status_code status;
1374         u8 module, transaction;
1375         bool last;
1376
1377         transaction = i40e_nvmupd_get_transaction(cmd->config);
1378         module = i40e_nvmupd_get_module(cmd->config);
1379         last = (transaction == I40E_NVM_LCB) || (transaction == I40E_NVM_SA);
1380
1381         memset(&cmd_details, 0, sizeof(cmd_details));
1382         cmd_details.wb_desc = &hw->nvm_wb_desc;
1383
1384         status = i40e_aq_read_nvm(hw, module, cmd->offset, (u16)cmd->data_size,
1385                                   bytes, last, &cmd_details);
1386         if (status) {
1387                 i40e_debug(hw, I40E_DEBUG_NVM,
1388                            "i40e_nvmupd_nvm_read mod 0x%x  off 0x%x  len 0x%x\n",
1389                            module, cmd->offset, cmd->data_size);
1390                 i40e_debug(hw, I40E_DEBUG_NVM,
1391                            "i40e_nvmupd_nvm_read status %d aq %d\n",
1392                            status, hw->aq.asq_last_status);
1393                 *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
1394         }
1395
1396         return status;
1397 }
1398
1399 /**
1400  * i40e_nvmupd_nvm_erase - Erase an NVM module
1401  * @hw: pointer to hardware structure
1402  * @cmd: pointer to nvm update command buffer
1403  * @perrno: pointer to return error code
1404  *
1405  * module, offset, data_size and data are in cmd structure
1406  **/
1407 STATIC enum i40e_status_code i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
1408                                                    struct i40e_nvm_access *cmd,
1409                                                    int *perrno)
1410 {
1411         enum i40e_status_code status = I40E_SUCCESS;
1412         struct i40e_asq_cmd_details cmd_details;
1413         u8 module, transaction;
1414         bool last;
1415
1416         transaction = i40e_nvmupd_get_transaction(cmd->config);
1417         module = i40e_nvmupd_get_module(cmd->config);
1418         last = (transaction & I40E_NVM_LCB);
1419
1420         memset(&cmd_details, 0, sizeof(cmd_details));
1421         cmd_details.wb_desc = &hw->nvm_wb_desc;
1422
1423         status = i40e_aq_erase_nvm(hw, module, cmd->offset, (u16)cmd->data_size,
1424                                    last, &cmd_details);
1425         if (status) {
1426                 i40e_debug(hw, I40E_DEBUG_NVM,
1427                            "i40e_nvmupd_nvm_erase mod 0x%x  off 0x%x len 0x%x\n",
1428                            module, cmd->offset, cmd->data_size);
1429                 i40e_debug(hw, I40E_DEBUG_NVM,
1430                            "i40e_nvmupd_nvm_erase status %d aq %d\n",
1431                            status, hw->aq.asq_last_status);
1432                 *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
1433         }
1434
1435         return status;
1436 }
1437
1438 /**
1439  * i40e_nvmupd_nvm_write - Write NVM
1440  * @hw: pointer to hardware structure
1441  * @cmd: pointer to nvm update command buffer
1442  * @bytes: pointer to the data buffer
1443  * @perrno: pointer to return error code
1444  *
1445  * module, offset, data_size and data are in cmd structure
1446  **/
1447 STATIC enum i40e_status_code i40e_nvmupd_nvm_write(struct i40e_hw *hw,
1448                                                    struct i40e_nvm_access *cmd,
1449                                                    u8 *bytes, int *perrno)
1450 {
1451         enum i40e_status_code status = I40E_SUCCESS;
1452         struct i40e_asq_cmd_details cmd_details;
1453         u8 module, transaction;
1454         bool last;
1455
1456         transaction = i40e_nvmupd_get_transaction(cmd->config);
1457         module = i40e_nvmupd_get_module(cmd->config);
1458         last = (transaction & I40E_NVM_LCB);
1459
1460         memset(&cmd_details, 0, sizeof(cmd_details));
1461         cmd_details.wb_desc = &hw->nvm_wb_desc;
1462
1463         status = i40e_aq_update_nvm(hw, module, cmd->offset,
1464                                     (u16)cmd->data_size, bytes, last,
1465                                     &cmd_details);
1466         if (status) {
1467                 i40e_debug(hw, I40E_DEBUG_NVM,
1468                            "i40e_nvmupd_nvm_write mod 0x%x off 0x%x len 0x%x\n",
1469                            module, cmd->offset, cmd->data_size);
1470                 i40e_debug(hw, I40E_DEBUG_NVM,
1471                            "i40e_nvmupd_nvm_write status %d aq %d\n",
1472                            status, hw->aq.asq_last_status);
1473                 *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
1474         }
1475
1476         return status;
1477 }