Skip to content

Commit 544cd2a

Browse files
stcudzidavem330
authored andcommitted
ice: Add AdminQ commands for FW update
Add structures, identifiers, and helper functions for several AdminQ commands related to performing a firmware update for the ice hardware. These will be used in future code for implementing the devlink .flash_update handler. Signed-off-by: Cudzilo, Szymon T <[email protected]> Signed-off-by: Jacob Keller <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent de9b277 commit 544cd2a

File tree

5 files changed

+281
-2
lines changed

5 files changed

+281
-2
lines changed

drivers/net/ethernet/intel/ice/ice_adminq_cmd.h

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,7 +1299,14 @@ struct ice_aqc_nvm {
12991299
#define ICE_AQC_NVM_PRESERVATION_M (3 << ICE_AQC_NVM_PRESERVATION_S)
13001300
#define ICE_AQC_NVM_NO_PRESERVATION (0 << ICE_AQC_NVM_PRESERVATION_S)
13011301
#define ICE_AQC_NVM_PRESERVE_ALL BIT(1)
1302+
#define ICE_AQC_NVM_FACTORY_DEFAULT (2 << ICE_AQC_NVM_PRESERVATION_S)
13021303
#define ICE_AQC_NVM_PRESERVE_SELECTED (3 << ICE_AQC_NVM_PRESERVATION_S)
1304+
#define ICE_AQC_NVM_ACTIV_SEL_NVM BIT(3) /* Write Activate/SR Dump only */
1305+
#define ICE_AQC_NVM_ACTIV_SEL_OROM BIT(4)
1306+
#define ICE_AQC_NVM_ACTIV_SEL_NETLIST BIT(5)
1307+
#define ICE_AQC_NVM_SPECIAL_UPDATE BIT(6)
1308+
#define ICE_AQC_NVM_REVERT_LAST_ACTIV BIT(6) /* Write Activate only */
1309+
#define ICE_AQC_NVM_ACTIV_SEL_MASK ICE_M(0x7, 3)
13031310
#define ICE_AQC_NVM_FLASH_ONLY BIT(7)
13041311
__le16 module_typeid;
13051312
__le16 length;
@@ -1348,6 +1355,67 @@ struct ice_aqc_nvm_checksum {
13481355
#define ICE_AQC_NVM_NETLIST_ID_BLK_SHA_HASH 0xA
13491356
#define ICE_AQC_NVM_NETLIST_ID_BLK_CUST_VER 0x2F
13501357

1358+
/* Used for NVM Set Package Data command - 0x070A */
1359+
struct ice_aqc_nvm_pkg_data {
1360+
u8 reserved[3];
1361+
u8 cmd_flags;
1362+
#define ICE_AQC_NVM_PKG_DELETE BIT(0) /* used for command call */
1363+
#define ICE_AQC_NVM_PKG_SKIPPED BIT(0) /* used for command response */
1364+
1365+
u32 reserved1;
1366+
__le32 addr_high;
1367+
__le32 addr_low;
1368+
};
1369+
1370+
/* Used for Pass Component Table command - 0x070B */
1371+
struct ice_aqc_nvm_pass_comp_tbl {
1372+
u8 component_response; /* Response only */
1373+
#define ICE_AQ_NVM_PASS_COMP_CAN_BE_UPDATED 0x0
1374+
#define ICE_AQ_NVM_PASS_COMP_CAN_MAY_BE_UPDATEABLE 0x1
1375+
#define ICE_AQ_NVM_PASS_COMP_CAN_NOT_BE_UPDATED 0x2
1376+
u8 component_response_code; /* Response only */
1377+
#define ICE_AQ_NVM_PASS_COMP_CAN_BE_UPDATED_CODE 0x0
1378+
#define ICE_AQ_NVM_PASS_COMP_STAMP_IDENTICAL_CODE 0x1
1379+
#define ICE_AQ_NVM_PASS_COMP_STAMP_LOWER 0x2
1380+
#define ICE_AQ_NVM_PASS_COMP_INVALID_STAMP_CODE 0x3
1381+
#define ICE_AQ_NVM_PASS_COMP_CONFLICT_CODE 0x4
1382+
#define ICE_AQ_NVM_PASS_COMP_PRE_REQ_NOT_MET_CODE 0x5
1383+
#define ICE_AQ_NVM_PASS_COMP_NOT_SUPPORTED_CODE 0x6
1384+
#define ICE_AQ_NVM_PASS_COMP_CANNOT_DOWNGRADE_CODE 0x7
1385+
#define ICE_AQ_NVM_PASS_COMP_INCOMPLETE_IMAGE_CODE 0x8
1386+
#define ICE_AQ_NVM_PASS_COMP_VER_STR_IDENTICAL_CODE 0xA
1387+
#define ICE_AQ_NVM_PASS_COMP_VER_STR_LOWER_CODE 0xB
1388+
u8 reserved;
1389+
u8 transfer_flag;
1390+
#define ICE_AQ_NVM_PASS_COMP_TBL_START 0x1
1391+
#define ICE_AQ_NVM_PASS_COMP_TBL_MIDDLE 0x2
1392+
#define ICE_AQ_NVM_PASS_COMP_TBL_END 0x4
1393+
#define ICE_AQ_NVM_PASS_COMP_TBL_START_AND_END 0x5
1394+
__le32 reserved1;
1395+
__le32 addr_high;
1396+
__le32 addr_low;
1397+
};
1398+
1399+
struct ice_aqc_nvm_comp_tbl {
1400+
__le16 comp_class;
1401+
#define NVM_COMP_CLASS_ALL_FW 0x000A
1402+
1403+
__le16 comp_id;
1404+
#define NVM_COMP_ID_OROM 0x5
1405+
#define NVM_COMP_ID_NVM 0x6
1406+
#define NVM_COMP_ID_NETLIST 0x8
1407+
1408+
u8 comp_class_idx;
1409+
#define FWU_COMP_CLASS_IDX_NOT_USE 0x0
1410+
1411+
__le32 comp_cmp_stamp;
1412+
u8 cvs_type;
1413+
#define NVM_CVS_TYPE_ASCII 0x1
1414+
1415+
u8 cvs_len;
1416+
u8 cvs[]; /* Component Version String */
1417+
} __packed;
1418+
13511419
/**
13521420
* Send to PF command (indirect 0x0801) ID is only used by PF
13531421
*
@@ -1795,6 +1863,8 @@ struct ice_aq_desc {
17951863
struct ice_aqc_rl_profile rl_profile;
17961864
struct ice_aqc_nvm nvm;
17971865
struct ice_aqc_nvm_checksum nvm_checksum;
1866+
struct ice_aqc_nvm_pkg_data pkg_data;
1867+
struct ice_aqc_nvm_pass_comp_tbl pass_comp_tbl;
17981868
struct ice_aqc_pf_vf_msg virt;
17991869
struct ice_aqc_lldp_get_mib lldp_get_mib;
18001870
struct ice_aqc_lldp_set_mib_change lldp_set_event;
@@ -1923,7 +1993,13 @@ enum ice_adminq_opc {
19231993

19241994
/* NVM commands */
19251995
ice_aqc_opc_nvm_read = 0x0701,
1996+
ice_aqc_opc_nvm_erase = 0x0702,
1997+
ice_aqc_opc_nvm_write = 0x0703,
19261998
ice_aqc_opc_nvm_checksum = 0x0706,
1999+
ice_aqc_opc_nvm_write_activate = 0x0707,
2000+
ice_aqc_opc_nvm_update_empr = 0x0709,
2001+
ice_aqc_opc_nvm_pkg_data = 0x070A,
2002+
ice_aqc_opc_nvm_pass_component_tbl = 0x070B,
19272003

19282004
/* PF/VF mailbox commands */
19292005
ice_mbx_opc_send_msg_to_pf = 0x0801,

drivers/net/ethernet/intel/ice/ice_common.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
#include "ice_switch.h"
1212
#include <linux/avf/virtchnl.h>
1313

14-
enum ice_status ice_nvm_validate_checksum(struct ice_hw *hw);
15-
1614
enum ice_status ice_init_hw(struct ice_hw *hw);
1715
void ice_deinit_hw(struct ice_hw *hw);
1816
enum ice_status ice_check_reset(struct ice_hw *hw);

drivers/net/ethernet/intel/ice/ice_nvm.c

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,76 @@ ice_read_flat_nvm(struct ice_hw *hw, u32 offset, u32 *length, u8 *data,
107107
return status;
108108
}
109109

110+
/**
111+
* ice_aq_update_nvm
112+
* @hw: pointer to the HW struct
113+
* @module_typeid: module pointer location in words from the NVM beginning
114+
* @offset: byte offset from the module beginning
115+
* @length: length of the section to be written (in bytes from the offset)
116+
* @data: command buffer (size [bytes] = length)
117+
* @last_command: tells if this is the last command in a series
118+
* @command_flags: command parameters
119+
* @cd: pointer to command details structure or NULL
120+
*
121+
* Update the NVM using the admin queue commands (0x0703)
122+
*/
123+
enum ice_status
124+
ice_aq_update_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset,
125+
u16 length, void *data, bool last_command, u8 command_flags,
126+
struct ice_sq_cd *cd)
127+
{
128+
struct ice_aq_desc desc;
129+
struct ice_aqc_nvm *cmd;
130+
131+
cmd = &desc.params.nvm;
132+
133+
/* In offset the highest byte must be zeroed. */
134+
if (offset & 0xFF000000)
135+
return ICE_ERR_PARAM;
136+
137+
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_write);
138+
139+
cmd->cmd_flags |= command_flags;
140+
141+
/* If this is the last command in a series, set the proper flag. */
142+
if (last_command)
143+
cmd->cmd_flags |= ICE_AQC_NVM_LAST_CMD;
144+
cmd->module_typeid = cpu_to_le16(module_typeid);
145+
cmd->offset_low = cpu_to_le16(offset & 0xFFFF);
146+
cmd->offset_high = (offset >> 16) & 0xFF;
147+
cmd->length = cpu_to_le16(length);
148+
149+
desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
150+
151+
return ice_aq_send_cmd(hw, &desc, data, length, cd);
152+
}
153+
154+
/**
155+
* ice_aq_erase_nvm
156+
* @hw: pointer to the HW struct
157+
* @module_typeid: module pointer location in words from the NVM beginning
158+
* @cd: pointer to command details structure or NULL
159+
*
160+
* Erase the NVM sector using the admin queue commands (0x0702)
161+
*/
162+
enum ice_status
163+
ice_aq_erase_nvm(struct ice_hw *hw, u16 module_typeid, struct ice_sq_cd *cd)
164+
{
165+
struct ice_aq_desc desc;
166+
struct ice_aqc_nvm *cmd;
167+
168+
cmd = &desc.params.nvm;
169+
170+
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_erase);
171+
172+
cmd->module_typeid = cpu_to_le16(module_typeid);
173+
cmd->length = cpu_to_le16(ICE_AQC_NVM_ERASE_LEN);
174+
cmd->offset_low = 0;
175+
cmd->offset_high = 0;
176+
177+
return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
178+
}
179+
110180
/**
111181
* ice_read_sr_word_aq - Reads Shadow RAM via AQ
112182
* @hw: pointer to the HW structure
@@ -634,3 +704,119 @@ enum ice_status ice_nvm_validate_checksum(struct ice_hw *hw)
634704

635705
return status;
636706
}
707+
708+
/**
709+
* ice_nvm_write_activate
710+
* @hw: pointer to the HW struct
711+
* @cmd_flags: NVM activate admin command bits (banks to be validated)
712+
*
713+
* Update the control word with the required banks' validity bits
714+
* and dumps the Shadow RAM to flash (0x0707)
715+
*/
716+
enum ice_status ice_nvm_write_activate(struct ice_hw *hw, u8 cmd_flags)
717+
{
718+
struct ice_aqc_nvm *cmd;
719+
struct ice_aq_desc desc;
720+
721+
cmd = &desc.params.nvm;
722+
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_write_activate);
723+
724+
cmd->cmd_flags = cmd_flags;
725+
726+
return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
727+
}
728+
729+
/**
730+
* ice_aq_nvm_update_empr
731+
* @hw: pointer to the HW struct
732+
*
733+
* Update empr (0x0709). This command allows SW to
734+
* request an EMPR to activate new FW.
735+
*/
736+
enum ice_status ice_aq_nvm_update_empr(struct ice_hw *hw)
737+
{
738+
struct ice_aq_desc desc;
739+
740+
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_update_empr);
741+
742+
return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
743+
}
744+
745+
/* ice_nvm_set_pkg_data
746+
* @hw: pointer to the HW struct
747+
* @del_pkg_data_flag: If is set then the current pkg_data store by FW
748+
* is deleted.
749+
* If bit is set to 1, then buffer should be size 0.
750+
* @data: pointer to buffer
751+
* @length: length of the buffer
752+
* @cd: pointer to command details structure or NULL
753+
*
754+
* Set package data (0x070A). This command is equivalent to the reception
755+
* of a PLDM FW Update GetPackageData cmd. This command should be sent
756+
* as part of the NVM update as the first cmd in the flow.
757+
*/
758+
759+
enum ice_status
760+
ice_nvm_set_pkg_data(struct ice_hw *hw, bool del_pkg_data_flag, u8 *data,
761+
u16 length, struct ice_sq_cd *cd)
762+
{
763+
struct ice_aqc_nvm_pkg_data *cmd;
764+
struct ice_aq_desc desc;
765+
766+
if (length != 0 && !data)
767+
return ICE_ERR_PARAM;
768+
769+
cmd = &desc.params.pkg_data;
770+
771+
ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_nvm_pkg_data);
772+
desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
773+
774+
if (del_pkg_data_flag)
775+
cmd->cmd_flags |= ICE_AQC_NVM_PKG_DELETE;
776+
777+
return ice_aq_send_cmd(hw, &desc, data, length, cd);
778+
}
779+
780+
/* ice_nvm_pass_component_tbl
781+
* @hw: pointer to the HW struct
782+
* @data: pointer to buffer
783+
* @length: length of the buffer
784+
* @transfer_flag: parameter for determining stage of the update
785+
* @comp_response: a pointer to the response from the 0x070B AQC.
786+
* @comp_response_code: a pointer to the response code from the 0x070B AQC.
787+
* @cd: pointer to command details structure or NULL
788+
*
789+
* Pass component table (0x070B). This command is equivalent to the reception
790+
* of a PLDM FW Update PassComponentTable cmd. This command should be sent once
791+
* per component. It can be only sent after Set Package Data cmd and before
792+
* actual update. FW will assume these commands are going to be sent until
793+
* the TransferFlag is set to End or StartAndEnd.
794+
*/
795+
796+
enum ice_status
797+
ice_nvm_pass_component_tbl(struct ice_hw *hw, u8 *data, u16 length,
798+
u8 transfer_flag, u8 *comp_response,
799+
u8 *comp_response_code, struct ice_sq_cd *cd)
800+
{
801+
struct ice_aqc_nvm_pass_comp_tbl *cmd;
802+
struct ice_aq_desc desc;
803+
enum ice_status status;
804+
805+
if (!data || !comp_response || !comp_response_code)
806+
return ICE_ERR_PARAM;
807+
808+
cmd = &desc.params.pass_comp_tbl;
809+
810+
ice_fill_dflt_direct_cmd_desc(&desc,
811+
ice_aqc_opc_nvm_pass_component_tbl);
812+
desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
813+
814+
cmd->transfer_flag = transfer_flag;
815+
status = ice_aq_send_cmd(hw, &desc, data, length, cd);
816+
817+
if (!status) {
818+
*comp_response = cmd->component_response;
819+
*comp_response_code = cmd->component_response_code;
820+
}
821+
return status;
822+
}

