cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

i40e_nvm.c (48566B)


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