1/*******************************************************************************
2 *
3 * Intel Ethernet Controller XL710 Family Linux Driver
4 * Copyright(c) 2013 - 2014 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program.  If not, see <http://www.gnu.org/licenses/>.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 * Contact Information:
22 * e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
23 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24 *
25 ******************************************************************************/
26
27#include "i40e_prototype.h"
28
29/**
30 * i40e_init_nvm_ops - Initialize NVM function pointers
31 * @hw: pointer to the HW structure
32 *
33 * Setup the function pointers and the NVM info structure. Should be called
34 * once per NVM initialization, e.g. inside the i40e_init_shared_code().
35 * Please notice that the NVM term is used here (& in all methods covered
36 * in this file) as an equivalent of the FLASH part mapped into the SR.
37 * We are accessing FLASH always thru the Shadow RAM.
38 **/
39i40e_status i40e_init_nvm(struct i40e_hw *hw)
40{
41	struct i40e_nvm_info *nvm = &hw->nvm;
42	i40e_status ret_code = 0;
43	u32 fla, gens;
44	u8 sr_size;
45
46	/* The SR size is stored regardless of the nvm programming mode
47	 * as the blank mode may be used in the factory line.
48	 */
49	gens = rd32(hw, I40E_GLNVM_GENS);
50	sr_size = ((gens & I40E_GLNVM_GENS_SR_SIZE_MASK) >>
51			   I40E_GLNVM_GENS_SR_SIZE_SHIFT);
52	/* Switching to words (sr_size contains power of 2KB) */
53	nvm->sr_size = (1 << sr_size) * I40E_SR_WORDS_IN_1KB;
54
55	/* Check if we are in the normal or blank NVM programming mode */
56	fla = rd32(hw, I40E_GLNVM_FLA);
57	if (fla & I40E_GLNVM_FLA_LOCKED_MASK) { /* Normal programming mode */
58		/* Max NVM timeout */
59		nvm->timeout = I40E_MAX_NVM_TIMEOUT;
60		nvm->blank_nvm_mode = false;
61	} else { /* Blank programming mode */
62		nvm->blank_nvm_mode = true;
63		ret_code = I40E_ERR_NVM_BLANK_MODE;
64		i40e_debug(hw, I40E_DEBUG_NVM, "NVM init error: unsupported blank mode.\n");
65	}
66
67	return ret_code;
68}
69
70/**
71 * i40e_acquire_nvm - Generic request for acquiring the NVM ownership
72 * @hw: pointer to the HW structure
73 * @access: NVM access type (read or write)
74 *
75 * This function will request NVM ownership for reading
76 * via the proper Admin Command.
77 **/
78i40e_status i40e_acquire_nvm(struct i40e_hw *hw,
79				       enum i40e_aq_resource_access_type access)
80{
81	i40e_status ret_code = 0;
82	u64 gtime, timeout;
83	u64 time_left = 0;
84
85	if (hw->nvm.blank_nvm_mode)
86		goto i40e_i40e_acquire_nvm_exit;
87
88	ret_code = i40e_aq_request_resource(hw, I40E_NVM_RESOURCE_ID, access,
89					    0, &time_left, NULL);
90	/* Reading the Global Device Timer */
91	gtime = rd32(hw, I40E_GLVFGEN_TIMER);
92
93	/* Store the timeout */
94	hw->nvm.hw_semaphore_timeout = I40E_MS_TO_GTIME(time_left) + gtime;
95
96	if (ret_code)
97		i40e_debug(hw, I40E_DEBUG_NVM,
98			   "NVM acquire type %d failed time_left=%llu ret=%d aq_err=%d\n",
99			   access, time_left, ret_code, hw->aq.asq_last_status);
100
101	if (ret_code && time_left) {
102		/* Poll until the current NVM owner timeouts */
103		timeout = I40E_MS_TO_GTIME(I40E_MAX_NVM_TIMEOUT) + gtime;
104		while ((gtime < timeout) && time_left) {
105			usleep_range(10000, 20000);
106			gtime = rd32(hw, I40E_GLVFGEN_TIMER);
107			ret_code = i40e_aq_request_resource(hw,
108							I40E_NVM_RESOURCE_ID,
109							access, 0, &time_left,
110							NULL);
111			if (!ret_code) {
112				hw->nvm.hw_semaphore_timeout =
113					    I40E_MS_TO_GTIME(time_left) + gtime;
114				break;
115			}
116		}
117		if (ret_code) {
118			hw->nvm.hw_semaphore_timeout = 0;
119			i40e_debug(hw, I40E_DEBUG_NVM,
120				   "NVM acquire timed out, wait %llu ms before trying again. status=%d aq_err=%d\n",
121				   time_left, ret_code, hw->aq.asq_last_status);
122		}
123	}
124
125i40e_i40e_acquire_nvm_exit:
126	return ret_code;
127}
128
129/**
130 * i40e_release_nvm - Generic request for releasing the NVM ownership
131 * @hw: pointer to the HW structure
132 *
133 * This function will release NVM resource via the proper Admin Command.
134 **/
135void i40e_release_nvm(struct i40e_hw *hw)
136{
137	if (!hw->nvm.blank_nvm_mode)
138		i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL);
139}
140
141/**
142 * i40e_poll_sr_srctl_done_bit - Polls the GLNVM_SRCTL done bit
143 * @hw: pointer to the HW structure
144 *
145 * Polls the SRCTL Shadow RAM register done bit.
146 **/
147static i40e_status i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw)
148{
149	i40e_status ret_code = I40E_ERR_TIMEOUT;
150	u32 srctl, wait_cnt;
151
152	/* Poll the I40E_GLNVM_SRCTL until the done bit is set */
153	for (wait_cnt = 0; wait_cnt < I40E_SRRD_SRCTL_ATTEMPTS; wait_cnt++) {
154		srctl = rd32(hw, I40E_GLNVM_SRCTL);
155		if (srctl & I40E_GLNVM_SRCTL_DONE_MASK) {
156			ret_code = 0;
157			break;
158		}
159		udelay(5);
160	}
161	if (ret_code == I40E_ERR_TIMEOUT)
162		i40e_debug(hw, I40E_DEBUG_NVM, "Done bit in GLNVM_SRCTL not set");
163	return ret_code;
164}
165
166/**
167 * i40e_read_nvm_word_srctl - Reads Shadow RAM via SRCTL register
168 * @hw: pointer to the HW structure
169 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
170 * @data: word read from the Shadow RAM
171 *
172 * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
173 **/
174static i40e_status i40e_read_nvm_word_srctl(struct i40e_hw *hw, u16 offset,
175					    u16 *data)
176{
177	i40e_status ret_code = I40E_ERR_TIMEOUT;
178	u32 sr_reg;
179
180	if (offset >= hw->nvm.sr_size) {
181		i40e_debug(hw, I40E_DEBUG_NVM,
182			   "NVM read error: offset %d beyond Shadow RAM limit %d\n",
183			   offset, hw->nvm.sr_size);
184		ret_code = I40E_ERR_PARAM;
185		goto read_nvm_exit;
186	}
187
188	/* Poll the done bit first */
189	ret_code = i40e_poll_sr_srctl_done_bit(hw);
190	if (!ret_code) {
191		/* Write the address and start reading */
192		sr_reg = (u32)(offset << I40E_GLNVM_SRCTL_ADDR_SHIFT) |
193			 (1 << I40E_GLNVM_SRCTL_START_SHIFT);
194		wr32(hw, I40E_GLNVM_SRCTL, sr_reg);
195
196		/* Poll I40E_GLNVM_SRCTL until the done bit is set */
197		ret_code = i40e_poll_sr_srctl_done_bit(hw);
198		if (!ret_code) {
199			sr_reg = rd32(hw, I40E_GLNVM_SRDATA);
200			*data = (u16)((sr_reg &
201				       I40E_GLNVM_SRDATA_RDDATA_MASK)
202				    >> I40E_GLNVM_SRDATA_RDDATA_SHIFT);
203		}
204	}
205	if (ret_code)
206		i40e_debug(hw, I40E_DEBUG_NVM,
207			   "NVM read error: Couldn't access Shadow RAM address: 0x%x\n",
208			   offset);
209
210read_nvm_exit:
211	return ret_code;
212}
213
214/**
215 * i40e_read_nvm_word - Reads Shadow RAM
216 * @hw: pointer to the HW structure
217 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
218 * @data: word read from the Shadow RAM
219 *
220 * Reads one 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
221 **/
222i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
223			       u16 *data)
224{
225	return i40e_read_nvm_word_srctl(hw, offset, data);
226}
227
228/**
229 * i40e_read_nvm_buffer_srctl - Reads Shadow RAM buffer via SRCTL register
230 * @hw: pointer to the HW structure
231 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
232 * @words: (in) number of words to read; (out) number of words actually read
233 * @data: words read from the Shadow RAM
234 *
235 * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd()
236 * method. The buffer read is preceded by the NVM ownership take
237 * and followed by the release.
238 **/
239static i40e_status i40e_read_nvm_buffer_srctl(struct i40e_hw *hw, u16 offset,
240					      u16 *words, u16 *data)
241{
242	i40e_status ret_code = 0;
243	u16 index, word;
244
245	/* Loop thru the selected region */
246	for (word = 0; word < *words; word++) {
247		index = offset + word;
248		ret_code = i40e_read_nvm_word_srctl(hw, index, &data[word]);
249		if (ret_code)
250			break;
251	}
252
253	/* Update the number of words read from the Shadow RAM */
254	*words = word;
255
256	return ret_code;
257}
258
259/**
260 * i40e_read_nvm_buffer - Reads Shadow RAM buffer
261 * @hw: pointer to the HW structure
262 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
263 * @words: (in) number of words to read; (out) number of words actually read
264 * @data: words read from the Shadow RAM
265 *
266 * Reads 16 bit words (data buffer) from the SR using the i40e_read_nvm_srrd()
267 * method. The buffer read is preceded by the NVM ownership take
268 * and followed by the release.
269 **/
270i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
271				 u16 *words, u16 *data)
272{
273	return i40e_read_nvm_buffer_srctl(hw, offset, words, data);
274}
275
276/**
277 * i40e_write_nvm_aq - Writes Shadow RAM.
278 * @hw: pointer to the HW structure.
279 * @module_pointer: module pointer location in words from the NVM beginning
280 * @offset: offset in words from module start
281 * @words: number of words to write
282 * @data: buffer with words to write to the Shadow RAM
283 * @last_command: tells the AdminQ that this is the last command
284 *
285 * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
286 **/
287static i40e_status i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
288				     u32 offset, u16 words, void *data,
289				     bool last_command)
290{
291	i40e_status ret_code = I40E_ERR_NVM;
292
293	/* Here we are checking the SR limit only for the flat memory model.
294	 * We cannot do it for the module-based model, as we did not acquire
295	 * the NVM resource yet (we cannot get the module pointer value).
296	 * Firmware will check the module-based model.
297	 */
298	if ((offset + words) > hw->nvm.sr_size)
299		i40e_debug(hw, I40E_DEBUG_NVM,
300			   "NVM write error: offset %d beyond Shadow RAM limit %d\n",
301			   (offset + words), hw->nvm.sr_size);
302	else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS)
303		/* We can write only up to 4KB (one sector), in one AQ write */
304		i40e_debug(hw, I40E_DEBUG_NVM,
305			   "NVM write fail error: tried to write %d words, limit is %d.\n",
306			   words, I40E_SR_SECTOR_SIZE_IN_WORDS);
307	else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS)
308		 != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS))
309		/* A single write cannot spread over two sectors */
310		i40e_debug(hw, I40E_DEBUG_NVM,
311			   "NVM write error: cannot spread over two sectors in a single write offset=%d words=%d\n",
312			   offset, words);
313	else
314		ret_code = i40e_aq_update_nvm(hw, module_pointer,
315					      2 * offset,  /*bytes*/
316					      2 * words,   /*bytes*/
317					      data, last_command, NULL);
318
319	return ret_code;
320}
321
322/**
323 * i40e_calc_nvm_checksum - Calculates and returns the checksum
324 * @hw: pointer to hardware structure
325 * @checksum: pointer to the checksum
326 *
327 * This function calculates SW Checksum that covers the whole 64kB shadow RAM
328 * except the VPD and PCIe ALT Auto-load modules. The structure and size of VPD
329 * is customer specific and unknown. Therefore, this function skips all maximum
330 * possible size of VPD (1kB).
331 **/
332static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw,
333						    u16 *checksum)
334{
335	i40e_status ret_code = 0;
336	struct i40e_virt_mem vmem;
337	u16 pcie_alt_module = 0;
338	u16 checksum_local = 0;
339	u16 vpd_module = 0;
340	u16 *data;
341	u16 i = 0;
342
343	ret_code = i40e_allocate_virt_mem(hw, &vmem,
344				    I40E_SR_SECTOR_SIZE_IN_WORDS * sizeof(u16));
345	if (ret_code)
346		goto i40e_calc_nvm_checksum_exit;
347	data = (u16 *)vmem.va;
348
349	/* read pointer to VPD area */
350	ret_code = i40e_read_nvm_word(hw, I40E_SR_VPD_PTR, &vpd_module);
351	if (ret_code) {
352		ret_code = I40E_ERR_NVM_CHECKSUM;
353		goto i40e_calc_nvm_checksum_exit;
354	}
355
356	/* read pointer to PCIe Alt Auto-load module */
357	ret_code = i40e_read_nvm_word(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR,
358				      &pcie_alt_module);
359	if (ret_code) {
360		ret_code = I40E_ERR_NVM_CHECKSUM;
361		goto i40e_calc_nvm_checksum_exit;
362	}
363
364	/* Calculate SW checksum that covers the whole 64kB shadow RAM
365	 * except the VPD and PCIe ALT Auto-load modules
366	 */
367	for (i = 0; i < hw->nvm.sr_size; i++) {
368		/* Read SR page */
369		if ((i % I40E_SR_SECTOR_SIZE_IN_WORDS) == 0) {
370			u16 words = I40E_SR_SECTOR_SIZE_IN_WORDS;
371
372			ret_code = i40e_read_nvm_buffer(hw, i, &words, data);
373			if (ret_code) {
374				ret_code = I40E_ERR_NVM_CHECKSUM;
375				goto i40e_calc_nvm_checksum_exit;
376			}
377		}
378
379		/* Skip Checksum word */
380		if (i == I40E_SR_SW_CHECKSUM_WORD)
381			continue;
382		/* Skip VPD module (convert byte size to word count) */
383		if ((i >= (u32)vpd_module) &&
384		    (i < ((u32)vpd_module +
385		     (I40E_SR_VPD_MODULE_MAX_SIZE / 2)))) {
386			continue;
387		}
388		/* Skip PCIe ALT module (convert byte size to word count) */
389		if ((i >= (u32)pcie_alt_module) &&
390		    (i < ((u32)pcie_alt_module +
391		     (I40E_SR_PCIE_ALT_MODULE_MAX_SIZE / 2)))) {
392			continue;
393		}
394
395		checksum_local += data[i % I40E_SR_SECTOR_SIZE_IN_WORDS];
396	}
397
398	*checksum = (u16)I40E_SR_SW_CHECKSUM_BASE - checksum_local;
399
400i40e_calc_nvm_checksum_exit:
401	i40e_free_virt_mem(hw, &vmem);
402	return ret_code;
403}
404
405/**
406 * i40e_update_nvm_checksum - Updates the NVM checksum
407 * @hw: pointer to hardware structure
408 *
409 * NVM ownership must be acquired before calling this function and released
410 * on ARQ completion event reception by caller.
411 * This function will commit SR to NVM.
412 **/
413i40e_status i40e_update_nvm_checksum(struct i40e_hw *hw)
414{
415	i40e_status ret_code = 0;
416	u16 checksum;
417
418	ret_code = i40e_calc_nvm_checksum(hw, &checksum);
419	if (!ret_code)
420		ret_code = i40e_write_nvm_aq(hw, 0x00, I40E_SR_SW_CHECKSUM_WORD,
421					     1, &checksum, true);
422
423	return ret_code;
424}
425
426/**
427 * i40e_validate_nvm_checksum - Validate EEPROM checksum
428 * @hw: pointer to hardware structure
429 * @checksum: calculated checksum
430 *
431 * Performs checksum calculation and validates the NVM SW checksum. If the
432 * caller does not need checksum, the value can be NULL.
433 **/
434i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
435						 u16 *checksum)
436{
437	i40e_status ret_code = 0;
438	u16 checksum_sr = 0;
439	u16 checksum_local = 0;
440
441	ret_code = i40e_calc_nvm_checksum(hw, &checksum_local);
442	if (ret_code)
443		goto i40e_validate_nvm_checksum_exit;
444
445	/* Do not use i40e_read_nvm_word() because we do not want to take
446	 * the synchronization semaphores twice here.
447	 */
448	i40e_read_nvm_word(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr);
449
450	/* Verify read checksum from EEPROM is the same as
451	 * calculated checksum
452	 */
453	if (checksum_local != checksum_sr)
454		ret_code = I40E_ERR_NVM_CHECKSUM;
455
456	/* If the user cares, return the calculated checksum */
457	if (checksum)
458		*checksum = checksum_local;
459
460i40e_validate_nvm_checksum_exit:
461	return ret_code;
462}
463
464static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
465					  struct i40e_nvm_access *cmd,
466					  u8 *bytes, int *errno);
467static i40e_status i40e_nvmupd_state_reading(struct i40e_hw *hw,
468					     struct i40e_nvm_access *cmd,
469					     u8 *bytes, int *errno);
470static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
471					     struct i40e_nvm_access *cmd,
472					     u8 *bytes, int *errno);
473static enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
474						struct i40e_nvm_access *cmd,
475						int *errno);
476static i40e_status i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
477					 struct i40e_nvm_access *cmd,
478					 int *errno);
479static i40e_status i40e_nvmupd_nvm_write(struct i40e_hw *hw,
480					 struct i40e_nvm_access *cmd,
481					 u8 *bytes, int *errno);
482static i40e_status i40e_nvmupd_nvm_read(struct i40e_hw *hw,
483					struct i40e_nvm_access *cmd,
484					u8 *bytes, int *errno);
485static inline u8 i40e_nvmupd_get_module(u32 val)
486{
487	return (u8)(val & I40E_NVM_MOD_PNT_MASK);
488}
489static inline u8 i40e_nvmupd_get_transaction(u32 val)
490{
491	return (u8)((val & I40E_NVM_TRANS_MASK) >> I40E_NVM_TRANS_SHIFT);
492}
493
494static char *i40e_nvm_update_state_str[] = {
495	"I40E_NVMUPD_INVALID",
496	"I40E_NVMUPD_READ_CON",
497	"I40E_NVMUPD_READ_SNT",
498	"I40E_NVMUPD_READ_LCB",
499	"I40E_NVMUPD_READ_SA",
500	"I40E_NVMUPD_WRITE_ERA",
501	"I40E_NVMUPD_WRITE_CON",
502	"I40E_NVMUPD_WRITE_SNT",
503	"I40E_NVMUPD_WRITE_LCB",
504	"I40E_NVMUPD_WRITE_SA",
505	"I40E_NVMUPD_CSUM_CON",
506	"I40E_NVMUPD_CSUM_SA",
507	"I40E_NVMUPD_CSUM_LCB",
508};
509
510/**
511 * i40e_nvmupd_command - Process an NVM update command
512 * @hw: pointer to hardware structure
513 * @cmd: pointer to nvm update command
514 * @bytes: pointer to the data buffer
515 * @errno: pointer to return error code
516 *
517 * Dispatches command depending on what update state is current
518 **/
519i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
520				struct i40e_nvm_access *cmd,
521				u8 *bytes, int *errno)
522{
523	i40e_status status;
524
525	/* assume success */
526	*errno = 0;
527
528	switch (hw->nvmupd_state) {
529	case I40E_NVMUPD_STATE_INIT:
530		status = i40e_nvmupd_state_init(hw, cmd, bytes, errno);
531		break;
532
533	case I40E_NVMUPD_STATE_READING:
534		status = i40e_nvmupd_state_reading(hw, cmd, bytes, errno);
535		break;
536
537	case I40E_NVMUPD_STATE_WRITING:
538		status = i40e_nvmupd_state_writing(hw, cmd, bytes, errno);
539		break;
540
541	default:
542		/* invalid state, should never happen */
543		i40e_debug(hw, I40E_DEBUG_NVM,
544			   "NVMUPD: no such state %d\n", hw->nvmupd_state);
545		status = I40E_NOT_SUPPORTED;
546		*errno = -ESRCH;
547		break;
548	}
549	return status;
550}
551
552/**
553 * i40e_nvmupd_state_init - Handle NVM update state Init
554 * @hw: pointer to hardware structure
555 * @cmd: pointer to nvm update command buffer
556 * @bytes: pointer to the data buffer
557 * @errno: pointer to return error code
558 *
559 * Process legitimate commands of the Init state and conditionally set next
560 * state. Reject all other commands.
561 **/
562static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
563					  struct i40e_nvm_access *cmd,
564					  u8 *bytes, int *errno)
565{
566	i40e_status status = 0;
567	enum i40e_nvmupd_cmd upd_cmd;
568
569	upd_cmd = i40e_nvmupd_validate_command(hw, cmd, errno);
570
571	switch (upd_cmd) {
572	case I40E_NVMUPD_READ_SA:
573		status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
574		if (status) {
575			*errno = i40e_aq_rc_to_posix(status,
576						     hw->aq.asq_last_status);
577		} else {
578			status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno);
579			i40e_release_nvm(hw);
580		}
581		break;
582
583	case I40E_NVMUPD_READ_SNT:
584		status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
585		if (status) {
586			*errno = i40e_aq_rc_to_posix(status,
587						     hw->aq.asq_last_status);
588		} else {
589			status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno);
590			if (status)
591				i40e_release_nvm(hw);
592			else
593				hw->nvmupd_state = I40E_NVMUPD_STATE_READING;
594		}
595		break;
596
597	case I40E_NVMUPD_WRITE_ERA:
598		status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
599		if (status) {
600			*errno = i40e_aq_rc_to_posix(status,
601						     hw->aq.asq_last_status);
602		} else {
603			status = i40e_nvmupd_nvm_erase(hw, cmd, errno);
604			if (status)
605				i40e_release_nvm(hw);
606			else
607				hw->aq.nvm_release_on_done = true;
608		}
609		break;
610
611	case I40E_NVMUPD_WRITE_SA:
612		status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
613		if (status) {
614			*errno = i40e_aq_rc_to_posix(status,
615						     hw->aq.asq_last_status);
616		} else {
617			status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno);
618			if (status)
619				i40e_release_nvm(hw);
620			else
621				hw->aq.nvm_release_on_done = true;
622		}
623		break;
624
625	case I40E_NVMUPD_WRITE_SNT:
626		status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
627		if (status) {
628			*errno = i40e_aq_rc_to_posix(status,
629						     hw->aq.asq_last_status);
630		} else {
631			status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno);
632			if (status)
633				i40e_release_nvm(hw);
634			else
635				hw->nvmupd_state = I40E_NVMUPD_STATE_WRITING;
636		}
637		break;
638
639	case I40E_NVMUPD_CSUM_SA:
640		status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
641		if (status) {
642			*errno = i40e_aq_rc_to_posix(status,
643						     hw->aq.asq_last_status);
644		} else {
645			status = i40e_update_nvm_checksum(hw);
646			if (status) {
647				*errno = hw->aq.asq_last_status ?
648				   i40e_aq_rc_to_posix(status,
649						       hw->aq.asq_last_status) :
650				   -EIO;
651				i40e_release_nvm(hw);
652			} else {
653				hw->aq.nvm_release_on_done = true;
654			}
655		}
656		break;
657
658	default:
659		i40e_debug(hw, I40E_DEBUG_NVM,
660			   "NVMUPD: bad cmd %s in init state\n",
661			   i40e_nvm_update_state_str[upd_cmd]);
662		status = I40E_ERR_NVM;
663		*errno = -ESRCH;
664		break;
665	}
666	return status;
667}
668
669/**
670 * i40e_nvmupd_state_reading - Handle NVM update state Reading
671 * @hw: pointer to hardware structure
672 * @cmd: pointer to nvm update command buffer
673 * @bytes: pointer to the data buffer
674 * @errno: pointer to return error code
675 *
676 * NVM ownership is already held.  Process legitimate commands and set any
677 * change in state; reject all other commands.
678 **/
679static i40e_status i40e_nvmupd_state_reading(struct i40e_hw *hw,
680					     struct i40e_nvm_access *cmd,
681					     u8 *bytes, int *errno)
682{
683	i40e_status status;
684	enum i40e_nvmupd_cmd upd_cmd;
685
686	upd_cmd = i40e_nvmupd_validate_command(hw, cmd, errno);
687
688	switch (upd_cmd) {
689	case I40E_NVMUPD_READ_SA:
690	case I40E_NVMUPD_READ_CON:
691		status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno);
692		break;
693
694	case I40E_NVMUPD_READ_LCB:
695		status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno);
696		i40e_release_nvm(hw);
697		hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
698		break;
699
700	default:
701		i40e_debug(hw, I40E_DEBUG_NVM,
702			   "NVMUPD: bad cmd %s in reading state.\n",
703			   i40e_nvm_update_state_str[upd_cmd]);
704		status = I40E_NOT_SUPPORTED;
705		*errno = -ESRCH;
706		break;
707	}
708	return status;
709}
710
711/**
712 * i40e_nvmupd_state_writing - Handle NVM update state Writing
713 * @hw: pointer to hardware structure
714 * @cmd: pointer to nvm update command buffer
715 * @bytes: pointer to the data buffer
716 * @errno: pointer to return error code
717 *
718 * NVM ownership is already held.  Process legitimate commands and set any
719 * change in state; reject all other commands
720 **/
721static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
722					     struct i40e_nvm_access *cmd,
723					     u8 *bytes, int *errno)
724{
725	i40e_status status;
726	enum i40e_nvmupd_cmd upd_cmd;
727	bool retry_attempt = false;
728
729	upd_cmd = i40e_nvmupd_validate_command(hw, cmd, errno);
730
731retry:
732	switch (upd_cmd) {
733	case I40E_NVMUPD_WRITE_CON:
734		status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno);
735		break;
736
737	case I40E_NVMUPD_WRITE_LCB:
738		status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno);
739		if (!status)
740			hw->aq.nvm_release_on_done = true;
741		hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
742		break;
743
744	case I40E_NVMUPD_CSUM_CON:
745		status = i40e_update_nvm_checksum(hw);
746		if (status) {
747			*errno = hw->aq.asq_last_status ?
748				   i40e_aq_rc_to_posix(status,
749						       hw->aq.asq_last_status) :
750				   -EIO;
751			hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
752		}
753		break;
754
755	case I40E_NVMUPD_CSUM_LCB:
756		status = i40e_update_nvm_checksum(hw);
757		if (status)
758			*errno = hw->aq.asq_last_status ?
759				   i40e_aq_rc_to_posix(status,
760						       hw->aq.asq_last_status) :
761				   -EIO;
762		else
763			hw->aq.nvm_release_on_done = true;
764		hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
765		break;
766
767	default:
768		i40e_debug(hw, I40E_DEBUG_NVM,
769			   "NVMUPD: bad cmd %s in writing state.\n",
770			   i40e_nvm_update_state_str[upd_cmd]);
771		status = I40E_NOT_SUPPORTED;
772		*errno = -ESRCH;
773		break;
774	}
775
776	/* In some circumstances, a multi-write transaction takes longer
777	 * than the default 3 minute timeout on the write semaphore.  If
778	 * the write failed with an EBUSY status, this is likely the problem,
779	 * so here we try to reacquire the semaphore then retry the write.
780	 * We only do one retry, then give up.
781	 */
782	if (status && (hw->aq.asq_last_status == I40E_AQ_RC_EBUSY) &&
783	    !retry_attempt) {
784		i40e_status old_status = status;
785		u32 old_asq_status = hw->aq.asq_last_status;
786		u32 gtime;
787
788		gtime = rd32(hw, I40E_GLVFGEN_TIMER);
789		if (gtime >= hw->nvm.hw_semaphore_timeout) {
790			i40e_debug(hw, I40E_DEBUG_ALL,
791				   "NVMUPD: write semaphore expired (%d >= %lld), retrying\n",
792				   gtime, hw->nvm.hw_semaphore_timeout);
793			i40e_release_nvm(hw);
794			status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
795			if (status) {
796				i40e_debug(hw, I40E_DEBUG_ALL,
797					   "NVMUPD: write semaphore reacquire failed aq_err = %d\n",
798					   hw->aq.asq_last_status);
799				status = old_status;
800				hw->aq.asq_last_status = old_asq_status;
801			} else {
802				retry_attempt = true;
803				goto retry;
804			}
805		}
806	}
807
808	return status;
809}
810
811/**
812 * i40e_nvmupd_validate_command - Validate given command
813 * @hw: pointer to hardware structure
814 * @cmd: pointer to nvm update command buffer
815 * @errno: pointer to return error code
816 *
817 * Return one of the valid command types or I40E_NVMUPD_INVALID
818 **/
819static enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
820						 struct i40e_nvm_access *cmd,
821						 int *errno)
822{
823	enum i40e_nvmupd_cmd upd_cmd;
824	u8 transaction;
825
826	/* anything that doesn't match a recognized case is an error */
827	upd_cmd = I40E_NVMUPD_INVALID;
828
829	transaction = i40e_nvmupd_get_transaction(cmd->config);
830
831	/* limits on data size */
832	if ((cmd->data_size < 1) ||
833	    (cmd->data_size > I40E_NVMUPD_MAX_DATA)) {
834		i40e_debug(hw, I40E_DEBUG_NVM,
835			   "i40e_nvmupd_validate_command data_size %d\n",
836			   cmd->data_size);
837		*errno = -EFAULT;
838		return I40E_NVMUPD_INVALID;
839	}
840
841	switch (cmd->command) {
842	case I40E_NVM_READ:
843		switch (transaction) {
844		case I40E_NVM_CON:
845			upd_cmd = I40E_NVMUPD_READ_CON;
846			break;
847		case I40E_NVM_SNT:
848			upd_cmd = I40E_NVMUPD_READ_SNT;
849			break;
850		case I40E_NVM_LCB:
851			upd_cmd = I40E_NVMUPD_READ_LCB;
852			break;
853		case I40E_NVM_SA:
854			upd_cmd = I40E_NVMUPD_READ_SA;
855			break;
856		}
857		break;
858
859	case I40E_NVM_WRITE:
860		switch (transaction) {
861		case I40E_NVM_CON:
862			upd_cmd = I40E_NVMUPD_WRITE_CON;
863			break;
864		case I40E_NVM_SNT:
865			upd_cmd = I40E_NVMUPD_WRITE_SNT;
866			break;
867		case I40E_NVM_LCB:
868			upd_cmd = I40E_NVMUPD_WRITE_LCB;
869			break;
870		case I40E_NVM_SA:
871			upd_cmd = I40E_NVMUPD_WRITE_SA;
872			break;
873		case I40E_NVM_ERA:
874			upd_cmd = I40E_NVMUPD_WRITE_ERA;
875			break;
876		case I40E_NVM_CSUM:
877			upd_cmd = I40E_NVMUPD_CSUM_CON;
878			break;
879		case (I40E_NVM_CSUM|I40E_NVM_SA):
880			upd_cmd = I40E_NVMUPD_CSUM_SA;
881			break;
882		case (I40E_NVM_CSUM|I40E_NVM_LCB):
883			upd_cmd = I40E_NVMUPD_CSUM_LCB;
884			break;
885		}
886		break;
887	}
888	i40e_debug(hw, I40E_DEBUG_NVM, "%s state %d nvm_release_on_hold %d\n",
889		   i40e_nvm_update_state_str[upd_cmd],
890		   hw->nvmupd_state,
891		   hw->aq.nvm_release_on_done);
892
893	if (upd_cmd == I40E_NVMUPD_INVALID) {
894		*errno = -EFAULT;
895		i40e_debug(hw, I40E_DEBUG_NVM,
896			   "i40e_nvmupd_validate_command returns %d errno %d\n",
897			   upd_cmd, *errno);
898	}
899	return upd_cmd;
900}
901
902/**
903 * i40e_nvmupd_nvm_read - Read NVM
904 * @hw: pointer to hardware structure
905 * @cmd: pointer to nvm update command buffer
906 * @bytes: pointer to the data buffer
907 * @errno: pointer to return error code
908 *
909 * cmd structure contains identifiers and data buffer
910 **/
911static i40e_status i40e_nvmupd_nvm_read(struct i40e_hw *hw,
912					struct i40e_nvm_access *cmd,
913					u8 *bytes, int *errno)
914{
915	i40e_status status;
916	u8 module, transaction;
917	bool last;
918
919	transaction = i40e_nvmupd_get_transaction(cmd->config);
920	module = i40e_nvmupd_get_module(cmd->config);
921	last = (transaction == I40E_NVM_LCB) || (transaction == I40E_NVM_SA);
922
923	status = i40e_aq_read_nvm(hw, module, cmd->offset, (u16)cmd->data_size,
924				  bytes, last, NULL);
925	if (status) {
926		i40e_debug(hw, I40E_DEBUG_NVM,
927			   "i40e_nvmupd_nvm_read mod 0x%x  off 0x%x  len 0x%x\n",
928			   module, cmd->offset, cmd->data_size);
929		i40e_debug(hw, I40E_DEBUG_NVM,
930			   "i40e_nvmupd_nvm_read status %d aq %d\n",
931			   status, hw->aq.asq_last_status);
932		*errno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
933	}
934
935	return status;
936}
937
938/**
939 * i40e_nvmupd_nvm_erase - Erase an NVM module
940 * @hw: pointer to hardware structure
941 * @cmd: pointer to nvm update command buffer
942 * @errno: pointer to return error code
943 *
944 * module, offset, data_size and data are in cmd structure
945 **/
946static i40e_status i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
947					 struct i40e_nvm_access *cmd,
948					 int *errno)
949{
950	i40e_status status = 0;
951	u8 module, transaction;
952	bool last;
953
954	transaction = i40e_nvmupd_get_transaction(cmd->config);
955	module = i40e_nvmupd_get_module(cmd->config);
956	last = (transaction & I40E_NVM_LCB);
957	status = i40e_aq_erase_nvm(hw, module, cmd->offset, (u16)cmd->data_size,
958				   last, NULL);
959	if (status) {
960		i40e_debug(hw, I40E_DEBUG_NVM,
961			   "i40e_nvmupd_nvm_erase mod 0x%x  off 0x%x len 0x%x\n",
962			   module, cmd->offset, cmd->data_size);
963		i40e_debug(hw, I40E_DEBUG_NVM,
964			   "i40e_nvmupd_nvm_erase status %d aq %d\n",
965			   status, hw->aq.asq_last_status);
966		*errno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
967	}
968
969	return status;
970}
971
972/**
973 * i40e_nvmupd_nvm_write - Write NVM
974 * @hw: pointer to hardware structure
975 * @cmd: pointer to nvm update command buffer
976 * @bytes: pointer to the data buffer
977 * @errno: pointer to return error code
978 *
979 * module, offset, data_size and data are in cmd structure
980 **/
981static i40e_status i40e_nvmupd_nvm_write(struct i40e_hw *hw,
982					 struct i40e_nvm_access *cmd,
983					 u8 *bytes, int *errno)
984{
985	i40e_status status = 0;
986	u8 module, transaction;
987	bool last;
988
989	transaction = i40e_nvmupd_get_transaction(cmd->config);
990	module = i40e_nvmupd_get_module(cmd->config);
991	last = (transaction & I40E_NVM_LCB);
992
993	status = i40e_aq_update_nvm(hw, module, cmd->offset,
994				    (u16)cmd->data_size, bytes, last, NULL);
995	if (status) {
996		i40e_debug(hw, I40E_DEBUG_NVM,
997			   "i40e_nvmupd_nvm_write mod 0x%x off 0x%x len 0x%x\n",
998			   module, cmd->offset, cmd->data_size);
999		i40e_debug(hw, I40E_DEBUG_NVM,
1000			   "i40e_nvmupd_nvm_write status %d aq %d\n",
1001			   status, hw->aq.asq_last_status);
1002		*errno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
1003	}
1004
1005	return status;
1006}
1007