net/i40e/base: support persistent LLDP
[dpdk.git] / drivers / net / i40e / base / i40e_nvm.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2001-2018
3  */
4
5 #include "i40e_prototype.h"
6
7 /**
8  * i40e_init_nvm_ops - Initialize NVM function pointers
9  * @hw: pointer to the HW structure
10  *
11  * Setup the function pointers and the NVM info structure. Should be called
12  * once per NVM initialization, e.g. inside the i40e_init_shared_code().
13  * Please notice that the NVM term is used here (& in all methods covered
14  * in this file) as an equivalent of the FLASH part mapped into the SR.
15  * We are accessing FLASH always through the Shadow RAM.
16  **/
17 enum i40e_status_code i40e_init_nvm(struct i40e_hw *hw)
18 {
19         struct i40e_nvm_info *nvm = &hw->nvm;
20         enum i40e_status_code ret_code = I40E_SUCCESS;
21         u32 fla, gens;
22         u8 sr_size;
23
24         DEBUGFUNC("i40e_init_nvm");
25
26         /* The SR size is stored regardless of the nvm programming mode
27          * as the blank mode may be used in the factory line.
28          */
29         gens = rd32(hw, I40E_GLNVM_GENS);
30         sr_size = ((gens & I40E_GLNVM_GENS_SR_SIZE_MASK) >>
31                            I40E_GLNVM_GENS_SR_SIZE_SHIFT);
32         /* Switching to words (sr_size contains power of 2KB) */
33         nvm->sr_size = BIT(sr_size) * I40E_SR_WORDS_IN_1KB;
34
35         /* Check if we are in the normal or blank NVM programming mode */
36         fla = rd32(hw, I40E_GLNVM_FLA);
37         if (fla & I40E_GLNVM_FLA_LOCKED_MASK) { /* Normal programming mode */
38                 /* Max NVM timeout */
39                 nvm->timeout = I40E_MAX_NVM_TIMEOUT;
40                 nvm->blank_nvm_mode = false;
41         } else { /* Blank programming mode */
42                 nvm->blank_nvm_mode = true;
43                 ret_code = I40E_ERR_NVM_BLANK_MODE;
44                 i40e_debug(hw, I40E_DEBUG_NVM, "NVM init error: unsupported blank mode.\n");
45         }
46
47         return ret_code;
48 }
49
50 /**
51  * i40e_acquire_nvm - Generic request for acquiring the NVM ownership
52  * @hw: pointer to the HW structure
53  * @access: NVM access type (read or write)
54  *
55  * This function will request NVM ownership for reading
56  * via the proper Admin Command.
57  **/
58 enum i40e_status_code i40e_acquire_nvm(struct i40e_hw *hw,
59                                        enum i40e_aq_resource_access_type access)
60 {
61         enum i40e_status_code ret_code = I40E_SUCCESS;
62         u64 gtime, timeout;
63         u64 time_left = 0;
64
65         DEBUGFUNC("i40e_acquire_nvm");
66
67         if (hw->nvm.blank_nvm_mode)
68                 goto i40e_i40e_acquire_nvm_exit;
69
70         ret_code = i40e_aq_request_resource(hw, I40E_NVM_RESOURCE_ID, access,
71                                             0, &time_left, NULL);
72         /* Reading the Global Device Timer */
73         gtime = rd32(hw, I40E_GLVFGEN_TIMER);
74
75         /* Store the timeout */
76         hw->nvm.hw_semaphore_timeout = I40E_MS_TO_GTIME(time_left) + gtime;
77
78         if (ret_code)
79                 i40e_debug(hw, I40E_DEBUG_NVM,
80                            "NVM acquire type %d failed time_left=%llu ret=%d aq_err=%d\n",
81                            access, time_left, ret_code, hw->aq.asq_last_status);
82
83         if (ret_code && time_left) {
84                 /* Poll until the current NVM owner timeouts */
85                 timeout = I40E_MS_TO_GTIME(I40E_MAX_NVM_TIMEOUT) + gtime;
86                 while ((gtime < timeout) && time_left) {
87                         i40e_msec_delay(10);
88                         gtime = rd32(hw, I40E_GLVFGEN_TIMER);
89                         ret_code = i40e_aq_request_resource(hw,
90                                                         I40E_NVM_RESOURCE_ID,
91                                                         access, 0, &time_left,
92                                                         NULL);
93                         if (ret_code == I40E_SUCCESS) {
94                                 hw->nvm.hw_semaphore_timeout =
95                                             I40E_MS_TO_GTIME(time_left) + gtime;
96                                 break;
97                         }
98                 }
99                 if (ret_code != I40E_SUCCESS) {
100                         hw->nvm.hw_semaphore_timeout = 0;
101                         i40e_debug(hw, I40E_DEBUG_NVM,
102                                    "NVM acquire timed out, wait %llu ms before trying again. status=%d aq_err=%d\n",
103                                    time_left, ret_code, hw->aq.asq_last_status);
104                 }
105         }
106
107 i40e_i40e_acquire_nvm_exit:
108         return ret_code;
109 }
110
111 /**
112  * i40e_release_nvm - Generic request for releasing the NVM ownership
113  * @hw: pointer to the HW structure
114  *
115  * This function will release NVM resource via the proper Admin Command.
116  **/
117 void i40e_release_nvm(struct i40e_hw *hw)
118 {
119         enum i40e_status_code ret_code = I40E_SUCCESS;
120         u32 total_delay = 0;
121
122         DEBUGFUNC("i40e_release_nvm");
123
124         if (hw->nvm.blank_nvm_mode)
125                 return;
126
127         ret_code = i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL);
128
129         /* there are some rare cases when trying to release the resource
130          * results in an admin Q timeout, so handle them correctly
131          */
132         while ((ret_code == I40E_ERR_ADMIN_QUEUE_TIMEOUT) &&
133                (total_delay < hw->aq.asq_cmd_timeout)) {
134                         i40e_msec_delay(1);
135                         ret_code = i40e_aq_release_resource(hw,
136                                                 I40E_NVM_RESOURCE_ID, 0, NULL);
137                         total_delay++;
138         }
139 }
140
141 /**
142  * i40e_poll_sr_srctl_done_bit - Polls the GLNVM_SRCTL done bit
143  * @hw: pointer to the HW structure
144  *
145  * Polls the SRCTL Shadow RAM register done bit.
146  **/
147 static enum i40e_status_code i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw)
148 {
149         enum i40e_status_code ret_code = I40E_ERR_TIMEOUT;
150         u32 srctl, wait_cnt;
151
152         DEBUGFUNC("i40e_poll_sr_srctl_done_bit");
153
154         /* Poll the I40E_GLNVM_SRCTL until the done bit is set */
155         for (wait_cnt = 0; wait_cnt < I40E_SRRD_SRCTL_ATTEMPTS; wait_cnt++) {
156                 srctl = rd32(hw, I40E_GLNVM_SRCTL);
157                 if (srctl & I40E_GLNVM_SRCTL_DONE_MASK) {
158                         ret_code = I40E_SUCCESS;
159                         break;
160                 }
161                 i40e_usec_delay(5);
162         }
163         if (ret_code == I40E_ERR_TIMEOUT)
164                 i40e_debug(hw, I40E_DEBUG_NVM, "Done bit in GLNVM_SRCTL not set");
165         return ret_code;
166 }
167
168 /**
169  * i40e_read_nvm_word_srctl - Reads Shadow RAM via SRCTL register
170  * @hw: pointer to the HW structure
171  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
172  * @data: word read from the Shadow RAM
173  *
174  * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
175  **/
176 STATIC enum i40e_status_code i40e_read_nvm_word_srctl(struct i40e_hw *hw,
177                                                       u16 offset,
178                                                       u16 *data)
179 {
180         enum i40e_status_code ret_code = I40E_ERR_TIMEOUT;
181         u32 sr_reg;
182
183         DEBUGFUNC("i40e_read_nvm_word_srctl");
184
185         if (offset >= hw->nvm.sr_size) {
186                 i40e_debug(hw, I40E_DEBUG_NVM,
187                            "NVM read error: Offset %d beyond Shadow RAM limit %d\n",
188                            offset, hw->nvm.sr_size);
189                 ret_code = I40E_ERR_PARAM;
190                 goto read_nvm_exit;
191         }
192
193         /* Poll the done bit first */
194         ret_code = i40e_poll_sr_srctl_done_bit(hw);
195         if (ret_code == I40E_SUCCESS) {
196                 /* Write the address and start reading */
197                 sr_reg = ((u32)offset << I40E_GLNVM_SRCTL_ADDR_SHIFT) |
198                          BIT(I40E_GLNVM_SRCTL_START_SHIFT);
199                 wr32(hw, I40E_GLNVM_SRCTL, sr_reg);
200
201                 /* Poll I40E_GLNVM_SRCTL until the done bit is set */
202                 ret_code = i40e_poll_sr_srctl_done_bit(hw);
203                 if (ret_code == I40E_SUCCESS) {
204                         sr_reg = rd32(hw, I40E_GLNVM_SRDATA);
205                         *data = (u16)((sr_reg &
206                                        I40E_GLNVM_SRDATA_RDDATA_MASK)
207                                     >> I40E_GLNVM_SRDATA_RDDATA_SHIFT);
208                 }
209         }
210         if (ret_code != I40E_SUCCESS)
211                 i40e_debug(hw, I40E_DEBUG_NVM,
212                            "NVM read error: Couldn't access Shadow RAM address: 0x%x\n",
213                            offset);
214
215 read_nvm_exit:
216         return ret_code;
217 }
218
219 /**
220  * i40e_read_nvm_aq - Read Shadow RAM.
221  * @hw: pointer to the HW structure.
222  * @module_pointer: module pointer location in words from the NVM beginning
223  * @offset: offset in words from module start
224  * @words: number of words to write
225  * @data: buffer with words to write to the Shadow RAM
226  * @last_command: tells the AdminQ that this is the last command
227  *
228  * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
229  **/
230 STATIC enum i40e_status_code i40e_read_nvm_aq(struct i40e_hw *hw,
231                                               u8 module_pointer, u32 offset,
232                                               u16 words, void *data,
233                                               bool last_command)
234 {
235         enum i40e_status_code ret_code = I40E_ERR_NVM;
236         struct i40e_asq_cmd_details cmd_details;
237
238         DEBUGFUNC("i40e_read_nvm_aq");
239
240         memset(&cmd_details, 0, sizeof(cmd_details));
241         cmd_details.wb_desc = &hw->nvm_wb_desc;
242
243         /* Here we are checking the SR limit only for the flat memory model.
244          * We cannot do it for the module-based model, as we did not acquire
245          * the NVM resource yet (we cannot get the module pointer value).
246          * Firmware will check the module-based model.
247          */
248         if ((offset + words) > hw->nvm.sr_size)
249                 i40e_debug(hw, I40E_DEBUG_NVM,
250                            "NVM write error: offset %d beyond Shadow RAM limit %d\n",
251                            (offset + words), hw->nvm.sr_size);
252         else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS)
253                 /* We can write only up to 4KB (one sector), in one AQ write */
254                 i40e_debug(hw, I40E_DEBUG_NVM,
255                            "NVM write fail error: tried to write %d words, limit is %d.\n",
256                            words, I40E_SR_SECTOR_SIZE_IN_WORDS);
257         else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS)
258                  != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS))
259                 /* A single write cannot spread over two sectors */
260                 i40e_debug(hw, I40E_DEBUG_NVM,
261                            "NVM write error: cannot spread over two sectors in a single write offset=%d words=%d\n",
262                            offset, words);
263         else
264                 ret_code = i40e_aq_read_nvm(hw, module_pointer,
265                                             2 * offset,  /*bytes*/
266                                             2 * words,   /*bytes*/
267                                             data, last_command, &cmd_details);
268
269         return ret_code;
270 }
271
272 /**
273  * i40e_read_nvm_word_aq - Reads Shadow RAM via AQ
274  * @hw: pointer to the HW structure
275  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
276  * @data: word read from the Shadow RAM
277  *
278  * Reads one 16 bit word from the Shadow RAM using the AdminQ
279  **/
280 STATIC enum i40e_status_code i40e_read_nvm_word_aq(struct i40e_hw *hw, u16 offset,
281                                                    u16 *data)
282 {
283         enum i40e_status_code ret_code = I40E_ERR_TIMEOUT;
284
285         DEBUGFUNC("i40e_read_nvm_word_aq");
286
287         ret_code = i40e_read_nvm_aq(hw, 0x0, offset, 1, data, true);
288         *data = LE16_TO_CPU(*(__le16 *)data);
289
290         return ret_code;
291 }
292
293 /**
294  * __i40e_read_nvm_word - Reads NVM word, assumes caller does the locking
295  * @hw: pointer to the HW structure
296  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
297  * @data: word read from the Shadow RAM
298  *
299  * Reads one 16 bit word from the Shadow RAM.
300  *
301  * Do not use this function except in cases where the nvm lock is already
302  * taken via i40e_acquire_nvm().
303  **/
304 enum i40e_status_code __i40e_read_nvm_word(struct i40e_hw *hw,
305                                            u16 offset,
306                                            u16 *data)
307 {
308
309         if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE)
310                 return i40e_read_nvm_word_aq(hw, offset, data);
311
312         return i40e_read_nvm_word_srctl(hw, offset, data);
313 }
314
315 /**
316  * i40e_read_nvm_word - Reads NVM word, acquires lock if necessary
317  * @hw: pointer to the HW structure
318  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
319  * @data: word read from the Shadow RAM
320  *
321  * Reads one 16 bit word from the Shadow RAM.
322  **/
323 enum i40e_status_code i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
324                                          u16 *data)
325 {
326         enum i40e_status_code ret_code = I40E_SUCCESS;
327
328         if (hw->flags & I40E_HW_FLAG_NVM_READ_REQUIRES_LOCK)
329                 ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
330
331         if (ret_code)
332                 return ret_code;
333         ret_code = __i40e_read_nvm_word(hw, offset, data);
334
335         if (hw->flags & I40E_HW_FLAG_NVM_READ_REQUIRES_LOCK)
336                 i40e_release_nvm(hw);
337         return ret_code;
338 }
339
340 /**
341  * i40e_read_nvm_module_data - Reads NVM Buffer to specified memory location
342  * @hw: Pointer to the HW structure
343  * @module_ptr: Pointer to module in words with respect to NVM beginning
344  * @module_offset: Offset in words from module start
345  * @data_offset: Offset in words from reading data area start
346  * @words_data_size: Words to read from NVM
347  * @data_ptr: Pointer to memory location where resulting buffer will be stored
348  **/
349 enum i40e_status_code
350 i40e_read_nvm_module_data(struct i40e_hw *hw, u8 module_ptr, u16 module_offset,
351                           u16 data_offset, u16 words_data_size, u16 *data_ptr)
352 {
353         enum i40e_status_code status;
354         u16 specific_ptr = 0;
355         u16 ptr_value = 0;
356         u16 offset = 0;
357
358         if (module_ptr != 0) {
359                 status = i40e_read_nvm_word(hw, module_ptr, &ptr_value);
360                 if (status != I40E_SUCCESS) {
361                         i40e_debug(hw, I40E_DEBUG_ALL,
362                                    "Reading nvm word failed.Error code: %d.\n",
363                                    status);
364                         return I40E_ERR_NVM;
365                 }
366         }
367 #define I40E_NVM_INVALID_PTR_VAL 0x7FFF
368 #define I40E_NVM_INVALID_VAL 0xFFFF
369
370         /* Pointer not initialized */
371         if (ptr_value == I40E_NVM_INVALID_PTR_VAL ||
372             ptr_value == I40E_NVM_INVALID_VAL) {
373                 i40e_debug(hw, I40E_DEBUG_ALL, "Pointer not initialized.\n");
374                 return I40E_ERR_BAD_PTR;
375         }
376
377         /* Check whether the module is in SR mapped area or outside */
378         if (ptr_value & I40E_PTR_TYPE) {
379                 /* Pointer points outside of the Shared RAM mapped area */
380                 i40e_debug(hw, I40E_DEBUG_ALL,
381                            "Reading nvm data failed. Pointer points outside of the Shared RAM mapped area.\n");
382
383                 return I40E_ERR_PARAM;
384         } else {
385                 /* Read from the Shadow RAM */
386
387                 status = i40e_read_nvm_word(hw, ptr_value + module_offset,
388                                             &specific_ptr);
389                 if (status != I40E_SUCCESS) {
390                         i40e_debug(hw, I40E_DEBUG_ALL,
391                                    "Reading nvm word failed.Error code: %d.\n",
392                                    status);
393                         return I40E_ERR_NVM;
394                 }
395
396                 offset = ptr_value + module_offset + specific_ptr +
397                         data_offset;
398
399                 status = i40e_read_nvm_buffer(hw, offset, &words_data_size,
400                                               data_ptr);
401                 if (status != I40E_SUCCESS) {
402                         i40e_debug(hw, I40E_DEBUG_ALL,
403                                    "Reading nvm buffer failed.Error code: %d.\n",
404                                    status);
405                 }
406         }
407
408         return status;
409 }
410
411 /**
412  * i40e_read_nvm_buffer_srctl - Reads Shadow RAM buffer via SRCTL register
413  * @hw: pointer to the HW structure
414  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
415  * @words: (in) number of words to read; (out) number of words actually read
416  * @data: words read from the Shadow RAM
417  *
418  * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd()
419  * method. The buffer read is preceded by the NVM ownership take
420  * and followed by the release.
421  **/
422 STATIC enum i40e_status_code i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
423                                                         u16 *words, u16 *data)
424 {
425         enum i40e_status_code ret_code = I40E_SUCCESS;
426         u16 index, word;
427
428         DEBUGFUNC("i40e_read_nvm_buffer_srctl");
429
430         /* Loop through the selected region */
431         for (word = 0; word < *words; word++) {
432                 index = offset + word;
433                 ret_code = i40e_read_nvm_word_srctl(hw, index, &data[word]);
434                 if (ret_code != I40E_SUCCESS)
435                         break;
436         }
437
438         /* Update the number of words read from the Shadow RAM */
439         *words = word;
440
441         return ret_code;
442 }
443
444 /**
445  * i40e_read_nvm_buffer_aq - Reads Shadow RAM buffer via AQ
446  * @hw: pointer to the HW structure
447  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
448  * @words: (in) number of words to read; (out) number of words actually read
449  * @data: words read from the Shadow RAM
450  *
451  * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_aq()
452  * method. The buffer read is preceded by the NVM ownership take
453  * and followed by the release.
454  **/
455 STATIC enum i40e_status_code i40e_read_nvm_buffer_aq(struct i40e_hw *hw, u16 offset,
456                                                      u16 *words, u16 *data)
457 {
458         enum i40e_status_code ret_code;
459         u16 read_size = *words;
460         bool last_cmd = false;
461         u16 words_read = 0;
462         u16 i = 0;
463
464         DEBUGFUNC("i40e_read_nvm_buffer_aq");
465
466         do {
467                 /* Calculate number of bytes we should read in this step.
468                  * FVL AQ do not allow to read more than one page at a time or
469                  * to cross page boundaries.
470                  */
471                 if (offset % I40E_SR_SECTOR_SIZE_IN_WORDS)
472                         read_size = min(*words,
473                                         (u16)(I40E_SR_SECTOR_SIZE_IN_WORDS -
474                                       (offset % I40E_SR_SECTOR_SIZE_IN_WORDS)));
475                 else
476                         read_size = min((*words - words_read),
477                                         I40E_SR_SECTOR_SIZE_IN_WORDS);
478
479                 /* Check if this is last command, if so set proper flag */
480                 if ((words_read + read_size) >= *words)
481                         last_cmd = true;
482
483                 ret_code = i40e_read_nvm_aq(hw, 0x0, offset, read_size,
484                                             data + words_read, last_cmd);
485                 if (ret_code != I40E_SUCCESS)
486                         goto read_nvm_buffer_aq_exit;
487
488                 /* Increment counter for words already read and move offset to
489                  * new read location
490                  */
491                 words_read += read_size;
492                 offset += read_size;
493         } while (words_read < *words);
494
495         for (i = 0; i < *words; i++)
496                 data[i] = LE16_TO_CPU(((__le16 *)data)[i]);
497
498 read_nvm_buffer_aq_exit:
499         *words = words_read;
500         return ret_code;
501 }
502
503 /**
504  * __i40e_read_nvm_buffer - Reads NVM buffer, caller must acquire lock
505  * @hw: pointer to the HW structure
506  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
507  * @words: (in) number of words to read; (out) number of words actually read
508  * @data: words read from the Shadow RAM
509  *
510  * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd()
511  * method.
512  **/
513 enum i40e_status_code __i40e_read_nvm_buffer(struct i40e_hw *hw,
514                                              u16 offset,
515                                              u16 *words, u16 *data)
516 {
517         if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE)
518                 return i40e_read_nvm_buffer_aq(hw, offset, words, data);
519
520         return i40e_read_nvm_buffer_srctl(hw, offset, words, data);
521 }
522
523 /**
524  * i40e_read_nvm_buffer - Reads Shadow RAM buffer and acquire lock if necessary
525  * @hw: pointer to the HW structure
526  * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
527  * @words: (in) number of words to read; (out) number of words actually read
528  * @data: words read from the Shadow RAM
529  *
530  * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd()
531  * method. The buffer read is preceded by the NVM ownership take
532  * and followed by the release.
533  **/
534 enum i40e_status_code i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
535                                            u16 *words, u16 *data)
536 {
537         enum i40e_status_code ret_code = I40E_SUCCESS;
538
539         if (hw->flags & I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE) {
540                 ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
541                 if (!ret_code) {
542                         ret_code = i40e_read_nvm_buffer_aq(hw, offset, words,
543                                                          data);
544                         i40e_release_nvm(hw);
545                 }
546         } else {
547                 ret_code = i40e_read_nvm_buffer_srctl(hw, offset, words, data);
548         }
549
550         return ret_code;
551 }
552
553 /**
554  * i40e_write_nvm_aq - Writes Shadow RAM.
555  * @hw: pointer to the HW structure.
556  * @module_pointer: module pointer location in words from the NVM beginning
557  * @offset: offset in words from module start
558  * @words: number of words to write
559  * @data: buffer with words to write to the Shadow RAM
560  * @last_command: tells the AdminQ that this is the last command
561  *
562  * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
563  **/
564 enum i40e_status_code i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
565                                         u32 offset, u16 words, void *data,
566                                         bool last_command)
567 {
568         enum i40e_status_code ret_code = I40E_ERR_NVM;
569         struct i40e_asq_cmd_details cmd_details;
570
571         DEBUGFUNC("i40e_write_nvm_aq");
572
573         memset(&cmd_details, 0, sizeof(cmd_details));
574         cmd_details.wb_desc = &hw->nvm_wb_desc;
575
576         /* Here we are checking the SR limit only for the flat memory model.
577          * We cannot do it for the module-based model, as we did not acquire
578          * the NVM resource yet (we cannot get the module pointer value).
579          * Firmware will check the module-based model.
580          */
581         if ((offset + words) > hw->nvm.sr_size)
582                 DEBUGOUT("NVM write error: offset beyond Shadow RAM limit.\n");
583         else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS)
584                 /* We can write only up to 4KB (one sector), in one AQ write */
585                 DEBUGOUT("NVM write fail error: cannot write more than 4KB in a single write.\n");
586         else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS)
587                  != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS))
588                 /* A single write cannot spread over two sectors */
589                 DEBUGOUT("NVM write error: cannot spread over two sectors in a single write.\n");
590         else
591                 ret_code = i40e_aq_update_nvm(hw, module_pointer,
592                                               2 * offset,  /*bytes*/
593                                               2 * words,   /*bytes*/
594                                               data, last_command, 0,
595                                               &cmd_details);
596
597         return ret_code;
598 }
599
600 /**
601  * __i40e_write_nvm_word - Writes Shadow RAM word
602  * @hw: pointer to the HW structure
603  * @offset: offset of the Shadow RAM word to write
604  * @data: word to write to the Shadow RAM
605  *
606  * Writes a 16 bit word to the SR using the i40e_write_nvm_aq() method.
607  * NVM ownership have to be acquired and released (on ARQ completion event
608  * reception) by caller. To commit SR to NVM update checksum function
609  * should be called.
610  **/
611 enum i40e_status_code __i40e_write_nvm_word(struct i40e_hw *hw, u32 offset,
612                                             void *data)
613 {
614         DEBUGFUNC("i40e_write_nvm_word");
615
616         *((__le16 *)data) = CPU_TO_LE16(*((u16 *)data));
617
618         /* Value 0x00 below means that we treat SR as a flat mem */
619         return i40e_write_nvm_aq(hw, 0x00, offset, 1, data, false);
620 }
621
622 /**
623  * __i40e_write_nvm_buffer - Writes Shadow RAM buffer
624  * @hw: pointer to the HW structure
625  * @module_pointer: module pointer location in words from the NVM beginning
626  * @offset: offset of the Shadow RAM buffer to write
627  * @words: number of words to write
628  * @data: words to write to the Shadow RAM
629  *
630  * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
631  * NVM ownership must be acquired before calling this function and released
632  * on ARQ completion event reception by caller. To commit SR to NVM update
633  * checksum function should be called.
634  **/
635 enum i40e_status_code __i40e_write_nvm_buffer(struct i40e_hw *hw,
636                                               u8 module_pointer, u32 offset,
637                                               u16 words, void *data)
638 {
639         __le16 *le_word_ptr = (__le16 *)data;
640         u16 *word_ptr = (u16 *)data;
641         u32 i = 0;
642
643         DEBUGFUNC("i40e_write_nvm_buffer");
644
645         for (i = 0; i < words; i++)
646                 le_word_ptr[i] = CPU_TO_LE16(word_ptr[i]);
647
648         /* Here we will only write one buffer as the size of the modules
649          * mirrored in the Shadow RAM is always less than 4K.
650          */
651         return i40e_write_nvm_aq(hw, module_pointer, offset, words,
652                                  data, false);
653 }
654
655 /**
656  * i40e_calc_nvm_checksum - Calculates and returns the checksum
657  * @hw: pointer to hardware structure
658  * @checksum: pointer to the checksum
659  *
660  * This function calculates SW Checksum that covers the whole 64kB shadow RAM
661  * except the VPD and PCIe ALT Auto-load modules. The structure and size of VPD
662  * is customer specific and unknown. Therefore, this function skips all maximum
663  * possible size of VPD (1kB).
664  **/
665 enum i40e_status_code i40e_calc_nvm_checksum(struct i40e_hw *hw, u16 *checksum)
666 {
667         enum i40e_status_code ret_code = I40E_SUCCESS;
668         struct i40e_virt_mem vmem;
669         u16 pcie_alt_module = 0;
670         u16 checksum_local = 0;
671         u16 vpd_module = 0;
672         u16 *data;
673         u16 i = 0;
674
675         DEBUGFUNC("i40e_calc_nvm_checksum");
676
677         ret_code = i40e_allocate_virt_mem(hw, &vmem,
678                                     I40E_SR_SECTOR_SIZE_IN_WORDS * sizeof(u16));
679         if (ret_code)
680                 goto i40e_calc_nvm_checksum_exit;
681         data = (u16 *)vmem.va;
682
683         /* read pointer to VPD area */
684         ret_code = __i40e_read_nvm_word(hw, I40E_SR_VPD_PTR, &vpd_module);
685         if (ret_code != I40E_SUCCESS) {
686                 ret_code = I40E_ERR_NVM_CHECKSUM;
687                 goto i40e_calc_nvm_checksum_exit;
688         }
689
690         /* read pointer to PCIe Alt Auto-load module */
691         ret_code = __i40e_read_nvm_word(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR,
692                                         &pcie_alt_module);
693         if (ret_code != I40E_SUCCESS) {
694                 ret_code = I40E_ERR_NVM_CHECKSUM;
695                 goto i40e_calc_nvm_checksum_exit;
696         }
697
698         /* Calculate SW checksum that covers the whole 64kB shadow RAM
699          * except the VPD and PCIe ALT Auto-load modules
700          */
701         for (i = 0; i < hw->nvm.sr_size; i++) {
702                 /* Read SR page */
703                 if ((i % I40E_SR_SECTOR_SIZE_IN_WORDS) == 0) {
704                         u16 words = I40E_SR_SECTOR_SIZE_IN_WORDS;
705
706                         ret_code = __i40e_read_nvm_buffer(hw, i, &words, data);
707                         if (ret_code != I40E_SUCCESS) {
708                                 ret_code = I40E_ERR_NVM_CHECKSUM;
709                                 goto i40e_calc_nvm_checksum_exit;
710                         }
711                 }
712
713                 /* Skip Checksum word */
714                 if (i == I40E_SR_SW_CHECKSUM_WORD)
715                         continue;
716                 /* Skip VPD module (convert byte size to word count) */
717                 if ((i >= (u32)vpd_module) &&
718                     (i < ((u32)vpd_module +
719                      (I40E_SR_VPD_MODULE_MAX_SIZE / 2)))) {
720                         continue;
721                 }
722                 /* Skip PCIe ALT module (convert byte size to word count) */
723                 if ((i >= (u32)pcie_alt_module) &&
724                     (i < ((u32)pcie_alt_module +
725                      (I40E_SR_PCIE_ALT_MODULE_MAX_SIZE / 2)))) {
726                         continue;
727                 }
728
729                 checksum_local += data[i % I40E_SR_SECTOR_SIZE_IN_WORDS];
730         }
731
732         *checksum = (u16)I40E_SR_SW_CHECKSUM_BASE - checksum_local;
733
734 i40e_calc_nvm_checksum_exit:
735         i40e_free_virt_mem(hw, &vmem);
736         return ret_code;
737 }
738
739 /**
740  * i40e_update_nvm_checksum - Updates the NVM checksum
741  * @hw: pointer to hardware structure
742  *
743  * NVM ownership must be acquired before calling this function and released
744  * on ARQ completion event reception by caller.
745  * This function will commit SR to NVM.
746  **/
747 enum i40e_status_code i40e_update_nvm_checksum(struct i40e_hw *hw)
748 {
749         enum i40e_status_code ret_code = I40E_SUCCESS;
750         u16 checksum;
751         __le16 le_sum;
752
753         DEBUGFUNC("i40e_update_nvm_checksum");
754
755         ret_code = i40e_calc_nvm_checksum(hw, &checksum);
756         le_sum = CPU_TO_LE16(checksum);
757         if (ret_code == I40E_SUCCESS)
758                 ret_code = i40e_write_nvm_aq(hw, 0x00, I40E_SR_SW_CHECKSUM_WORD,
759                                              1, &le_sum, true);
760
761         return ret_code;
762 }
763
764 /**
765  * i40e_validate_nvm_checksum - Validate EEPROM checksum
766  * @hw: pointer to hardware structure
767  * @checksum: calculated checksum
768  *
769  * Performs checksum calculation and validates the NVM SW checksum. If the
770  * caller does not need checksum, the value can be NULL.
771  **/
772 enum i40e_status_code i40e_validate_nvm_checksum(struct i40e_hw *hw,
773                                                  u16 *checksum)
774 {
775         enum i40e_status_code ret_code = I40E_SUCCESS;
776         u16 checksum_sr = 0;
777         u16 checksum_local = 0;
778
779         DEBUGFUNC("i40e_validate_nvm_checksum");
780
781         /* We must acquire the NVM lock in order to correctly synchronize the
782          * NVM accesses across multiple PFs. Without doing so it is possible
783          * for one of the PFs to read invalid data potentially indicating that
784          * the checksum is invalid.
785          */
786         ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
787         if (ret_code)
788                 return ret_code;
789         ret_code = i40e_calc_nvm_checksum(hw, &checksum_local);
790         __i40e_read_nvm_word(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr);
791         i40e_release_nvm(hw);
792         if (ret_code)
793                 return ret_code;
794
795         /* Verify read checksum from EEPROM is the same as
796          * calculated checksum
797          */
798         if (checksum_local != checksum_sr)
799                 ret_code = I40E_ERR_NVM_CHECKSUM;
800
801         /* If the user cares, return the calculated checksum */
802         if (checksum)
803                 *checksum = checksum_local;
804
805         return ret_code;
806 }
807
808 STATIC enum i40e_status_code i40e_nvmupd_state_init(struct i40e_hw *hw,
809                                                     struct i40e_nvm_access *cmd,
810                                                     u8 *bytes, int *perrno);
811 STATIC enum i40e_status_code i40e_nvmupd_state_reading(struct i40e_hw *hw,
812                                                     struct i40e_nvm_access *cmd,
813                                                     u8 *bytes, int *perrno);
814 STATIC enum i40e_status_code i40e_nvmupd_state_writing(struct i40e_hw *hw,
815                                                     struct i40e_nvm_access *cmd,
816                                                     u8 *bytes, int *perrno);
817 STATIC enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
818                                                     struct i40e_nvm_access *cmd,
819                                                     int *perrno);
820 STATIC enum i40e_status_code i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
821                                                    struct i40e_nvm_access *cmd,
822                                                    int *perrno);
823 STATIC enum i40e_status_code i40e_nvmupd_nvm_write(struct i40e_hw *hw,
824                                                    struct i40e_nvm_access *cmd,
825                                                    u8 *bytes, int *perrno);
826 STATIC enum i40e_status_code i40e_nvmupd_nvm_read(struct i40e_hw *hw,
827                                                   struct i40e_nvm_access *cmd,
828                                                   u8 *bytes, int *perrno);
829 STATIC enum i40e_status_code i40e_nvmupd_exec_aq(struct i40e_hw *hw,
830                                                  struct i40e_nvm_access *cmd,
831                                                  u8 *bytes, int *perrno);
832 STATIC enum i40e_status_code i40e_nvmupd_get_aq_result(struct i40e_hw *hw,
833                                                     struct i40e_nvm_access *cmd,
834                                                     u8 *bytes, int *perrno);
835 STATIC enum i40e_status_code i40e_nvmupd_get_aq_event(struct i40e_hw *hw,
836                                                     struct i40e_nvm_access *cmd,
837                                                     u8 *bytes, int *perrno);
838 STATIC INLINE u8 i40e_nvmupd_get_module(u32 val)
839 {
840         return (u8)(val & I40E_NVM_MOD_PNT_MASK);
841 }
842 STATIC INLINE u8 i40e_nvmupd_get_transaction(u32 val)
843 {
844         return (u8)((val & I40E_NVM_TRANS_MASK) >> I40E_NVM_TRANS_SHIFT);
845 }
846
847 STATIC INLINE u8 i40e_nvmupd_get_preservation_flags(u32 val)
848 {
849         return (u8)((val & I40E_NVM_PRESERVATION_FLAGS_MASK) >>
850                     I40E_NVM_PRESERVATION_FLAGS_SHIFT);
851 }
852
853 STATIC const char *i40e_nvm_update_state_str[] = {
854         "I40E_NVMUPD_INVALID",
855         "I40E_NVMUPD_READ_CON",
856         "I40E_NVMUPD_READ_SNT",
857         "I40E_NVMUPD_READ_LCB",
858         "I40E_NVMUPD_READ_SA",
859         "I40E_NVMUPD_WRITE_ERA",
860         "I40E_NVMUPD_WRITE_CON",
861         "I40E_NVMUPD_WRITE_SNT",
862         "I40E_NVMUPD_WRITE_LCB",
863         "I40E_NVMUPD_WRITE_SA",
864         "I40E_NVMUPD_CSUM_CON",
865         "I40E_NVMUPD_CSUM_SA",
866         "I40E_NVMUPD_CSUM_LCB",
867         "I40E_NVMUPD_STATUS",
868         "I40E_NVMUPD_EXEC_AQ",
869         "I40E_NVMUPD_GET_AQ_RESULT",
870         "I40E_NVMUPD_GET_AQ_EVENT",
871         "I40E_NVMUPD_GET_FEATURES",
872 };
873
874 /**
875  * i40e_nvmupd_command - Process an NVM update command
876  * @hw: pointer to hardware structure
877  * @cmd: pointer to nvm update command
878  * @bytes: pointer to the data buffer
879  * @perrno: pointer to return error code
880  *
881  * Dispatches command depending on what update state is current
882  **/
883 enum i40e_status_code i40e_nvmupd_command(struct i40e_hw *hw,
884                                           struct i40e_nvm_access *cmd,
885                                           u8 *bytes, int *perrno)
886 {
887         enum i40e_status_code status;
888         enum i40e_nvmupd_cmd upd_cmd;
889
890         DEBUGFUNC("i40e_nvmupd_command");
891
892         /* assume success */
893         *perrno = 0;
894
895         /* early check for status command and debug msgs */
896         upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
897
898         i40e_debug(hw, I40E_DEBUG_NVM, "%s state %d nvm_release_on_hold %d opc 0x%04x cmd 0x%08x config 0x%08x offset 0x%08x data_size 0x%08x\n",
899                    i40e_nvm_update_state_str[upd_cmd],
900                    hw->nvmupd_state,
901                    hw->nvm_release_on_done, hw->nvm_wait_opcode,
902                    cmd->command, cmd->config, cmd->offset, cmd->data_size);
903
904         if (upd_cmd == I40E_NVMUPD_INVALID) {
905                 *perrno = -EFAULT;
906                 i40e_debug(hw, I40E_DEBUG_NVM,
907                            "i40e_nvmupd_validate_command returns %d errno %d\n",
908                            upd_cmd, *perrno);
909         }
910
911         /* a status request returns immediately rather than
912          * going into the state machine
913          */
914         if (upd_cmd == I40E_NVMUPD_STATUS) {
915                 if (!cmd->data_size) {
916                         *perrno = -EFAULT;
917                         return I40E_ERR_BUF_TOO_SHORT;
918                 }
919
920                 bytes[0] = hw->nvmupd_state;
921
922                 if (cmd->data_size >= 4) {
923                         bytes[1] = 0;
924                         *((u16 *)&bytes[2]) = hw->nvm_wait_opcode;
925                 }
926
927                 /* Clear error status on read */
928                 if (hw->nvmupd_state == I40E_NVMUPD_STATE_ERROR)
929                         hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
930
931                 return I40E_SUCCESS;
932         }
933
934         /*
935          * A supported features request returns immediately
936          * rather than going into state machine
937          */
938         if (upd_cmd == I40E_NVMUPD_FEATURES) {
939                 if (cmd->data_size < hw->nvmupd_features.size) {
940                         *perrno = -EFAULT;
941                         return I40E_ERR_BUF_TOO_SHORT;
942                 }
943
944                 /*
945                  * If buffer is bigger than i40e_nvmupd_features structure,
946                  * make sure the trailing bytes are set to 0x0.
947                  */
948                 if (cmd->data_size > hw->nvmupd_features.size)
949                         i40e_memset(bytes + hw->nvmupd_features.size, 0x0,
950                                     cmd->data_size - hw->nvmupd_features.size,
951                                     I40E_NONDMA_MEM);
952
953                 i40e_memcpy(bytes, &hw->nvmupd_features,
954                             hw->nvmupd_features.size, I40E_NONDMA_MEM);
955
956                 return I40E_SUCCESS;
957         }
958
959         /* Clear status even it is not read and log */
960         if (hw->nvmupd_state == I40E_NVMUPD_STATE_ERROR) {
961                 i40e_debug(hw, I40E_DEBUG_NVM,
962                            "Clearing I40E_NVMUPD_STATE_ERROR state without reading\n");
963                 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
964         }
965
966         /* Acquire lock to prevent race condition where adminq_task
967          * can execute after i40e_nvmupd_nvm_read/write but before state
968          * variables (nvm_wait_opcode, nvm_release_on_done) are updated.
969          *
970          * During NVMUpdate, it is observed that lock could be held for
971          * ~5ms for most commands. However lock is held for ~60ms for
972          * NVMUPD_CSUM_LCB command.
973          */
974         i40e_acquire_spinlock(&hw->aq.arq_spinlock);
975         switch (hw->nvmupd_state) {
976         case I40E_NVMUPD_STATE_INIT:
977                 status = i40e_nvmupd_state_init(hw, cmd, bytes, perrno);
978                 break;
979
980         case I40E_NVMUPD_STATE_READING:
981                 status = i40e_nvmupd_state_reading(hw, cmd, bytes, perrno);
982                 break;
983
984         case I40E_NVMUPD_STATE_WRITING:
985                 status = i40e_nvmupd_state_writing(hw, cmd, bytes, perrno);
986                 break;
987
988         case I40E_NVMUPD_STATE_INIT_WAIT:
989         case I40E_NVMUPD_STATE_WRITE_WAIT:
990                 /* if we need to stop waiting for an event, clear
991                  * the wait info and return before doing anything else
992                  */
993                 if (cmd->offset == 0xffff) {
994                         i40e_nvmupd_clear_wait_state(hw);
995                         status = I40E_SUCCESS;
996                         break;
997                 }
998
999                 status = I40E_ERR_NOT_READY;
1000                 *perrno = -EBUSY;
1001                 break;
1002
1003         default:
1004                 /* invalid state, should never happen */
1005                 i40e_debug(hw, I40E_DEBUG_NVM,
1006                            "NVMUPD: no such state %d\n", hw->nvmupd_state);
1007                 status = I40E_NOT_SUPPORTED;
1008                 *perrno = -ESRCH;
1009                 break;
1010         }
1011
1012         i40e_release_spinlock(&hw->aq.arq_spinlock);
1013         return status;
1014 }
1015
1016 /**
1017  * i40e_nvmupd_state_init - Handle NVM update state Init
1018  * @hw: pointer to hardware structure
1019  * @cmd: pointer to nvm update command buffer
1020  * @bytes: pointer to the data buffer
1021  * @perrno: pointer to return error code
1022  *
1023  * Process legitimate commands of the Init state and conditionally set next
1024  * state. Reject all other commands.
1025  **/
1026 STATIC enum i40e_status_code i40e_nvmupd_state_init(struct i40e_hw *hw,
1027                                                     struct i40e_nvm_access *cmd,
1028                                                     u8 *bytes, int *perrno)
1029 {
1030         enum i40e_status_code status = I40E_SUCCESS;
1031         enum i40e_nvmupd_cmd upd_cmd;
1032
1033         DEBUGFUNC("i40e_nvmupd_state_init");
1034
1035         upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
1036
1037         switch (upd_cmd) {
1038         case I40E_NVMUPD_READ_SA:
1039                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
1040                 if (status) {
1041                         *perrno = i40e_aq_rc_to_posix(status,
1042                                                      hw->aq.asq_last_status);
1043                 } else {
1044                         status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno);
1045                         i40e_release_nvm(hw);
1046                 }
1047                 break;
1048
1049         case I40E_NVMUPD_READ_SNT:
1050                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
1051                 if (status) {
1052                         *perrno = i40e_aq_rc_to_posix(status,
1053                                                      hw->aq.asq_last_status);
1054                 } else {
1055                         status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno);
1056                         if (status)
1057                                 i40e_release_nvm(hw);
1058                         else
1059                                 hw->nvmupd_state = I40E_NVMUPD_STATE_READING;
1060                 }
1061                 break;
1062
1063         case I40E_NVMUPD_WRITE_ERA:
1064                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
1065                 if (status) {
1066                         *perrno = i40e_aq_rc_to_posix(status,
1067                                                      hw->aq.asq_last_status);
1068                 } else {
1069                         status = i40e_nvmupd_nvm_erase(hw, cmd, perrno);
1070                         if (status) {
1071                                 i40e_release_nvm(hw);
1072                         } else {
1073                                 hw->nvm_release_on_done = true;
1074                                 hw->nvm_wait_opcode = i40e_aqc_opc_nvm_erase;
1075                                 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
1076                         }
1077                 }
1078                 break;
1079
1080         case I40E_NVMUPD_WRITE_SA:
1081                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
1082                 if (status) {
1083                         *perrno = i40e_aq_rc_to_posix(status,
1084                                                      hw->aq.asq_last_status);
1085                 } else {
1086                         status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
1087                         if (status) {
1088                                 i40e_release_nvm(hw);
1089                         } else {
1090                                 hw->nvm_release_on_done = true;
1091                                 hw->nvm_wait_opcode = i40e_aqc_opc_nvm_update;
1092                                 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
1093                         }
1094                 }
1095                 break;
1096
1097         case I40E_NVMUPD_WRITE_SNT:
1098                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
1099                 if (status) {
1100                         *perrno = i40e_aq_rc_to_posix(status,
1101                                                      hw->aq.asq_last_status);
1102                 } else {
1103                         status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
1104                         if (status) {
1105                                 i40e_release_nvm(hw);
1106                         } else {
1107                                 hw->nvm_wait_opcode = i40e_aqc_opc_nvm_update;
1108                                 hw->nvmupd_state = I40E_NVMUPD_STATE_WRITE_WAIT;
1109                         }
1110                 }
1111                 break;
1112
1113         case I40E_NVMUPD_CSUM_SA:
1114                 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
1115                 if (status) {
1116                         *perrno = i40e_aq_rc_to_posix(status,
1117                                                      hw->aq.asq_last_status);
1118                 } else {
1119                         status = i40e_update_nvm_checksum(hw);
1120                         if (status) {
1121                                 *perrno = hw->aq.asq_last_status ?
1122                                    i40e_aq_rc_to_posix(status,
1123                                                        hw->aq.asq_last_status) :
1124                                    -EIO;
1125                                 i40e_release_nvm(hw);
1126                         } else {
1127                                 hw->nvm_release_on_done = true;
1128                                 hw->nvm_wait_opcode = i40e_aqc_opc_nvm_update;
1129                                 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
1130                         }
1131                 }
1132                 break;
1133
1134         case I40E_NVMUPD_EXEC_AQ:
1135                 status = i40e_nvmupd_exec_aq(hw, cmd, bytes, perrno);
1136                 break;
1137
1138         case I40E_NVMUPD_GET_AQ_RESULT:
1139                 status = i40e_nvmupd_get_aq_result(hw, cmd, bytes, perrno);
1140                 break;
1141
1142         case I40E_NVMUPD_GET_AQ_EVENT:
1143                 status = i40e_nvmupd_get_aq_event(hw, cmd, bytes, perrno);
1144                 break;
1145
1146         default:
1147                 i40e_debug(hw, I40E_DEBUG_NVM,
1148                            "NVMUPD: bad cmd %s in init state\n",
1149                            i40e_nvm_update_state_str[upd_cmd]);
1150                 status = I40E_ERR_NVM;
1151                 *perrno = -ESRCH;
1152                 break;
1153         }
1154         return status;
1155 }
1156
1157 /**
1158  * i40e_nvmupd_state_reading - Handle NVM update state Reading
1159  * @hw: pointer to hardware structure
1160  * @cmd: pointer to nvm update command buffer
1161  * @bytes: pointer to the data buffer
1162  * @perrno: pointer to return error code
1163  *
1164  * NVM ownership is already held.  Process legitimate commands and set any
1165  * change in state; reject all other commands.
1166  **/
1167 STATIC enum i40e_status_code i40e_nvmupd_state_reading(struct i40e_hw *hw,
1168                                                     struct i40e_nvm_access *cmd,
1169                                                     u8 *bytes, int *perrno)
1170 {
1171         enum i40e_status_code status = I40E_SUCCESS;
1172         enum i40e_nvmupd_cmd upd_cmd;
1173
1174         DEBUGFUNC("i40e_nvmupd_state_reading");
1175
1176         upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
1177
1178         switch (upd_cmd) {
1179         case I40E_NVMUPD_READ_SA:
1180         case I40E_NVMUPD_READ_CON:
1181                 status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno);
1182                 break;
1183
1184         case I40E_NVMUPD_READ_LCB:
1185                 status = i40e_nvmupd_nvm_read(hw, cmd, bytes, perrno);
1186                 i40e_release_nvm(hw);
1187                 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
1188                 break;
1189
1190         default:
1191                 i40e_debug(hw, I40E_DEBUG_NVM,
1192                            "NVMUPD: bad cmd %s in reading state.\n",
1193                            i40e_nvm_update_state_str[upd_cmd]);
1194                 status = I40E_NOT_SUPPORTED;
1195                 *perrno = -ESRCH;
1196                 break;
1197         }
1198         return status;
1199 }
1200
1201 /**
1202  * i40e_nvmupd_state_writing - Handle NVM update state Writing
1203  * @hw: pointer to hardware structure
1204  * @cmd: pointer to nvm update command buffer
1205  * @bytes: pointer to the data buffer
1206  * @perrno: pointer to return error code
1207  *
1208  * NVM ownership is already held.  Process legitimate commands and set any
1209  * change in state; reject all other commands
1210  **/
1211 STATIC enum i40e_status_code i40e_nvmupd_state_writing(struct i40e_hw *hw,
1212                                                     struct i40e_nvm_access *cmd,
1213                                                     u8 *bytes, int *perrno)
1214 {
1215         enum i40e_status_code status = I40E_SUCCESS;
1216         enum i40e_nvmupd_cmd upd_cmd;
1217         bool retry_attempt = false;
1218
1219         DEBUGFUNC("i40e_nvmupd_state_writing");
1220
1221         upd_cmd = i40e_nvmupd_validate_command(hw, cmd, perrno);
1222
1223 retry:
1224         switch (upd_cmd) {
1225         case I40E_NVMUPD_WRITE_CON:
1226                 status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
1227                 if (!status) {
1228                         hw->nvm_wait_opcode = i40e_aqc_opc_nvm_update;
1229                         hw->nvmupd_state = I40E_NVMUPD_STATE_WRITE_WAIT;
1230                 }
1231                 break;
1232
1233         case I40E_NVMUPD_WRITE_LCB:
1234                 status = i40e_nvmupd_nvm_write(hw, cmd, bytes, perrno);
1235                 if (status) {
1236                         *perrno = hw->aq.asq_last_status ?
1237                                    i40e_aq_rc_to_posix(status,
1238                                                        hw->aq.asq_last_status) :
1239                                    -EIO;
1240                         hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
1241                 } else {
1242                         hw->nvm_release_on_done = true;
1243                         hw->nvm_wait_opcode = i40e_aqc_opc_nvm_update;
1244                         hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
1245                 }
1246                 break;
1247
1248         case I40E_NVMUPD_CSUM_CON:
1249                 /* Assumes the caller has acquired the nvm */
1250                 status = i40e_update_nvm_checksum(hw);
1251                 if (status) {
1252                         *perrno = hw->aq.asq_last_status ?
1253                                    i40e_aq_rc_to_posix(status,
1254                                                        hw->aq.asq_last_status) :
1255                                    -EIO;
1256                         hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
1257                 } else {
1258                         hw->nvm_wait_opcode = i40e_aqc_opc_nvm_update;
1259                         hw->nvmupd_state = I40E_NVMUPD_STATE_WRITE_WAIT;
1260                 }
1261                 break;
1262
1263         case I40E_NVMUPD_CSUM_LCB:
1264                 /* Assumes the caller has acquired the nvm */
1265                 status = i40e_update_nvm_checksum(hw);
1266                 if (status) {
1267                         *perrno = hw->aq.asq_last_status ?
1268                                    i40e_aq_rc_to_posix(status,
1269                                                        hw->aq.asq_last_status) :
1270                                    -EIO;
1271                         hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
1272                 } else {
1273                         hw->nvm_release_on_done = true;
1274                         hw->nvm_wait_opcode = i40e_aqc_opc_nvm_update;
1275                         hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
1276                 }
1277                 break;
1278
1279         default:
1280                 i40e_debug(hw, I40E_DEBUG_NVM,
1281                            "NVMUPD: bad cmd %s in writing state.\n",
1282                            i40e_nvm_update_state_str[upd_cmd]);
1283                 status = I40E_NOT_SUPPORTED;
1284                 *perrno = -ESRCH;
1285                 break;
1286         }
1287
1288         /* In some circumstances, a multi-write transaction takes longer
1289          * than the default 3 minute timeout on the write semaphore.  If
1290          * the write failed with an EBUSY status, this is likely the problem,
1291          * so here we try to reacquire the semaphore then retry the write.
1292          * We only do one retry, then give up.
1293          */
1294         if (status && (hw->aq.asq_last_status == I40E_AQ_RC_EBUSY) &&
1295             !retry_attempt) {
1296                 enum i40e_status_code old_status = status;
1297                 u32 old_asq_status = hw->aq.asq_last_status;
1298                 u32 gtime;
1299
1300                 gtime = rd32(hw, I40E_GLVFGEN_TIMER);
1301                 if (gtime >= hw->nvm.hw_semaphore_timeout) {
1302                         i40e_debug(hw, I40E_DEBUG_ALL,
1303                                    "NVMUPD: write semaphore expired (%d >= %lld), retrying\n",
1304                                    gtime, hw->nvm.hw_semaphore_timeout);
1305                         i40e_release_nvm(hw);
1306                         status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
1307                         if (status) {
1308                                 i40e_debug(hw, I40E_DEBUG_ALL,
1309                                            "NVMUPD: write semaphore reacquire failed aq_err = %d\n",
1310                                            hw->aq.asq_last_status);
1311                                 status = old_status;
1312                                 hw->aq.asq_last_status = old_asq_status;
1313                         } else {
1314                                 retry_attempt = true;
1315                                 goto retry;
1316                         }
1317                 }
1318         }
1319
1320         return status;
1321 }
1322
1323 /**
1324  * i40e_nvmupd_clear_wait_state - clear wait state on hw
1325  * @hw: pointer to the hardware structure
1326  **/
1327 void i40e_nvmupd_clear_wait_state(struct i40e_hw *hw)
1328 {
1329         i40e_debug(hw, I40E_DEBUG_NVM,
1330                    "NVMUPD: clearing wait on opcode 0x%04x\n",
1331                    hw->nvm_wait_opcode);
1332
1333         if (hw->nvm_release_on_done) {
1334                 i40e_release_nvm(hw);
1335                 hw->nvm_release_on_done = false;
1336         }
1337         hw->nvm_wait_opcode = 0;
1338
1339         if (hw->aq.arq_last_status) {
1340                 hw->nvmupd_state = I40E_NVMUPD_STATE_ERROR;
1341                 return;
1342         }
1343
1344         switch (hw->nvmupd_state) {
1345         case I40E_NVMUPD_STATE_INIT_WAIT:
1346                 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
1347                 break;
1348
1349         case I40E_NVMUPD_STATE_WRITE_WAIT:
1350                 hw->nvmupd_state = I40E_NVMUPD_STATE_WRITING;
1351                 break;
1352
1353         default:
1354                 break;
1355         }
1356 }
1357
1358 /**
1359  * i40e_nvmupd_check_wait_event - handle NVM update operation events
1360  * @hw: pointer to the hardware structure
1361  * @opcode: the event that just happened
1362  * @desc: AdminQ descriptor
1363  **/
1364 void i40e_nvmupd_check_wait_event(struct i40e_hw *hw, u16 opcode,
1365                                   struct i40e_aq_desc *desc)
1366 {
1367         u32 aq_desc_len = sizeof(struct i40e_aq_desc);
1368
1369         if (opcode == hw->nvm_wait_opcode) {
1370                 i40e_memcpy(&hw->nvm_aq_event_desc, desc,
1371                             aq_desc_len, I40E_NONDMA_TO_NONDMA);
1372                 i40e_nvmupd_clear_wait_state(hw);
1373         }
1374 }
1375
1376 /**
1377  * i40e_nvmupd_validate_command - Validate given command
1378  * @hw: pointer to hardware structure
1379  * @cmd: pointer to nvm update command buffer
1380  * @perrno: pointer to return error code
1381  *
1382  * Return one of the valid command types or I40E_NVMUPD_INVALID
1383  **/
1384 STATIC enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
1385                                                     struct i40e_nvm_access *cmd,
1386                                                     int *perrno)
1387 {
1388         enum i40e_nvmupd_cmd upd_cmd;
1389         u8 module, transaction;
1390
1391         DEBUGFUNC("i40e_nvmupd_validate_command\n");
1392
1393         /* anything that doesn't match a recognized case is an error */
1394         upd_cmd = I40E_NVMUPD_INVALID;
1395
1396         transaction = i40e_nvmupd_get_transaction(cmd->config);
1397         module = i40e_nvmupd_get_module(cmd->config);
1398
1399         /* limits on data size */
1400         if ((cmd->data_size < 1) ||
1401             (cmd->data_size > I40E_NVMUPD_MAX_DATA)) {
1402                 i40e_debug(hw, I40E_DEBUG_NVM,
1403                            "i40e_nvmupd_validate_command data_size %d\n",
1404                            cmd->data_size);
1405                 *perrno = -EFAULT;
1406                 return I40E_NVMUPD_INVALID;
1407         }
1408
1409         switch (cmd->command) {
1410         case I40E_NVM_READ:
1411                 switch (transaction) {
1412                 case I40E_NVM_CON:
1413                         upd_cmd = I40E_NVMUPD_READ_CON;
1414                         break;
1415                 case I40E_NVM_SNT:
1416                         upd_cmd = I40E_NVMUPD_READ_SNT;
1417                         break;
1418                 case I40E_NVM_LCB:
1419                         upd_cmd = I40E_NVMUPD_READ_LCB;
1420                         break;
1421                 case I40E_NVM_SA:
1422                         upd_cmd = I40E_NVMUPD_READ_SA;
1423                         break;
1424                 case I40E_NVM_EXEC:
1425                         switch (module) {
1426                         case I40E_NVM_EXEC_GET_AQ_RESULT:
1427                                 upd_cmd = I40E_NVMUPD_GET_AQ_RESULT;
1428                                 break;
1429                         case I40E_NVM_EXEC_FEATURES:
1430                                 upd_cmd = I40E_NVMUPD_FEATURES;
1431                                 break;
1432                         case I40E_NVM_EXEC_STATUS:
1433                                 upd_cmd = I40E_NVMUPD_STATUS;
1434                                 break;
1435                         default:
1436                                 *perrno = -EFAULT;
1437                                 return I40E_NVMUPD_INVALID;
1438                         }
1439                         break;
1440                 case I40E_NVM_AQE:
1441                         upd_cmd = I40E_NVMUPD_GET_AQ_EVENT;
1442                         break;
1443                 }
1444                 break;
1445
1446         case I40E_NVM_WRITE:
1447                 switch (transaction) {
1448                 case I40E_NVM_CON:
1449                         upd_cmd = I40E_NVMUPD_WRITE_CON;
1450                         break;
1451                 case I40E_NVM_SNT:
1452                         upd_cmd = I40E_NVMUPD_WRITE_SNT;
1453                         break;
1454                 case I40E_NVM_LCB:
1455                         upd_cmd = I40E_NVMUPD_WRITE_LCB;
1456                         break;
1457                 case I40E_NVM_SA:
1458                         upd_cmd = I40E_NVMUPD_WRITE_SA;
1459                         break;
1460                 case I40E_NVM_ERA:
1461                         upd_cmd = I40E_NVMUPD_WRITE_ERA;
1462                         break;
1463                 case I40E_NVM_CSUM:
1464                         upd_cmd = I40E_NVMUPD_CSUM_CON;
1465                         break;
1466                 case (I40E_NVM_CSUM|I40E_NVM_SA):
1467                         upd_cmd = I40E_NVMUPD_CSUM_SA;
1468                         break;
1469                 case (I40E_NVM_CSUM|I40E_NVM_LCB):
1470                         upd_cmd = I40E_NVMUPD_CSUM_LCB;
1471                         break;
1472                 case I40E_NVM_EXEC:
1473                         if (module == 0)
1474                                 upd_cmd = I40E_NVMUPD_EXEC_AQ;
1475                         break;
1476                 }
1477                 break;
1478         }
1479
1480         return upd_cmd;
1481 }
1482
1483 /**
1484  * i40e_nvmupd_exec_aq - Run an AQ command
1485  * @hw: pointer to hardware structure
1486  * @cmd: pointer to nvm update command buffer
1487  * @bytes: pointer to the data buffer
1488  * @perrno: pointer to return error code
1489  *
1490  * cmd structure contains identifiers and data buffer
1491  **/
1492 STATIC enum i40e_status_code i40e_nvmupd_exec_aq(struct i40e_hw *hw,
1493                                                  struct i40e_nvm_access *cmd,
1494                                                  u8 *bytes, int *perrno)
1495 {
1496         struct i40e_asq_cmd_details cmd_details;
1497         enum i40e_status_code status;
1498         struct i40e_aq_desc *aq_desc;
1499         u32 buff_size = 0;
1500         u8 *buff = NULL;
1501         u32 aq_desc_len;
1502         u32 aq_data_len;
1503
1504         i40e_debug(hw, I40E_DEBUG_NVM, "NVMUPD: %s\n", __func__);
1505         if (cmd->offset == 0xffff)
1506                 return I40E_SUCCESS;
1507
1508         memset(&cmd_details, 0, sizeof(cmd_details));
1509         cmd_details.wb_desc = &hw->nvm_wb_desc;
1510
1511         aq_desc_len = sizeof(struct i40e_aq_desc);
1512         memset(&hw->nvm_wb_desc, 0, aq_desc_len);
1513
1514         /* get the aq descriptor */
1515         if (cmd->data_size < aq_desc_len) {
1516                 i40e_debug(hw, I40E_DEBUG_NVM,
1517                            "NVMUPD: not enough aq desc bytes for exec, size %d < %d\n",
1518                            cmd->data_size, aq_desc_len);
1519                 *perrno = -EINVAL;
1520                 return I40E_ERR_PARAM;
1521         }
1522         aq_desc = (struct i40e_aq_desc *)bytes;
1523
1524         /* if data buffer needed, make sure it's ready */
1525         aq_data_len = cmd->data_size - aq_desc_len;
1526         buff_size = max(aq_data_len, (u32)LE16_TO_CPU(aq_desc->datalen));
1527         if (buff_size) {
1528                 if (!hw->nvm_buff.va) {
1529                         status = i40e_allocate_virt_mem(hw, &hw->nvm_buff,
1530                                                         hw->aq.asq_buf_size);
1531                         if (status)
1532                                 i40e_debug(hw, I40E_DEBUG_NVM,
1533                                            "NVMUPD: i40e_allocate_virt_mem for exec buff failed, %d\n",
1534                                            status);
1535                 }
1536
1537                 if (hw->nvm_buff.va) {
1538                         buff = hw->nvm_buff.va;
1539                         i40e_memcpy(buff, &bytes[aq_desc_len], aq_data_len,
1540                                 I40E_NONDMA_TO_NONDMA);
1541                 }
1542         }
1543
1544         if (cmd->offset)
1545                 memset(&hw->nvm_aq_event_desc, 0, aq_desc_len);
1546
1547         /* and away we go! */
1548         status = i40e_asq_send_command(hw, aq_desc, buff,
1549                                        buff_size, &cmd_details);
1550         if (status) {
1551                 i40e_debug(hw, I40E_DEBUG_NVM,
1552                            "i40e_nvmupd_exec_aq err %s aq_err %s\n",
1553                            i40e_stat_str(hw, status),
1554                            i40e_aq_str(hw, hw->aq.asq_last_status));
1555                 *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
1556                 return status;
1557         }
1558
1559         /* should we wait for a followup event? */
1560         if (cmd->offset) {
1561                 hw->nvm_wait_opcode = cmd->offset;
1562                 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT_WAIT;
1563         }
1564
1565         return status;
1566 }
1567
1568 /**
1569  * i40e_nvmupd_get_aq_result - Get the results from the previous exec_aq
1570  * @hw: pointer to hardware structure
1571  * @cmd: pointer to nvm update command buffer
1572  * @bytes: pointer to the data buffer
1573  * @perrno: pointer to return error code
1574  *
1575  * cmd structure contains identifiers and data buffer
1576  **/
1577 STATIC enum i40e_status_code i40e_nvmupd_get_aq_result(struct i40e_hw *hw,
1578                                                     struct i40e_nvm_access *cmd,
1579                                                     u8 *bytes, int *perrno)
1580 {
1581         u32 aq_total_len;
1582         u32 aq_desc_len;
1583         int remainder;
1584         u8 *buff;
1585
1586         i40e_debug(hw, I40E_DEBUG_NVM, "NVMUPD: %s\n", __func__);
1587
1588         aq_desc_len = sizeof(struct i40e_aq_desc);
1589         aq_total_len = aq_desc_len + LE16_TO_CPU(hw->nvm_wb_desc.datalen);
1590
1591         /* check offset range */
1592         if (cmd->offset > aq_total_len) {
1593                 i40e_debug(hw, I40E_DEBUG_NVM, "%s: offset too big %d > %d\n",
1594                            __func__, cmd->offset, aq_total_len);
1595                 *perrno = -EINVAL;
1596                 return I40E_ERR_PARAM;
1597         }
1598
1599         /* check copylength range */
1600         if (cmd->data_size > (aq_total_len - cmd->offset)) {
1601                 int new_len = aq_total_len - cmd->offset;
1602
1603                 i40e_debug(hw, I40E_DEBUG_NVM, "%s: copy length %d too big, trimming to %d\n",
1604                            __func__, cmd->data_size, new_len);
1605                 cmd->data_size = new_len;
1606         }
1607
1608         remainder = cmd->data_size;
1609         if (cmd->offset < aq_desc_len) {
1610                 u32 len = aq_desc_len - cmd->offset;
1611
1612                 len = min(len, cmd->data_size);
1613                 i40e_debug(hw, I40E_DEBUG_NVM, "%s: aq_desc bytes %d to %d\n",
1614                            __func__, cmd->offset, cmd->offset + len);
1615
1616                 buff = ((u8 *)&hw->nvm_wb_desc) + cmd->offset;
1617                 i40e_memcpy(bytes, buff, len, I40E_NONDMA_TO_NONDMA);
1618
1619                 bytes += len;
1620                 remainder -= len;
1621                 buff = hw->nvm_buff.va;
1622         } else {
1623                 buff = (u8 *)hw->nvm_buff.va + (cmd->offset - aq_desc_len);
1624         }
1625
1626         if (remainder > 0) {
1627                 int start_byte = buff - (u8 *)hw->nvm_buff.va;
1628
1629                 i40e_debug(hw, I40E_DEBUG_NVM, "%s: databuf bytes %d to %d\n",
1630                            __func__, start_byte, start_byte + remainder);
1631                 i40e_memcpy(bytes, buff, remainder, I40E_NONDMA_TO_NONDMA);
1632         }
1633
1634         return I40E_SUCCESS;
1635 }
1636
1637 /**
1638  * i40e_nvmupd_get_aq_event - Get the Admin Queue event from previous exec_aq
1639  * @hw: pointer to hardware structure
1640  * @cmd: pointer to nvm update command buffer
1641  * @bytes: pointer to the data buffer
1642  * @perrno: pointer to return error code
1643  *
1644  * cmd structure contains identifiers and data buffer
1645  **/
1646 STATIC enum i40e_status_code i40e_nvmupd_get_aq_event(struct i40e_hw *hw,
1647                                                     struct i40e_nvm_access *cmd,
1648                                                     u8 *bytes, int *perrno)
1649 {
1650         u32 aq_total_len;
1651         u32 aq_desc_len;
1652
1653         i40e_debug(hw, I40E_DEBUG_NVM, "NVMUPD: %s\n", __func__);
1654
1655         aq_desc_len = sizeof(struct i40e_aq_desc);
1656         aq_total_len = aq_desc_len + LE16_TO_CPU(hw->nvm_aq_event_desc.datalen);
1657
1658         /* check copylength range */
1659         if (cmd->data_size > aq_total_len) {
1660                 i40e_debug(hw, I40E_DEBUG_NVM,
1661                            "%s: copy length %d too big, trimming to %d\n",
1662                            __func__, cmd->data_size, aq_total_len);
1663                 cmd->data_size = aq_total_len;
1664         }
1665
1666         i40e_memcpy(bytes, &hw->nvm_aq_event_desc, cmd->data_size,
1667                     I40E_NONDMA_TO_NONDMA);
1668
1669         return I40E_SUCCESS;
1670 }
1671
1672 /**
1673  * i40e_nvmupd_nvm_read - Read NVM
1674  * @hw: pointer to hardware structure
1675  * @cmd: pointer to nvm update command buffer
1676  * @bytes: pointer to the data buffer
1677  * @perrno: pointer to return error code
1678  *
1679  * cmd structure contains identifiers and data buffer
1680  **/
1681 STATIC enum i40e_status_code i40e_nvmupd_nvm_read(struct i40e_hw *hw,
1682                                                   struct i40e_nvm_access *cmd,
1683                                                   u8 *bytes, int *perrno)
1684 {
1685         struct i40e_asq_cmd_details cmd_details;
1686         enum i40e_status_code status;
1687         u8 module, transaction;
1688         bool last;
1689
1690         transaction = i40e_nvmupd_get_transaction(cmd->config);
1691         module = i40e_nvmupd_get_module(cmd->config);
1692         last = (transaction == I40E_NVM_LCB) || (transaction == I40E_NVM_SA);
1693
1694         memset(&cmd_details, 0, sizeof(cmd_details));
1695         cmd_details.wb_desc = &hw->nvm_wb_desc;
1696
1697         status = i40e_aq_read_nvm(hw, module, cmd->offset, (u16)cmd->data_size,
1698                                   bytes, last, &cmd_details);
1699         if (status) {
1700                 i40e_debug(hw, I40E_DEBUG_NVM,
1701                            "i40e_nvmupd_nvm_read mod 0x%x  off 0x%x  len 0x%x\n",
1702                            module, cmd->offset, cmd->data_size);
1703                 i40e_debug(hw, I40E_DEBUG_NVM,
1704                            "i40e_nvmupd_nvm_read status %d aq %d\n",
1705                            status, hw->aq.asq_last_status);
1706                 *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
1707         }
1708
1709         return status;
1710 }
1711
1712 /**
1713  * i40e_nvmupd_nvm_erase - Erase an NVM module
1714  * @hw: pointer to hardware structure
1715  * @cmd: pointer to nvm update command buffer
1716  * @perrno: pointer to return error code
1717  *
1718  * module, offset, data_size and data are in cmd structure
1719  **/
1720 STATIC enum i40e_status_code i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
1721                                                    struct i40e_nvm_access *cmd,
1722                                                    int *perrno)
1723 {
1724         enum i40e_status_code status = I40E_SUCCESS;
1725         struct i40e_asq_cmd_details cmd_details;
1726         u8 module, transaction;
1727         bool last;
1728
1729         transaction = i40e_nvmupd_get_transaction(cmd->config);
1730         module = i40e_nvmupd_get_module(cmd->config);
1731         last = (transaction & I40E_NVM_LCB);
1732
1733         memset(&cmd_details, 0, sizeof(cmd_details));
1734         cmd_details.wb_desc = &hw->nvm_wb_desc;
1735
1736         status = i40e_aq_erase_nvm(hw, module, cmd->offset, (u16)cmd->data_size,
1737                                    last, &cmd_details);
1738         if (status) {
1739                 i40e_debug(hw, I40E_DEBUG_NVM,
1740                            "i40e_nvmupd_nvm_erase mod 0x%x  off 0x%x len 0x%x\n",
1741                            module, cmd->offset, cmd->data_size);
1742                 i40e_debug(hw, I40E_DEBUG_NVM,
1743                            "i40e_nvmupd_nvm_erase status %d aq %d\n",
1744                            status, hw->aq.asq_last_status);
1745                 *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
1746         }
1747
1748         return status;
1749 }
1750
1751 /**
1752  * i40e_nvmupd_nvm_write - Write NVM
1753  * @hw: pointer to hardware structure
1754  * @cmd: pointer to nvm update command buffer
1755  * @bytes: pointer to the data buffer
1756  * @perrno: pointer to return error code
1757  *
1758  * module, offset, data_size and data are in cmd structure
1759  **/
1760 STATIC enum i40e_status_code i40e_nvmupd_nvm_write(struct i40e_hw *hw,
1761                                                    struct i40e_nvm_access *cmd,
1762                                                    u8 *bytes, int *perrno)
1763 {
1764         enum i40e_status_code status = I40E_SUCCESS;
1765         struct i40e_asq_cmd_details cmd_details;
1766         u8 module, transaction;
1767         u8 preservation_flags;
1768         bool last;
1769
1770         transaction = i40e_nvmupd_get_transaction(cmd->config);
1771         module = i40e_nvmupd_get_module(cmd->config);
1772         last = (transaction & I40E_NVM_LCB);
1773         preservation_flags = i40e_nvmupd_get_preservation_flags(cmd->config);
1774
1775         memset(&cmd_details, 0, sizeof(cmd_details));
1776         cmd_details.wb_desc = &hw->nvm_wb_desc;
1777
1778         status = i40e_aq_update_nvm(hw, module, cmd->offset,
1779                                     (u16)cmd->data_size, bytes, last,
1780                                     preservation_flags, &cmd_details);
1781         if (status) {
1782                 i40e_debug(hw, I40E_DEBUG_NVM,
1783                            "i40e_nvmupd_nvm_write mod 0x%x off 0x%x len 0x%x\n",
1784                            module, cmd->offset, cmd->data_size);
1785                 i40e_debug(hw, I40E_DEBUG_NVM,
1786                            "i40e_nvmupd_nvm_write status %d aq %d\n",
1787                            status, hw->aq.asq_last_status);
1788                 *perrno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
1789         }
1790
1791         return status;
1792 }