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