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