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