aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_adminq.c21
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_adminq.h36
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_common.c88
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_ethtool.c61
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_nvm.c511
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_prototype.h7
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_type.h58
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_adminq.c6
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_adminq.h36
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_type.h58
10 files changed, 866 insertions, 16 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
index 0e551f281d59..1e21fbb1359c 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
@@ -38,8 +38,8 @@ static void i40e_resume_aq(struct i40e_hw *hw);
38 **/ 38 **/
39static inline bool i40e_is_nvm_update_op(struct i40e_aq_desc *desc) 39static inline bool i40e_is_nvm_update_op(struct i40e_aq_desc *desc)
40{ 40{
41 return (desc->opcode == i40e_aqc_opc_nvm_erase) || 41 return (desc->opcode == cpu_to_le16(i40e_aqc_opc_nvm_erase)) ||
42 (desc->opcode == i40e_aqc_opc_nvm_update); 42 (desc->opcode == cpu_to_le16(i40e_aqc_opc_nvm_update));
43} 43}
44 44
45/** 45/**
@@ -889,9 +889,6 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
889 hw->aq.asq_last_status = (enum i40e_admin_queue_err)retval; 889 hw->aq.asq_last_status = (enum i40e_admin_queue_err)retval;
890 } 890 }
891 891
892 if (i40e_is_nvm_update_op(desc))
893 hw->aq.nvm_busy = true;
894
895 if (le16_to_cpu(desc->datalen) == buff_size) { 892 if (le16_to_cpu(desc->datalen) == buff_size) {
896 i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, 893 i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
897 "AQTX: desc and buffer writeback:\n"); 894 "AQTX: desc and buffer writeback:\n");
@@ -907,6 +904,9 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
907 status = I40E_ERR_ADMIN_QUEUE_TIMEOUT; 904 status = I40E_ERR_ADMIN_QUEUE_TIMEOUT;
908 } 905 }
909 906
907 if (!status && i40e_is_nvm_update_op(desc))
908 hw->aq.nvm_busy = true;
909
910asq_send_command_error: 910asq_send_command_error:
911 mutex_unlock(&hw->aq.asq_mutex); 911 mutex_unlock(&hw->aq.asq_mutex);
912asq_send_command_exit: 912asq_send_command_exit:
@@ -988,9 +988,6 @@ i40e_status i40e_clean_arq_element(struct i40e_hw *hw,
988 e->msg_size); 988 e->msg_size);
989 } 989 }
990 990
991 if (i40e_is_nvm_update_op(&e->desc))
992 hw->aq.nvm_busy = false;
993
994 i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQRX: desc and buffer:\n"); 991 i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQRX: desc and buffer:\n");
995 i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, e->msg_buf); 992 i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, e->msg_buf);
996 993
@@ -1023,6 +1020,14 @@ clean_arq_element_out:
1023 *pending = (ntc > ntu ? hw->aq.arq.count : 0) + (ntu - ntc); 1020 *pending = (ntc > ntu ? hw->aq.arq.count : 0) + (ntu - ntc);
1024 mutex_unlock(&hw->aq.arq_mutex); 1021 mutex_unlock(&hw->aq.arq_mutex);
1025 1022
1023 if (i40e_is_nvm_update_op(&e->desc)) {
1024 hw->aq.nvm_busy = false;
1025 if (hw->aq.nvm_release_on_done) {
1026 i40e_release_nvm(hw);
1027 hw->aq.nvm_release_on_done = false;
1028 }
1029 }
1030
1026 return ret_code; 1031 return ret_code;
1027} 1032}
1028 1033
diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.h b/drivers/net/ethernet/intel/i40e/i40e_adminq.h
index bb76be1d38f7..ba38a89c79d6 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.h
@@ -94,6 +94,7 @@ struct i40e_adminq_info {
94 u16 api_maj_ver; /* api major version */ 94 u16 api_maj_ver; /* api major version */
95 u16 api_min_ver; /* api minor version */ 95 u16 api_min_ver; /* api minor version */
96 bool nvm_busy; 96 bool nvm_busy;
97 bool nvm_release_on_done;
97 98
98 struct mutex asq_mutex; /* Send queue lock */ 99 struct mutex asq_mutex; /* Send queue lock */
99 struct mutex arq_mutex; /* Receive queue lock */ 100 struct mutex arq_mutex; /* Receive queue lock */
@@ -103,6 +104,41 @@ struct i40e_adminq_info {
103 enum i40e_admin_queue_err arq_last_status; 104 enum i40e_admin_queue_err arq_last_status;
104}; 105};
105 106
107/**
108 * i40e_aq_rc_to_posix - convert errors to user-land codes
109 * aq_rc: AdminQ error code to convert
110 **/
111static inline int i40e_aq_rc_to_posix(u16 aq_rc)
112{
113 int aq_to_posix[] = {
114 0, /* I40E_AQ_RC_OK */
115 -EPERM, /* I40E_AQ_RC_EPERM */
116 -ENOENT, /* I40E_AQ_RC_ENOENT */
117 -ESRCH, /* I40E_AQ_RC_ESRCH */
118 -EINTR, /* I40E_AQ_RC_EINTR */
119 -EIO, /* I40E_AQ_RC_EIO */
120 -ENXIO, /* I40E_AQ_RC_ENXIO */
121 -E2BIG, /* I40E_AQ_RC_E2BIG */
122 -EAGAIN, /* I40E_AQ_RC_EAGAIN */
123 -ENOMEM, /* I40E_AQ_RC_ENOMEM */
124 -EACCES, /* I40E_AQ_RC_EACCES */
125 -EFAULT, /* I40E_AQ_RC_EFAULT */
126 -EBUSY, /* I40E_AQ_RC_EBUSY */
127 -EEXIST, /* I40E_AQ_RC_EEXIST */
128 -EINVAL, /* I40E_AQ_RC_EINVAL */
129 -ENOTTY, /* I40E_AQ_RC_ENOTTY */
130 -ENOSPC, /* I40E_AQ_RC_ENOSPC */
131 -ENOSYS, /* I40E_AQ_RC_ENOSYS */
132 -ERANGE, /* I40E_AQ_RC_ERANGE */
133 -EPIPE, /* I40E_AQ_RC_EFLUSHED */
134 -ESPIPE, /* I40E_AQ_RC_BAD_ADDR */
135 -EROFS, /* I40E_AQ_RC_EMODE */
136 -EFBIG, /* I40E_AQ_RC_EFBIG */
137 };
138
139 return aq_to_posix[aq_rc];
140}
141
106/* general information */ 142/* general information */
107#define I40E_AQ_LARGE_BUF 512 143#define I40E_AQ_LARGE_BUF 512
108#define I40E_ASQ_CMD_TIMEOUT 100000 /* usecs */ 144#define I40E_ASQ_CMD_TIMEOUT 100000 /* usecs */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index c65f4e8e6cee..f4e502a305ff 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -2121,6 +2121,47 @@ i40e_aq_read_nvm_exit:
2121 return status; 2121 return status;
2122} 2122}
2123 2123
2124/**
2125 * i40e_aq_erase_nvm
2126 * @hw: pointer to the hw struct
2127 * @module_pointer: module pointer location in words from the NVM beginning
2128 * @offset: offset in the module (expressed in 4 KB from module's beginning)
2129 * @length: length of the section to be erased (expressed in 4 KB)
2130 * @last_command: tells if this is the last command in a series
2131 * @cmd_details: pointer to command details structure or NULL
2132 *
2133 * Erase the NVM sector using the admin queue commands
2134 **/
2135i40e_status i40e_aq_erase_nvm(struct i40e_hw *hw, u8 module_pointer,
2136 u32 offset, u16 length, bool last_command,
2137 struct i40e_asq_cmd_details *cmd_details)
2138{
2139 struct i40e_aq_desc desc;
2140 struct i40e_aqc_nvm_update *cmd =
2141 (struct i40e_aqc_nvm_update *)&desc.params.raw;
2142 i40e_status status;
2143
2144 /* In offset the highest byte must be zeroed. */
2145 if (offset & 0xFF000000) {
2146 status = I40E_ERR_PARAM;
2147 goto i40e_aq_erase_nvm_exit;
2148 }
2149
2150 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_erase);
2151
2152 /* If this is the last command in a series, set the proper flag. */
2153 if (last_command)
2154 cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
2155 cmd->module_pointer = module_pointer;
2156 cmd->offset = cpu_to_le32(offset);
2157 cmd->length = cpu_to_le16(length);
2158
2159 status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
2160
2161i40e_aq_erase_nvm_exit:
2162 return status;
2163}
2164
2124#define I40E_DEV_FUNC_CAP_SWITCH_MODE 0x01 2165#define I40E_DEV_FUNC_CAP_SWITCH_MODE 0x01
2125#define I40E_DEV_FUNC_CAP_MGMT_MODE 0x02 2166#define I40E_DEV_FUNC_CAP_MGMT_MODE 0x02
2126#define I40E_DEV_FUNC_CAP_NPAR 0x03 2167#define I40E_DEV_FUNC_CAP_NPAR 0x03
@@ -2351,6 +2392,53 @@ exit:
2351} 2392}
2352 2393
2353/** 2394/**
2395 * i40e_aq_update_nvm
2396 * @hw: pointer to the hw struct
2397 * @module_pointer: module pointer location in words from the NVM beginning
2398 * @offset: byte offset from the module beginning
2399 * @length: length of the section to be written (in bytes from the offset)
2400 * @data: command buffer (size [bytes] = length)
2401 * @last_command: tells if this is the last command in a series
2402 * @cmd_details: pointer to command details structure or NULL
2403 *
2404 * Update the NVM using the admin queue commands
2405 **/
2406i40e_status i40e_aq_update_nvm(struct i40e_hw *hw, u8 module_pointer,
2407 u32 offset, u16 length, void *data,
2408 bool last_command,
2409 struct i40e_asq_cmd_details *cmd_details)
2410{
2411 struct i40e_aq_desc desc;
2412 struct i40e_aqc_nvm_update *cmd =
2413 (struct i40e_aqc_nvm_update *)&desc.params.raw;
2414 i40e_status status;
2415
2416 /* In offset the highest byte must be zeroed. */
2417 if (offset & 0xFF000000) {
2418 status = I40E_ERR_PARAM;
2419 goto i40e_aq_update_nvm_exit;
2420 }
2421
2422 i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_update);
2423
2424 /* If this is the last command in a series, set the proper flag. */
2425 if (last_command)
2426 cmd->command_flags |= I40E_AQ_NVM_LAST_CMD;
2427 cmd->module_pointer = module_pointer;
2428 cmd->offset = cpu_to_le32(offset);
2429 cmd->length = cpu_to_le16(length);
2430
2431 desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
2432 if (length > I40E_AQ_LARGE_BUF)
2433 desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
2434
2435 status = i40e_asq_send_command(hw, &desc, data, length, cmd_details);
2436
2437i40e_aq_update_nvm_exit:
2438 return status;
2439}
2440
2441/**
2354 * i40e_aq_get_lldp_mib 2442 * i40e_aq_get_lldp_mib
2355 * @hw: pointer to the hw struct 2443 * @hw: pointer to the hw struct
2356 * @bridge_type: type of bridge requested 2444 * @bridge_type: type of bridge requested
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index 3abd3cbab75f..f1d241ec1fc3 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -759,10 +759,33 @@ static int i40e_get_eeprom(struct net_device *netdev,
759 u8 *eeprom_buff; 759 u8 *eeprom_buff;
760 u16 i, sectors; 760 u16 i, sectors;
761 bool last; 761 bool last;
762 u32 magic;
763
762#define I40E_NVM_SECTOR_SIZE 4096 764#define I40E_NVM_SECTOR_SIZE 4096
763 if (eeprom->len == 0) 765 if (eeprom->len == 0)
764 return -EINVAL; 766 return -EINVAL;
765 767
768 /* check for NVMUpdate access method */
769 magic = hw->vendor_id | (hw->device_id << 16);
770 if (eeprom->magic && eeprom->magic != magic) {
771 int errno;
772
773 /* make sure it is the right magic for NVMUpdate */
774 if ((eeprom->magic >> 16) != hw->device_id)
775 return -EINVAL;
776
777 ret_val = i40e_nvmupd_command(hw,
778 (struct i40e_nvm_access *)eeprom,
779 bytes, &errno);
780 if (ret_val)
781 dev_info(&pf->pdev->dev,
782 "NVMUpdate read failed err=%d status=0x%x\n",
783 ret_val, hw->aq.asq_last_status);
784
785 return errno;
786 }
787
788 /* normal ethtool get_eeprom support */
766 eeprom->magic = hw->vendor_id | (hw->device_id << 16); 789 eeprom->magic = hw->vendor_id | (hw->device_id << 16);
767 790
768 eeprom_buff = kzalloc(eeprom->len, GFP_KERNEL); 791 eeprom_buff = kzalloc(eeprom->len, GFP_KERNEL);
@@ -789,7 +812,7 @@ static int i40e_get_eeprom(struct net_device *netdev,
789 ret_val = i40e_aq_read_nvm(hw, 0x0, 812 ret_val = i40e_aq_read_nvm(hw, 0x0,
790 eeprom->offset + (I40E_NVM_SECTOR_SIZE * i), 813 eeprom->offset + (I40E_NVM_SECTOR_SIZE * i),
791 len, 814 len,
792 eeprom_buff + (I40E_NVM_SECTOR_SIZE * i), 815 (u8 *)eeprom_buff + (I40E_NVM_SECTOR_SIZE * i),
793 last, NULL); 816 last, NULL);
794 if (ret_val) { 817 if (ret_val) {
795 dev_info(&pf->pdev->dev, 818 dev_info(&pf->pdev->dev,
@@ -801,7 +824,7 @@ static int i40e_get_eeprom(struct net_device *netdev,
801 824
802release_nvm: 825release_nvm:
803 i40e_release_nvm(hw); 826 i40e_release_nvm(hw);
804 memcpy(bytes, eeprom_buff, eeprom->len); 827 memcpy(bytes, (u8 *)eeprom_buff, eeprom->len);
805free_buff: 828free_buff:
806 kfree(eeprom_buff); 829 kfree(eeprom_buff);
807 return ret_val; 830 return ret_val;
@@ -821,6 +844,39 @@ static int i40e_get_eeprom_len(struct net_device *netdev)
821 return val; 844 return val;
822} 845}
823 846
847static int i40e_set_eeprom(struct net_device *netdev,
848 struct ethtool_eeprom *eeprom, u8 *bytes)
849{
850 struct i40e_netdev_priv *np = netdev_priv(netdev);
851 struct i40e_hw *hw = &np->vsi->back->hw;
852 struct i40e_pf *pf = np->vsi->back;
853 int ret_val = 0;
854 int errno;
855 u32 magic;
856
857 /* normal ethtool set_eeprom is not supported */
858 magic = hw->vendor_id | (hw->device_id << 16);
859 if (eeprom->magic == magic)
860 return -EOPNOTSUPP;
861
862 /* check for NVMUpdate access method */
863 if (!eeprom->magic || (eeprom->magic >> 16) != hw->device_id)
864 return -EINVAL;
865
866 if (test_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state) ||
867 test_bit(__I40E_RESET_INTR_RECEIVED, &pf->state))
868 return -EBUSY;
869
870 ret_val = i40e_nvmupd_command(hw, (struct i40e_nvm_access *)eeprom,
871 bytes, &errno);
872 if (ret_val)
873 dev_info(&pf->pdev->dev,
874 "NVMUpdate write failed err=%d status=0x%x\n",
875 ret_val, hw->aq.asq_last_status);
876
877 return errno;
878}
879
824static void i40e_get_drvinfo(struct net_device *netdev, 880static void i40e_get_drvinfo(struct net_device *netdev,
825 struct ethtool_drvinfo *drvinfo) 881 struct ethtool_drvinfo *drvinfo)
826{ 882{
@@ -2094,6 +2150,7 @@ static const struct ethtool_ops i40e_ethtool_ops = {
2094 .get_link = ethtool_op_get_link, 2150 .get_link = ethtool_op_get_link,
2095 .get_wol = i40e_get_wol, 2151 .get_wol = i40e_get_wol,
2096 .set_wol = i40e_set_wol, 2152 .set_wol = i40e_set_wol,
2153 .set_eeprom = i40e_set_eeprom,
2097 .get_eeprom_len = i40e_get_eeprom_len, 2154 .get_eeprom_len = i40e_get_eeprom_len,
2098 .get_eeprom = i40e_get_eeprom, 2155 .get_eeprom = i40e_get_eeprom,
2099 .get_ringparam = i40e_get_ringparam, 2156 .get_ringparam = i40e_get_ringparam,
diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
index 66bcb15422da..97bda3dffd49 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
@@ -241,6 +241,46 @@ i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
241} 241}
242 242
243/** 243/**
244 * i40e_write_nvm_aq - Writes Shadow RAM.
245 * @hw: pointer to the HW structure.
246 * @module_pointer: module pointer location in words from the NVM beginning
247 * @offset: offset in words from module start
248 * @words: number of words to write
249 * @data: buffer with words to write to the Shadow RAM
250 * @last_command: tells the AdminQ that this is the last command
251 *
252 * Writes a 16 bit words buffer to the Shadow RAM using the admin command.
253 **/
254i40e_status i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
255 u32 offset, u16 words, void *data,
256 bool last_command)
257{
258 i40e_status ret_code = I40E_ERR_NVM;
259
260 /* Here we are checking the SR limit only for the flat memory model.
261 * We cannot do it for the module-based model, as we did not acquire
262 * the NVM resource yet (we cannot get the module pointer value).
263 * Firmware will check the module-based model.
264 */
265 if ((offset + words) > hw->nvm.sr_size)
266 hw_dbg(hw, "NVM write error: offset beyond Shadow RAM limit.\n");
267 else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS)
268 /* We can write only up to 4KB (one sector), in one AQ write */
269 hw_dbg(hw, "NVM write fail error: cannot write more than 4KB in a single write.\n");
270 else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS)
271 != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS))
272 /* A single write cannot spread over two sectors */
273 hw_dbg(hw, "NVM write error: cannot spread over two sectors in a single write.\n");
274 else
275 ret_code = i40e_aq_update_nvm(hw, module_pointer,
276 2 * offset, /*bytes*/
277 2 * words, /*bytes*/
278 data, last_command, NULL);
279
280 return ret_code;
281}
282
283/**
244 * i40e_calc_nvm_checksum - Calculates and returns the checksum 284 * i40e_calc_nvm_checksum - Calculates and returns the checksum
245 * @hw: pointer to hardware structure 285 * @hw: pointer to hardware structure
246 * @checksum: pointer to the checksum 286 * @checksum: pointer to the checksum
@@ -310,6 +350,27 @@ i40e_calc_nvm_checksum_exit:
310} 350}
311 351
312/** 352/**
353 * i40e_update_nvm_checksum - Updates the NVM checksum
354 * @hw: pointer to hardware structure
355 *
356 * NVM ownership must be acquired before calling this function and released
357 * on ARQ completion event reception by caller.
358 * This function will commit SR to NVM.
359 **/
360i40e_status i40e_update_nvm_checksum(struct i40e_hw *hw)
361{
362 i40e_status ret_code = 0;
363 u16 checksum;
364
365 ret_code = i40e_calc_nvm_checksum(hw, &checksum);
366 if (!ret_code)
367 ret_code = i40e_write_nvm_aq(hw, 0x00, I40E_SR_SW_CHECKSUM_WORD,
368 1, &checksum, true);
369
370 return ret_code;
371}
372
373/**
313 * i40e_validate_nvm_checksum - Validate EEPROM checksum 374 * i40e_validate_nvm_checksum - Validate EEPROM checksum
314 * @hw: pointer to hardware structure 375 * @hw: pointer to hardware structure
315 * @checksum: calculated checksum 376 * @checksum: calculated checksum
@@ -346,3 +407,453 @@ i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
346i40e_validate_nvm_checksum_exit: 407i40e_validate_nvm_checksum_exit:
347 return ret_code; 408 return ret_code;
348} 409}
410
411static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
412 struct i40e_nvm_access *cmd,
413 u8 *bytes, int *errno);
414static i40e_status i40e_nvmupd_state_reading(struct i40e_hw *hw,
415 struct i40e_nvm_access *cmd,
416 u8 *bytes, int *errno);
417static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
418 struct i40e_nvm_access *cmd,
419 u8 *bytes, int *errno);
420static enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
421 struct i40e_nvm_access *cmd,
422 int *errno);
423static i40e_status i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
424 struct i40e_nvm_access *cmd,
425 int *errno);
426static i40e_status i40e_nvmupd_nvm_write(struct i40e_hw *hw,
427 struct i40e_nvm_access *cmd,
428 u8 *bytes, int *errno);
429static i40e_status i40e_nvmupd_nvm_read(struct i40e_hw *hw,
430 struct i40e_nvm_access *cmd,
431 u8 *bytes, int *errno);
432static inline u8 i40e_nvmupd_get_module(u32 val)
433{
434 return (u8)(val & I40E_NVM_MOD_PNT_MASK);
435}
436static inline u8 i40e_nvmupd_get_transaction(u32 val)
437{
438 return (u8)((val & I40E_NVM_TRANS_MASK) >> I40E_NVM_TRANS_SHIFT);
439}
440
441/**
442 * i40e_nvmupd_command - Process an NVM update command
443 * @hw: pointer to hardware structure
444 * @cmd: pointer to nvm update command
445 * @bytes: pointer to the data buffer
446 * @errno: pointer to return error code
447 *
448 * Dispatches command depending on what update state is current
449 **/
450i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
451 struct i40e_nvm_access *cmd,
452 u8 *bytes, int *errno)
453{
454 i40e_status status;
455
456 /* assume success */
457 *errno = 0;
458
459 switch (hw->nvmupd_state) {
460 case I40E_NVMUPD_STATE_INIT:
461 status = i40e_nvmupd_state_init(hw, cmd, bytes, errno);
462 break;
463
464 case I40E_NVMUPD_STATE_READING:
465 status = i40e_nvmupd_state_reading(hw, cmd, bytes, errno);
466 break;
467
468 case I40E_NVMUPD_STATE_WRITING:
469 status = i40e_nvmupd_state_writing(hw, cmd, bytes, errno);
470 break;
471
472 default:
473 /* invalid state, should never happen */
474 status = I40E_NOT_SUPPORTED;
475 *errno = -ESRCH;
476 break;
477 }
478 return status;
479}
480
481/**
482 * i40e_nvmupd_state_init - Handle NVM update state Init
483 * @hw: pointer to hardware structure
484 * @cmd: pointer to nvm update command buffer
485 * @bytes: pointer to the data buffer
486 * @errno: pointer to return error code
487 *
488 * Process legitimate commands of the Init state and conditionally set next
489 * state. Reject all other commands.
490 **/
491static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
492 struct i40e_nvm_access *cmd,
493 u8 *bytes, int *errno)
494{
495 i40e_status status = 0;
496 enum i40e_nvmupd_cmd upd_cmd;
497
498 upd_cmd = i40e_nvmupd_validate_command(hw, cmd, errno);
499
500 switch (upd_cmd) {
501 case I40E_NVMUPD_READ_SA:
502 status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
503 if (status) {
504 *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
505 } else {
506 status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno);
507 i40e_release_nvm(hw);
508 }
509 break;
510
511 case I40E_NVMUPD_READ_SNT:
512 status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
513 if (status) {
514 *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
515 } else {
516 status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno);
517 hw->nvmupd_state = I40E_NVMUPD_STATE_READING;
518 }
519 break;
520
521 case I40E_NVMUPD_WRITE_ERA:
522 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
523 if (status) {
524 *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
525 } else {
526 status = i40e_nvmupd_nvm_erase(hw, cmd, errno);
527 if (status)
528 i40e_release_nvm(hw);
529 else
530 hw->aq.nvm_release_on_done = true;
531 }
532 break;
533
534 case I40E_NVMUPD_WRITE_SA:
535 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
536 if (status) {
537 *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
538 } else {
539 status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno);
540 if (status)
541 i40e_release_nvm(hw);
542 else
543 hw->aq.nvm_release_on_done = true;
544 }
545 break;
546
547 case I40E_NVMUPD_WRITE_SNT:
548 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
549 if (status) {
550 *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
551 } else {
552 status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno);
553 hw->nvmupd_state = I40E_NVMUPD_STATE_WRITING;
554 }
555 break;
556
557 case I40E_NVMUPD_CSUM_SA:
558 status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
559 if (status) {
560 *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
561 } else {
562 status = i40e_update_nvm_checksum(hw);
563 if (status) {
564 *errno = hw->aq.asq_last_status ?
565 i40e_aq_rc_to_posix(hw->aq.asq_last_status) :
566 -EIO;
567 i40e_release_nvm(hw);
568 } else {
569 hw->aq.nvm_release_on_done = true;
570 }
571 }
572 break;
573
574 default:
575 status = I40E_ERR_NVM;
576 *errno = -ESRCH;
577 break;
578 }
579 return status;
580}
581
582/**
583 * i40e_nvmupd_state_reading - Handle NVM update state Reading
584 * @hw: pointer to hardware structure
585 * @cmd: pointer to nvm update command buffer
586 * @bytes: pointer to the data buffer
587 * @errno: pointer to return error code
588 *
589 * NVM ownership is already held. Process legitimate commands and set any
590 * change in state; reject all other commands.
591 **/
592static i40e_status i40e_nvmupd_state_reading(struct i40e_hw *hw,
593 struct i40e_nvm_access *cmd,
594 u8 *bytes, int *errno)
595{
596 i40e_status status;
597 enum i40e_nvmupd_cmd upd_cmd;
598
599 upd_cmd = i40e_nvmupd_validate_command(hw, cmd, errno);
600
601 switch (upd_cmd) {
602 case I40E_NVMUPD_READ_SA:
603 case I40E_NVMUPD_READ_CON:
604 status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno);
605 break;
606
607 case I40E_NVMUPD_READ_LCB:
608 status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno);
609 i40e_release_nvm(hw);
610 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
611 break;
612
613 default:
614 status = I40E_NOT_SUPPORTED;
615 *errno = -ESRCH;
616 break;
617 }
618 return status;
619}
620
621/**
622 * i40e_nvmupd_state_writing - Handle NVM update state Writing
623 * @hw: pointer to hardware structure
624 * @cmd: pointer to nvm update command buffer
625 * @bytes: pointer to the data buffer
626 * @errno: pointer to return error code
627 *
628 * NVM ownership is already held. Process legitimate commands and set any
629 * change in state; reject all other commands
630 **/
631static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
632 struct i40e_nvm_access *cmd,
633 u8 *bytes, int *errno)
634{
635 i40e_status status;
636 enum i40e_nvmupd_cmd upd_cmd;
637
638 upd_cmd = i40e_nvmupd_validate_command(hw, cmd, errno);
639
640 switch (upd_cmd) {
641 case I40E_NVMUPD_WRITE_CON:
642 status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno);
643 break;
644
645 case I40E_NVMUPD_WRITE_LCB:
646 status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno);
647 if (!status) {
648 hw->aq.nvm_release_on_done = true;
649 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
650 }
651 break;
652
653 case I40E_NVMUPD_CSUM_CON:
654 status = i40e_update_nvm_checksum(hw);
655 if (status)
656 *errno = hw->aq.asq_last_status ?
657 i40e_aq_rc_to_posix(hw->aq.asq_last_status) :
658 -EIO;
659 break;
660
661 case I40E_NVMUPD_CSUM_LCB:
662 status = i40e_update_nvm_checksum(hw);
663 if (status) {
664 *errno = hw->aq.asq_last_status ?
665 i40e_aq_rc_to_posix(hw->aq.asq_last_status) :
666 -EIO;
667 } else {
668 hw->aq.nvm_release_on_done = true;
669 hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
670 }
671 break;
672
673 default:
674 status = I40E_NOT_SUPPORTED;
675 *errno = -ESRCH;
676 break;
677 }
678 return status;
679}
680
681/**
682 * i40e_nvmupd_validate_command - Validate given command
683 * @hw: pointer to hardware structure
684 * @cmd: pointer to nvm update command buffer
685 * @errno: pointer to return error code
686 *
687 * Return one of the valid command types or I40E_NVMUPD_INVALID
688 **/
689static enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
690 struct i40e_nvm_access *cmd,
691 int *errno)
692{
693 enum i40e_nvmupd_cmd upd_cmd;
694 u8 transaction, module;
695
696 /* anything that doesn't match a recognized case is an error */
697 upd_cmd = I40E_NVMUPD_INVALID;
698
699 transaction = i40e_nvmupd_get_transaction(cmd->config);
700 module = i40e_nvmupd_get_module(cmd->config);
701
702 /* limits on data size */
703 if ((cmd->data_size < 1) ||
704 (cmd->data_size > I40E_NVMUPD_MAX_DATA)) {
705 hw_dbg(hw, "i40e_nvmupd_validate_command data_size %d\n",
706 cmd->data_size);
707 *errno = -EFAULT;
708 return I40E_NVMUPD_INVALID;
709 }
710
711 switch (cmd->command) {
712 case I40E_NVM_READ:
713 switch (transaction) {
714 case I40E_NVM_CON:
715 upd_cmd = I40E_NVMUPD_READ_CON;
716 break;
717 case I40E_NVM_SNT:
718 upd_cmd = I40E_NVMUPD_READ_SNT;
719 break;
720 case I40E_NVM_LCB:
721 upd_cmd = I40E_NVMUPD_READ_LCB;
722 break;
723 case I40E_NVM_SA:
724 upd_cmd = I40E_NVMUPD_READ_SA;
725 break;
726 }
727 break;
728
729 case I40E_NVM_WRITE:
730 switch (transaction) {
731 case I40E_NVM_CON:
732 upd_cmd = I40E_NVMUPD_WRITE_CON;
733 break;
734 case I40E_NVM_SNT:
735 upd_cmd = I40E_NVMUPD_WRITE_SNT;
736 break;
737 case I40E_NVM_LCB:
738 upd_cmd = I40E_NVMUPD_WRITE_LCB;
739 break;
740 case I40E_NVM_SA:
741 upd_cmd = I40E_NVMUPD_WRITE_SA;
742 break;
743 case I40E_NVM_ERA:
744 upd_cmd = I40E_NVMUPD_WRITE_ERA;
745 break;
746 case I40E_NVM_CSUM:
747 upd_cmd = I40E_NVMUPD_CSUM_CON;
748 break;
749 case (I40E_NVM_CSUM|I40E_NVM_SA):
750 upd_cmd = I40E_NVMUPD_CSUM_SA;
751 break;
752 case (I40E_NVM_CSUM|I40E_NVM_LCB):
753 upd_cmd = I40E_NVMUPD_CSUM_LCB;
754 break;
755 }
756 break;
757 }
758
759 if (upd_cmd == I40E_NVMUPD_INVALID) {
760 *errno = -EFAULT;
761 hw_dbg(hw,
762 "i40e_nvmupd_validate_command returns %d errno: %d\n",
763 upd_cmd, *errno);
764 }
765 return upd_cmd;
766}
767
768/**
769 * i40e_nvmupd_nvm_read - Read NVM
770 * @hw: pointer to hardware structure
771 * @cmd: pointer to nvm update command buffer
772 * @bytes: pointer to the data buffer
773 * @errno: pointer to return error code
774 *
775 * cmd structure contains identifiers and data buffer
776 **/
777static i40e_status i40e_nvmupd_nvm_read(struct i40e_hw *hw,
778 struct i40e_nvm_access *cmd,
779 u8 *bytes, int *errno)
780{
781 i40e_status status;
782 u8 module, transaction;
783 bool last;
784
785 transaction = i40e_nvmupd_get_transaction(cmd->config);
786 module = i40e_nvmupd_get_module(cmd->config);
787 last = (transaction == I40E_NVM_LCB) || (transaction == I40E_NVM_SA);
788 hw_dbg(hw, "i40e_nvmupd_nvm_read mod 0x%x off 0x%x len 0x%x\n",
789 module, cmd->offset, cmd->data_size);
790
791 status = i40e_aq_read_nvm(hw, module, cmd->offset, (u16)cmd->data_size,
792 bytes, last, NULL);
793 hw_dbg(hw, "i40e_nvmupd_nvm_read status %d\n", status);
794 if (status)
795 *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
796
797 return status;
798}
799
800/**
801 * i40e_nvmupd_nvm_erase - Erase an NVM module
802 * @hw: pointer to hardware structure
803 * @cmd: pointer to nvm update command buffer
804 * @errno: pointer to return error code
805 *
806 * module, offset, data_size and data are in cmd structure
807 **/
808static i40e_status i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
809 struct i40e_nvm_access *cmd,
810 int *errno)
811{
812 i40e_status status = 0;
813 u8 module, transaction;
814 bool last;
815
816 transaction = i40e_nvmupd_get_transaction(cmd->config);
817 module = i40e_nvmupd_get_module(cmd->config);
818 last = (transaction & I40E_NVM_LCB);
819 hw_dbg(hw, "i40e_nvmupd_nvm_erase mod 0x%x off 0x%x len 0x%x\n",
820 module, cmd->offset, cmd->data_size);
821 status = i40e_aq_erase_nvm(hw, module, cmd->offset, (u16)cmd->data_size,
822 last, NULL);
823 hw_dbg(hw, "i40e_nvmupd_nvm_erase status %d\n", status);
824 if (status)
825 *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
826
827 return status;
828}
829
830/**
831 * i40e_nvmupd_nvm_write - Write NVM
832 * @hw: pointer to hardware structure
833 * @cmd: pointer to nvm update command buffer
834 * @bytes: pointer to the data buffer
835 * @errno: pointer to return error code
836 *
837 * module, offset, data_size and data are in cmd structure
838 **/
839static i40e_status i40e_nvmupd_nvm_write(struct i40e_hw *hw,
840 struct i40e_nvm_access *cmd,
841 u8 *bytes, int *errno)
842{
843 i40e_status status = 0;
844 u8 module, transaction;
845 bool last;
846
847 transaction = i40e_nvmupd_get_transaction(cmd->config);
848 module = i40e_nvmupd_get_module(cmd->config);
849 last = (transaction & I40E_NVM_LCB);
850 hw_dbg(hw, "i40e_nvmupd_nvm_write mod 0x%x off 0x%x len 0x%x\n",
851 module, cmd->offset, cmd->data_size);
852 status = i40e_aq_update_nvm(hw, module, cmd->offset,
853 (u16)cmd->data_size, bytes, last, NULL);
854 hw_dbg(hw, "i40e_nvmupd_nvm_write status %d\n", status);
855 if (status)
856 *errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
857
858 return status;
859}
diff --git a/drivers/net/ethernet/intel/i40e/i40e_prototype.h b/drivers/net/ethernet/intel/i40e/i40e_prototype.h
index 9383f08ff4e3..a91d7e1a5b5b 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_prototype.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_prototype.h
@@ -150,6 +150,9 @@ i40e_status i40e_aq_read_nvm(struct i40e_hw *hw, u8 module_pointer,
150 u32 offset, u16 length, void *data, 150 u32 offset, u16 length, void *data,
151 bool last_command, 151 bool last_command,
152 struct i40e_asq_cmd_details *cmd_details); 152 struct i40e_asq_cmd_details *cmd_details);
153i40e_status i40e_aq_erase_nvm(struct i40e_hw *hw, u8 module_pointer,
154 u32 offset, u16 length, bool last_command,
155 struct i40e_asq_cmd_details *cmd_details);
153i40e_status i40e_aq_discover_capabilities(struct i40e_hw *hw, 156i40e_status i40e_aq_discover_capabilities(struct i40e_hw *hw,
154 void *buff, u16 buff_size, u16 *data_size, 157 void *buff, u16 buff_size, u16 *data_size,
155 enum i40e_admin_queue_opc list_type_opc, 158 enum i40e_admin_queue_opc list_type_opc,
@@ -245,8 +248,12 @@ i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
245 u16 *data); 248 u16 *data);
246i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset, 249i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
247 u16 *words, u16 *data); 250 u16 *words, u16 *data);
251i40e_status i40e_update_nvm_checksum(struct i40e_hw *hw);
248i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw, 252i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
249 u16 *checksum); 253 u16 *checksum);
254i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
255 struct i40e_nvm_access *cmd,
256 u8 *bytes, int *);
250void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status); 257void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status);
251 258
252extern struct i40e_rx_ptype_decoded i40e_ptype_lookup[]; 259extern struct i40e_rx_ptype_decoded i40e_ptype_lookup[];
diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h
index 1fcf2205ffe6..8bb9049191cb 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_type.h
@@ -269,6 +269,61 @@ struct i40e_nvm_info {
269 u32 eetrack; /* NVM data version */ 269 u32 eetrack; /* NVM data version */
270}; 270};
271 271
272/* definitions used in NVM update support */
273
274enum i40e_nvmupd_cmd {
275 I40E_NVMUPD_INVALID,
276 I40E_NVMUPD_READ_CON,
277 I40E_NVMUPD_READ_SNT,
278 I40E_NVMUPD_READ_LCB,
279 I40E_NVMUPD_READ_SA,
280 I40E_NVMUPD_WRITE_ERA,
281 I40E_NVMUPD_WRITE_CON,
282 I40E_NVMUPD_WRITE_SNT,
283 I40E_NVMUPD_WRITE_LCB,
284 I40E_NVMUPD_WRITE_SA,
285 I40E_NVMUPD_CSUM_CON,
286 I40E_NVMUPD_CSUM_SA,
287 I40E_NVMUPD_CSUM_LCB,
288};
289
290enum i40e_nvmupd_state {
291 I40E_NVMUPD_STATE_INIT,
292 I40E_NVMUPD_STATE_READING,
293 I40E_NVMUPD_STATE_WRITING
294};
295
296/* nvm_access definition and its masks/shifts need to be accessible to
297 * application, core driver, and shared code. Where is the right file?
298 */
299#define I40E_NVM_READ 0xB
300#define I40E_NVM_WRITE 0xC
301
302#define I40E_NVM_MOD_PNT_MASK 0xFF
303
304#define I40E_NVM_TRANS_SHIFT 8
305#define I40E_NVM_TRANS_MASK (0xf << I40E_NVM_TRANS_SHIFT)
306#define I40E_NVM_CON 0x0
307#define I40E_NVM_SNT 0x1
308#define I40E_NVM_LCB 0x2
309#define I40E_NVM_SA (I40E_NVM_SNT | I40E_NVM_LCB)
310#define I40E_NVM_ERA 0x4
311#define I40E_NVM_CSUM 0x8
312
313#define I40E_NVM_ADAPT_SHIFT 16
314#define I40E_NVM_ADAPT_MASK (0xffff << I40E_NVM_ADAPT_SHIFT)
315
316#define I40E_NVMUPD_MAX_DATA 4096
317#define I40E_NVMUPD_IFACE_TIMEOUT 2 /* seconds */
318
319struct i40e_nvm_access {
320 u32 command;
321 u32 config;
322 u32 offset; /* in bytes */
323 u32 data_size; /* in bytes */
324 u8 data[1];
325};
326
272/* PCI bus types */ 327/* PCI bus types */
273enum i40e_bus_type { 328enum i40e_bus_type {
274 i40e_bus_type_unknown = 0, 329 i40e_bus_type_unknown = 0,
@@ -404,6 +459,9 @@ struct i40e_hw {
404 /* Admin Queue info */ 459 /* Admin Queue info */
405 struct i40e_adminq_info aq; 460 struct i40e_adminq_info aq;
406 461
462 /* state of nvm update process */
463 enum i40e_nvmupd_state nvmupd_state;
464
407 /* HMC info */ 465 /* HMC info */
408 struct i40e_hmc_info hmc; /* HMC info struct */ 466 struct i40e_hmc_info hmc; /* HMC info struct */
409 467
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq.c b/drivers/net/ethernet/intel/i40evf/i40e_adminq.c
index 8330744b02f1..ee3a934043bb 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_adminq.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq.c
@@ -708,12 +708,6 @@ i40e_status i40evf_asq_send_command(struct i40e_hw *hw,
708 goto asq_send_command_exit; 708 goto asq_send_command_exit;
709 } 709 }
710 710
711 if (i40e_is_nvm_update_op(desc) && hw->aq.nvm_busy) {
712 i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: NVM busy.\n");
713 status = I40E_ERR_NVM;
714 goto asq_send_command_exit;
715 }
716
717 details = I40E_ADMINQ_DETAILS(hw->aq.asq, hw->aq.asq.next_to_use); 711 details = I40E_ADMINQ_DETAILS(hw->aq.asq, hw->aq.asq.next_to_use);
718 if (cmd_details) { 712 if (cmd_details) {
719 *details = *cmd_details; 713 *details = *cmd_details;
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq.h b/drivers/net/ethernet/intel/i40evf/i40e_adminq.h
index 162845589bf7..91a5c5bd80f3 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_adminq.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq.h
@@ -94,6 +94,7 @@ struct i40e_adminq_info {
94 u16 api_maj_ver; /* api major version */ 94 u16 api_maj_ver; /* api major version */
95 u16 api_min_ver; /* api minor version */ 95 u16 api_min_ver; /* api minor version */
96 bool nvm_busy; 96 bool nvm_busy;
97 bool nvm_release_on_done;
97 98
98 struct mutex asq_mutex; /* Send queue lock */ 99 struct mutex asq_mutex; /* Send queue lock */
99 struct mutex arq_mutex; /* Receive queue lock */ 100 struct mutex arq_mutex; /* Receive queue lock */
@@ -103,6 +104,41 @@ struct i40e_adminq_info {
103 enum i40e_admin_queue_err arq_last_status; 104 enum i40e_admin_queue_err arq_last_status;
104}; 105};
105 106
107/**
108 * i40e_aq_rc_to_posix - convert errors to user-land codes
109 * aq_rc: AdminQ error code to convert
110 **/
111static inline int i40e_aq_rc_to_posix(u16 aq_rc)
112{
113 int aq_to_posix[] = {
114 0, /* I40E_AQ_RC_OK */
115 -EPERM, /* I40E_AQ_RC_EPERM */
116 -ENOENT, /* I40E_AQ_RC_ENOENT */
117 -ESRCH, /* I40E_AQ_RC_ESRCH */
118 -EINTR, /* I40E_AQ_RC_EINTR */
119 -EIO, /* I40E_AQ_RC_EIO */
120 -ENXIO, /* I40E_AQ_RC_ENXIO */
121 -E2BIG, /* I40E_AQ_RC_E2BIG */
122 -EAGAIN, /* I40E_AQ_RC_EAGAIN */
123 -ENOMEM, /* I40E_AQ_RC_ENOMEM */
124 -EACCES, /* I40E_AQ_RC_EACCES */
125 -EFAULT, /* I40E_AQ_RC_EFAULT */
126 -EBUSY, /* I40E_AQ_RC_EBUSY */
127 -EEXIST, /* I40E_AQ_RC_EEXIST */
128 -EINVAL, /* I40E_AQ_RC_EINVAL */
129 -ENOTTY, /* I40E_AQ_RC_ENOTTY */
130 -ENOSPC, /* I40E_AQ_RC_ENOSPC */
131 -ENOSYS, /* I40E_AQ_RC_ENOSYS */
132 -ERANGE, /* I40E_AQ_RC_ERANGE */
133 -EPIPE, /* I40E_AQ_RC_EFLUSHED */
134 -ESPIPE, /* I40E_AQ_RC_BAD_ADDR */
135 -EROFS, /* I40E_AQ_RC_EMODE */
136 -EFBIG, /* I40E_AQ_RC_EFBIG */
137 };
138
139 return aq_to_posix[aq_rc];
140}
141
106/* general information */ 142/* general information */
107#define I40E_AQ_LARGE_BUF 512 143#define I40E_AQ_LARGE_BUF 512
108#define I40E_ASQ_CMD_TIMEOUT 100000 /* usecs */ 144#define I40E_ASQ_CMD_TIMEOUT 100000 /* usecs */
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_type.h b/drivers/net/ethernet/intel/i40evf/i40e_type.h
index 6dd72ad58e7d..15376436cead 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_type.h
@@ -268,6 +268,61 @@ struct i40e_nvm_info {
268 u32 eetrack; /* NVM data version */ 268 u32 eetrack; /* NVM data version */
269}; 269};
270 270
271/* definitions used in NVM update support */
272
273enum i40e_nvmupd_cmd {
274 I40E_NVMUPD_INVALID,
275 I40E_NVMUPD_READ_CON,
276 I40E_NVMUPD_READ_SNT,
277 I40E_NVMUPD_READ_LCB,
278 I40E_NVMUPD_READ_SA,
279 I40E_NVMUPD_WRITE_ERA,
280 I40E_NVMUPD_WRITE_CON,
281 I40E_NVMUPD_WRITE_SNT,
282 I40E_NVMUPD_WRITE_LCB,
283 I40E_NVMUPD_WRITE_SA,
284 I40E_NVMUPD_CSUM_CON,
285 I40E_NVMUPD_CSUM_SA,
286 I40E_NVMUPD_CSUM_LCB,
287};
288
289enum i40e_nvmupd_state {
290 I40E_NVMUPD_STATE_INIT,
291 I40E_NVMUPD_STATE_READING,
292 I40E_NVMUPD_STATE_WRITING
293};
294
295/* nvm_access definition and its masks/shifts need to be accessible to
296 * application, core driver, and shared code. Where is the right file?
297 */
298#define I40E_NVM_READ 0xB
299#define I40E_NVM_WRITE 0xC
300
301#define I40E_NVM_MOD_PNT_MASK 0xFF
302
303#define I40E_NVM_TRANS_SHIFT 8
304#define I40E_NVM_TRANS_MASK (0xf << I40E_NVM_TRANS_SHIFT)
305#define I40E_NVM_CON 0x0
306#define I40E_NVM_SNT 0x1
307#define I40E_NVM_LCB 0x2
308#define I40E_NVM_SA (I40E_NVM_SNT | I40E_NVM_LCB)
309#define I40E_NVM_ERA 0x4
310#define I40E_NVM_CSUM 0x8
311
312#define I40E_NVM_ADAPT_SHIFT 16
313#define I40E_NVM_ADAPT_MASK (0xffff << I40E_NVM_ADAPT_SHIFT)
314
315#define I40E_NVMUPD_MAX_DATA 4096
316#define I40E_NVMUPD_IFACE_TIMEOUT 2 /* seconds */
317
318struct i40e_nvm_access {
319 u32 command;
320 u32 config;
321 u32 offset; /* in bytes */
322 u32 data_size; /* in bytes */
323 u8 data[1];
324};
325
271/* PCI bus types */ 326/* PCI bus types */
272enum i40e_bus_type { 327enum i40e_bus_type {
273 i40e_bus_type_unknown = 0, 328 i40e_bus_type_unknown = 0,
@@ -403,6 +458,9 @@ struct i40e_hw {
403 /* Admin Queue info */ 458 /* Admin Queue info */
404 struct i40e_adminq_info aq; 459 struct i40e_adminq_info aq;
405 460
461 /* state of nvm update process */
462 enum i40e_nvmupd_state nvmupd_state;
463
406 /* HMC info */ 464 /* HMC info */
407 struct i40e_hmc_info hmc; /* HMC info struct */ 465 struct i40e_hmc_info hmc; /* HMC info struct */
408 466