drivers/net/ethernet/intel/ice/ice_nvm.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,20 @@ enum ice_status
1717
ice_read_pba_string(struct ice_hw *hw, u8 *pba_num, u32 pba_num_size);
1818
enum ice_status ice_init_nvm(struct ice_hw *hw);
1919
enum ice_status ice_read_sr_word(struct ice_hw *hw, u16 offset, u16 *data);
20+
enum ice_status
21+
ice_aq_update_nvm(struct ice_hw *hw, u16 module_typeid, u32 offset,
22+
u16 length, void *data, bool last_command, u8 command_flags,
23+
struct ice_sq_cd *cd);
24+
enum ice_status
25+
ice_aq_erase_nvm(struct ice_hw *hw, u16 module_typeid, struct ice_sq_cd *cd);
26+
enum ice_status ice_nvm_validate_checksum(struct ice_hw *hw);
27+
enum ice_status ice_nvm_write_activate(struct ice_hw *hw, u8 cmd_flags);
28+
enum ice_status ice_aq_nvm_update_empr(struct ice_hw *hw);
29+
enum ice_status
30+
ice_nvm_set_pkg_data(struct ice_hw *hw, bool del_pkg_data_flag, u8 *data,
31+
u16 length, struct ice_sq_cd *cd);
32+
enum ice_status
33+
ice_nvm_pass_component_tbl(struct ice_hw *hw, u8 *data, u16 length,
34+
u8 transfer_flag, u8 *comp_response,
35+
u8 *comp_response_code, struct ice_sq_cd *cd);
2036
#endif /* _ICE_NVM_H_ */

drivers/net/ethernet/intel/ice/ice_type.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,9 @@ struct ice_hw_port_stats {
774774
#define ICE_OROM_VER_SHIFT 24
775775
#define ICE_OROM_VER_MASK (0xff << ICE_OROM_VER_SHIFT)
776776
#define ICE_SR_PFA_PTR 0x40
777+
#define ICE_SR_1ST_NVM_BANK_PTR 0x42
778+
#define ICE_SR_1ST_OROM_BANK_PTR 0x44
779+
#define ICE_SR_NETLIST_BANK_PTR 0x46
777780
#define ICE_SR_SECTOR_SIZE_IN_WORDS 0x800
778781

779782
/* Link override related */

0 commit comments

Comments
 (0)