17ec59eeaSAnirudh Venkataramanan // SPDX-License-Identifier: GPL-2.0
27ec59eeaSAnirudh Venkataramanan /* Copyright (c) 2018, Intel Corporation. */
37ec59eeaSAnirudh Venkataramanan 
47ec59eeaSAnirudh Venkataramanan #include "ice_common.h"
5348048e7SDave Ertman #include "ice_lib.h"
69c20346bSAnirudh Venkataramanan #include "ice_sched.h"
77ec59eeaSAnirudh Venkataramanan #include "ice_adminq_cmd.h"
8c90ed40cSTony Nguyen #include "ice_flow.h"
97ec59eeaSAnirudh Venkataramanan 
1071245072SJacob Keller #define ICE_PF_RESET_WAIT_COUNT	300
11f31e4b6fSAnirudh Venkataramanan 
12f31e4b6fSAnirudh Venkataramanan /**
13f31e4b6fSAnirudh Venkataramanan  * ice_set_mac_type - Sets MAC type
14f31e4b6fSAnirudh Venkataramanan  * @hw: pointer to the HW structure
15f31e4b6fSAnirudh Venkataramanan  *
16f31e4b6fSAnirudh Venkataramanan  * This function sets the MAC type of the adapter based on the
17f9867df6SAnirudh Venkataramanan  * vendor ID and device ID stored in the HW structure.
18f31e4b6fSAnirudh Venkataramanan  */
19*5e24d598STony Nguyen static int ice_set_mac_type(struct ice_hw *hw)
20f31e4b6fSAnirudh Venkataramanan {
21f31e4b6fSAnirudh Venkataramanan 	if (hw->vendor_id != PCI_VENDOR_ID_INTEL)
22f31e4b6fSAnirudh Venkataramanan 		return ICE_ERR_DEVICE_NOT_SUPPORTED;
23f31e4b6fSAnirudh Venkataramanan 
24ea78ce4dSPaul Greenwalt 	switch (hw->device_id) {
25ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E810C_BACKPLANE:
26ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E810C_QSFP:
27ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E810C_SFP:
287dcf78b8STony Nguyen 	case ICE_DEV_ID_E810_XXV_BACKPLANE:
297dcf78b8STony Nguyen 	case ICE_DEV_ID_E810_XXV_QSFP:
30ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E810_XXV_SFP:
31ea78ce4dSPaul Greenwalt 		hw->mac_type = ICE_MAC_E810;
32ea78ce4dSPaul Greenwalt 		break;
33ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E823C_10G_BASE_T:
34ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E823C_BACKPLANE:
35ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E823C_QSFP:
36ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E823C_SFP:
37ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E823C_SGMII:
38ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E822C_10G_BASE_T:
39ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E822C_BACKPLANE:
40ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E822C_QSFP:
41ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E822C_SFP:
42ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E822C_SGMII:
43ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E822L_10G_BASE_T:
44ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E822L_BACKPLANE:
45ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E822L_SFP:
46ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E822L_SGMII:
47ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E823L_10G_BASE_T:
48ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E823L_1GBE:
49ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E823L_BACKPLANE:
50ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E823L_QSFP:
51ea78ce4dSPaul Greenwalt 	case ICE_DEV_ID_E823L_SFP:
52f31e4b6fSAnirudh Venkataramanan 		hw->mac_type = ICE_MAC_GENERIC;
53ea78ce4dSPaul Greenwalt 		break;
54ea78ce4dSPaul Greenwalt 	default:
55ea78ce4dSPaul Greenwalt 		hw->mac_type = ICE_MAC_UNKNOWN;
56ea78ce4dSPaul Greenwalt 		break;
57ea78ce4dSPaul Greenwalt 	}
58ea78ce4dSPaul Greenwalt 
59ea78ce4dSPaul Greenwalt 	ice_debug(hw, ICE_DBG_INIT, "mac_type: %d\n", hw->mac_type);
60f31e4b6fSAnirudh Venkataramanan 	return 0;
61f31e4b6fSAnirudh Venkataramanan }
62f31e4b6fSAnirudh Venkataramanan 
63f31e4b6fSAnirudh Venkataramanan /**
6406c16d89SJacob Keller  * ice_is_e810
6506c16d89SJacob Keller  * @hw: pointer to the hardware structure
6606c16d89SJacob Keller  *
6706c16d89SJacob Keller  * returns true if the device is E810 based, false if not.
6806c16d89SJacob Keller  */
6906c16d89SJacob Keller bool ice_is_e810(struct ice_hw *hw)
7006c16d89SJacob Keller {
7106c16d89SJacob Keller 	return hw->mac_type == ICE_MAC_E810;
7206c16d89SJacob Keller }
7306c16d89SJacob Keller 
7406c16d89SJacob Keller /**
75885fe693SMaciej Machnikowski  * ice_is_e810t
76885fe693SMaciej Machnikowski  * @hw: pointer to the hardware structure
77885fe693SMaciej Machnikowski  *
78885fe693SMaciej Machnikowski  * returns true if the device is E810T based, false if not.
79885fe693SMaciej Machnikowski  */
80885fe693SMaciej Machnikowski bool ice_is_e810t(struct ice_hw *hw)
81885fe693SMaciej Machnikowski {
82885fe693SMaciej Machnikowski 	switch (hw->device_id) {
83885fe693SMaciej Machnikowski 	case ICE_DEV_ID_E810C_SFP:
84885fe693SMaciej Machnikowski 		if (hw->subsystem_device_id == ICE_SUBDEV_ID_E810T ||
85885fe693SMaciej Machnikowski 		    hw->subsystem_device_id == ICE_SUBDEV_ID_E810T2)
86885fe693SMaciej Machnikowski 			return true;
87885fe693SMaciej Machnikowski 		break;
88885fe693SMaciej Machnikowski 	default:
89885fe693SMaciej Machnikowski 		break;
90885fe693SMaciej Machnikowski 	}
91885fe693SMaciej Machnikowski 
92885fe693SMaciej Machnikowski 	return false;
93885fe693SMaciej Machnikowski }
94885fe693SMaciej Machnikowski 
95885fe693SMaciej Machnikowski /**
96f31e4b6fSAnirudh Venkataramanan  * ice_clear_pf_cfg - Clear PF configuration
97f31e4b6fSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
983968540bSAnirudh Venkataramanan  *
993968540bSAnirudh Venkataramanan  * Clears any existing PF configuration (VSIs, VSI lists, switch rules, port
1003968540bSAnirudh Venkataramanan  * configuration, flow director filters, etc.).
101f31e4b6fSAnirudh Venkataramanan  */
102*5e24d598STony Nguyen int ice_clear_pf_cfg(struct ice_hw *hw)
103f31e4b6fSAnirudh Venkataramanan {
104f31e4b6fSAnirudh Venkataramanan 	struct ice_aq_desc desc;
105f31e4b6fSAnirudh Venkataramanan 
106f31e4b6fSAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_clear_pf_cfg);
107f31e4b6fSAnirudh Venkataramanan 
108f31e4b6fSAnirudh Venkataramanan 	return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
109f31e4b6fSAnirudh Venkataramanan }
110f31e4b6fSAnirudh Venkataramanan 
111f31e4b6fSAnirudh Venkataramanan /**
112dc49c772SAnirudh Venkataramanan  * ice_aq_manage_mac_read - manage MAC address read command
113f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
114dc49c772SAnirudh Venkataramanan  * @buf: a virtual buffer to hold the manage MAC read response
115dc49c772SAnirudh Venkataramanan  * @buf_size: Size of the virtual buffer
116dc49c772SAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
117dc49c772SAnirudh Venkataramanan  *
118dc49c772SAnirudh Venkataramanan  * This function is used to return per PF station MAC address (0x0107).
119dc49c772SAnirudh Venkataramanan  * NOTE: Upon successful completion of this command, MAC address information
120dc49c772SAnirudh Venkataramanan  * is returned in user specified buffer. Please interpret user specified
121dc49c772SAnirudh Venkataramanan  * buffer as "manage_mac_read" response.
122dc49c772SAnirudh Venkataramanan  * Response such as various MAC addresses are stored in HW struct (port.mac)
12381aed647SJacob Keller  * ice_discover_dev_caps is expected to be called before this function is
12481aed647SJacob Keller  * called.
125dc49c772SAnirudh Venkataramanan  */
126*5e24d598STony Nguyen static int
127dc49c772SAnirudh Venkataramanan ice_aq_manage_mac_read(struct ice_hw *hw, void *buf, u16 buf_size,
128dc49c772SAnirudh Venkataramanan 		       struct ice_sq_cd *cd)
129dc49c772SAnirudh Venkataramanan {
130dc49c772SAnirudh Venkataramanan 	struct ice_aqc_manage_mac_read_resp *resp;
131dc49c772SAnirudh Venkataramanan 	struct ice_aqc_manage_mac_read *cmd;
132dc49c772SAnirudh Venkataramanan 	struct ice_aq_desc desc;
133*5e24d598STony Nguyen 	int status;
134dc49c772SAnirudh Venkataramanan 	u16 flags;
135d6fef10cSMd Fahad Iqbal Polash 	u8 i;
136dc49c772SAnirudh Venkataramanan 
137dc49c772SAnirudh Venkataramanan 	cmd = &desc.params.mac_read;
138dc49c772SAnirudh Venkataramanan 
139dc49c772SAnirudh Venkataramanan 	if (buf_size < sizeof(*resp))
140dc49c772SAnirudh Venkataramanan 		return ICE_ERR_BUF_TOO_SHORT;
141dc49c772SAnirudh Venkataramanan 
142dc49c772SAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_manage_mac_read);
143dc49c772SAnirudh Venkataramanan 
144dc49c772SAnirudh Venkataramanan 	status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
145dc49c772SAnirudh Venkataramanan 	if (status)
146dc49c772SAnirudh Venkataramanan 		return status;
147dc49c772SAnirudh Venkataramanan 
1487a63dae0SBruce Allan 	resp = buf;
149dc49c772SAnirudh Venkataramanan 	flags = le16_to_cpu(cmd->flags) & ICE_AQC_MAN_MAC_READ_M;
150dc49c772SAnirudh Venkataramanan 
151dc49c772SAnirudh Venkataramanan 	if (!(flags & ICE_AQC_MAN_MAC_LAN_ADDR_VALID)) {
152dc49c772SAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_LAN, "got invalid MAC address\n");
153dc49c772SAnirudh Venkataramanan 		return ICE_ERR_CFG;
154dc49c772SAnirudh Venkataramanan 	}
155dc49c772SAnirudh Venkataramanan 
156d6fef10cSMd Fahad Iqbal Polash 	/* A single port can report up to two (LAN and WoL) addresses */
157d6fef10cSMd Fahad Iqbal Polash 	for (i = 0; i < cmd->num_addr; i++)
158d6fef10cSMd Fahad Iqbal Polash 		if (resp[i].addr_type == ICE_AQC_MAN_MAC_ADDR_TYPE_LAN) {
159d6fef10cSMd Fahad Iqbal Polash 			ether_addr_copy(hw->port_info->mac.lan_addr,
160d6fef10cSMd Fahad Iqbal Polash 					resp[i].mac_addr);
161d6fef10cSMd Fahad Iqbal Polash 			ether_addr_copy(hw->port_info->mac.perm_addr,
162d6fef10cSMd Fahad Iqbal Polash 					resp[i].mac_addr);
163d6fef10cSMd Fahad Iqbal Polash 			break;
164d6fef10cSMd Fahad Iqbal Polash 		}
165d6fef10cSMd Fahad Iqbal Polash 
166dc49c772SAnirudh Venkataramanan 	return 0;
167dc49c772SAnirudh Venkataramanan }
168dc49c772SAnirudh Venkataramanan 
169dc49c772SAnirudh Venkataramanan /**
170dc49c772SAnirudh Venkataramanan  * ice_aq_get_phy_caps - returns PHY capabilities
171dc49c772SAnirudh Venkataramanan  * @pi: port information structure
172dc49c772SAnirudh Venkataramanan  * @qual_mods: report qualified modules
173dc49c772SAnirudh Venkataramanan  * @report_mode: report mode capabilities
174dc49c772SAnirudh Venkataramanan  * @pcaps: structure for PHY capabilities to be filled
175dc49c772SAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
176dc49c772SAnirudh Venkataramanan  *
177dc49c772SAnirudh Venkataramanan  * Returns the various PHY capabilities supported on the Port (0x0600)
178dc49c772SAnirudh Venkataramanan  */
179*5e24d598STony Nguyen int
180dc49c772SAnirudh Venkataramanan ice_aq_get_phy_caps(struct ice_port_info *pi, bool qual_mods, u8 report_mode,
181dc49c772SAnirudh Venkataramanan 		    struct ice_aqc_get_phy_caps_data *pcaps,
182dc49c772SAnirudh Venkataramanan 		    struct ice_sq_cd *cd)
183dc49c772SAnirudh Venkataramanan {
184dc49c772SAnirudh Venkataramanan 	struct ice_aqc_get_phy_caps *cmd;
185dc49c772SAnirudh Venkataramanan 	u16 pcaps_size = sizeof(*pcaps);
186dc49c772SAnirudh Venkataramanan 	struct ice_aq_desc desc;
187*5e24d598STony Nguyen 	int status;
18855df52a0SPaul Greenwalt 	struct ice_hw *hw;
189dc49c772SAnirudh Venkataramanan 
190dc49c772SAnirudh Venkataramanan 	cmd = &desc.params.get_phy;
191dc49c772SAnirudh Venkataramanan 
192dc49c772SAnirudh Venkataramanan 	if (!pcaps || (report_mode & ~ICE_AQC_REPORT_MODE_M) || !pi)
193dc49c772SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
19455df52a0SPaul Greenwalt 	hw = pi->hw;
195dc49c772SAnirudh Venkataramanan 
1960a02944fSAnirudh Venkataramanan 	if (report_mode == ICE_AQC_REPORT_DFLT_CFG &&
1970a02944fSAnirudh Venkataramanan 	    !ice_fw_supports_report_dflt_cfg(hw))
1980a02944fSAnirudh Venkataramanan 		return ICE_ERR_PARAM;
1990a02944fSAnirudh Venkataramanan 
200dc49c772SAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_phy_caps);
201dc49c772SAnirudh Venkataramanan 
202dc49c772SAnirudh Venkataramanan 	if (qual_mods)
203dc49c772SAnirudh Venkataramanan 		cmd->param0 |= cpu_to_le16(ICE_AQC_GET_PHY_RQM);
204dc49c772SAnirudh Venkataramanan 
205dc49c772SAnirudh Venkataramanan 	cmd->param0 |= cpu_to_le16(report_mode);
20655df52a0SPaul Greenwalt 	status = ice_aq_send_cmd(hw, &desc, pcaps, pcaps_size, cd);
20755df52a0SPaul Greenwalt 
20855df52a0SPaul Greenwalt 	ice_debug(hw, ICE_DBG_LINK, "get phy caps - report_mode = 0x%x\n",
20955df52a0SPaul Greenwalt 		  report_mode);
21055df52a0SPaul Greenwalt 	ice_debug(hw, ICE_DBG_LINK, "	phy_type_low = 0x%llx\n",
21155df52a0SPaul Greenwalt 		  (unsigned long long)le64_to_cpu(pcaps->phy_type_low));
21255df52a0SPaul Greenwalt 	ice_debug(hw, ICE_DBG_LINK, "	phy_type_high = 0x%llx\n",
21355df52a0SPaul Greenwalt 		  (unsigned long long)le64_to_cpu(pcaps->phy_type_high));
21455df52a0SPaul Greenwalt 	ice_debug(hw, ICE_DBG_LINK, "	caps = 0x%x\n", pcaps->caps);
215bdeff971SLev Faerman 	ice_debug(hw, ICE_DBG_LINK, "	low_power_ctrl_an = 0x%x\n",
216bdeff971SLev Faerman 		  pcaps->low_power_ctrl_an);
21755df52a0SPaul Greenwalt 	ice_debug(hw, ICE_DBG_LINK, "	eee_cap = 0x%x\n", pcaps->eee_cap);
21855df52a0SPaul Greenwalt 	ice_debug(hw, ICE_DBG_LINK, "	eeer_value = 0x%x\n",
21955df52a0SPaul Greenwalt 		  pcaps->eeer_value);
22055df52a0SPaul Greenwalt 	ice_debug(hw, ICE_DBG_LINK, "	link_fec_options = 0x%x\n",
22155df52a0SPaul Greenwalt 		  pcaps->link_fec_options);
22255df52a0SPaul Greenwalt 	ice_debug(hw, ICE_DBG_LINK, "	module_compliance_enforcement = 0x%x\n",
22355df52a0SPaul Greenwalt 		  pcaps->module_compliance_enforcement);
22455df52a0SPaul Greenwalt 	ice_debug(hw, ICE_DBG_LINK, "   extended_compliance_code = 0x%x\n",
22555df52a0SPaul Greenwalt 		  pcaps->extended_compliance_code);
22655df52a0SPaul Greenwalt 	ice_debug(hw, ICE_DBG_LINK, "   module_type[0] = 0x%x\n",
22755df52a0SPaul Greenwalt 		  pcaps->module_type[0]);
22855df52a0SPaul Greenwalt 	ice_debug(hw, ICE_DBG_LINK, "   module_type[1] = 0x%x\n",
22955df52a0SPaul Greenwalt 		  pcaps->module_type[1]);
23055df52a0SPaul Greenwalt 	ice_debug(hw, ICE_DBG_LINK, "   module_type[2] = 0x%x\n",
23155df52a0SPaul Greenwalt 		  pcaps->module_type[2]);
232dc49c772SAnirudh Venkataramanan 
233d6730a87SAnirudh Venkataramanan 	if (!status && report_mode == ICE_AQC_REPORT_TOPO_CAP_MEDIA) {
234dc49c772SAnirudh Venkataramanan 		pi->phy.phy_type_low = le64_to_cpu(pcaps->phy_type_low);
235aef74145SAnirudh Venkataramanan 		pi->phy.phy_type_high = le64_to_cpu(pcaps->phy_type_high);
236c2b35226SPaul M Stillwell Jr 		memcpy(pi->phy.link_info.module_type, &pcaps->module_type,
237c2b35226SPaul M Stillwell Jr 		       sizeof(pi->phy.link_info.module_type));
238aef74145SAnirudh Venkataramanan 	}
239dc49c772SAnirudh Venkataramanan 
240dc49c772SAnirudh Venkataramanan 	return status;
241dc49c772SAnirudh Venkataramanan }
242dc49c772SAnirudh Venkataramanan 
243dc49c772SAnirudh Venkataramanan /**
2448ea1da59SPaul Greenwalt  * ice_aq_get_link_topo_handle - get link topology node return status
2458ea1da59SPaul Greenwalt  * @pi: port information structure
2468ea1da59SPaul Greenwalt  * @node_type: requested node type
2478ea1da59SPaul Greenwalt  * @cd: pointer to command details structure or NULL
2488ea1da59SPaul Greenwalt  *
2498ea1da59SPaul Greenwalt  * Get link topology node return status for specified node type (0x06E0)
2508ea1da59SPaul Greenwalt  *
2518ea1da59SPaul Greenwalt  * Node type cage can be used to determine if cage is present. If AQC
2528ea1da59SPaul Greenwalt  * returns error (ENOENT), then no cage present. If no cage present, then
2538ea1da59SPaul Greenwalt  * connection type is backplane or BASE-T.
2548ea1da59SPaul Greenwalt  */
255*5e24d598STony Nguyen static int
2568ea1da59SPaul Greenwalt ice_aq_get_link_topo_handle(struct ice_port_info *pi, u8 node_type,
2578ea1da59SPaul Greenwalt 			    struct ice_sq_cd *cd)
2588ea1da59SPaul Greenwalt {
2598ea1da59SPaul Greenwalt 	struct ice_aqc_get_link_topo *cmd;
2608ea1da59SPaul Greenwalt 	struct ice_aq_desc desc;
2618ea1da59SPaul Greenwalt 
2628ea1da59SPaul Greenwalt 	cmd = &desc.params.get_link_topo;
2638ea1da59SPaul Greenwalt 
2648ea1da59SPaul Greenwalt 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_topo);
2658ea1da59SPaul Greenwalt 
266e00ae1a2SMaciej Machnikowski 	cmd->addr.topo_params.node_type_ctx =
267e00ae1a2SMaciej Machnikowski 		(ICE_AQC_LINK_TOPO_NODE_CTX_PORT <<
2688ea1da59SPaul Greenwalt 		 ICE_AQC_LINK_TOPO_NODE_CTX_S);
2698ea1da59SPaul Greenwalt 
2708ea1da59SPaul Greenwalt 	/* set node type */
271e00ae1a2SMaciej Machnikowski 	cmd->addr.topo_params.node_type_ctx |=
272e00ae1a2SMaciej Machnikowski 		(ICE_AQC_LINK_TOPO_NODE_TYPE_M & node_type);
2738ea1da59SPaul Greenwalt 
2748ea1da59SPaul Greenwalt 	return ice_aq_send_cmd(pi->hw, &desc, NULL, 0, cd);
2758ea1da59SPaul Greenwalt }
2768ea1da59SPaul Greenwalt 
2778ea1da59SPaul Greenwalt /**
2788ea1da59SPaul Greenwalt  * ice_is_media_cage_present
2798ea1da59SPaul Greenwalt  * @pi: port information structure
2808ea1da59SPaul Greenwalt  *
2818ea1da59SPaul Greenwalt  * Returns true if media cage is present, else false. If no cage, then
2828ea1da59SPaul Greenwalt  * media type is backplane or BASE-T.
2838ea1da59SPaul Greenwalt  */
2848ea1da59SPaul Greenwalt static bool ice_is_media_cage_present(struct ice_port_info *pi)
2858ea1da59SPaul Greenwalt {
2868ea1da59SPaul Greenwalt 	/* Node type cage can be used to determine if cage is present. If AQC
2878ea1da59SPaul Greenwalt 	 * returns error (ENOENT), then no cage present. If no cage present then
2888ea1da59SPaul Greenwalt 	 * connection type is backplane or BASE-T.
2898ea1da59SPaul Greenwalt 	 */
2908ea1da59SPaul Greenwalt 	return !ice_aq_get_link_topo_handle(pi,
2918ea1da59SPaul Greenwalt 					    ICE_AQC_LINK_TOPO_NODE_TYPE_CAGE,
2928ea1da59SPaul Greenwalt 					    NULL);
2938ea1da59SPaul Greenwalt }
2948ea1da59SPaul Greenwalt 
2958ea1da59SPaul Greenwalt /**
296dc49c772SAnirudh Venkataramanan  * ice_get_media_type - Gets media type
297dc49c772SAnirudh Venkataramanan  * @pi: port information structure
298dc49c772SAnirudh Venkataramanan  */
299dc49c772SAnirudh Venkataramanan static enum ice_media_type ice_get_media_type(struct ice_port_info *pi)
300dc49c772SAnirudh Venkataramanan {
301dc49c772SAnirudh Venkataramanan 	struct ice_link_status *hw_link_info;
302dc49c772SAnirudh Venkataramanan 
303dc49c772SAnirudh Venkataramanan 	if (!pi)
304dc49c772SAnirudh Venkataramanan 		return ICE_MEDIA_UNKNOWN;
305dc49c772SAnirudh Venkataramanan 
306dc49c772SAnirudh Venkataramanan 	hw_link_info = &pi->phy.link_info;
307aef74145SAnirudh Venkataramanan 	if (hw_link_info->phy_type_low && hw_link_info->phy_type_high)
308aef74145SAnirudh Venkataramanan 		/* If more than one media type is selected, report unknown */
309aef74145SAnirudh Venkataramanan 		return ICE_MEDIA_UNKNOWN;
310dc49c772SAnirudh Venkataramanan 
311dc49c772SAnirudh Venkataramanan 	if (hw_link_info->phy_type_low) {
312c2b35226SPaul M Stillwell Jr 		/* 1G SGMII is a special case where some DA cable PHYs
313c2b35226SPaul M Stillwell Jr 		 * may show this as an option when it really shouldn't
314c2b35226SPaul M Stillwell Jr 		 * be since SGMII is meant to be between a MAC and a PHY
315c2b35226SPaul M Stillwell Jr 		 * in a backplane. Try to detect this case and handle it
316c2b35226SPaul M Stillwell Jr 		 */
317c2b35226SPaul M Stillwell Jr 		if (hw_link_info->phy_type_low == ICE_PHY_TYPE_LOW_1G_SGMII &&
318c2b35226SPaul M Stillwell Jr 		    (hw_link_info->module_type[ICE_AQC_MOD_TYPE_IDENT] ==
319c2b35226SPaul M Stillwell Jr 		    ICE_AQC_MOD_TYPE_BYTE1_SFP_PLUS_CU_ACTIVE ||
320c2b35226SPaul M Stillwell Jr 		    hw_link_info->module_type[ICE_AQC_MOD_TYPE_IDENT] ==
321c2b35226SPaul M Stillwell Jr 		    ICE_AQC_MOD_TYPE_BYTE1_SFP_PLUS_CU_PASSIVE))
322c2b35226SPaul M Stillwell Jr 			return ICE_MEDIA_DA;
323c2b35226SPaul M Stillwell Jr 
324dc49c772SAnirudh Venkataramanan 		switch (hw_link_info->phy_type_low) {
325dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_1000BASE_SX:
326dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_1000BASE_LX:
327dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_10GBASE_SR:
328dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_10GBASE_LR:
329dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_10G_SFI_C2C:
330dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_25GBASE_SR:
331dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_25GBASE_LR:
332dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_40GBASE_SR4:
333dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_40GBASE_LR4:
334aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_50GBASE_SR2:
335aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_50GBASE_LR2:
336aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_50GBASE_SR:
337aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_50GBASE_FR:
338aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_50GBASE_LR:
339aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_100GBASE_SR4:
340aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_100GBASE_LR4:
341aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_100GBASE_SR2:
342aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_100GBASE_DR:
343c1eb3b6bSDoug Dziggel 		case ICE_PHY_TYPE_LOW_10G_SFI_AOC_ACC:
344c1eb3b6bSDoug Dziggel 		case ICE_PHY_TYPE_LOW_25G_AUI_AOC_ACC:
345c1eb3b6bSDoug Dziggel 		case ICE_PHY_TYPE_LOW_40G_XLAUI_AOC_ACC:
346c1eb3b6bSDoug Dziggel 		case ICE_PHY_TYPE_LOW_50G_LAUI2_AOC_ACC:
347c1eb3b6bSDoug Dziggel 		case ICE_PHY_TYPE_LOW_50G_AUI2_AOC_ACC:
348c1eb3b6bSDoug Dziggel 		case ICE_PHY_TYPE_LOW_50G_AUI1_AOC_ACC:
349c1eb3b6bSDoug Dziggel 		case ICE_PHY_TYPE_LOW_100G_CAUI4_AOC_ACC:
350c1eb3b6bSDoug Dziggel 		case ICE_PHY_TYPE_LOW_100G_AUI4_AOC_ACC:
351dc49c772SAnirudh Venkataramanan 			return ICE_MEDIA_FIBER;
352dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_100BASE_TX:
353dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_1000BASE_T:
354dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_2500BASE_T:
355dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_5GBASE_T:
356dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_10GBASE_T:
357dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_25GBASE_T:
358dc49c772SAnirudh Venkataramanan 			return ICE_MEDIA_BASET;
359dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_10G_SFI_DA:
360dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_25GBASE_CR:
361dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_25GBASE_CR_S:
362dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_25GBASE_CR1:
363dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_40GBASE_CR4:
364aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_50GBASE_CR2:
365aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_50GBASE_CP:
366aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_100GBASE_CR4:
367aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_100GBASE_CR_PAM4:
368aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_100GBASE_CP2:
369dc49c772SAnirudh Venkataramanan 			return ICE_MEDIA_DA;
3708ea1da59SPaul Greenwalt 		case ICE_PHY_TYPE_LOW_25G_AUI_C2C:
3718ea1da59SPaul Greenwalt 		case ICE_PHY_TYPE_LOW_40G_XLAUI:
3728ea1da59SPaul Greenwalt 		case ICE_PHY_TYPE_LOW_50G_LAUI2:
3738ea1da59SPaul Greenwalt 		case ICE_PHY_TYPE_LOW_50G_AUI2:
3748ea1da59SPaul Greenwalt 		case ICE_PHY_TYPE_LOW_50G_AUI1:
3758ea1da59SPaul Greenwalt 		case ICE_PHY_TYPE_LOW_100G_AUI4:
3768ea1da59SPaul Greenwalt 		case ICE_PHY_TYPE_LOW_100G_CAUI4:
3778ea1da59SPaul Greenwalt 			if (ice_is_media_cage_present(pi))
3788ea1da59SPaul Greenwalt 				return ICE_MEDIA_DA;
3798ea1da59SPaul Greenwalt 			fallthrough;
380dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_1000BASE_KX:
381dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_2500BASE_KX:
382dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_2500BASE_X:
383dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_5GBASE_KR:
384dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_10GBASE_KR_CR1:
385dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_25GBASE_KR:
386dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_25GBASE_KR1:
387dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_25GBASE_KR_S:
388dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_40GBASE_KR4:
389aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_50GBASE_KR_PAM4:
390aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_50GBASE_KR2:
391aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_100GBASE_KR4:
392aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_100GBASE_KR_PAM4:
393aef74145SAnirudh Venkataramanan 			return ICE_MEDIA_BACKPLANE;
394aef74145SAnirudh Venkataramanan 		}
395aef74145SAnirudh Venkataramanan 	} else {
396aef74145SAnirudh Venkataramanan 		switch (hw_link_info->phy_type_high) {
3978ea1da59SPaul Greenwalt 		case ICE_PHY_TYPE_HIGH_100G_AUI2:
3988ea1da59SPaul Greenwalt 		case ICE_PHY_TYPE_HIGH_100G_CAUI2:
3998ea1da59SPaul Greenwalt 			if (ice_is_media_cage_present(pi))
4008ea1da59SPaul Greenwalt 				return ICE_MEDIA_DA;
4018ea1da59SPaul Greenwalt 			fallthrough;
402aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_HIGH_100GBASE_KR2_PAM4:
403dc49c772SAnirudh Venkataramanan 			return ICE_MEDIA_BACKPLANE;
404c1eb3b6bSDoug Dziggel 		case ICE_PHY_TYPE_HIGH_100G_CAUI2_AOC_ACC:
405c1eb3b6bSDoug Dziggel 		case ICE_PHY_TYPE_HIGH_100G_AUI2_AOC_ACC:
406c1eb3b6bSDoug Dziggel 			return ICE_MEDIA_FIBER;
407dc49c772SAnirudh Venkataramanan 		}
408dc49c772SAnirudh Venkataramanan 	}
409dc49c772SAnirudh Venkataramanan 	return ICE_MEDIA_UNKNOWN;
410dc49c772SAnirudh Venkataramanan }
411dc49c772SAnirudh Venkataramanan 
412dc49c772SAnirudh Venkataramanan /**
413dc49c772SAnirudh Venkataramanan  * ice_aq_get_link_info
414dc49c772SAnirudh Venkataramanan  * @pi: port information structure
415dc49c772SAnirudh Venkataramanan  * @ena_lse: enable/disable LinkStatusEvent reporting
416dc49c772SAnirudh Venkataramanan  * @link: pointer to link status structure - optional
417dc49c772SAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
418dc49c772SAnirudh Venkataramanan  *
419dc49c772SAnirudh Venkataramanan  * Get Link Status (0x607). Returns the link status of the adapter.
420dc49c772SAnirudh Venkataramanan  */
421*5e24d598STony Nguyen int
422dc49c772SAnirudh Venkataramanan ice_aq_get_link_info(struct ice_port_info *pi, bool ena_lse,
423dc49c772SAnirudh Venkataramanan 		     struct ice_link_status *link, struct ice_sq_cd *cd)
424dc49c772SAnirudh Venkataramanan {
425dc49c772SAnirudh Venkataramanan 	struct ice_aqc_get_link_status_data link_data = { 0 };
426dc49c772SAnirudh Venkataramanan 	struct ice_aqc_get_link_status *resp;
427dc67039bSJesse Brandeburg 	struct ice_link_status *li_old, *li;
428dc49c772SAnirudh Venkataramanan 	enum ice_media_type *hw_media_type;
429dc49c772SAnirudh Venkataramanan 	struct ice_fc_info *hw_fc_info;
430dc49c772SAnirudh Venkataramanan 	bool tx_pause, rx_pause;
431dc49c772SAnirudh Venkataramanan 	struct ice_aq_desc desc;
432*5e24d598STony Nguyen 	int status;
433dc67039bSJesse Brandeburg 	struct ice_hw *hw;
434dc49c772SAnirudh Venkataramanan 	u16 cmd_flags;
435dc49c772SAnirudh Venkataramanan 
436dc49c772SAnirudh Venkataramanan 	if (!pi)
437dc49c772SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
438dc67039bSJesse Brandeburg 	hw = pi->hw;
439dc67039bSJesse Brandeburg 	li_old = &pi->phy.link_info_old;
440dc49c772SAnirudh Venkataramanan 	hw_media_type = &pi->phy.media_type;
441dc67039bSJesse Brandeburg 	li = &pi->phy.link_info;
442dc49c772SAnirudh Venkataramanan 	hw_fc_info = &pi->fc;
443dc49c772SAnirudh Venkataramanan 
444dc49c772SAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_status);
445dc49c772SAnirudh Venkataramanan 	cmd_flags = (ena_lse) ? ICE_AQ_LSE_ENA : ICE_AQ_LSE_DIS;
446dc49c772SAnirudh Venkataramanan 	resp = &desc.params.get_link_status;
447dc49c772SAnirudh Venkataramanan 	resp->cmd_flags = cpu_to_le16(cmd_flags);
448dc49c772SAnirudh Venkataramanan 	resp->lport_num = pi->lport;
449dc49c772SAnirudh Venkataramanan 
450dc67039bSJesse Brandeburg 	status = ice_aq_send_cmd(hw, &desc, &link_data, sizeof(link_data), cd);
451dc49c772SAnirudh Venkataramanan 
452dc49c772SAnirudh Venkataramanan 	if (status)
453dc49c772SAnirudh Venkataramanan 		return status;
454dc49c772SAnirudh Venkataramanan 
455dc49c772SAnirudh Venkataramanan 	/* save off old link status information */
456dc67039bSJesse Brandeburg 	*li_old = *li;
457dc49c772SAnirudh Venkataramanan 
458dc49c772SAnirudh Venkataramanan 	/* update current link status information */
459dc67039bSJesse Brandeburg 	li->link_speed = le16_to_cpu(link_data.link_speed);
460dc67039bSJesse Brandeburg 	li->phy_type_low = le64_to_cpu(link_data.phy_type_low);
461dc67039bSJesse Brandeburg 	li->phy_type_high = le64_to_cpu(link_data.phy_type_high);
462dc49c772SAnirudh Venkataramanan 	*hw_media_type = ice_get_media_type(pi);
463dc67039bSJesse Brandeburg 	li->link_info = link_data.link_info;
464c77849f5SAnirudh Venkataramanan 	li->link_cfg_err = link_data.link_cfg_err;
465dc67039bSJesse Brandeburg 	li->an_info = link_data.an_info;
466dc67039bSJesse Brandeburg 	li->ext_info = link_data.ext_info;
467dc67039bSJesse Brandeburg 	li->max_frame_size = le16_to_cpu(link_data.max_frame_size);
468dc67039bSJesse Brandeburg 	li->fec_info = link_data.cfg & ICE_AQ_FEC_MASK;
469dc67039bSJesse Brandeburg 	li->topo_media_conflict = link_data.topo_media_conflict;
470dc67039bSJesse Brandeburg 	li->pacing = link_data.cfg & (ICE_AQ_CFG_PACING_M |
471dc67039bSJesse Brandeburg 				      ICE_AQ_CFG_PACING_TYPE_M);
472dc49c772SAnirudh Venkataramanan 
473dc49c772SAnirudh Venkataramanan 	/* update fc info */
474dc49c772SAnirudh Venkataramanan 	tx_pause = !!(link_data.an_info & ICE_AQ_LINK_PAUSE_TX);
475dc49c772SAnirudh Venkataramanan 	rx_pause = !!(link_data.an_info & ICE_AQ_LINK_PAUSE_RX);
476dc49c772SAnirudh Venkataramanan 	if (tx_pause && rx_pause)
477dc49c772SAnirudh Venkataramanan 		hw_fc_info->current_mode = ICE_FC_FULL;
478dc49c772SAnirudh Venkataramanan 	else if (tx_pause)
479dc49c772SAnirudh Venkataramanan 		hw_fc_info->current_mode = ICE_FC_TX_PAUSE;
480dc49c772SAnirudh Venkataramanan 	else if (rx_pause)
481dc49c772SAnirudh Venkataramanan 		hw_fc_info->current_mode = ICE_FC_RX_PAUSE;
482dc49c772SAnirudh Venkataramanan 	else
483dc49c772SAnirudh Venkataramanan 		hw_fc_info->current_mode = ICE_FC_NONE;
484dc49c772SAnirudh Venkataramanan 
485dc67039bSJesse Brandeburg 	li->lse_ena = !!(resp->cmd_flags & cpu_to_le16(ICE_AQ_LSE_IS_ENABLED));
486dc67039bSJesse Brandeburg 
48755df52a0SPaul Greenwalt 	ice_debug(hw, ICE_DBG_LINK, "get link info\n");
488dc67039bSJesse Brandeburg 	ice_debug(hw, ICE_DBG_LINK, "	link_speed = 0x%x\n", li->link_speed);
489dc67039bSJesse Brandeburg 	ice_debug(hw, ICE_DBG_LINK, "	phy_type_low = 0x%llx\n",
490dc67039bSJesse Brandeburg 		  (unsigned long long)li->phy_type_low);
491dc67039bSJesse Brandeburg 	ice_debug(hw, ICE_DBG_LINK, "	phy_type_high = 0x%llx\n",
492dc67039bSJesse Brandeburg 		  (unsigned long long)li->phy_type_high);
493dc67039bSJesse Brandeburg 	ice_debug(hw, ICE_DBG_LINK, "	media_type = 0x%x\n", *hw_media_type);
494dc67039bSJesse Brandeburg 	ice_debug(hw, ICE_DBG_LINK, "	link_info = 0x%x\n", li->link_info);
495c77849f5SAnirudh Venkataramanan 	ice_debug(hw, ICE_DBG_LINK, "	link_cfg_err = 0x%x\n", li->link_cfg_err);
496dc67039bSJesse Brandeburg 	ice_debug(hw, ICE_DBG_LINK, "	an_info = 0x%x\n", li->an_info);
497dc67039bSJesse Brandeburg 	ice_debug(hw, ICE_DBG_LINK, "	ext_info = 0x%x\n", li->ext_info);
49855df52a0SPaul Greenwalt 	ice_debug(hw, ICE_DBG_LINK, "	fec_info = 0x%x\n", li->fec_info);
499dc67039bSJesse Brandeburg 	ice_debug(hw, ICE_DBG_LINK, "	lse_ena = 0x%x\n", li->lse_ena);
50055df52a0SPaul Greenwalt 	ice_debug(hw, ICE_DBG_LINK, "	max_frame = 0x%x\n",
50155df52a0SPaul Greenwalt 		  li->max_frame_size);
502dc67039bSJesse Brandeburg 	ice_debug(hw, ICE_DBG_LINK, "	pacing = 0x%x\n", li->pacing);
503dc49c772SAnirudh Venkataramanan 
504dc49c772SAnirudh Venkataramanan 	/* save link status information */
505dc49c772SAnirudh Venkataramanan 	if (link)
506dc67039bSJesse Brandeburg 		*link = *li;
507dc49c772SAnirudh Venkataramanan 
508dc49c772SAnirudh Venkataramanan 	/* flag cleared so calling functions don't call AQ again */
509dc49c772SAnirudh Venkataramanan 	pi->phy.get_link_info = false;
510dc49c772SAnirudh Venkataramanan 
5111b5c19c7SBruce Allan 	return 0;
512dc49c772SAnirudh Venkataramanan }
513dc49c772SAnirudh Venkataramanan 
514dc49c772SAnirudh Venkataramanan /**
51542449105SAnirudh Venkataramanan  * ice_fill_tx_timer_and_fc_thresh
51642449105SAnirudh Venkataramanan  * @hw: pointer to the HW struct
51742449105SAnirudh Venkataramanan  * @cmd: pointer to MAC cfg structure
51842449105SAnirudh Venkataramanan  *
51942449105SAnirudh Venkataramanan  * Add Tx timer and FC refresh threshold info to Set MAC Config AQ command
52042449105SAnirudh Venkataramanan  * descriptor
52142449105SAnirudh Venkataramanan  */
52242449105SAnirudh Venkataramanan static void
52342449105SAnirudh Venkataramanan ice_fill_tx_timer_and_fc_thresh(struct ice_hw *hw,
52442449105SAnirudh Venkataramanan 				struct ice_aqc_set_mac_cfg *cmd)
52542449105SAnirudh Venkataramanan {
52642449105SAnirudh Venkataramanan 	u16 fc_thres_val, tx_timer_val;
52742449105SAnirudh Venkataramanan 	u32 val;
52842449105SAnirudh Venkataramanan 
52942449105SAnirudh Venkataramanan 	/* We read back the transmit timer and FC threshold value of
53042449105SAnirudh Venkataramanan 	 * LFC. Thus, we will use index =
53142449105SAnirudh Venkataramanan 	 * PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_MAX_INDEX.
53242449105SAnirudh Venkataramanan 	 *
53342449105SAnirudh Venkataramanan 	 * Also, because we are operating on transmit timer and FC
53442449105SAnirudh Venkataramanan 	 * threshold of LFC, we don't turn on any bit in tx_tmr_priority
53542449105SAnirudh Venkataramanan 	 */
53642449105SAnirudh Venkataramanan #define IDX_OF_LFC PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_MAX_INDEX
53742449105SAnirudh Venkataramanan 
53842449105SAnirudh Venkataramanan 	/* Retrieve the transmit timer */
53942449105SAnirudh Venkataramanan 	val = rd32(hw, PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA(IDX_OF_LFC));
54042449105SAnirudh Venkataramanan 	tx_timer_val = val &
54142449105SAnirudh Venkataramanan 		PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_HSEC_CTL_TX_PAUSE_QUANTA_M;
54242449105SAnirudh Venkataramanan 	cmd->tx_tmr_value = cpu_to_le16(tx_timer_val);
54342449105SAnirudh Venkataramanan 
54442449105SAnirudh Venkataramanan 	/* Retrieve the FC threshold */
54542449105SAnirudh Venkataramanan 	val = rd32(hw, PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER(IDX_OF_LFC));
54642449105SAnirudh Venkataramanan 	fc_thres_val = val & PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_M;
54742449105SAnirudh Venkataramanan 
54842449105SAnirudh Venkataramanan 	cmd->fc_refresh_threshold = cpu_to_le16(fc_thres_val);
54942449105SAnirudh Venkataramanan }
55042449105SAnirudh Venkataramanan 
55142449105SAnirudh Venkataramanan /**
55242449105SAnirudh Venkataramanan  * ice_aq_set_mac_cfg
55342449105SAnirudh Venkataramanan  * @hw: pointer to the HW struct
55442449105SAnirudh Venkataramanan  * @max_frame_size: Maximum Frame Size to be supported
55542449105SAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
55642449105SAnirudh Venkataramanan  *
55742449105SAnirudh Venkataramanan  * Set MAC configuration (0x0603)
55842449105SAnirudh Venkataramanan  */
559*5e24d598STony Nguyen int
56042449105SAnirudh Venkataramanan ice_aq_set_mac_cfg(struct ice_hw *hw, u16 max_frame_size, struct ice_sq_cd *cd)
56142449105SAnirudh Venkataramanan {
56242449105SAnirudh Venkataramanan 	struct ice_aqc_set_mac_cfg *cmd;
56342449105SAnirudh Venkataramanan 	struct ice_aq_desc desc;
56442449105SAnirudh Venkataramanan 
56542449105SAnirudh Venkataramanan 	cmd = &desc.params.set_mac_cfg;
56642449105SAnirudh Venkataramanan 
56742449105SAnirudh Venkataramanan 	if (max_frame_size == 0)
56842449105SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
56942449105SAnirudh Venkataramanan 
57042449105SAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_mac_cfg);
57142449105SAnirudh Venkataramanan 
57242449105SAnirudh Venkataramanan 	cmd->max_frame_size = cpu_to_le16(max_frame_size);
57342449105SAnirudh Venkataramanan 
57442449105SAnirudh Venkataramanan 	ice_fill_tx_timer_and_fc_thresh(hw, cmd);
57542449105SAnirudh Venkataramanan 
57642449105SAnirudh Venkataramanan 	return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
57742449105SAnirudh Venkataramanan }
57842449105SAnirudh Venkataramanan 
57942449105SAnirudh Venkataramanan /**
5809daf8208SAnirudh Venkataramanan  * ice_init_fltr_mgmt_struct - initializes filter management list and locks
581f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
5829daf8208SAnirudh Venkataramanan  */
583*5e24d598STony Nguyen static int ice_init_fltr_mgmt_struct(struct ice_hw *hw)
5849daf8208SAnirudh Venkataramanan {
5859daf8208SAnirudh Venkataramanan 	struct ice_switch_info *sw;
586*5e24d598STony Nguyen 	int status;
5879daf8208SAnirudh Venkataramanan 
5889daf8208SAnirudh Venkataramanan 	hw->switch_info = devm_kzalloc(ice_hw_to_dev(hw),
5899daf8208SAnirudh Venkataramanan 				       sizeof(*hw->switch_info), GFP_KERNEL);
5909daf8208SAnirudh Venkataramanan 	sw = hw->switch_info;
5919daf8208SAnirudh Venkataramanan 
5929daf8208SAnirudh Venkataramanan 	if (!sw)
5939daf8208SAnirudh Venkataramanan 		return ICE_ERR_NO_MEMORY;
5949daf8208SAnirudh Venkataramanan 
5959daf8208SAnirudh Venkataramanan 	INIT_LIST_HEAD(&sw->vsi_list_map_head);
5960f94570dSGrishma Kotecha 	sw->prof_res_bm_init = 0;
5979daf8208SAnirudh Venkataramanan 
5981aaef2bcSSurabhi Boob 	status = ice_init_def_sw_recp(hw);
5991aaef2bcSSurabhi Boob 	if (status) {
6001aaef2bcSSurabhi Boob 		devm_kfree(ice_hw_to_dev(hw), hw->switch_info);
6011aaef2bcSSurabhi Boob 		return status;
6021aaef2bcSSurabhi Boob 	}
6031aaef2bcSSurabhi Boob 	return 0;
6049daf8208SAnirudh Venkataramanan }
6059daf8208SAnirudh Venkataramanan 
6069daf8208SAnirudh Venkataramanan /**
6079daf8208SAnirudh Venkataramanan  * ice_cleanup_fltr_mgmt_struct - cleanup filter management list and locks
608f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
6099daf8208SAnirudh Venkataramanan  */
6109daf8208SAnirudh Venkataramanan static void ice_cleanup_fltr_mgmt_struct(struct ice_hw *hw)
6119daf8208SAnirudh Venkataramanan {
6129daf8208SAnirudh Venkataramanan 	struct ice_switch_info *sw = hw->switch_info;
6139daf8208SAnirudh Venkataramanan 	struct ice_vsi_list_map_info *v_pos_map;
6149daf8208SAnirudh Venkataramanan 	struct ice_vsi_list_map_info *v_tmp_map;
61580d144c9SAnirudh Venkataramanan 	struct ice_sw_recipe *recps;
61680d144c9SAnirudh Venkataramanan 	u8 i;
6179daf8208SAnirudh Venkataramanan 
6189daf8208SAnirudh Venkataramanan 	list_for_each_entry_safe(v_pos_map, v_tmp_map, &sw->vsi_list_map_head,
6199daf8208SAnirudh Venkataramanan 				 list_entry) {
6209daf8208SAnirudh Venkataramanan 		list_del(&v_pos_map->list_entry);
6219daf8208SAnirudh Venkataramanan 		devm_kfree(ice_hw_to_dev(hw), v_pos_map);
6229daf8208SAnirudh Venkataramanan 	}
6238b8ef05bSVictor Raj 	recps = sw->recp_list;
6248b8ef05bSVictor Raj 	for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
6258b8ef05bSVictor Raj 		struct ice_recp_grp_entry *rg_entry, *tmprg_entry;
6269daf8208SAnirudh Venkataramanan 
62780d144c9SAnirudh Venkataramanan 		recps[i].root_rid = i;
6288b8ef05bSVictor Raj 		list_for_each_entry_safe(rg_entry, tmprg_entry,
6298b8ef05bSVictor Raj 					 &recps[i].rg_list, l_entry) {
6308b8ef05bSVictor Raj 			list_del(&rg_entry->l_entry);
6318b8ef05bSVictor Raj 			devm_kfree(ice_hw_to_dev(hw), rg_entry);
6328b8ef05bSVictor Raj 		}
6338b8ef05bSVictor Raj 
6348b8ef05bSVictor Raj 		if (recps[i].adv_rule) {
6358b8ef05bSVictor Raj 			struct ice_adv_fltr_mgmt_list_entry *tmp_entry;
6368b8ef05bSVictor Raj 			struct ice_adv_fltr_mgmt_list_entry *lst_itr;
6378b8ef05bSVictor Raj 
63880d144c9SAnirudh Venkataramanan 			mutex_destroy(&recps[i].filt_rule_lock);
63980d144c9SAnirudh Venkataramanan 			list_for_each_entry_safe(lst_itr, tmp_entry,
6408b8ef05bSVictor Raj 						 &recps[i].filt_rules,
6418b8ef05bSVictor Raj 						 list_entry) {
6428b8ef05bSVictor Raj 				list_del(&lst_itr->list_entry);
6438b8ef05bSVictor Raj 				devm_kfree(ice_hw_to_dev(hw), lst_itr->lkups);
6448b8ef05bSVictor Raj 				devm_kfree(ice_hw_to_dev(hw), lst_itr);
6458b8ef05bSVictor Raj 			}
6468b8ef05bSVictor Raj 		} else {
6478b8ef05bSVictor Raj 			struct ice_fltr_mgmt_list_entry *lst_itr, *tmp_entry;
6488b8ef05bSVictor Raj 
6498b8ef05bSVictor Raj 			mutex_destroy(&recps[i].filt_rule_lock);
6508b8ef05bSVictor Raj 			list_for_each_entry_safe(lst_itr, tmp_entry,
6518b8ef05bSVictor Raj 						 &recps[i].filt_rules,
6528b8ef05bSVictor Raj 						 list_entry) {
65380d144c9SAnirudh Venkataramanan 				list_del(&lst_itr->list_entry);
65480d144c9SAnirudh Venkataramanan 				devm_kfree(ice_hw_to_dev(hw), lst_itr);
65580d144c9SAnirudh Venkataramanan 			}
65680d144c9SAnirudh Venkataramanan 		}
6578b8ef05bSVictor Raj 		if (recps[i].root_buf)
6588b8ef05bSVictor Raj 			devm_kfree(ice_hw_to_dev(hw), recps[i].root_buf);
6598b8ef05bSVictor Raj 	}
660334cb062SAnirudh Venkataramanan 	ice_rm_all_sw_replay_rule_info(hw);
66180d144c9SAnirudh Venkataramanan 	devm_kfree(ice_hw_to_dev(hw), sw->recp_list);
6629daf8208SAnirudh Venkataramanan 	devm_kfree(ice_hw_to_dev(hw), sw);
6639daf8208SAnirudh Venkataramanan }
6649daf8208SAnirudh Venkataramanan 
6658b97ceb1SHieu Tran /**
66611fe1b3aSDan Nowlin  * ice_get_fw_log_cfg - get FW logging configuration
66711fe1b3aSDan Nowlin  * @hw: pointer to the HW struct
66811fe1b3aSDan Nowlin  */
669*5e24d598STony Nguyen static int ice_get_fw_log_cfg(struct ice_hw *hw)
67011fe1b3aSDan Nowlin {
67111fe1b3aSDan Nowlin 	struct ice_aq_desc desc;
672*5e24d598STony Nguyen 	int status;
673b3c38904SBruce Allan 	__le16 *config;
67411fe1b3aSDan Nowlin 	u16 size;
67511fe1b3aSDan Nowlin 
676b3c38904SBruce Allan 	size = sizeof(*config) * ICE_AQC_FW_LOG_ID_MAX;
67711fe1b3aSDan Nowlin 	config = devm_kzalloc(ice_hw_to_dev(hw), size, GFP_KERNEL);
67811fe1b3aSDan Nowlin 	if (!config)
67911fe1b3aSDan Nowlin 		return ICE_ERR_NO_MEMORY;
68011fe1b3aSDan Nowlin 
68111fe1b3aSDan Nowlin 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logging_info);
68211fe1b3aSDan Nowlin 
68311fe1b3aSDan Nowlin 	status = ice_aq_send_cmd(hw, &desc, config, size, NULL);
68411fe1b3aSDan Nowlin 	if (!status) {
68511fe1b3aSDan Nowlin 		u16 i;
68611fe1b3aSDan Nowlin 
6872f2da36eSAnirudh Venkataramanan 		/* Save FW logging information into the HW structure */
68811fe1b3aSDan Nowlin 		for (i = 0; i < ICE_AQC_FW_LOG_ID_MAX; i++) {
68911fe1b3aSDan Nowlin 			u16 v, m, flgs;
69011fe1b3aSDan Nowlin 
691b3c38904SBruce Allan 			v = le16_to_cpu(config[i]);
69211fe1b3aSDan Nowlin 			m = (v & ICE_AQC_FW_LOG_ID_M) >> ICE_AQC_FW_LOG_ID_S;
69311fe1b3aSDan Nowlin 			flgs = (v & ICE_AQC_FW_LOG_EN_M) >> ICE_AQC_FW_LOG_EN_S;
69411fe1b3aSDan Nowlin 
69511fe1b3aSDan Nowlin 			if (m < ICE_AQC_FW_LOG_ID_MAX)
69611fe1b3aSDan Nowlin 				hw->fw_log.evnts[m].cur = flgs;
69711fe1b3aSDan Nowlin 		}
69811fe1b3aSDan Nowlin 	}
69911fe1b3aSDan Nowlin 
70011fe1b3aSDan Nowlin 	devm_kfree(ice_hw_to_dev(hw), config);
70111fe1b3aSDan Nowlin 
70211fe1b3aSDan Nowlin 	return status;
70311fe1b3aSDan Nowlin }
70411fe1b3aSDan Nowlin 
70511fe1b3aSDan Nowlin /**
7068b97ceb1SHieu Tran  * ice_cfg_fw_log - configure FW logging
707f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
7088b97ceb1SHieu Tran  * @enable: enable certain FW logging events if true, disable all if false
7098b97ceb1SHieu Tran  *
7108b97ceb1SHieu Tran  * This function enables/disables the FW logging via Rx CQ events and a UART
7118b97ceb1SHieu Tran  * port based on predetermined configurations. FW logging via the Rx CQ can be
7128b97ceb1SHieu Tran  * enabled/disabled for individual PF's. However, FW logging via the UART can
7138b97ceb1SHieu Tran  * only be enabled/disabled for all PFs on the same device.
7148b97ceb1SHieu Tran  *
7158b97ceb1SHieu Tran  * To enable overall FW logging, the "cq_en" and "uart_en" enable bits in
7168b97ceb1SHieu Tran  * hw->fw_log need to be set accordingly, e.g. based on user-provided input,
7178b97ceb1SHieu Tran  * before initializing the device.
7188b97ceb1SHieu Tran  *
7198b97ceb1SHieu Tran  * When re/configuring FW logging, callers need to update the "cfg" elements of
7208b97ceb1SHieu Tran  * the hw->fw_log.evnts array with the desired logging event configurations for
7218b97ceb1SHieu Tran  * modules of interest. When disabling FW logging completely, the callers can
7228b97ceb1SHieu Tran  * just pass false in the "enable" parameter. On completion, the function will
7238b97ceb1SHieu Tran  * update the "cur" element of the hw->fw_log.evnts array with the resulting
7248b97ceb1SHieu Tran  * logging event configurations of the modules that are being re/configured. FW
7258b97ceb1SHieu Tran  * logging modules that are not part of a reconfiguration operation retain their
7268b97ceb1SHieu Tran  * previous states.
7278b97ceb1SHieu Tran  *
7288b97ceb1SHieu Tran  * Before resetting the device, it is recommended that the driver disables FW
7298b97ceb1SHieu Tran  * logging before shutting down the control queue. When disabling FW logging
7308b97ceb1SHieu Tran  * ("enable" = false), the latest configurations of FW logging events stored in
7318b97ceb1SHieu Tran  * hw->fw_log.evnts[] are not overridden to allow them to be reconfigured after
7328b97ceb1SHieu Tran  * a device reset.
7338b97ceb1SHieu Tran  *
7348b97ceb1SHieu Tran  * When enabling FW logging to emit log messages via the Rx CQ during the
7358b97ceb1SHieu Tran  * device's initialization phase, a mechanism alternative to interrupt handlers
7368b97ceb1SHieu Tran  * needs to be used to extract FW log messages from the Rx CQ periodically and
7378b97ceb1SHieu Tran  * to prevent the Rx CQ from being full and stalling other types of control
7388b97ceb1SHieu Tran  * messages from FW to SW. Interrupts are typically disabled during the device's
7398b97ceb1SHieu Tran  * initialization phase.
7408b97ceb1SHieu Tran  */
741*5e24d598STony Nguyen static int ice_cfg_fw_log(struct ice_hw *hw, bool enable)
7428b97ceb1SHieu Tran {
7438b97ceb1SHieu Tran 	struct ice_aqc_fw_logging *cmd;
744*5e24d598STony Nguyen 	int status = 0;
7458b97ceb1SHieu Tran 	u16 i, chgs = 0, len = 0;
7468b97ceb1SHieu Tran 	struct ice_aq_desc desc;
747b3c38904SBruce Allan 	__le16 *data = NULL;
7488b97ceb1SHieu Tran 	u8 actv_evnts = 0;
7498b97ceb1SHieu Tran 	void *buf = NULL;
7508b97ceb1SHieu Tran 
7518b97ceb1SHieu Tran 	if (!hw->fw_log.cq_en && !hw->fw_log.uart_en)
7528b97ceb1SHieu Tran 		return 0;
7538b97ceb1SHieu Tran 
7548b97ceb1SHieu Tran 	/* Disable FW logging only when the control queue is still responsive */
7558b97ceb1SHieu Tran 	if (!enable &&
7568b97ceb1SHieu Tran 	    (!hw->fw_log.actv_evnts || !ice_check_sq_alive(hw, &hw->adminq)))
7578b97ceb1SHieu Tran 		return 0;
7588b97ceb1SHieu Tran 
75911fe1b3aSDan Nowlin 	/* Get current FW log settings */
76011fe1b3aSDan Nowlin 	status = ice_get_fw_log_cfg(hw);
76111fe1b3aSDan Nowlin 	if (status)
76211fe1b3aSDan Nowlin 		return status;
76311fe1b3aSDan Nowlin 
7648b97ceb1SHieu Tran 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logging);
7658b97ceb1SHieu Tran 	cmd = &desc.params.fw_logging;
7668b97ceb1SHieu Tran 
7678b97ceb1SHieu Tran 	/* Indicate which controls are valid */
7688b97ceb1SHieu Tran 	if (hw->fw_log.cq_en)
7698b97ceb1SHieu Tran 		cmd->log_ctrl_valid |= ICE_AQC_FW_LOG_AQ_VALID;
7708b97ceb1SHieu Tran 
7718b97ceb1SHieu Tran 	if (hw->fw_log.uart_en)
7728b97ceb1SHieu Tran 		cmd->log_ctrl_valid |= ICE_AQC_FW_LOG_UART_VALID;
7738b97ceb1SHieu Tran 
7748b97ceb1SHieu Tran 	if (enable) {
7758b97ceb1SHieu Tran 		/* Fill in an array of entries with FW logging modules and
7768b97ceb1SHieu Tran 		 * logging events being reconfigured.
7778b97ceb1SHieu Tran 		 */
7788b97ceb1SHieu Tran 		for (i = 0; i < ICE_AQC_FW_LOG_ID_MAX; i++) {
7798b97ceb1SHieu Tran 			u16 val;
7808b97ceb1SHieu Tran 
7818b97ceb1SHieu Tran 			/* Keep track of enabled event types */
7828b97ceb1SHieu Tran 			actv_evnts |= hw->fw_log.evnts[i].cfg;
7838b97ceb1SHieu Tran 
7848b97ceb1SHieu Tran 			if (hw->fw_log.evnts[i].cfg == hw->fw_log.evnts[i].cur)
7858b97ceb1SHieu Tran 				continue;
7868b97ceb1SHieu Tran 
7878b97ceb1SHieu Tran 			if (!data) {
788b3c38904SBruce Allan 				data = devm_kcalloc(ice_hw_to_dev(hw),
789b3c38904SBruce Allan 						    ICE_AQC_FW_LOG_ID_MAX,
79059df14f9SBruce Allan 						    sizeof(*data),
7918b97ceb1SHieu Tran 						    GFP_KERNEL);
7928b97ceb1SHieu Tran 				if (!data)
7938b97ceb1SHieu Tran 					return ICE_ERR_NO_MEMORY;
7948b97ceb1SHieu Tran 			}
7958b97ceb1SHieu Tran 
7968b97ceb1SHieu Tran 			val = i << ICE_AQC_FW_LOG_ID_S;
7978b97ceb1SHieu Tran 			val |= hw->fw_log.evnts[i].cfg << ICE_AQC_FW_LOG_EN_S;
798b3c38904SBruce Allan 			data[chgs++] = cpu_to_le16(val);
7998b97ceb1SHieu Tran 		}
8008b97ceb1SHieu Tran 
8018b97ceb1SHieu Tran 		/* Only enable FW logging if at least one module is specified.
8028b97ceb1SHieu Tran 		 * If FW logging is currently enabled but all modules are not
8038b97ceb1SHieu Tran 		 * enabled to emit log messages, disable FW logging altogether.
8048b97ceb1SHieu Tran 		 */
8058b97ceb1SHieu Tran 		if (actv_evnts) {
8068b97ceb1SHieu Tran 			/* Leave if there is effectively no change */
8078b97ceb1SHieu Tran 			if (!chgs)
8088b97ceb1SHieu Tran 				goto out;
8098b97ceb1SHieu Tran 
8108b97ceb1SHieu Tran 			if (hw->fw_log.cq_en)
8118b97ceb1SHieu Tran 				cmd->log_ctrl |= ICE_AQC_FW_LOG_AQ_EN;
8128b97ceb1SHieu Tran 
8138b97ceb1SHieu Tran 			if (hw->fw_log.uart_en)
8148b97ceb1SHieu Tran 				cmd->log_ctrl |= ICE_AQC_FW_LOG_UART_EN;
8158b97ceb1SHieu Tran 
8168b97ceb1SHieu Tran 			buf = data;
817b3c38904SBruce Allan 			len = sizeof(*data) * chgs;
8188b97ceb1SHieu Tran 			desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
8198b97ceb1SHieu Tran 		}
8208b97ceb1SHieu Tran 	}
8218b97ceb1SHieu Tran 
8228b97ceb1SHieu Tran 	status = ice_aq_send_cmd(hw, &desc, buf, len, NULL);
8238b97ceb1SHieu Tran 	if (!status) {
8248b97ceb1SHieu Tran 		/* Update the current configuration to reflect events enabled.
8258b97ceb1SHieu Tran 		 * hw->fw_log.cq_en and hw->fw_log.uart_en indicate if the FW
8268b97ceb1SHieu Tran 		 * logging mode is enabled for the device. They do not reflect
8278b97ceb1SHieu Tran 		 * actual modules being enabled to emit log messages. So, their
8288b97ceb1SHieu Tran 		 * values remain unchanged even when all modules are disabled.
8298b97ceb1SHieu Tran 		 */
8308b97ceb1SHieu Tran 		u16 cnt = enable ? chgs : (u16)ICE_AQC_FW_LOG_ID_MAX;
8318b97ceb1SHieu Tran 
8328b97ceb1SHieu Tran 		hw->fw_log.actv_evnts = actv_evnts;
8338b97ceb1SHieu Tran 		for (i = 0; i < cnt; i++) {
8348b97ceb1SHieu Tran 			u16 v, m;
8358b97ceb1SHieu Tran 
8368b97ceb1SHieu Tran 			if (!enable) {
8378b97ceb1SHieu Tran 				/* When disabling all FW logging events as part
8388b97ceb1SHieu Tran 				 * of device's de-initialization, the original
8398b97ceb1SHieu Tran 				 * configurations are retained, and can be used
8408b97ceb1SHieu Tran 				 * to reconfigure FW logging later if the device
8418b97ceb1SHieu Tran 				 * is re-initialized.
8428b97ceb1SHieu Tran 				 */
8438b97ceb1SHieu Tran 				hw->fw_log.evnts[i].cur = 0;
8448b97ceb1SHieu Tran 				continue;
8458b97ceb1SHieu Tran 			}
8468b97ceb1SHieu Tran 
847b3c38904SBruce Allan 			v = le16_to_cpu(data[i]);
8488b97ceb1SHieu Tran 			m = (v & ICE_AQC_FW_LOG_ID_M) >> ICE_AQC_FW_LOG_ID_S;
8498b97ceb1SHieu Tran 			hw->fw_log.evnts[m].cur = hw->fw_log.evnts[m].cfg;
8508b97ceb1SHieu Tran 		}
8518b97ceb1SHieu Tran 	}
8528b97ceb1SHieu Tran 
8538b97ceb1SHieu Tran out:
8548b97ceb1SHieu Tran 	if (data)
8558b97ceb1SHieu Tran 		devm_kfree(ice_hw_to_dev(hw), data);
8568b97ceb1SHieu Tran 
8578b97ceb1SHieu Tran 	return status;
8588b97ceb1SHieu Tran }
8598b97ceb1SHieu Tran 
8608b97ceb1SHieu Tran /**
8618b97ceb1SHieu Tran  * ice_output_fw_log
862f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
8638b97ceb1SHieu Tran  * @desc: pointer to the AQ message descriptor
8648b97ceb1SHieu Tran  * @buf: pointer to the buffer accompanying the AQ message
8658b97ceb1SHieu Tran  *
8668b97ceb1SHieu Tran  * Formats a FW Log message and outputs it via the standard driver logs.
8678b97ceb1SHieu Tran  */
8688b97ceb1SHieu Tran void ice_output_fw_log(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf)
8698b97ceb1SHieu Tran {
8704f70daa0SJacob Keller 	ice_debug(hw, ICE_DBG_FW_LOG, "[ FW Log Msg Start ]\n");
8714f70daa0SJacob Keller 	ice_debug_array(hw, ICE_DBG_FW_LOG, 16, 1, (u8 *)buf,
8728b97ceb1SHieu Tran 			le16_to_cpu(desc->datalen));
8734f70daa0SJacob Keller 	ice_debug(hw, ICE_DBG_FW_LOG, "[ FW Log Msg End ]\n");
8748b97ceb1SHieu Tran }
8758b97ceb1SHieu Tran 
8769daf8208SAnirudh Venkataramanan /**
8774ee656bbSTony Nguyen  * ice_get_itr_intrl_gran
878f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
8799e4ab4c2SBrett Creeley  *
8804ee656bbSTony Nguyen  * Determines the ITR/INTRL granularities based on the maximum aggregate
8819e4ab4c2SBrett Creeley  * bandwidth according to the device's configuration during power-on.
8829e4ab4c2SBrett Creeley  */
883fe7219faSBruce Allan static void ice_get_itr_intrl_gran(struct ice_hw *hw)
8849e4ab4c2SBrett Creeley {
8859e4ab4c2SBrett Creeley 	u8 max_agg_bw = (rd32(hw, GL_PWR_MODE_CTL) &
8869e4ab4c2SBrett Creeley 			 GL_PWR_MODE_CTL_CAR_MAX_BW_M) >>
8879e4ab4c2SBrett Creeley 			GL_PWR_MODE_CTL_CAR_MAX_BW_S;
8889e4ab4c2SBrett Creeley 
8899e4ab4c2SBrett Creeley 	switch (max_agg_bw) {
8909e4ab4c2SBrett Creeley 	case ICE_MAX_AGG_BW_200G:
8919e4ab4c2SBrett Creeley 	case ICE_MAX_AGG_BW_100G:
8929e4ab4c2SBrett Creeley 	case ICE_MAX_AGG_BW_50G:
8939e4ab4c2SBrett Creeley 		hw->itr_gran = ICE_ITR_GRAN_ABOVE_25;
8949e4ab4c2SBrett Creeley 		hw->intrl_gran = ICE_INTRL_GRAN_ABOVE_25;
8959e4ab4c2SBrett Creeley 		break;
8969e4ab4c2SBrett Creeley 	case ICE_MAX_AGG_BW_25G:
8979e4ab4c2SBrett Creeley 		hw->itr_gran = ICE_ITR_GRAN_MAX_25;
8989e4ab4c2SBrett Creeley 		hw->intrl_gran = ICE_INTRL_GRAN_MAX_25;
8999e4ab4c2SBrett Creeley 		break;
9009e4ab4c2SBrett Creeley 	}
9019e4ab4c2SBrett Creeley }
9029e4ab4c2SBrett Creeley 
9039e4ab4c2SBrett Creeley /**
904f31e4b6fSAnirudh Venkataramanan  * ice_init_hw - main hardware initialization routine
905f31e4b6fSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
906f31e4b6fSAnirudh Venkataramanan  */
907*5e24d598STony Nguyen int ice_init_hw(struct ice_hw *hw)
908f31e4b6fSAnirudh Venkataramanan {
909dc49c772SAnirudh Venkataramanan 	struct ice_aqc_get_phy_caps_data *pcaps;
910*5e24d598STony Nguyen 	int status;
911dc49c772SAnirudh Venkataramanan 	u16 mac_buf_len;
912dc49c772SAnirudh Venkataramanan 	void *mac_buf;
913f31e4b6fSAnirudh Venkataramanan 
914f31e4b6fSAnirudh Venkataramanan 	/* Set MAC type based on DeviceID */
915f31e4b6fSAnirudh Venkataramanan 	status = ice_set_mac_type(hw);
916f31e4b6fSAnirudh Venkataramanan 	if (status)
917f31e4b6fSAnirudh Venkataramanan 		return status;
918f31e4b6fSAnirudh Venkataramanan 
919f31e4b6fSAnirudh Venkataramanan 	hw->pf_id = (u8)(rd32(hw, PF_FUNC_RID) &
920f31e4b6fSAnirudh Venkataramanan 			 PF_FUNC_RID_FUNC_NUM_M) >>
921f31e4b6fSAnirudh Venkataramanan 		PF_FUNC_RID_FUNC_NUM_S;
922f31e4b6fSAnirudh Venkataramanan 
923f31e4b6fSAnirudh Venkataramanan 	status = ice_reset(hw, ICE_RESET_PFR);
924f31e4b6fSAnirudh Venkataramanan 	if (status)
925f31e4b6fSAnirudh Venkataramanan 		return status;
926f31e4b6fSAnirudh Venkataramanan 
927fe7219faSBruce Allan 	ice_get_itr_intrl_gran(hw);
928940b61afSAnirudh Venkataramanan 
9295c91ecfdSJacob Keller 	status = ice_create_all_ctrlq(hw);
930f31e4b6fSAnirudh Venkataramanan 	if (status)
931f31e4b6fSAnirudh Venkataramanan 		goto err_unroll_cqinit;
932f31e4b6fSAnirudh Venkataramanan 
9338b97ceb1SHieu Tran 	/* Enable FW logging. Not fatal if this fails. */
9348b97ceb1SHieu Tran 	status = ice_cfg_fw_log(hw, true);
9358b97ceb1SHieu Tran 	if (status)
9368b97ceb1SHieu Tran 		ice_debug(hw, ICE_DBG_INIT, "Failed to enable FW logging.\n");
9378b97ceb1SHieu Tran 
938f31e4b6fSAnirudh Venkataramanan 	status = ice_clear_pf_cfg(hw);
939f31e4b6fSAnirudh Venkataramanan 	if (status)
940f31e4b6fSAnirudh Venkataramanan 		goto err_unroll_cqinit;
941f31e4b6fSAnirudh Venkataramanan 
942148beb61SHenry Tieman 	/* Set bit to enable Flow Director filters */
943148beb61SHenry Tieman 	wr32(hw, PFQF_FD_ENA, PFQF_FD_ENA_FD_ENA_M);
944148beb61SHenry Tieman 	INIT_LIST_HEAD(&hw->fdir_list_head);
945148beb61SHenry Tieman 
946f31e4b6fSAnirudh Venkataramanan 	ice_clear_pxe_mode(hw);
947f31e4b6fSAnirudh Venkataramanan 
948f31e4b6fSAnirudh Venkataramanan 	status = ice_init_nvm(hw);
949f31e4b6fSAnirudh Venkataramanan 	if (status)
950f31e4b6fSAnirudh Venkataramanan 		goto err_unroll_cqinit;
951f31e4b6fSAnirudh Venkataramanan 
9529c20346bSAnirudh Venkataramanan 	status = ice_get_caps(hw);
9539c20346bSAnirudh Venkataramanan 	if (status)
9549c20346bSAnirudh Venkataramanan 		goto err_unroll_cqinit;
9559c20346bSAnirudh Venkataramanan 
9569c20346bSAnirudh Venkataramanan 	hw->port_info = devm_kzalloc(ice_hw_to_dev(hw),
9579c20346bSAnirudh Venkataramanan 				     sizeof(*hw->port_info), GFP_KERNEL);
9589c20346bSAnirudh Venkataramanan 	if (!hw->port_info) {
9599c20346bSAnirudh Venkataramanan 		status = ICE_ERR_NO_MEMORY;
9609c20346bSAnirudh Venkataramanan 		goto err_unroll_cqinit;
9619c20346bSAnirudh Venkataramanan 	}
9629c20346bSAnirudh Venkataramanan 
963f9867df6SAnirudh Venkataramanan 	/* set the back pointer to HW */
9649c20346bSAnirudh Venkataramanan 	hw->port_info->hw = hw;
9659c20346bSAnirudh Venkataramanan 
9669c20346bSAnirudh Venkataramanan 	/* Initialize port_info struct with switch configuration data */
9679c20346bSAnirudh Venkataramanan 	status = ice_get_initial_sw_cfg(hw);
9689c20346bSAnirudh Venkataramanan 	if (status)
9699c20346bSAnirudh Venkataramanan 		goto err_unroll_alloc;
9709c20346bSAnirudh Venkataramanan 
9719daf8208SAnirudh Venkataramanan 	hw->evb_veb = true;
9729daf8208SAnirudh Venkataramanan 
973d337f2afSAnirudh Venkataramanan 	/* Query the allocated resources for Tx scheduler */
9749c20346bSAnirudh Venkataramanan 	status = ice_sched_query_res_alloc(hw);
9759c20346bSAnirudh Venkataramanan 	if (status) {
9769228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_SCHED, "Failed to get scheduler allocated resources\n");
9779c20346bSAnirudh Venkataramanan 		goto err_unroll_alloc;
9789c20346bSAnirudh Venkataramanan 	}
9794f8a1497SBen Shelton 	ice_sched_get_psm_clk_freq(hw);
9809c20346bSAnirudh Venkataramanan 
981dc49c772SAnirudh Venkataramanan 	/* Initialize port_info struct with scheduler data */
982dc49c772SAnirudh Venkataramanan 	status = ice_sched_init_port(hw->port_info);
983dc49c772SAnirudh Venkataramanan 	if (status)
984dc49c772SAnirudh Venkataramanan 		goto err_unroll_sched;
985dc49c772SAnirudh Venkataramanan 
986dc49c772SAnirudh Venkataramanan 	pcaps = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*pcaps), GFP_KERNEL);
987dc49c772SAnirudh Venkataramanan 	if (!pcaps) {
988dc49c772SAnirudh Venkataramanan 		status = ICE_ERR_NO_MEMORY;
989dc49c772SAnirudh Venkataramanan 		goto err_unroll_sched;
990dc49c772SAnirudh Venkataramanan 	}
991dc49c772SAnirudh Venkataramanan 
992dc49c772SAnirudh Venkataramanan 	/* Initialize port_info struct with PHY capabilities */
993dc49c772SAnirudh Venkataramanan 	status = ice_aq_get_phy_caps(hw->port_info, false,
994d6730a87SAnirudh Venkataramanan 				     ICE_AQC_REPORT_TOPO_CAP_MEDIA, pcaps,
995d6730a87SAnirudh Venkataramanan 				     NULL);
996dc49c772SAnirudh Venkataramanan 	devm_kfree(ice_hw_to_dev(hw), pcaps);
997dc49c772SAnirudh Venkataramanan 	if (status)
998f2651a91SPaul M Stillwell Jr 		dev_warn(ice_hw_to_dev(hw), "Get PHY capabilities failed status = %d, continuing anyway\n",
999f2651a91SPaul M Stillwell Jr 			 status);
1000dc49c772SAnirudh Venkataramanan 
1001dc49c772SAnirudh Venkataramanan 	/* Initialize port_info struct with link information */
1002dc49c772SAnirudh Venkataramanan 	status = ice_aq_get_link_info(hw->port_info, false, NULL, NULL);
1003dc49c772SAnirudh Venkataramanan 	if (status)
1004dc49c772SAnirudh Venkataramanan 		goto err_unroll_sched;
1005dc49c772SAnirudh Venkataramanan 
1006b36c598cSAnirudh Venkataramanan 	/* need a valid SW entry point to build a Tx tree */
1007b36c598cSAnirudh Venkataramanan 	if (!hw->sw_entry_point_layer) {
1008b36c598cSAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_SCHED, "invalid sw entry point\n");
1009b36c598cSAnirudh Venkataramanan 		status = ICE_ERR_CFG;
1010b36c598cSAnirudh Venkataramanan 		goto err_unroll_sched;
1011b36c598cSAnirudh Venkataramanan 	}
10129be1d6f8SAnirudh Venkataramanan 	INIT_LIST_HEAD(&hw->agg_list);
10131ddef455SUsha Ketineni 	/* Initialize max burst size */
10141ddef455SUsha Ketineni 	if (!hw->max_burst_size)
10151ddef455SUsha Ketineni 		ice_cfg_rl_burst_size(hw, ICE_SCHED_DFLT_BURST_SIZE);
1016b36c598cSAnirudh Venkataramanan 
10179daf8208SAnirudh Venkataramanan 	status = ice_init_fltr_mgmt_struct(hw);
10189daf8208SAnirudh Venkataramanan 	if (status)
10199daf8208SAnirudh Venkataramanan 		goto err_unroll_sched;
10209daf8208SAnirudh Venkataramanan 
1021d6fef10cSMd Fahad Iqbal Polash 	/* Get MAC information */
1022d6fef10cSMd Fahad Iqbal Polash 	/* A single port can report up to two (LAN and WoL) addresses */
1023d6fef10cSMd Fahad Iqbal Polash 	mac_buf = devm_kcalloc(ice_hw_to_dev(hw), 2,
1024d6fef10cSMd Fahad Iqbal Polash 			       sizeof(struct ice_aqc_manage_mac_read_resp),
1025d6fef10cSMd Fahad Iqbal Polash 			       GFP_KERNEL);
1026d6fef10cSMd Fahad Iqbal Polash 	mac_buf_len = 2 * sizeof(struct ice_aqc_manage_mac_read_resp);
1027dc49c772SAnirudh Venkataramanan 
102863bb4e1eSWei Yongjun 	if (!mac_buf) {
102963bb4e1eSWei Yongjun 		status = ICE_ERR_NO_MEMORY;
10309daf8208SAnirudh Venkataramanan 		goto err_unroll_fltr_mgmt_struct;
103163bb4e1eSWei Yongjun 	}
1032dc49c772SAnirudh Venkataramanan 
1033dc49c772SAnirudh Venkataramanan 	status = ice_aq_manage_mac_read(hw, mac_buf, mac_buf_len, NULL);
1034dc49c772SAnirudh Venkataramanan 	devm_kfree(ice_hw_to_dev(hw), mac_buf);
1035dc49c772SAnirudh Venkataramanan 
1036dc49c772SAnirudh Venkataramanan 	if (status)
10379daf8208SAnirudh Venkataramanan 		goto err_unroll_fltr_mgmt_struct;
103842449105SAnirudh Venkataramanan 	/* enable jumbo frame support at MAC level */
103942449105SAnirudh Venkataramanan 	status = ice_aq_set_mac_cfg(hw, ICE_AQ_SET_MAC_FRAME_SIZE_MAX, NULL);
104042449105SAnirudh Venkataramanan 	if (status)
104142449105SAnirudh Venkataramanan 		goto err_unroll_fltr_mgmt_struct;
1042148beb61SHenry Tieman 	/* Obtain counter base index which would be used by flow director */
1043148beb61SHenry Tieman 	status = ice_alloc_fd_res_cntr(hw, &hw->fd_ctr_base);
1044148beb61SHenry Tieman 	if (status)
1045148beb61SHenry Tieman 		goto err_unroll_fltr_mgmt_struct;
104632d63fa1STony Nguyen 	status = ice_init_hw_tbls(hw);
104732d63fa1STony Nguyen 	if (status)
104832d63fa1STony Nguyen 		goto err_unroll_fltr_mgmt_struct;
1049a4e82a81STony Nguyen 	mutex_init(&hw->tnl_lock);
1050f31e4b6fSAnirudh Venkataramanan 	return 0;
1051f31e4b6fSAnirudh Venkataramanan 
10529daf8208SAnirudh Venkataramanan err_unroll_fltr_mgmt_struct:
10539daf8208SAnirudh Venkataramanan 	ice_cleanup_fltr_mgmt_struct(hw);
1054dc49c772SAnirudh Venkataramanan err_unroll_sched:
1055dc49c772SAnirudh Venkataramanan 	ice_sched_cleanup_all(hw);
10569c20346bSAnirudh Venkataramanan err_unroll_alloc:
10579c20346bSAnirudh Venkataramanan 	devm_kfree(ice_hw_to_dev(hw), hw->port_info);
1058f31e4b6fSAnirudh Venkataramanan err_unroll_cqinit:
10595c91ecfdSJacob Keller 	ice_destroy_all_ctrlq(hw);
1060f31e4b6fSAnirudh Venkataramanan 	return status;
1061f31e4b6fSAnirudh Venkataramanan }
1062f31e4b6fSAnirudh Venkataramanan 
1063f31e4b6fSAnirudh Venkataramanan /**
1064f31e4b6fSAnirudh Venkataramanan  * ice_deinit_hw - unroll initialization operations done by ice_init_hw
1065f31e4b6fSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
1066ed14245aSAnirudh Venkataramanan  *
1067ed14245aSAnirudh Venkataramanan  * This should be called only during nominal operation, not as a result of
1068ed14245aSAnirudh Venkataramanan  * ice_init_hw() failing since ice_init_hw() will take care of unrolling
1069ed14245aSAnirudh Venkataramanan  * applicable initializations if it fails for any reason.
1070f31e4b6fSAnirudh Venkataramanan  */
1071f31e4b6fSAnirudh Venkataramanan void ice_deinit_hw(struct ice_hw *hw)
1072f31e4b6fSAnirudh Venkataramanan {
1073148beb61SHenry Tieman 	ice_free_fd_res_cntr(hw, hw->fd_ctr_base);
10748b97ceb1SHieu Tran 	ice_cleanup_fltr_mgmt_struct(hw);
10758b97ceb1SHieu Tran 
10769c20346bSAnirudh Venkataramanan 	ice_sched_cleanup_all(hw);
10779be1d6f8SAnirudh Venkataramanan 	ice_sched_clear_agg(hw);
1078c7648810STony Nguyen 	ice_free_seg(hw);
107932d63fa1STony Nguyen 	ice_free_hw_tbls(hw);
1080a4e82a81STony Nguyen 	mutex_destroy(&hw->tnl_lock);
1081dc49c772SAnirudh Venkataramanan 
10829c20346bSAnirudh Venkataramanan 	if (hw->port_info) {
10839c20346bSAnirudh Venkataramanan 		devm_kfree(ice_hw_to_dev(hw), hw->port_info);
10849c20346bSAnirudh Venkataramanan 		hw->port_info = NULL;
10859c20346bSAnirudh Venkataramanan 	}
10869daf8208SAnirudh Venkataramanan 
10878b97ceb1SHieu Tran 	/* Attempt to disable FW logging before shutting down control queues */
10888b97ceb1SHieu Tran 	ice_cfg_fw_log(hw, false);
10895c91ecfdSJacob Keller 	ice_destroy_all_ctrlq(hw);
109033e055fcSVictor Raj 
109133e055fcSVictor Raj 	/* Clear VSI contexts if not already cleared */
109233e055fcSVictor Raj 	ice_clear_all_vsi_ctx(hw);
1093f31e4b6fSAnirudh Venkataramanan }
1094f31e4b6fSAnirudh Venkataramanan 
1095f31e4b6fSAnirudh Venkataramanan /**
1096f31e4b6fSAnirudh Venkataramanan  * ice_check_reset - Check to see if a global reset is complete
1097f31e4b6fSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
1098f31e4b6fSAnirudh Venkataramanan  */
1099*5e24d598STony Nguyen int ice_check_reset(struct ice_hw *hw)
1100f31e4b6fSAnirudh Venkataramanan {
1101585cdabdSNick Nunley 	u32 cnt, reg = 0, grst_timeout, uld_mask;
1102f31e4b6fSAnirudh Venkataramanan 
1103f31e4b6fSAnirudh Venkataramanan 	/* Poll for Device Active state in case a recent CORER, GLOBR,
1104f31e4b6fSAnirudh Venkataramanan 	 * or EMPR has occurred. The grst delay value is in 100ms units.
1105f31e4b6fSAnirudh Venkataramanan 	 * Add 1sec for outstanding AQ commands that can take a long time.
1106f31e4b6fSAnirudh Venkataramanan 	 */
1107585cdabdSNick Nunley 	grst_timeout = ((rd32(hw, GLGEN_RSTCTL) & GLGEN_RSTCTL_GRSTDEL_M) >>
1108f31e4b6fSAnirudh Venkataramanan 			GLGEN_RSTCTL_GRSTDEL_S) + 10;
1109f31e4b6fSAnirudh Venkataramanan 
1110585cdabdSNick Nunley 	for (cnt = 0; cnt < grst_timeout; cnt++) {
1111f31e4b6fSAnirudh Venkataramanan 		mdelay(100);
1112f31e4b6fSAnirudh Venkataramanan 		reg = rd32(hw, GLGEN_RSTAT);
1113f31e4b6fSAnirudh Venkataramanan 		if (!(reg & GLGEN_RSTAT_DEVSTATE_M))
1114f31e4b6fSAnirudh Venkataramanan 			break;
1115f31e4b6fSAnirudh Venkataramanan 	}
1116f31e4b6fSAnirudh Venkataramanan 
1117585cdabdSNick Nunley 	if (cnt == grst_timeout) {
11189228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "Global reset polling failed to complete.\n");
1119f31e4b6fSAnirudh Venkataramanan 		return ICE_ERR_RESET_FAILED;
1120f31e4b6fSAnirudh Venkataramanan 	}
1121f31e4b6fSAnirudh Venkataramanan 
1122cf8fc2a0SBruce Allan #define ICE_RESET_DONE_MASK	(GLNVM_ULD_PCIER_DONE_M |\
1123cf8fc2a0SBruce Allan 				 GLNVM_ULD_PCIER_DONE_1_M |\
1124cf8fc2a0SBruce Allan 				 GLNVM_ULD_CORER_DONE_M |\
1125cf8fc2a0SBruce Allan 				 GLNVM_ULD_GLOBR_DONE_M |\
1126cf8fc2a0SBruce Allan 				 GLNVM_ULD_POR_DONE_M |\
1127cf8fc2a0SBruce Allan 				 GLNVM_ULD_POR_DONE_1_M |\
1128cf8fc2a0SBruce Allan 				 GLNVM_ULD_PCIER_DONE_2_M)
1129cf8fc2a0SBruce Allan 
1130d25a0fc4SDave Ertman 	uld_mask = ICE_RESET_DONE_MASK | (hw->func_caps.common_cap.rdma ?
1131d25a0fc4SDave Ertman 					  GLNVM_ULD_PE_DONE_M : 0);
1132f31e4b6fSAnirudh Venkataramanan 
1133f31e4b6fSAnirudh Venkataramanan 	/* Device is Active; check Global Reset processes are done */
1134f31e4b6fSAnirudh Venkataramanan 	for (cnt = 0; cnt < ICE_PF_RESET_WAIT_COUNT; cnt++) {
1135cf8fc2a0SBruce Allan 		reg = rd32(hw, GLNVM_ULD) & uld_mask;
1136cf8fc2a0SBruce Allan 		if (reg == uld_mask) {
11379228d8b2SJacob Keller 			ice_debug(hw, ICE_DBG_INIT, "Global reset processes done. %d\n", cnt);
1138f31e4b6fSAnirudh Venkataramanan 			break;
1139f31e4b6fSAnirudh Venkataramanan 		}
1140f31e4b6fSAnirudh Venkataramanan 		mdelay(10);
1141f31e4b6fSAnirudh Venkataramanan 	}
1142f31e4b6fSAnirudh Venkataramanan 
1143f31e4b6fSAnirudh Venkataramanan 	if (cnt == ICE_PF_RESET_WAIT_COUNT) {
11449228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "Wait for Reset Done timed out. GLNVM_ULD = 0x%x\n",
1145f31e4b6fSAnirudh Venkataramanan 			  reg);
1146f31e4b6fSAnirudh Venkataramanan 		return ICE_ERR_RESET_FAILED;
1147f31e4b6fSAnirudh Venkataramanan 	}
1148f31e4b6fSAnirudh Venkataramanan 
1149f31e4b6fSAnirudh Venkataramanan 	return 0;
1150f31e4b6fSAnirudh Venkataramanan }
1151f31e4b6fSAnirudh Venkataramanan 
1152f31e4b6fSAnirudh Venkataramanan /**
1153f31e4b6fSAnirudh Venkataramanan  * ice_pf_reset - Reset the PF
1154f31e4b6fSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
1155f31e4b6fSAnirudh Venkataramanan  *
1156f31e4b6fSAnirudh Venkataramanan  * If a global reset has been triggered, this function checks
1157f31e4b6fSAnirudh Venkataramanan  * for its completion and then issues the PF reset
1158f31e4b6fSAnirudh Venkataramanan  */
1159*5e24d598STony Nguyen static int ice_pf_reset(struct ice_hw *hw)
1160f31e4b6fSAnirudh Venkataramanan {
1161f31e4b6fSAnirudh Venkataramanan 	u32 cnt, reg;
1162f31e4b6fSAnirudh Venkataramanan 
1163f31e4b6fSAnirudh Venkataramanan 	/* If at function entry a global reset was already in progress, i.e.
1164f31e4b6fSAnirudh Venkataramanan 	 * state is not 'device active' or any of the reset done bits are not
1165f31e4b6fSAnirudh Venkataramanan 	 * set in GLNVM_ULD, there is no need for a PF Reset; poll until the
1166f31e4b6fSAnirudh Venkataramanan 	 * global reset is done.
1167f31e4b6fSAnirudh Venkataramanan 	 */
1168f31e4b6fSAnirudh Venkataramanan 	if ((rd32(hw, GLGEN_RSTAT) & GLGEN_RSTAT_DEVSTATE_M) ||
1169f31e4b6fSAnirudh Venkataramanan 	    (rd32(hw, GLNVM_ULD) & ICE_RESET_DONE_MASK) ^ ICE_RESET_DONE_MASK) {
1170f31e4b6fSAnirudh Venkataramanan 		/* poll on global reset currently in progress until done */
1171f31e4b6fSAnirudh Venkataramanan 		if (ice_check_reset(hw))
1172f31e4b6fSAnirudh Venkataramanan 			return ICE_ERR_RESET_FAILED;
1173f31e4b6fSAnirudh Venkataramanan 
1174f31e4b6fSAnirudh Venkataramanan 		return 0;
1175f31e4b6fSAnirudh Venkataramanan 	}
1176f31e4b6fSAnirudh Venkataramanan 
1177f31e4b6fSAnirudh Venkataramanan 	/* Reset the PF */
1178f31e4b6fSAnirudh Venkataramanan 	reg = rd32(hw, PFGEN_CTRL);
1179f31e4b6fSAnirudh Venkataramanan 
1180f31e4b6fSAnirudh Venkataramanan 	wr32(hw, PFGEN_CTRL, (reg | PFGEN_CTRL_PFSWR_M));
1181f31e4b6fSAnirudh Venkataramanan 
1182c9a12d6dSDan Nowlin 	/* Wait for the PFR to complete. The wait time is the global config lock
1183c9a12d6dSDan Nowlin 	 * timeout plus the PFR timeout which will account for a possible reset
1184c9a12d6dSDan Nowlin 	 * that is occurring during a download package operation.
1185c9a12d6dSDan Nowlin 	 */
1186c9a12d6dSDan Nowlin 	for (cnt = 0; cnt < ICE_GLOBAL_CFG_LOCK_TIMEOUT +
1187c9a12d6dSDan Nowlin 	     ICE_PF_RESET_WAIT_COUNT; cnt++) {
1188f31e4b6fSAnirudh Venkataramanan 		reg = rd32(hw, PFGEN_CTRL);
1189f31e4b6fSAnirudh Venkataramanan 		if (!(reg & PFGEN_CTRL_PFSWR_M))
1190f31e4b6fSAnirudh Venkataramanan 			break;
1191f31e4b6fSAnirudh Venkataramanan 
1192f31e4b6fSAnirudh Venkataramanan 		mdelay(1);
1193f31e4b6fSAnirudh Venkataramanan 	}
1194f31e4b6fSAnirudh Venkataramanan 
1195f31e4b6fSAnirudh Venkataramanan 	if (cnt == ICE_PF_RESET_WAIT_COUNT) {
11969228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "PF reset polling failed to complete.\n");
1197f31e4b6fSAnirudh Venkataramanan 		return ICE_ERR_RESET_FAILED;
1198f31e4b6fSAnirudh Venkataramanan 	}
1199f31e4b6fSAnirudh Venkataramanan 
1200f31e4b6fSAnirudh Venkataramanan 	return 0;
1201f31e4b6fSAnirudh Venkataramanan }
1202f31e4b6fSAnirudh Venkataramanan 
1203f31e4b6fSAnirudh Venkataramanan /**
1204f31e4b6fSAnirudh Venkataramanan  * ice_reset - Perform different types of reset
1205f31e4b6fSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
1206f31e4b6fSAnirudh Venkataramanan  * @req: reset request
1207f31e4b6fSAnirudh Venkataramanan  *
1208f31e4b6fSAnirudh Venkataramanan  * This function triggers a reset as specified by the req parameter.
1209f31e4b6fSAnirudh Venkataramanan  *
1210f31e4b6fSAnirudh Venkataramanan  * Note:
1211f31e4b6fSAnirudh Venkataramanan  * If anything other than a PF reset is triggered, PXE mode is restored.
1212f31e4b6fSAnirudh Venkataramanan  * This has to be cleared using ice_clear_pxe_mode again, once the AQ
1213f31e4b6fSAnirudh Venkataramanan  * interface has been restored in the rebuild flow.
1214f31e4b6fSAnirudh Venkataramanan  */
1215*5e24d598STony Nguyen int ice_reset(struct ice_hw *hw, enum ice_reset_req req)
1216f31e4b6fSAnirudh Venkataramanan {
1217f31e4b6fSAnirudh Venkataramanan 	u32 val = 0;
1218f31e4b6fSAnirudh Venkataramanan 
1219f31e4b6fSAnirudh Venkataramanan 	switch (req) {
1220f31e4b6fSAnirudh Venkataramanan 	case ICE_RESET_PFR:
1221f31e4b6fSAnirudh Venkataramanan 		return ice_pf_reset(hw);
1222f31e4b6fSAnirudh Venkataramanan 	case ICE_RESET_CORER:
1223f31e4b6fSAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_INIT, "CoreR requested\n");
1224f31e4b6fSAnirudh Venkataramanan 		val = GLGEN_RTRIG_CORER_M;
1225f31e4b6fSAnirudh Venkataramanan 		break;
1226f31e4b6fSAnirudh Venkataramanan 	case ICE_RESET_GLOBR:
1227f31e4b6fSAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_INIT, "GlobalR requested\n");
1228f31e4b6fSAnirudh Venkataramanan 		val = GLGEN_RTRIG_GLOBR_M;
1229f31e4b6fSAnirudh Venkataramanan 		break;
12300f9d5027SAnirudh Venkataramanan 	default:
12310f9d5027SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
1232f31e4b6fSAnirudh Venkataramanan 	}
1233f31e4b6fSAnirudh Venkataramanan 
1234f31e4b6fSAnirudh Venkataramanan 	val |= rd32(hw, GLGEN_RTRIG);
1235f31e4b6fSAnirudh Venkataramanan 	wr32(hw, GLGEN_RTRIG, val);
1236f31e4b6fSAnirudh Venkataramanan 	ice_flush(hw);
1237f31e4b6fSAnirudh Venkataramanan 
1238f31e4b6fSAnirudh Venkataramanan 	/* wait for the FW to be ready */
1239f31e4b6fSAnirudh Venkataramanan 	return ice_check_reset(hw);
1240f31e4b6fSAnirudh Venkataramanan }
1241f31e4b6fSAnirudh Venkataramanan 
12427ec59eeaSAnirudh Venkataramanan /**
1243cdedef59SAnirudh Venkataramanan  * ice_copy_rxq_ctx_to_hw
1244cdedef59SAnirudh Venkataramanan  * @hw: pointer to the hardware structure
1245cdedef59SAnirudh Venkataramanan  * @ice_rxq_ctx: pointer to the rxq context
1246d337f2afSAnirudh Venkataramanan  * @rxq_index: the index of the Rx queue
1247cdedef59SAnirudh Venkataramanan  *
1248f9867df6SAnirudh Venkataramanan  * Copies rxq context from dense structure to HW register space
1249cdedef59SAnirudh Venkataramanan  */
1250*5e24d598STony Nguyen static int
1251cdedef59SAnirudh Venkataramanan ice_copy_rxq_ctx_to_hw(struct ice_hw *hw, u8 *ice_rxq_ctx, u32 rxq_index)
1252cdedef59SAnirudh Venkataramanan {
1253cdedef59SAnirudh Venkataramanan 	u8 i;
1254cdedef59SAnirudh Venkataramanan 
1255cdedef59SAnirudh Venkataramanan 	if (!ice_rxq_ctx)
1256cdedef59SAnirudh Venkataramanan 		return ICE_ERR_BAD_PTR;
1257cdedef59SAnirudh Venkataramanan 
1258cdedef59SAnirudh Venkataramanan 	if (rxq_index > QRX_CTRL_MAX_INDEX)
1259cdedef59SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
1260cdedef59SAnirudh Venkataramanan 
1261f9867df6SAnirudh Venkataramanan 	/* Copy each dword separately to HW */
1262cdedef59SAnirudh Venkataramanan 	for (i = 0; i < ICE_RXQ_CTX_SIZE_DWORDS; i++) {
1263cdedef59SAnirudh Venkataramanan 		wr32(hw, QRX_CONTEXT(i, rxq_index),
1264cdedef59SAnirudh Venkataramanan 		     *((u32 *)(ice_rxq_ctx + (i * sizeof(u32)))));
1265cdedef59SAnirudh Venkataramanan 
1266cdedef59SAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_QCTX, "qrxdata[%d]: %08X\n", i,
1267cdedef59SAnirudh Venkataramanan 			  *((u32 *)(ice_rxq_ctx + (i * sizeof(u32)))));
1268cdedef59SAnirudh Venkataramanan 	}
1269cdedef59SAnirudh Venkataramanan 
1270cdedef59SAnirudh Venkataramanan 	return 0;
1271cdedef59SAnirudh Venkataramanan }
1272cdedef59SAnirudh Venkataramanan 
1273cdedef59SAnirudh Venkataramanan /* LAN Rx Queue Context */
1274cdedef59SAnirudh Venkataramanan static const struct ice_ctx_ele ice_rlan_ctx_info[] = {
1275cdedef59SAnirudh Venkataramanan 	/* Field		Width	LSB */
1276cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, head,		13,	0),
1277cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, cpuid,		8,	13),
1278cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, base,		57,	32),
1279cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, qlen,		13,	89),
1280cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, dbuf,		7,	102),
1281cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, hbuf,		5,	109),
1282cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, dtype,		2,	114),
1283cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, dsize,		1,	116),
1284cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, crcstrip,		1,	117),
1285cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, l2tsel,		1,	119),
1286cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, hsplit_0,		4,	120),
1287cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, hsplit_1,		2,	124),
1288cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, showiv,		1,	127),
1289cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, rxmax,		14,	174),
1290cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, tphrdesc_ena,	1,	193),
1291cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, tphwdesc_ena,	1,	194),
1292cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, tphdata_ena,	1,	195),
1293cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, tphhead_ena,	1,	196),
1294cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, lrxqthresh,		3,	198),
1295c31a5c25SBrett Creeley 	ICE_CTX_STORE(ice_rlan_ctx, prefena,		1,	201),
1296cdedef59SAnirudh Venkataramanan 	{ 0 }
1297cdedef59SAnirudh Venkataramanan };
1298cdedef59SAnirudh Venkataramanan 
1299cdedef59SAnirudh Venkataramanan /**
1300cdedef59SAnirudh Venkataramanan  * ice_write_rxq_ctx
1301cdedef59SAnirudh Venkataramanan  * @hw: pointer to the hardware structure
1302cdedef59SAnirudh Venkataramanan  * @rlan_ctx: pointer to the rxq context
1303d337f2afSAnirudh Venkataramanan  * @rxq_index: the index of the Rx queue
1304cdedef59SAnirudh Venkataramanan  *
1305cdedef59SAnirudh Venkataramanan  * Converts rxq context from sparse to dense structure and then writes
1306c31a5c25SBrett Creeley  * it to HW register space and enables the hardware to prefetch descriptors
1307c31a5c25SBrett Creeley  * instead of only fetching them on demand
1308cdedef59SAnirudh Venkataramanan  */
1309*5e24d598STony Nguyen int
1310cdedef59SAnirudh Venkataramanan ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx,
1311cdedef59SAnirudh Venkataramanan 		  u32 rxq_index)
1312cdedef59SAnirudh Venkataramanan {
1313cdedef59SAnirudh Venkataramanan 	u8 ctx_buf[ICE_RXQ_CTX_SZ] = { 0 };
1314cdedef59SAnirudh Venkataramanan 
1315c31a5c25SBrett Creeley 	if (!rlan_ctx)
1316c31a5c25SBrett Creeley 		return ICE_ERR_BAD_PTR;
1317c31a5c25SBrett Creeley 
1318c31a5c25SBrett Creeley 	rlan_ctx->prefena = 1;
1319c31a5c25SBrett Creeley 
13207e34786aSBruce Allan 	ice_set_ctx(hw, (u8 *)rlan_ctx, ctx_buf, ice_rlan_ctx_info);
1321cdedef59SAnirudh Venkataramanan 	return ice_copy_rxq_ctx_to_hw(hw, ctx_buf, rxq_index);
1322cdedef59SAnirudh Venkataramanan }
1323cdedef59SAnirudh Venkataramanan 
1324cdedef59SAnirudh Venkataramanan /* LAN Tx Queue Context */
1325cdedef59SAnirudh Venkataramanan const struct ice_ctx_ele ice_tlan_ctx_info[] = {
1326cdedef59SAnirudh Venkataramanan 				    /* Field			Width	LSB */
1327cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, base,			57,	0),
1328cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, port_num,			3,	57),
1329cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, cgd_num,			5,	60),
1330cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, pf_num,			3,	65),
1331cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, vmvf_num,			10,	68),
1332cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, vmvf_type,			2,	78),
1333cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, src_vsi,			10,	80),
1334cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, tsyn_ena,			1,	90),
1335201beeb7SAshish Shah 	ICE_CTX_STORE(ice_tlan_ctx, internal_usage_flag,	1,	91),
1336cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, alt_vlan,			1,	92),
1337cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, cpuid,			8,	93),
1338cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, wb_mode,			1,	101),
1339cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, tphrd_desc,			1,	102),
1340cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, tphrd,			1,	103),
1341cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, tphwr_desc,			1,	104),
1342cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, cmpq_id,			9,	105),
1343cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, qnum_in_func,		14,	114),
1344cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, itr_notification_mode,	1,	128),
1345cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, adjust_prof_id,		6,	129),
1346cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, qlen,			13,	135),
1347cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, quanta_prof_idx,		4,	148),
1348cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, tso_ena,			1,	152),
1349cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, tso_qnum,			11,	153),
1350cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, legacy_int,			1,	164),
1351cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, drop_ena,			1,	165),
1352cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, cache_prof_idx,		2,	166),
1353cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, pkt_shaper_prof_idx,	3,	168),
1354201beeb7SAshish Shah 	ICE_CTX_STORE(ice_tlan_ctx, int_q_state,		122,	171),
1355cdedef59SAnirudh Venkataramanan 	{ 0 }
1356cdedef59SAnirudh Venkataramanan };
1357cdedef59SAnirudh Venkataramanan 
13588f5ee3c4SJacob Keller /* Sideband Queue command wrappers */
13598f5ee3c4SJacob Keller 
13608f5ee3c4SJacob Keller /**
13618f5ee3c4SJacob Keller  * ice_sbq_send_cmd - send Sideband Queue command to Sideband Queue
13628f5ee3c4SJacob Keller  * @hw: pointer to the HW struct
13638f5ee3c4SJacob Keller  * @desc: descriptor describing the command
13648f5ee3c4SJacob Keller  * @buf: buffer to use for indirect commands (NULL for direct commands)
13658f5ee3c4SJacob Keller  * @buf_size: size of buffer for indirect commands (0 for direct commands)
13668f5ee3c4SJacob Keller  * @cd: pointer to command details structure
13678f5ee3c4SJacob Keller  */
13688f5ee3c4SJacob Keller static int
13698f5ee3c4SJacob Keller ice_sbq_send_cmd(struct ice_hw *hw, struct ice_sbq_cmd_desc *desc,
13708f5ee3c4SJacob Keller 		 void *buf, u16 buf_size, struct ice_sq_cd *cd)
13718f5ee3c4SJacob Keller {
13728f5ee3c4SJacob Keller 	return ice_status_to_errno(ice_sq_send_cmd(hw, ice_get_sbq(hw),
13738f5ee3c4SJacob Keller 						   (struct ice_aq_desc *)desc,
13748f5ee3c4SJacob Keller 						   buf, buf_size, cd));
13758f5ee3c4SJacob Keller }
13768f5ee3c4SJacob Keller 
13778f5ee3c4SJacob Keller /**
13788f5ee3c4SJacob Keller  * ice_sbq_rw_reg - Fill Sideband Queue command
13798f5ee3c4SJacob Keller  * @hw: pointer to the HW struct
13808f5ee3c4SJacob Keller  * @in: message info to be filled in descriptor
13818f5ee3c4SJacob Keller  */
13828f5ee3c4SJacob Keller int ice_sbq_rw_reg(struct ice_hw *hw, struct ice_sbq_msg_input *in)
13838f5ee3c4SJacob Keller {
13848f5ee3c4SJacob Keller 	struct ice_sbq_cmd_desc desc = {0};
13858f5ee3c4SJacob Keller 	struct ice_sbq_msg_req msg = {0};
13868f5ee3c4SJacob Keller 	u16 msg_len;
13878f5ee3c4SJacob Keller 	int status;
13888f5ee3c4SJacob Keller 
13898f5ee3c4SJacob Keller 	msg_len = sizeof(msg);
13908f5ee3c4SJacob Keller 
13918f5ee3c4SJacob Keller 	msg.dest_dev = in->dest_dev;
13928f5ee3c4SJacob Keller 	msg.opcode = in->opcode;
13938f5ee3c4SJacob Keller 	msg.flags = ICE_SBQ_MSG_FLAGS;
13948f5ee3c4SJacob Keller 	msg.sbe_fbe = ICE_SBQ_MSG_SBE_FBE;
13958f5ee3c4SJacob Keller 	msg.msg_addr_low = cpu_to_le16(in->msg_addr_low);
13968f5ee3c4SJacob Keller 	msg.msg_addr_high = cpu_to_le32(in->msg_addr_high);
13978f5ee3c4SJacob Keller 
13988f5ee3c4SJacob Keller 	if (in->opcode)
13998f5ee3c4SJacob Keller 		msg.data = cpu_to_le32(in->data);
14008f5ee3c4SJacob Keller 	else
14018f5ee3c4SJacob Keller 		/* data read comes back in completion, so shorten the struct by
14028f5ee3c4SJacob Keller 		 * sizeof(msg.data)
14038f5ee3c4SJacob Keller 		 */
14048f5ee3c4SJacob Keller 		msg_len -= sizeof(msg.data);
14058f5ee3c4SJacob Keller 
14068f5ee3c4SJacob Keller 	desc.flags = cpu_to_le16(ICE_AQ_FLAG_RD);
14078f5ee3c4SJacob Keller 	desc.opcode = cpu_to_le16(ice_sbq_opc_neigh_dev_req);
14088f5ee3c4SJacob Keller 	desc.param0.cmd_len = cpu_to_le16(msg_len);
14098f5ee3c4SJacob Keller 	status = ice_sbq_send_cmd(hw, &desc, &msg, msg_len, NULL);
14108f5ee3c4SJacob Keller 	if (!status && !in->opcode)
14118f5ee3c4SJacob Keller 		in->data = le32_to_cpu
14128f5ee3c4SJacob Keller 			(((struct ice_sbq_msg_cmpl *)&msg)->data);
14138f5ee3c4SJacob Keller 	return status;
14148f5ee3c4SJacob Keller }
14158f5ee3c4SJacob Keller 
14167ec59eeaSAnirudh Venkataramanan /* FW Admin Queue command wrappers */
14177ec59eeaSAnirudh Venkataramanan 
1418c7648810STony Nguyen /* Software lock/mutex that is meant to be held while the Global Config Lock
1419c7648810STony Nguyen  * in firmware is acquired by the software to prevent most (but not all) types
1420c7648810STony Nguyen  * of AQ commands from being sent to FW
1421c7648810STony Nguyen  */
1422c7648810STony Nguyen DEFINE_MUTEX(ice_global_cfg_lock_sw);
1423c7648810STony Nguyen 
14247ec59eeaSAnirudh Venkataramanan /**
14253056df93SChinh T Cao  * ice_should_retry_sq_send_cmd
14263056df93SChinh T Cao  * @opcode: AQ opcode
14273056df93SChinh T Cao  *
14283056df93SChinh T Cao  * Decide if we should retry the send command routine for the ATQ, depending
14293056df93SChinh T Cao  * on the opcode.
14303056df93SChinh T Cao  */
14313056df93SChinh T Cao static bool ice_should_retry_sq_send_cmd(u16 opcode)
14323056df93SChinh T Cao {
14333056df93SChinh T Cao 	switch (opcode) {
14343056df93SChinh T Cao 	case ice_aqc_opc_get_link_topo:
14353056df93SChinh T Cao 	case ice_aqc_opc_lldp_stop:
14363056df93SChinh T Cao 	case ice_aqc_opc_lldp_start:
14373056df93SChinh T Cao 	case ice_aqc_opc_lldp_filter_ctrl:
14383056df93SChinh T Cao 		return true;
14393056df93SChinh T Cao 	}
14403056df93SChinh T Cao 
14413056df93SChinh T Cao 	return false;
14423056df93SChinh T Cao }
14433056df93SChinh T Cao 
14443056df93SChinh T Cao /**
14453056df93SChinh T Cao  * ice_sq_send_cmd_retry - send command to Control Queue (ATQ)
14463056df93SChinh T Cao  * @hw: pointer to the HW struct
14473056df93SChinh T Cao  * @cq: pointer to the specific Control queue
14483056df93SChinh T Cao  * @desc: prefilled descriptor describing the command
14493056df93SChinh T Cao  * @buf: buffer to use for indirect commands (or NULL for direct commands)
14503056df93SChinh T Cao  * @buf_size: size of buffer for indirect commands (or 0 for direct commands)
14513056df93SChinh T Cao  * @cd: pointer to command details structure
14523056df93SChinh T Cao  *
14533056df93SChinh T Cao  * Retry sending the FW Admin Queue command, multiple times, to the FW Admin
14543056df93SChinh T Cao  * Queue if the EBUSY AQ error is returned.
14553056df93SChinh T Cao  */
1456*5e24d598STony Nguyen static int
14573056df93SChinh T Cao ice_sq_send_cmd_retry(struct ice_hw *hw, struct ice_ctl_q_info *cq,
14583056df93SChinh T Cao 		      struct ice_aq_desc *desc, void *buf, u16 buf_size,
14593056df93SChinh T Cao 		      struct ice_sq_cd *cd)
14603056df93SChinh T Cao {
14613056df93SChinh T Cao 	struct ice_aq_desc desc_cpy;
1462*5e24d598STony Nguyen 	int status;
14633056df93SChinh T Cao 	bool is_cmd_for_retry;
14643056df93SChinh T Cao 	u8 *buf_cpy = NULL;
14653056df93SChinh T Cao 	u8 idx = 0;
14663056df93SChinh T Cao 	u16 opcode;
14673056df93SChinh T Cao 
14683056df93SChinh T Cao 	opcode = le16_to_cpu(desc->opcode);
14693056df93SChinh T Cao 	is_cmd_for_retry = ice_should_retry_sq_send_cmd(opcode);
14703056df93SChinh T Cao 	memset(&desc_cpy, 0, sizeof(desc_cpy));
14713056df93SChinh T Cao 
14723056df93SChinh T Cao 	if (is_cmd_for_retry) {
14733056df93SChinh T Cao 		if (buf) {
14743056df93SChinh T Cao 			buf_cpy = kzalloc(buf_size, GFP_KERNEL);
14753056df93SChinh T Cao 			if (!buf_cpy)
14763056df93SChinh T Cao 				return ICE_ERR_NO_MEMORY;
14773056df93SChinh T Cao 		}
14783056df93SChinh T Cao 
14793056df93SChinh T Cao 		memcpy(&desc_cpy, desc, sizeof(desc_cpy));
14803056df93SChinh T Cao 	}
14813056df93SChinh T Cao 
14823056df93SChinh T Cao 	do {
14833056df93SChinh T Cao 		status = ice_sq_send_cmd(hw, cq, desc, buf, buf_size, cd);
14843056df93SChinh T Cao 
14853056df93SChinh T Cao 		if (!is_cmd_for_retry || !status ||
14863056df93SChinh T Cao 		    hw->adminq.sq_last_status != ICE_AQ_RC_EBUSY)
14873056df93SChinh T Cao 			break;
14883056df93SChinh T Cao 
14893056df93SChinh T Cao 		if (buf_cpy)
14903056df93SChinh T Cao 			memcpy(buf, buf_cpy, buf_size);
14913056df93SChinh T Cao 
14923056df93SChinh T Cao 		memcpy(desc, &desc_cpy, sizeof(desc_cpy));
14933056df93SChinh T Cao 
14943056df93SChinh T Cao 		mdelay(ICE_SQ_SEND_DELAY_TIME_MS);
14953056df93SChinh T Cao 
14963056df93SChinh T Cao 	} while (++idx < ICE_SQ_SEND_MAX_EXECUTE);
14973056df93SChinh T Cao 
14983056df93SChinh T Cao 	kfree(buf_cpy);
14993056df93SChinh T Cao 
15003056df93SChinh T Cao 	return status;
15013056df93SChinh T Cao }
15023056df93SChinh T Cao 
15033056df93SChinh T Cao /**
15047ec59eeaSAnirudh Venkataramanan  * ice_aq_send_cmd - send FW Admin Queue command to FW Admin Queue
1505f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
15067ec59eeaSAnirudh Venkataramanan  * @desc: descriptor describing the command
15077ec59eeaSAnirudh Venkataramanan  * @buf: buffer to use for indirect commands (NULL for direct commands)
15087ec59eeaSAnirudh Venkataramanan  * @buf_size: size of buffer for indirect commands (0 for direct commands)
15097ec59eeaSAnirudh Venkataramanan  * @cd: pointer to command details structure
15107ec59eeaSAnirudh Venkataramanan  *
15117ec59eeaSAnirudh Venkataramanan  * Helper function to send FW Admin Queue commands to the FW Admin Queue.
15127ec59eeaSAnirudh Venkataramanan  */
1513*5e24d598STony Nguyen int
15147ec59eeaSAnirudh Venkataramanan ice_aq_send_cmd(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf,
15157ec59eeaSAnirudh Venkataramanan 		u16 buf_size, struct ice_sq_cd *cd)
15167ec59eeaSAnirudh Venkataramanan {
1517c7648810STony Nguyen 	struct ice_aqc_req_res *cmd = &desc->params.res_owner;
1518c7648810STony Nguyen 	bool lock_acquired = false;
1519*5e24d598STony Nguyen 	int status;
1520c7648810STony Nguyen 
1521c7648810STony Nguyen 	/* When a package download is in process (i.e. when the firmware's
1522c7648810STony Nguyen 	 * Global Configuration Lock resource is held), only the Download
1523c7648810STony Nguyen 	 * Package, Get Version, Get Package Info List and Release Resource
1524c7648810STony Nguyen 	 * (with resource ID set to Global Config Lock) AdminQ commands are
1525c7648810STony Nguyen 	 * allowed; all others must block until the package download completes
1526c7648810STony Nguyen 	 * and the Global Config Lock is released.  See also
1527c7648810STony Nguyen 	 * ice_acquire_global_cfg_lock().
1528c7648810STony Nguyen 	 */
1529c7648810STony Nguyen 	switch (le16_to_cpu(desc->opcode)) {
1530c7648810STony Nguyen 	case ice_aqc_opc_download_pkg:
1531c7648810STony Nguyen 	case ice_aqc_opc_get_pkg_info_list:
1532c7648810STony Nguyen 	case ice_aqc_opc_get_ver:
1533c7648810STony Nguyen 		break;
1534c7648810STony Nguyen 	case ice_aqc_opc_release_res:
1535c7648810STony Nguyen 		if (le16_to_cpu(cmd->res_id) == ICE_AQC_RES_ID_GLBL_LOCK)
1536c7648810STony Nguyen 			break;
15374e83fc93SBruce Allan 		fallthrough;
1538c7648810STony Nguyen 	default:
1539c7648810STony Nguyen 		mutex_lock(&ice_global_cfg_lock_sw);
1540c7648810STony Nguyen 		lock_acquired = true;
1541c7648810STony Nguyen 		break;
1542c7648810STony Nguyen 	}
1543c7648810STony Nguyen 
15443056df93SChinh T Cao 	status = ice_sq_send_cmd_retry(hw, &hw->adminq, desc, buf, buf_size, cd);
1545c7648810STony Nguyen 	if (lock_acquired)
1546c7648810STony Nguyen 		mutex_unlock(&ice_global_cfg_lock_sw);
1547c7648810STony Nguyen 
1548c7648810STony Nguyen 	return status;
15497ec59eeaSAnirudh Venkataramanan }
15507ec59eeaSAnirudh Venkataramanan 
15517ec59eeaSAnirudh Venkataramanan /**
15527ec59eeaSAnirudh Venkataramanan  * ice_aq_get_fw_ver
1553f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
15547ec59eeaSAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
15557ec59eeaSAnirudh Venkataramanan  *
15567ec59eeaSAnirudh Venkataramanan  * Get the firmware version (0x0001) from the admin queue commands
15577ec59eeaSAnirudh Venkataramanan  */
1558*5e24d598STony Nguyen int ice_aq_get_fw_ver(struct ice_hw *hw, struct ice_sq_cd *cd)
15597ec59eeaSAnirudh Venkataramanan {
15607ec59eeaSAnirudh Venkataramanan 	struct ice_aqc_get_ver *resp;
15617ec59eeaSAnirudh Venkataramanan 	struct ice_aq_desc desc;
1562*5e24d598STony Nguyen 	int status;
15637ec59eeaSAnirudh Venkataramanan 
15647ec59eeaSAnirudh Venkataramanan 	resp = &desc.params.get_ver;
15657ec59eeaSAnirudh Venkataramanan 
15667ec59eeaSAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_ver);
15677ec59eeaSAnirudh Venkataramanan 
15687ec59eeaSAnirudh Venkataramanan 	status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
15697ec59eeaSAnirudh Venkataramanan 
15707ec59eeaSAnirudh Venkataramanan 	if (!status) {
15717ec59eeaSAnirudh Venkataramanan 		hw->fw_branch = resp->fw_branch;
15727ec59eeaSAnirudh Venkataramanan 		hw->fw_maj_ver = resp->fw_major;
15737ec59eeaSAnirudh Venkataramanan 		hw->fw_min_ver = resp->fw_minor;
15747ec59eeaSAnirudh Venkataramanan 		hw->fw_patch = resp->fw_patch;
15757ec59eeaSAnirudh Venkataramanan 		hw->fw_build = le32_to_cpu(resp->fw_build);
15767ec59eeaSAnirudh Venkataramanan 		hw->api_branch = resp->api_branch;
15777ec59eeaSAnirudh Venkataramanan 		hw->api_maj_ver = resp->api_major;
15787ec59eeaSAnirudh Venkataramanan 		hw->api_min_ver = resp->api_minor;
15797ec59eeaSAnirudh Venkataramanan 		hw->api_patch = resp->api_patch;
15807ec59eeaSAnirudh Venkataramanan 	}
15817ec59eeaSAnirudh Venkataramanan 
15827ec59eeaSAnirudh Venkataramanan 	return status;
15837ec59eeaSAnirudh Venkataramanan }
15847ec59eeaSAnirudh Venkataramanan 
15857ec59eeaSAnirudh Venkataramanan /**
1586e3710a01SPaul M Stillwell Jr  * ice_aq_send_driver_ver
1587e3710a01SPaul M Stillwell Jr  * @hw: pointer to the HW struct
1588e3710a01SPaul M Stillwell Jr  * @dv: driver's major, minor version
1589e3710a01SPaul M Stillwell Jr  * @cd: pointer to command details structure or NULL
1590e3710a01SPaul M Stillwell Jr  *
1591e3710a01SPaul M Stillwell Jr  * Send the driver version (0x0002) to the firmware
1592e3710a01SPaul M Stillwell Jr  */
1593*5e24d598STony Nguyen int
1594e3710a01SPaul M Stillwell Jr ice_aq_send_driver_ver(struct ice_hw *hw, struct ice_driver_ver *dv,
1595e3710a01SPaul M Stillwell Jr 		       struct ice_sq_cd *cd)
1596e3710a01SPaul M Stillwell Jr {
1597e3710a01SPaul M Stillwell Jr 	struct ice_aqc_driver_ver *cmd;
1598e3710a01SPaul M Stillwell Jr 	struct ice_aq_desc desc;
1599e3710a01SPaul M Stillwell Jr 	u16 len;
1600e3710a01SPaul M Stillwell Jr 
1601e3710a01SPaul M Stillwell Jr 	cmd = &desc.params.driver_ver;
1602e3710a01SPaul M Stillwell Jr 
1603e3710a01SPaul M Stillwell Jr 	if (!dv)
1604e3710a01SPaul M Stillwell Jr 		return ICE_ERR_PARAM;
1605e3710a01SPaul M Stillwell Jr 
1606e3710a01SPaul M Stillwell Jr 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_driver_ver);
1607e3710a01SPaul M Stillwell Jr 
1608e3710a01SPaul M Stillwell Jr 	desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
1609e3710a01SPaul M Stillwell Jr 	cmd->major_ver = dv->major_ver;
1610e3710a01SPaul M Stillwell Jr 	cmd->minor_ver = dv->minor_ver;
1611e3710a01SPaul M Stillwell Jr 	cmd->build_ver = dv->build_ver;
1612e3710a01SPaul M Stillwell Jr 	cmd->subbuild_ver = dv->subbuild_ver;
1613e3710a01SPaul M Stillwell Jr 
1614e3710a01SPaul M Stillwell Jr 	len = 0;
1615e3710a01SPaul M Stillwell Jr 	while (len < sizeof(dv->driver_string) &&
1616e3710a01SPaul M Stillwell Jr 	       isascii(dv->driver_string[len]) && dv->driver_string[len])
1617e3710a01SPaul M Stillwell Jr 		len++;
1618e3710a01SPaul M Stillwell Jr 
1619e3710a01SPaul M Stillwell Jr 	return ice_aq_send_cmd(hw, &desc, dv->driver_string, len, cd);
1620e3710a01SPaul M Stillwell Jr }
1621e3710a01SPaul M Stillwell Jr 
1622e3710a01SPaul M Stillwell Jr /**
16237ec59eeaSAnirudh Venkataramanan  * ice_aq_q_shutdown
1624f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
16257ec59eeaSAnirudh Venkataramanan  * @unloading: is the driver unloading itself
16267ec59eeaSAnirudh Venkataramanan  *
16277ec59eeaSAnirudh Venkataramanan  * Tell the Firmware that we're shutting down the AdminQ and whether
16287ec59eeaSAnirudh Venkataramanan  * or not the driver is unloading as well (0x0003).
16297ec59eeaSAnirudh Venkataramanan  */
1630*5e24d598STony Nguyen int ice_aq_q_shutdown(struct ice_hw *hw, bool unloading)
16317ec59eeaSAnirudh Venkataramanan {
16327ec59eeaSAnirudh Venkataramanan 	struct ice_aqc_q_shutdown *cmd;
16337ec59eeaSAnirudh Venkataramanan 	struct ice_aq_desc desc;
16347ec59eeaSAnirudh Venkataramanan 
16357ec59eeaSAnirudh Venkataramanan 	cmd = &desc.params.q_shutdown;
16367ec59eeaSAnirudh Venkataramanan 
16377ec59eeaSAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_q_shutdown);
16387ec59eeaSAnirudh Venkataramanan 
16397ec59eeaSAnirudh Venkataramanan 	if (unloading)
16407404e84aSBruce Allan 		cmd->driver_unloading = ICE_AQC_DRIVER_UNLOADING;
16417ec59eeaSAnirudh Venkataramanan 
16427ec59eeaSAnirudh Venkataramanan 	return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
16437ec59eeaSAnirudh Venkataramanan }
1644f31e4b6fSAnirudh Venkataramanan 
1645f31e4b6fSAnirudh Venkataramanan /**
1646f31e4b6fSAnirudh Venkataramanan  * ice_aq_req_res
1647f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
1648f9867df6SAnirudh Venkataramanan  * @res: resource ID
1649f31e4b6fSAnirudh Venkataramanan  * @access: access type
1650f31e4b6fSAnirudh Venkataramanan  * @sdp_number: resource number
1651f31e4b6fSAnirudh Venkataramanan  * @timeout: the maximum time in ms that the driver may hold the resource
1652f31e4b6fSAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
1653f31e4b6fSAnirudh Venkataramanan  *
1654ff2b1321SDan Nowlin  * Requests common resource using the admin queue commands (0x0008).
1655ff2b1321SDan Nowlin  * When attempting to acquire the Global Config Lock, the driver can
1656ff2b1321SDan Nowlin  * learn of three states:
1657ff2b1321SDan Nowlin  *  1) ICE_SUCCESS -        acquired lock, and can perform download package
1658ff2b1321SDan Nowlin  *  2) ICE_ERR_AQ_ERROR -   did not get lock, driver should fail to load
1659ff2b1321SDan Nowlin  *  3) ICE_ERR_AQ_NO_WORK - did not get lock, but another driver has
1660ff2b1321SDan Nowlin  *                          successfully downloaded the package; the driver does
1661ff2b1321SDan Nowlin  *                          not have to download the package and can continue
1662ff2b1321SDan Nowlin  *                          loading
1663ff2b1321SDan Nowlin  *
1664ff2b1321SDan Nowlin  * Note that if the caller is in an acquire lock, perform action, release lock
1665ff2b1321SDan Nowlin  * phase of operation, it is possible that the FW may detect a timeout and issue
1666ff2b1321SDan Nowlin  * a CORER. In this case, the driver will receive a CORER interrupt and will
1667ff2b1321SDan Nowlin  * have to determine its cause. The calling thread that is handling this flow
1668ff2b1321SDan Nowlin  * will likely get an error propagated back to it indicating the Download
1669ff2b1321SDan Nowlin  * Package, Update Package or the Release Resource AQ commands timed out.
1670f31e4b6fSAnirudh Venkataramanan  */
1671*5e24d598STony Nguyen static int
1672f31e4b6fSAnirudh Venkataramanan ice_aq_req_res(struct ice_hw *hw, enum ice_aq_res_ids res,
1673f31e4b6fSAnirudh Venkataramanan 	       enum ice_aq_res_access_type access, u8 sdp_number, u32 *timeout,
1674f31e4b6fSAnirudh Venkataramanan 	       struct ice_sq_cd *cd)
1675f31e4b6fSAnirudh Venkataramanan {
1676f31e4b6fSAnirudh Venkataramanan 	struct ice_aqc_req_res *cmd_resp;
1677f31e4b6fSAnirudh Venkataramanan 	struct ice_aq_desc desc;
1678*5e24d598STony Nguyen 	int status;
1679f31e4b6fSAnirudh Venkataramanan 
1680f31e4b6fSAnirudh Venkataramanan 	cmd_resp = &desc.params.res_owner;
1681f31e4b6fSAnirudh Venkataramanan 
1682f31e4b6fSAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_req_res);
1683f31e4b6fSAnirudh Venkataramanan 
1684f31e4b6fSAnirudh Venkataramanan 	cmd_resp->res_id = cpu_to_le16(res);
1685f31e4b6fSAnirudh Venkataramanan 	cmd_resp->access_type = cpu_to_le16(access);
1686f31e4b6fSAnirudh Venkataramanan 	cmd_resp->res_number = cpu_to_le32(sdp_number);
1687ff2b1321SDan Nowlin 	cmd_resp->timeout = cpu_to_le32(*timeout);
1688ff2b1321SDan Nowlin 	*timeout = 0;
1689f31e4b6fSAnirudh Venkataramanan 
1690f31e4b6fSAnirudh Venkataramanan 	status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
1691ff2b1321SDan Nowlin 
1692f31e4b6fSAnirudh Venkataramanan 	/* The completion specifies the maximum time in ms that the driver
1693f31e4b6fSAnirudh Venkataramanan 	 * may hold the resource in the Timeout field.
1694ff2b1321SDan Nowlin 	 */
1695ff2b1321SDan Nowlin 
1696ff2b1321SDan Nowlin 	/* Global config lock response utilizes an additional status field.
1697ff2b1321SDan Nowlin 	 *
1698ff2b1321SDan Nowlin 	 * If the Global config lock resource is held by some other driver, the
1699ff2b1321SDan Nowlin 	 * command completes with ICE_AQ_RES_GLBL_IN_PROG in the status field
1700ff2b1321SDan Nowlin 	 * and the timeout field indicates the maximum time the current owner
1701ff2b1321SDan Nowlin 	 * of the resource has to free it.
1702ff2b1321SDan Nowlin 	 */
1703ff2b1321SDan Nowlin 	if (res == ICE_GLOBAL_CFG_LOCK_RES_ID) {
1704ff2b1321SDan Nowlin 		if (le16_to_cpu(cmd_resp->status) == ICE_AQ_RES_GLBL_SUCCESS) {
1705ff2b1321SDan Nowlin 			*timeout = le32_to_cpu(cmd_resp->timeout);
1706ff2b1321SDan Nowlin 			return 0;
1707ff2b1321SDan Nowlin 		} else if (le16_to_cpu(cmd_resp->status) ==
1708ff2b1321SDan Nowlin 			   ICE_AQ_RES_GLBL_IN_PROG) {
1709ff2b1321SDan Nowlin 			*timeout = le32_to_cpu(cmd_resp->timeout);
1710ff2b1321SDan Nowlin 			return ICE_ERR_AQ_ERROR;
1711ff2b1321SDan Nowlin 		} else if (le16_to_cpu(cmd_resp->status) ==
1712ff2b1321SDan Nowlin 			   ICE_AQ_RES_GLBL_DONE) {
1713ff2b1321SDan Nowlin 			return ICE_ERR_AQ_NO_WORK;
1714ff2b1321SDan Nowlin 		}
1715ff2b1321SDan Nowlin 
1716ff2b1321SDan Nowlin 		/* invalid FW response, force a timeout immediately */
1717ff2b1321SDan Nowlin 		*timeout = 0;
1718ff2b1321SDan Nowlin 		return ICE_ERR_AQ_ERROR;
1719ff2b1321SDan Nowlin 	}
1720ff2b1321SDan Nowlin 
1721ff2b1321SDan Nowlin 	/* If the resource is held by some other driver, the command completes
1722ff2b1321SDan Nowlin 	 * with a busy return value and the timeout field indicates the maximum
1723ff2b1321SDan Nowlin 	 * time the current owner of the resource has to free it.
1724f31e4b6fSAnirudh Venkataramanan 	 */
1725f31e4b6fSAnirudh Venkataramanan 	if (!status || hw->adminq.sq_last_status == ICE_AQ_RC_EBUSY)
1726f31e4b6fSAnirudh Venkataramanan 		*timeout = le32_to_cpu(cmd_resp->timeout);
1727f31e4b6fSAnirudh Venkataramanan 
1728f31e4b6fSAnirudh Venkataramanan 	return status;
1729f31e4b6fSAnirudh Venkataramanan }
1730f31e4b6fSAnirudh Venkataramanan 
1731f31e4b6fSAnirudh Venkataramanan /**
1732f31e4b6fSAnirudh Venkataramanan  * ice_aq_release_res
1733f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
1734f9867df6SAnirudh Venkataramanan  * @res: resource ID
1735f31e4b6fSAnirudh Venkataramanan  * @sdp_number: resource number
1736f31e4b6fSAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
1737f31e4b6fSAnirudh Venkataramanan  *
1738f31e4b6fSAnirudh Venkataramanan  * release common resource using the admin queue commands (0x0009)
1739f31e4b6fSAnirudh Venkataramanan  */
1740*5e24d598STony Nguyen static int
1741f31e4b6fSAnirudh Venkataramanan ice_aq_release_res(struct ice_hw *hw, enum ice_aq_res_ids res, u8 sdp_number,
1742f31e4b6fSAnirudh Venkataramanan 		   struct ice_sq_cd *cd)
1743f31e4b6fSAnirudh Venkataramanan {
1744f31e4b6fSAnirudh Venkataramanan 	struct ice_aqc_req_res *cmd;
1745f31e4b6fSAnirudh Venkataramanan 	struct ice_aq_desc desc;
1746f31e4b6fSAnirudh Venkataramanan 
1747f31e4b6fSAnirudh Venkataramanan 	cmd = &desc.params.res_owner;
1748f31e4b6fSAnirudh Venkataramanan 
1749f31e4b6fSAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_release_res);
1750f31e4b6fSAnirudh Venkataramanan 
1751f31e4b6fSAnirudh Venkataramanan 	cmd->res_id = cpu_to_le16(res);
1752f31e4b6fSAnirudh Venkataramanan 	cmd->res_number = cpu_to_le32(sdp_number);
1753f31e4b6fSAnirudh Venkataramanan 
1754f31e4b6fSAnirudh Venkataramanan 	return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
1755f31e4b6fSAnirudh Venkataramanan }
1756f31e4b6fSAnirudh Venkataramanan 
1757f31e4b6fSAnirudh Venkataramanan /**
1758f31e4b6fSAnirudh Venkataramanan  * ice_acquire_res
1759f31e4b6fSAnirudh Venkataramanan  * @hw: pointer to the HW structure
1760f9867df6SAnirudh Venkataramanan  * @res: resource ID
1761f31e4b6fSAnirudh Venkataramanan  * @access: access type (read or write)
1762ff2b1321SDan Nowlin  * @timeout: timeout in milliseconds
1763f31e4b6fSAnirudh Venkataramanan  *
1764f31e4b6fSAnirudh Venkataramanan  * This function will attempt to acquire the ownership of a resource.
1765f31e4b6fSAnirudh Venkataramanan  */
1766*5e24d598STony Nguyen int
1767f31e4b6fSAnirudh Venkataramanan ice_acquire_res(struct ice_hw *hw, enum ice_aq_res_ids res,
1768ff2b1321SDan Nowlin 		enum ice_aq_res_access_type access, u32 timeout)
1769f31e4b6fSAnirudh Venkataramanan {
1770f31e4b6fSAnirudh Venkataramanan #define ICE_RES_POLLING_DELAY_MS	10
1771f31e4b6fSAnirudh Venkataramanan 	u32 delay = ICE_RES_POLLING_DELAY_MS;
1772ff2b1321SDan Nowlin 	u32 time_left = timeout;
1773*5e24d598STony Nguyen 	int status;
1774f31e4b6fSAnirudh Venkataramanan 
1775f31e4b6fSAnirudh Venkataramanan 	status = ice_aq_req_res(hw, res, access, 0, &time_left, NULL);
1776f31e4b6fSAnirudh Venkataramanan 
1777ff2b1321SDan Nowlin 	/* A return code of ICE_ERR_AQ_NO_WORK means that another driver has
1778ff2b1321SDan Nowlin 	 * previously acquired the resource and performed any necessary updates;
1779ff2b1321SDan Nowlin 	 * in this case the caller does not obtain the resource and has no
1780ff2b1321SDan Nowlin 	 * further work to do.
1781f31e4b6fSAnirudh Venkataramanan 	 */
1782ff2b1321SDan Nowlin 	if (status == ICE_ERR_AQ_NO_WORK)
1783f31e4b6fSAnirudh Venkataramanan 		goto ice_acquire_res_exit;
1784f31e4b6fSAnirudh Venkataramanan 
1785f31e4b6fSAnirudh Venkataramanan 	if (status)
17869228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_RES, "resource %d acquire type %d failed.\n", res, access);
1787f31e4b6fSAnirudh Venkataramanan 
1788f31e4b6fSAnirudh Venkataramanan 	/* If necessary, poll until the current lock owner timeouts */
1789f31e4b6fSAnirudh Venkataramanan 	timeout = time_left;
1790f31e4b6fSAnirudh Venkataramanan 	while (status && timeout && time_left) {
1791f31e4b6fSAnirudh Venkataramanan 		mdelay(delay);
1792f31e4b6fSAnirudh Venkataramanan 		timeout = (timeout > delay) ? timeout - delay : 0;
1793f31e4b6fSAnirudh Venkataramanan 		status = ice_aq_req_res(hw, res, access, 0, &time_left, NULL);
1794f31e4b6fSAnirudh Venkataramanan 
1795ff2b1321SDan Nowlin 		if (status == ICE_ERR_AQ_NO_WORK)
1796f31e4b6fSAnirudh Venkataramanan 			/* lock free, but no work to do */
1797f31e4b6fSAnirudh Venkataramanan 			break;
1798f31e4b6fSAnirudh Venkataramanan 
1799f31e4b6fSAnirudh Venkataramanan 		if (!status)
1800f31e4b6fSAnirudh Venkataramanan 			/* lock acquired */
1801f31e4b6fSAnirudh Venkataramanan 			break;
1802f31e4b6fSAnirudh Venkataramanan 	}
1803f31e4b6fSAnirudh Venkataramanan 	if (status && status != ICE_ERR_AQ_NO_WORK)
1804f31e4b6fSAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_RES, "resource acquire timed out.\n");
1805f31e4b6fSAnirudh Venkataramanan 
1806f31e4b6fSAnirudh Venkataramanan ice_acquire_res_exit:
1807f31e4b6fSAnirudh Venkataramanan 	if (status == ICE_ERR_AQ_NO_WORK) {
1808f31e4b6fSAnirudh Venkataramanan 		if (access == ICE_RES_WRITE)
18099228d8b2SJacob Keller 			ice_debug(hw, ICE_DBG_RES, "resource indicates no work to do.\n");
1810f31e4b6fSAnirudh Venkataramanan 		else
18119228d8b2SJacob Keller 			ice_debug(hw, ICE_DBG_RES, "Warning: ICE_ERR_AQ_NO_WORK not expected\n");
1812f31e4b6fSAnirudh Venkataramanan 	}
1813f31e4b6fSAnirudh Venkataramanan 	return status;
1814f31e4b6fSAnirudh Venkataramanan }
1815f31e4b6fSAnirudh Venkataramanan 
1816f31e4b6fSAnirudh Venkataramanan /**
1817f31e4b6fSAnirudh Venkataramanan  * ice_release_res
1818f31e4b6fSAnirudh Venkataramanan  * @hw: pointer to the HW structure
1819f9867df6SAnirudh Venkataramanan  * @res: resource ID
1820f31e4b6fSAnirudh Venkataramanan  *
1821f31e4b6fSAnirudh Venkataramanan  * This function will release a resource using the proper Admin Command.
1822f31e4b6fSAnirudh Venkataramanan  */
1823f31e4b6fSAnirudh Venkataramanan void ice_release_res(struct ice_hw *hw, enum ice_aq_res_ids res)
1824f31e4b6fSAnirudh Venkataramanan {
1825*5e24d598STony Nguyen 	int status;
1826f31e4b6fSAnirudh Venkataramanan 	u32 total_delay = 0;
1827f31e4b6fSAnirudh Venkataramanan 
1828f31e4b6fSAnirudh Venkataramanan 	status = ice_aq_release_res(hw, res, 0, NULL);
1829f31e4b6fSAnirudh Venkataramanan 
1830f31e4b6fSAnirudh Venkataramanan 	/* there are some rare cases when trying to release the resource
1831f9867df6SAnirudh Venkataramanan 	 * results in an admin queue timeout, so handle them correctly
1832f31e4b6fSAnirudh Venkataramanan 	 */
1833f31e4b6fSAnirudh Venkataramanan 	while ((status == ICE_ERR_AQ_TIMEOUT) &&
1834f31e4b6fSAnirudh Venkataramanan 	       (total_delay < hw->adminq.sq_cmd_timeout)) {
1835f31e4b6fSAnirudh Venkataramanan 		mdelay(1);
1836f31e4b6fSAnirudh Venkataramanan 		status = ice_aq_release_res(hw, res, 0, NULL);
1837f31e4b6fSAnirudh Venkataramanan 		total_delay++;
1838f31e4b6fSAnirudh Venkataramanan 	}
1839f31e4b6fSAnirudh Venkataramanan }
1840f31e4b6fSAnirudh Venkataramanan 
1841f31e4b6fSAnirudh Venkataramanan /**
184231ad4e4eSTony Nguyen  * ice_aq_alloc_free_res - command to allocate/free resources
184331ad4e4eSTony Nguyen  * @hw: pointer to the HW struct
184431ad4e4eSTony Nguyen  * @num_entries: number of resource entries in buffer
184531ad4e4eSTony Nguyen  * @buf: Indirect buffer to hold data parameters and response
184631ad4e4eSTony Nguyen  * @buf_size: size of buffer for indirect commands
184731ad4e4eSTony Nguyen  * @opc: pass in the command opcode
184831ad4e4eSTony Nguyen  * @cd: pointer to command details structure or NULL
184931ad4e4eSTony Nguyen  *
185031ad4e4eSTony Nguyen  * Helper function to allocate/free resources using the admin queue commands
185131ad4e4eSTony Nguyen  */
1852*5e24d598STony Nguyen int
185331ad4e4eSTony Nguyen ice_aq_alloc_free_res(struct ice_hw *hw, u16 num_entries,
185431ad4e4eSTony Nguyen 		      struct ice_aqc_alloc_free_res_elem *buf, u16 buf_size,
185531ad4e4eSTony Nguyen 		      enum ice_adminq_opc opc, struct ice_sq_cd *cd)
185631ad4e4eSTony Nguyen {
185731ad4e4eSTony Nguyen 	struct ice_aqc_alloc_free_res_cmd *cmd;
185831ad4e4eSTony Nguyen 	struct ice_aq_desc desc;
185931ad4e4eSTony Nguyen 
186031ad4e4eSTony Nguyen 	cmd = &desc.params.sw_res_ctrl;
186131ad4e4eSTony Nguyen 
186231ad4e4eSTony Nguyen 	if (!buf)
186331ad4e4eSTony Nguyen 		return ICE_ERR_PARAM;
186431ad4e4eSTony Nguyen 
186511404310SBruce Allan 	if (buf_size < flex_array_size(buf, elem, num_entries))
186631ad4e4eSTony Nguyen 		return ICE_ERR_PARAM;
186731ad4e4eSTony Nguyen 
186831ad4e4eSTony Nguyen 	ice_fill_dflt_direct_cmd_desc(&desc, opc);
186931ad4e4eSTony Nguyen 
187031ad4e4eSTony Nguyen 	desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
187131ad4e4eSTony Nguyen 
187231ad4e4eSTony Nguyen 	cmd->num_entries = cpu_to_le16(num_entries);
187331ad4e4eSTony Nguyen 
187431ad4e4eSTony Nguyen 	return ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
187531ad4e4eSTony Nguyen }
187631ad4e4eSTony Nguyen 
187731ad4e4eSTony Nguyen /**
187831ad4e4eSTony Nguyen  * ice_alloc_hw_res - allocate resource
187931ad4e4eSTony Nguyen  * @hw: pointer to the HW struct
188031ad4e4eSTony Nguyen  * @type: type of resource
188131ad4e4eSTony Nguyen  * @num: number of resources to allocate
188231ad4e4eSTony Nguyen  * @btm: allocate from bottom
188331ad4e4eSTony Nguyen  * @res: pointer to array that will receive the resources
188431ad4e4eSTony Nguyen  */
1885*5e24d598STony Nguyen int
188631ad4e4eSTony Nguyen ice_alloc_hw_res(struct ice_hw *hw, u16 type, u16 num, bool btm, u16 *res)
188731ad4e4eSTony Nguyen {
188831ad4e4eSTony Nguyen 	struct ice_aqc_alloc_free_res_elem *buf;
1889*5e24d598STony Nguyen 	int status;
189031ad4e4eSTony Nguyen 	u16 buf_len;
189131ad4e4eSTony Nguyen 
189266486d89SBruce Allan 	buf_len = struct_size(buf, elem, num);
189331ad4e4eSTony Nguyen 	buf = kzalloc(buf_len, GFP_KERNEL);
189431ad4e4eSTony Nguyen 	if (!buf)
189531ad4e4eSTony Nguyen 		return ICE_ERR_NO_MEMORY;
189631ad4e4eSTony Nguyen 
189731ad4e4eSTony Nguyen 	/* Prepare buffer to allocate resource. */
189831ad4e4eSTony Nguyen 	buf->num_elems = cpu_to_le16(num);
189931ad4e4eSTony Nguyen 	buf->res_type = cpu_to_le16(type | ICE_AQC_RES_TYPE_FLAG_DEDICATED |
190031ad4e4eSTony Nguyen 				    ICE_AQC_RES_TYPE_FLAG_IGNORE_INDEX);
190131ad4e4eSTony Nguyen 	if (btm)
190231ad4e4eSTony Nguyen 		buf->res_type |= cpu_to_le16(ICE_AQC_RES_TYPE_FLAG_SCAN_BOTTOM);
190331ad4e4eSTony Nguyen 
190431ad4e4eSTony Nguyen 	status = ice_aq_alloc_free_res(hw, 1, buf, buf_len,
190531ad4e4eSTony Nguyen 				       ice_aqc_opc_alloc_res, NULL);
190631ad4e4eSTony Nguyen 	if (status)
190731ad4e4eSTony Nguyen 		goto ice_alloc_res_exit;
190831ad4e4eSTony Nguyen 
190966486d89SBruce Allan 	memcpy(res, buf->elem, sizeof(*buf->elem) * num);
191031ad4e4eSTony Nguyen 
191131ad4e4eSTony Nguyen ice_alloc_res_exit:
191231ad4e4eSTony Nguyen 	kfree(buf);
191331ad4e4eSTony Nguyen 	return status;
191431ad4e4eSTony Nguyen }
191531ad4e4eSTony Nguyen 
191631ad4e4eSTony Nguyen /**
1917451f2c44STony Nguyen  * ice_free_hw_res - free allocated HW resource
1918451f2c44STony Nguyen  * @hw: pointer to the HW struct
1919451f2c44STony Nguyen  * @type: type of resource to free
1920451f2c44STony Nguyen  * @num: number of resources
1921451f2c44STony Nguyen  * @res: pointer to array that contains the resources to free
1922451f2c44STony Nguyen  */
1923*5e24d598STony Nguyen int ice_free_hw_res(struct ice_hw *hw, u16 type, u16 num, u16 *res)
1924451f2c44STony Nguyen {
1925451f2c44STony Nguyen 	struct ice_aqc_alloc_free_res_elem *buf;
1926*5e24d598STony Nguyen 	int status;
1927451f2c44STony Nguyen 	u16 buf_len;
1928451f2c44STony Nguyen 
192966486d89SBruce Allan 	buf_len = struct_size(buf, elem, num);
1930451f2c44STony Nguyen 	buf = kzalloc(buf_len, GFP_KERNEL);
1931451f2c44STony Nguyen 	if (!buf)
1932451f2c44STony Nguyen 		return ICE_ERR_NO_MEMORY;
1933451f2c44STony Nguyen 
1934451f2c44STony Nguyen 	/* Prepare buffer to free resource. */
1935451f2c44STony Nguyen 	buf->num_elems = cpu_to_le16(num);
1936451f2c44STony Nguyen 	buf->res_type = cpu_to_le16(type);
193766486d89SBruce Allan 	memcpy(buf->elem, res, sizeof(*buf->elem) * num);
1938451f2c44STony Nguyen 
1939451f2c44STony Nguyen 	status = ice_aq_alloc_free_res(hw, num, buf, buf_len,
1940451f2c44STony Nguyen 				       ice_aqc_opc_free_res, NULL);
1941451f2c44STony Nguyen 	if (status)
1942451f2c44STony Nguyen 		ice_debug(hw, ICE_DBG_SW, "CQ CMD Buffer:\n");
1943451f2c44STony Nguyen 
1944451f2c44STony Nguyen 	kfree(buf);
1945451f2c44STony Nguyen 	return status;
1946451f2c44STony Nguyen }
1947451f2c44STony Nguyen 
1948451f2c44STony Nguyen /**
19497a1f7111SBrett Creeley  * ice_get_num_per_func - determine number of resources per PF
1950f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW structure
19517a1f7111SBrett Creeley  * @max: value to be evenly split between each PF
1952995c90f2SAnirudh Venkataramanan  *
1953995c90f2SAnirudh Venkataramanan  * Determine the number of valid functions by going through the bitmap returned
19547a1f7111SBrett Creeley  * from parsing capabilities and use this to calculate the number of resources
19557a1f7111SBrett Creeley  * per PF based on the max value passed in.
1956995c90f2SAnirudh Venkataramanan  */
19577a1f7111SBrett Creeley static u32 ice_get_num_per_func(struct ice_hw *hw, u32 max)
1958995c90f2SAnirudh Venkataramanan {
1959995c90f2SAnirudh Venkataramanan 	u8 funcs;
1960995c90f2SAnirudh Venkataramanan 
1961995c90f2SAnirudh Venkataramanan #define ICE_CAPS_VALID_FUNCS_M	0xFF
1962995c90f2SAnirudh Venkataramanan 	funcs = hweight8(hw->dev_caps.common_cap.valid_functions &
1963995c90f2SAnirudh Venkataramanan 			 ICE_CAPS_VALID_FUNCS_M);
1964995c90f2SAnirudh Venkataramanan 
1965995c90f2SAnirudh Venkataramanan 	if (!funcs)
1966995c90f2SAnirudh Venkataramanan 		return 0;
1967995c90f2SAnirudh Venkataramanan 
19687a1f7111SBrett Creeley 	return max / funcs;
1969995c90f2SAnirudh Venkataramanan }
1970995c90f2SAnirudh Venkataramanan 
1971995c90f2SAnirudh Venkataramanan /**
1972595b13e2SJacob Keller  * ice_parse_common_caps - parse common device/function capabilities
1973f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
1974595b13e2SJacob Keller  * @caps: pointer to common capabilities structure
1975595b13e2SJacob Keller  * @elem: the capability element to parse
1976595b13e2SJacob Keller  * @prefix: message prefix for tracing capabilities
19779c20346bSAnirudh Venkataramanan  *
1978595b13e2SJacob Keller  * Given a capability element, extract relevant details into the common
1979595b13e2SJacob Keller  * capability structure.
1980595b13e2SJacob Keller  *
1981595b13e2SJacob Keller  * Returns: true if the capability matches one of the common capability ids,
1982595b13e2SJacob Keller  * false otherwise.
19839c20346bSAnirudh Venkataramanan  */
1984595b13e2SJacob Keller static bool
1985595b13e2SJacob Keller ice_parse_common_caps(struct ice_hw *hw, struct ice_hw_common_caps *caps,
1986595b13e2SJacob Keller 		      struct ice_aqc_list_caps_elem *elem, const char *prefix)
19879c20346bSAnirudh Venkataramanan {
1988595b13e2SJacob Keller 	u32 logical_id = le32_to_cpu(elem->logical_id);
1989595b13e2SJacob Keller 	u32 phys_id = le32_to_cpu(elem->phys_id);
1990595b13e2SJacob Keller 	u32 number = le32_to_cpu(elem->number);
1991595b13e2SJacob Keller 	u16 cap = le16_to_cpu(elem->cap);
1992595b13e2SJacob Keller 	bool found = true;
19939c20346bSAnirudh Venkataramanan 
19949c20346bSAnirudh Venkataramanan 	switch (cap) {
1995995c90f2SAnirudh Venkataramanan 	case ICE_AQC_CAPS_VALID_FUNCTIONS:
1996995c90f2SAnirudh Venkataramanan 		caps->valid_functions = number;
19979228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "%s: valid_functions (bitmap) = %d\n", prefix,
1998995c90f2SAnirudh Venkataramanan 			  caps->valid_functions);
1999995c90f2SAnirudh Venkataramanan 		break;
200075d2b253SAnirudh Venkataramanan 	case ICE_AQC_CAPS_SRIOV:
200175d2b253SAnirudh Venkataramanan 		caps->sr_iov_1_1 = (number == 1);
20029228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "%s: sr_iov_1_1 = %d\n", prefix,
2003a84db525SAnirudh Venkataramanan 			  caps->sr_iov_1_1);
200475d2b253SAnirudh Venkataramanan 		break;
2005a257f188SUsha Ketineni 	case ICE_AQC_CAPS_DCB:
2006a257f188SUsha Ketineni 		caps->dcb = (number == 1);
2007a257f188SUsha Ketineni 		caps->active_tc_bitmap = logical_id;
2008a257f188SUsha Ketineni 		caps->maxtc = phys_id;
20099228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "%s: dcb = %d\n", prefix, caps->dcb);
20109228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "%s: active_tc_bitmap = %d\n", prefix,
2011a257f188SUsha Ketineni 			  caps->active_tc_bitmap);
20129228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "%s: maxtc = %d\n", prefix, caps->maxtc);
2013a257f188SUsha Ketineni 		break;
20149c20346bSAnirudh Venkataramanan 	case ICE_AQC_CAPS_RSS:
20159c20346bSAnirudh Venkataramanan 		caps->rss_table_size = number;
20169c20346bSAnirudh Venkataramanan 		caps->rss_table_entry_width = logical_id;
20179228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "%s: rss_table_size = %d\n", prefix,
20189c20346bSAnirudh Venkataramanan 			  caps->rss_table_size);
20199228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "%s: rss_table_entry_width = %d\n", prefix,
20209c20346bSAnirudh Venkataramanan 			  caps->rss_table_entry_width);
20219c20346bSAnirudh Venkataramanan 		break;
20229c20346bSAnirudh Venkataramanan 	case ICE_AQC_CAPS_RXQS:
20239c20346bSAnirudh Venkataramanan 		caps->num_rxq = number;
20249c20346bSAnirudh Venkataramanan 		caps->rxq_first_id = phys_id;
20259228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "%s: num_rxq = %d\n", prefix,
2026a84db525SAnirudh Venkataramanan 			  caps->num_rxq);
20279228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "%s: rxq_first_id = %d\n", prefix,
20289c20346bSAnirudh Venkataramanan 			  caps->rxq_first_id);
20299c20346bSAnirudh Venkataramanan 		break;
20309c20346bSAnirudh Venkataramanan 	case ICE_AQC_CAPS_TXQS:
20319c20346bSAnirudh Venkataramanan 		caps->num_txq = number;
20329c20346bSAnirudh Venkataramanan 		caps->txq_first_id = phys_id;
20339228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "%s: num_txq = %d\n", prefix,
2034a84db525SAnirudh Venkataramanan 			  caps->num_txq);
20359228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "%s: txq_first_id = %d\n", prefix,
20369c20346bSAnirudh Venkataramanan 			  caps->txq_first_id);
20379c20346bSAnirudh Venkataramanan 		break;
20389c20346bSAnirudh Venkataramanan 	case ICE_AQC_CAPS_MSIX:
20399c20346bSAnirudh Venkataramanan 		caps->num_msix_vectors = number;
20409c20346bSAnirudh Venkataramanan 		caps->msix_vector_first_id = phys_id;
20419228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "%s: num_msix_vectors = %d\n", prefix,
20429c20346bSAnirudh Venkataramanan 			  caps->num_msix_vectors);
20439228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "%s: msix_vector_first_id = %d\n", prefix,
20449c20346bSAnirudh Venkataramanan 			  caps->msix_vector_first_id);
20459c20346bSAnirudh Venkataramanan 		break;
20462ab560a7SJacob Keller 	case ICE_AQC_CAPS_PENDING_NVM_VER:
20472ab560a7SJacob Keller 		caps->nvm_update_pending_nvm = true;
20482ab560a7SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "%s: update_pending_nvm\n", prefix);
20492ab560a7SJacob Keller 		break;
20502ab560a7SJacob Keller 	case ICE_AQC_CAPS_PENDING_OROM_VER:
20512ab560a7SJacob Keller 		caps->nvm_update_pending_orom = true;
20522ab560a7SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "%s: update_pending_orom\n", prefix);
20532ab560a7SJacob Keller 		break;
20542ab560a7SJacob Keller 	case ICE_AQC_CAPS_PENDING_NET_VER:
20552ab560a7SJacob Keller 		caps->nvm_update_pending_netlist = true;
20562ab560a7SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "%s: update_pending_netlist\n", prefix);
20572ab560a7SJacob Keller 		break;
2058de9b277eSJacek Naczyk 	case ICE_AQC_CAPS_NVM_MGMT:
2059de9b277eSJacek Naczyk 		caps->nvm_unified_update =
2060de9b277eSJacek Naczyk 			(number & ICE_NVM_MGMT_UNIFIED_UPD_SUPPORT) ?
2061de9b277eSJacek Naczyk 			true : false;
2062de9b277eSJacek Naczyk 		ice_debug(hw, ICE_DBG_INIT, "%s: nvm_unified_update = %d\n", prefix,
2063de9b277eSJacek Naczyk 			  caps->nvm_unified_update);
2064de9b277eSJacek Naczyk 		break;
2065d25a0fc4SDave Ertman 	case ICE_AQC_CAPS_RDMA:
2066d25a0fc4SDave Ertman 		caps->rdma = (number == 1);
2067d25a0fc4SDave Ertman 		ice_debug(hw, ICE_DBG_INIT, "%s: rdma = %d\n", prefix, caps->rdma);
2068d25a0fc4SDave Ertman 		break;
2069595b13e2SJacob Keller 	case ICE_AQC_CAPS_MAX_MTU:
2070595b13e2SJacob Keller 		caps->max_mtu = number;
2071595b13e2SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "%s: max_mtu = %d\n",
2072595b13e2SJacob Keller 			  prefix, caps->max_mtu);
2073595b13e2SJacob Keller 		break;
2074595b13e2SJacob Keller 	default:
2075595b13e2SJacob Keller 		/* Not one of the recognized common capabilities */
2076595b13e2SJacob Keller 		found = false;
2077148beb61SHenry Tieman 	}
2078595b13e2SJacob Keller 
2079595b13e2SJacob Keller 	return found;
2080595b13e2SJacob Keller }
2081595b13e2SJacob Keller 
2082595b13e2SJacob Keller /**
2083595b13e2SJacob Keller  * ice_recalc_port_limited_caps - Recalculate port limited capabilities
2084595b13e2SJacob Keller  * @hw: pointer to the HW structure
2085595b13e2SJacob Keller  * @caps: pointer to capabilities structure to fix
2086595b13e2SJacob Keller  *
2087595b13e2SJacob Keller  * Re-calculate the capabilities that are dependent on the number of physical
2088595b13e2SJacob Keller  * ports; i.e. some features are not supported or function differently on
2089595b13e2SJacob Keller  * devices with more than 4 ports.
2090595b13e2SJacob Keller  */
2091595b13e2SJacob Keller static void
2092595b13e2SJacob Keller ice_recalc_port_limited_caps(struct ice_hw *hw, struct ice_hw_common_caps *caps)
2093595b13e2SJacob Keller {
2094595b13e2SJacob Keller 	/* This assumes device capabilities are always scanned before function
2095595b13e2SJacob Keller 	 * capabilities during the initialization flow.
2096595b13e2SJacob Keller 	 */
2097595b13e2SJacob Keller 	if (hw->dev_caps.num_funcs > 4) {
2098595b13e2SJacob Keller 		/* Max 4 TCs per port */
2099595b13e2SJacob Keller 		caps->maxtc = 4;
21009228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "reducing maxtc to %d (based on #ports)\n",
2101595b13e2SJacob Keller 			  caps->maxtc);
2102d25a0fc4SDave Ertman 		if (caps->rdma) {
2103d25a0fc4SDave Ertman 			ice_debug(hw, ICE_DBG_INIT, "forcing RDMA off\n");
2104d25a0fc4SDave Ertman 			caps->rdma = 0;
2105d25a0fc4SDave Ertman 		}
2106d25a0fc4SDave Ertman 
2107d25a0fc4SDave Ertman 		/* print message only when processing device capabilities
2108d25a0fc4SDave Ertman 		 * during initialization.
2109d25a0fc4SDave Ertman 		 */
2110d25a0fc4SDave Ertman 		if (caps == &hw->dev_caps.common_cap)
2111d25a0fc4SDave Ertman 			dev_info(ice_hw_to_dev(hw), "RDMA functionality is not available with the current device configuration.\n");
2112595b13e2SJacob Keller 	}
2113595b13e2SJacob Keller }
2114595b13e2SJacob Keller 
2115595b13e2SJacob Keller /**
2116595b13e2SJacob Keller  * ice_parse_vf_func_caps - Parse ICE_AQC_CAPS_VF function caps
2117595b13e2SJacob Keller  * @hw: pointer to the HW struct
2118595b13e2SJacob Keller  * @func_p: pointer to function capabilities structure
2119595b13e2SJacob Keller  * @cap: pointer to the capability element to parse
2120595b13e2SJacob Keller  *
2121595b13e2SJacob Keller  * Extract function capabilities for ICE_AQC_CAPS_VF.
2122595b13e2SJacob Keller  */
2123595b13e2SJacob Keller static void
2124595b13e2SJacob Keller ice_parse_vf_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p,
2125595b13e2SJacob Keller 		       struct ice_aqc_list_caps_elem *cap)
2126595b13e2SJacob Keller {
2127595b13e2SJacob Keller 	u32 logical_id = le32_to_cpu(cap->logical_id);
2128595b13e2SJacob Keller 	u32 number = le32_to_cpu(cap->number);
2129595b13e2SJacob Keller 
2130595b13e2SJacob Keller 	func_p->num_allocd_vfs = number;
2131595b13e2SJacob Keller 	func_p->vf_base_id = logical_id;
2132595b13e2SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "func caps: num_allocd_vfs = %d\n",
2133595b13e2SJacob Keller 		  func_p->num_allocd_vfs);
2134595b13e2SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "func caps: vf_base_id = %d\n",
2135595b13e2SJacob Keller 		  func_p->vf_base_id);
2136595b13e2SJacob Keller }
2137595b13e2SJacob Keller 
2138595b13e2SJacob Keller /**
2139595b13e2SJacob Keller  * ice_parse_vsi_func_caps - Parse ICE_AQC_CAPS_VSI function caps
2140595b13e2SJacob Keller  * @hw: pointer to the HW struct
2141595b13e2SJacob Keller  * @func_p: pointer to function capabilities structure
2142595b13e2SJacob Keller  * @cap: pointer to the capability element to parse
2143595b13e2SJacob Keller  *
2144595b13e2SJacob Keller  * Extract function capabilities for ICE_AQC_CAPS_VSI.
2145595b13e2SJacob Keller  */
2146595b13e2SJacob Keller static void
2147595b13e2SJacob Keller ice_parse_vsi_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p,
2148595b13e2SJacob Keller 			struct ice_aqc_list_caps_elem *cap)
2149595b13e2SJacob Keller {
2150595b13e2SJacob Keller 	func_p->guar_num_vsi = ice_get_num_per_func(hw, ICE_MAX_VSI);
2151595b13e2SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "func caps: guar_num_vsi (fw) = %d\n",
2152595b13e2SJacob Keller 		  le32_to_cpu(cap->number));
2153595b13e2SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "func caps: guar_num_vsi = %d\n",
2154595b13e2SJacob Keller 		  func_p->guar_num_vsi);
2155595b13e2SJacob Keller }
2156595b13e2SJacob Keller 
2157595b13e2SJacob Keller /**
21589733cc94SJacob Keller  * ice_parse_1588_func_caps - Parse ICE_AQC_CAPS_1588 function caps
21599733cc94SJacob Keller  * @hw: pointer to the HW struct
21609733cc94SJacob Keller  * @func_p: pointer to function capabilities structure
21619733cc94SJacob Keller  * @cap: pointer to the capability element to parse
21629733cc94SJacob Keller  *
21639733cc94SJacob Keller  * Extract function capabilities for ICE_AQC_CAPS_1588.
21649733cc94SJacob Keller  */
21659733cc94SJacob Keller static void
21669733cc94SJacob Keller ice_parse_1588_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p,
21679733cc94SJacob Keller 			 struct ice_aqc_list_caps_elem *cap)
21689733cc94SJacob Keller {
21699733cc94SJacob Keller 	struct ice_ts_func_info *info = &func_p->ts_func_info;
21709733cc94SJacob Keller 	u32 number = le32_to_cpu(cap->number);
21719733cc94SJacob Keller 
21729733cc94SJacob Keller 	info->ena = ((number & ICE_TS_FUNC_ENA_M) != 0);
21739733cc94SJacob Keller 	func_p->common_cap.ieee_1588 = info->ena;
21749733cc94SJacob Keller 
21759733cc94SJacob Keller 	info->src_tmr_owned = ((number & ICE_TS_SRC_TMR_OWND_M) != 0);
21769733cc94SJacob Keller 	info->tmr_ena = ((number & ICE_TS_TMR_ENA_M) != 0);
21779733cc94SJacob Keller 	info->tmr_index_owned = ((number & ICE_TS_TMR_IDX_OWND_M) != 0);
21789733cc94SJacob Keller 	info->tmr_index_assoc = ((number & ICE_TS_TMR_IDX_ASSOC_M) != 0);
21799733cc94SJacob Keller 
21809733cc94SJacob Keller 	info->clk_freq = (number & ICE_TS_CLK_FREQ_M) >> ICE_TS_CLK_FREQ_S;
21819733cc94SJacob Keller 	info->clk_src = ((number & ICE_TS_CLK_SRC_M) != 0);
21829733cc94SJacob Keller 
21839733cc94SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "func caps: ieee_1588 = %u\n",
21849733cc94SJacob Keller 		  func_p->common_cap.ieee_1588);
21859733cc94SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "func caps: src_tmr_owned = %u\n",
21869733cc94SJacob Keller 		  info->src_tmr_owned);
21879733cc94SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "func caps: tmr_ena = %u\n",
21889733cc94SJacob Keller 		  info->tmr_ena);
21899733cc94SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "func caps: tmr_index_owned = %u\n",
21909733cc94SJacob Keller 		  info->tmr_index_owned);
21919733cc94SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "func caps: tmr_index_assoc = %u\n",
21929733cc94SJacob Keller 		  info->tmr_index_assoc);
21939733cc94SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "func caps: clk_freq = %u\n",
21949733cc94SJacob Keller 		  info->clk_freq);
21959733cc94SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "func caps: clk_src = %u\n",
21969733cc94SJacob Keller 		  info->clk_src);
21979733cc94SJacob Keller }
21989733cc94SJacob Keller 
21999733cc94SJacob Keller /**
2200595b13e2SJacob Keller  * ice_parse_fdir_func_caps - Parse ICE_AQC_CAPS_FD function caps
2201595b13e2SJacob Keller  * @hw: pointer to the HW struct
2202595b13e2SJacob Keller  * @func_p: pointer to function capabilities structure
2203595b13e2SJacob Keller  *
2204595b13e2SJacob Keller  * Extract function capabilities for ICE_AQC_CAPS_FD.
2205595b13e2SJacob Keller  */
2206595b13e2SJacob Keller static void
2207595b13e2SJacob Keller ice_parse_fdir_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p)
2208595b13e2SJacob Keller {
2209148beb61SHenry Tieman 	u32 reg_val, val;
2210148beb61SHenry Tieman 
2211148beb61SHenry Tieman 	reg_val = rd32(hw, GLQF_FD_SIZE);
2212148beb61SHenry Tieman 	val = (reg_val & GLQF_FD_SIZE_FD_GSIZE_M) >>
2213148beb61SHenry Tieman 		GLQF_FD_SIZE_FD_GSIZE_S;
2214148beb61SHenry Tieman 	func_p->fd_fltr_guar =
2215148beb61SHenry Tieman 		ice_get_num_per_func(hw, val);
2216148beb61SHenry Tieman 	val = (reg_val & GLQF_FD_SIZE_FD_BSIZE_M) >>
2217148beb61SHenry Tieman 		GLQF_FD_SIZE_FD_BSIZE_S;
2218148beb61SHenry Tieman 	func_p->fd_fltr_best_effort = val;
2219595b13e2SJacob Keller 
22209228d8b2SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "func caps: fd_fltr_guar = %d\n",
2221595b13e2SJacob Keller 		  func_p->fd_fltr_guar);
22229228d8b2SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "func caps: fd_fltr_best_effort = %d\n",
2223595b13e2SJacob Keller 		  func_p->fd_fltr_best_effort);
2224148beb61SHenry Tieman }
2225595b13e2SJacob Keller 
2226595b13e2SJacob Keller /**
2227595b13e2SJacob Keller  * ice_parse_func_caps - Parse function capabilities
2228595b13e2SJacob Keller  * @hw: pointer to the HW struct
2229595b13e2SJacob Keller  * @func_p: pointer to function capabilities structure
2230595b13e2SJacob Keller  * @buf: buffer containing the function capability records
2231595b13e2SJacob Keller  * @cap_count: the number of capabilities
2232595b13e2SJacob Keller  *
2233595b13e2SJacob Keller  * Helper function to parse function (0x000A) capabilities list. For
2234595b13e2SJacob Keller  * capabilities shared between device and function, this relies on
2235595b13e2SJacob Keller  * ice_parse_common_caps.
2236595b13e2SJacob Keller  *
2237595b13e2SJacob Keller  * Loop through the list of provided capabilities and extract the relevant
2238595b13e2SJacob Keller  * data into the function capabilities structured.
2239595b13e2SJacob Keller  */
2240595b13e2SJacob Keller static void
2241595b13e2SJacob Keller ice_parse_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p,
2242595b13e2SJacob Keller 		    void *buf, u32 cap_count)
2243595b13e2SJacob Keller {
2244595b13e2SJacob Keller 	struct ice_aqc_list_caps_elem *cap_resp;
2245595b13e2SJacob Keller 	u32 i;
2246595b13e2SJacob Keller 
22477a63dae0SBruce Allan 	cap_resp = buf;
2248595b13e2SJacob Keller 
2249595b13e2SJacob Keller 	memset(func_p, 0, sizeof(*func_p));
2250595b13e2SJacob Keller 
2251595b13e2SJacob Keller 	for (i = 0; i < cap_count; i++) {
2252595b13e2SJacob Keller 		u16 cap = le16_to_cpu(cap_resp[i].cap);
2253595b13e2SJacob Keller 		bool found;
2254595b13e2SJacob Keller 
2255595b13e2SJacob Keller 		found = ice_parse_common_caps(hw, &func_p->common_cap,
2256595b13e2SJacob Keller 					      &cap_resp[i], "func caps");
2257595b13e2SJacob Keller 
2258595b13e2SJacob Keller 		switch (cap) {
2259595b13e2SJacob Keller 		case ICE_AQC_CAPS_VF:
2260595b13e2SJacob Keller 			ice_parse_vf_func_caps(hw, func_p, &cap_resp[i]);
2261148beb61SHenry Tieman 			break;
2262595b13e2SJacob Keller 		case ICE_AQC_CAPS_VSI:
2263595b13e2SJacob Keller 			ice_parse_vsi_func_caps(hw, func_p, &cap_resp[i]);
2264595b13e2SJacob Keller 			break;
22659733cc94SJacob Keller 		case ICE_AQC_CAPS_1588:
22669733cc94SJacob Keller 			ice_parse_1588_func_caps(hw, func_p, &cap_resp[i]);
22679733cc94SJacob Keller 			break;
2268595b13e2SJacob Keller 		case ICE_AQC_CAPS_FD:
2269595b13e2SJacob Keller 			ice_parse_fdir_func_caps(hw, func_p);
22709c20346bSAnirudh Venkataramanan 			break;
22719c20346bSAnirudh Venkataramanan 		default:
2272595b13e2SJacob Keller 			/* Don't list common capabilities as unknown */
2273595b13e2SJacob Keller 			if (!found)
22749228d8b2SJacob Keller 				ice_debug(hw, ICE_DBG_INIT, "func caps: unknown capability[%d]: 0x%x\n",
2275a84db525SAnirudh Venkataramanan 					  i, cap);
22769c20346bSAnirudh Venkataramanan 			break;
22779c20346bSAnirudh Venkataramanan 		}
22789c20346bSAnirudh Venkataramanan 	}
22799164f761SBruce Allan 
2280595b13e2SJacob Keller 	ice_recalc_port_limited_caps(hw, &func_p->common_cap);
22819164f761SBruce Allan }
2282595b13e2SJacob Keller 
2283595b13e2SJacob Keller /**
2284595b13e2SJacob Keller  * ice_parse_valid_functions_cap - Parse ICE_AQC_CAPS_VALID_FUNCTIONS caps
2285595b13e2SJacob Keller  * @hw: pointer to the HW struct
2286595b13e2SJacob Keller  * @dev_p: pointer to device capabilities structure
2287595b13e2SJacob Keller  * @cap: capability element to parse
2288595b13e2SJacob Keller  *
2289595b13e2SJacob Keller  * Parse ICE_AQC_CAPS_VALID_FUNCTIONS for device capabilities.
2290595b13e2SJacob Keller  */
2291595b13e2SJacob Keller static void
2292595b13e2SJacob Keller ice_parse_valid_functions_cap(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
2293595b13e2SJacob Keller 			      struct ice_aqc_list_caps_elem *cap)
2294595b13e2SJacob Keller {
2295595b13e2SJacob Keller 	u32 number = le32_to_cpu(cap->number);
2296595b13e2SJacob Keller 
2297595b13e2SJacob Keller 	dev_p->num_funcs = hweight32(number);
2298595b13e2SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "dev caps: num_funcs = %d\n",
2299595b13e2SJacob Keller 		  dev_p->num_funcs);
2300595b13e2SJacob Keller }
2301595b13e2SJacob Keller 
2302595b13e2SJacob Keller /**
2303595b13e2SJacob Keller  * ice_parse_vf_dev_caps - Parse ICE_AQC_CAPS_VF device caps
2304595b13e2SJacob Keller  * @hw: pointer to the HW struct
2305595b13e2SJacob Keller  * @dev_p: pointer to device capabilities structure
2306595b13e2SJacob Keller  * @cap: capability element to parse
2307595b13e2SJacob Keller  *
2308595b13e2SJacob Keller  * Parse ICE_AQC_CAPS_VF for device capabilities.
2309595b13e2SJacob Keller  */
2310595b13e2SJacob Keller static void
2311595b13e2SJacob Keller ice_parse_vf_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
2312595b13e2SJacob Keller 		      struct ice_aqc_list_caps_elem *cap)
2313595b13e2SJacob Keller {
2314595b13e2SJacob Keller 	u32 number = le32_to_cpu(cap->number);
2315595b13e2SJacob Keller 
2316595b13e2SJacob Keller 	dev_p->num_vfs_exposed = number;
2317595b13e2SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "dev_caps: num_vfs_exposed = %d\n",
2318595b13e2SJacob Keller 		  dev_p->num_vfs_exposed);
2319595b13e2SJacob Keller }
2320595b13e2SJacob Keller 
2321595b13e2SJacob Keller /**
2322595b13e2SJacob Keller  * ice_parse_vsi_dev_caps - Parse ICE_AQC_CAPS_VSI device caps
2323595b13e2SJacob Keller  * @hw: pointer to the HW struct
2324595b13e2SJacob Keller  * @dev_p: pointer to device capabilities structure
2325595b13e2SJacob Keller  * @cap: capability element to parse
2326595b13e2SJacob Keller  *
2327595b13e2SJacob Keller  * Parse ICE_AQC_CAPS_VSI for device capabilities.
2328595b13e2SJacob Keller  */
2329595b13e2SJacob Keller static void
2330595b13e2SJacob Keller ice_parse_vsi_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
2331595b13e2SJacob Keller 		       struct ice_aqc_list_caps_elem *cap)
2332595b13e2SJacob Keller {
2333595b13e2SJacob Keller 	u32 number = le32_to_cpu(cap->number);
2334595b13e2SJacob Keller 
2335595b13e2SJacob Keller 	dev_p->num_vsi_allocd_to_host = number;
2336595b13e2SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "dev caps: num_vsi_allocd_to_host = %d\n",
2337595b13e2SJacob Keller 		  dev_p->num_vsi_allocd_to_host);
2338595b13e2SJacob Keller }
2339595b13e2SJacob Keller 
2340595b13e2SJacob Keller /**
23419733cc94SJacob Keller  * ice_parse_1588_dev_caps - Parse ICE_AQC_CAPS_1588 device caps
23429733cc94SJacob Keller  * @hw: pointer to the HW struct
23439733cc94SJacob Keller  * @dev_p: pointer to device capabilities structure
23449733cc94SJacob Keller  * @cap: capability element to parse
23459733cc94SJacob Keller  *
23469733cc94SJacob Keller  * Parse ICE_AQC_CAPS_1588 for device capabilities.
23479733cc94SJacob Keller  */
23489733cc94SJacob Keller static void
23499733cc94SJacob Keller ice_parse_1588_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
23509733cc94SJacob Keller 			struct ice_aqc_list_caps_elem *cap)
23519733cc94SJacob Keller {
23529733cc94SJacob Keller 	struct ice_ts_dev_info *info = &dev_p->ts_dev_info;
23539733cc94SJacob Keller 	u32 logical_id = le32_to_cpu(cap->logical_id);
23549733cc94SJacob Keller 	u32 phys_id = le32_to_cpu(cap->phys_id);
23559733cc94SJacob Keller 	u32 number = le32_to_cpu(cap->number);
23569733cc94SJacob Keller 
23579733cc94SJacob Keller 	info->ena = ((number & ICE_TS_DEV_ENA_M) != 0);
23589733cc94SJacob Keller 	dev_p->common_cap.ieee_1588 = info->ena;
23599733cc94SJacob Keller 
23609733cc94SJacob Keller 	info->tmr0_owner = number & ICE_TS_TMR0_OWNR_M;
23619733cc94SJacob Keller 	info->tmr0_owned = ((number & ICE_TS_TMR0_OWND_M) != 0);
23629733cc94SJacob Keller 	info->tmr0_ena = ((number & ICE_TS_TMR0_ENA_M) != 0);
23639733cc94SJacob Keller 
23649733cc94SJacob Keller 	info->tmr1_owner = (number & ICE_TS_TMR1_OWNR_M) >> ICE_TS_TMR1_OWNR_S;
23659733cc94SJacob Keller 	info->tmr1_owned = ((number & ICE_TS_TMR1_OWND_M) != 0);
23669733cc94SJacob Keller 	info->tmr1_ena = ((number & ICE_TS_TMR1_ENA_M) != 0);
23679733cc94SJacob Keller 
23689733cc94SJacob Keller 	info->ena_ports = logical_id;
23699733cc94SJacob Keller 	info->tmr_own_map = phys_id;
23709733cc94SJacob Keller 
23719733cc94SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "dev caps: ieee_1588 = %u\n",
23729733cc94SJacob Keller 		  dev_p->common_cap.ieee_1588);
23739733cc94SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr0_owner = %u\n",
23749733cc94SJacob Keller 		  info->tmr0_owner);
23759733cc94SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr0_owned = %u\n",
23769733cc94SJacob Keller 		  info->tmr0_owned);
23779733cc94SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr0_ena = %u\n",
23789733cc94SJacob Keller 		  info->tmr0_ena);
23799733cc94SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr1_owner = %u\n",
23809733cc94SJacob Keller 		  info->tmr1_owner);
23819733cc94SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr1_owned = %u\n",
23829733cc94SJacob Keller 		  info->tmr1_owned);
23839733cc94SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr1_ena = %u\n",
23849733cc94SJacob Keller 		  info->tmr1_ena);
23859733cc94SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "dev caps: ieee_1588 ena_ports = %u\n",
23869733cc94SJacob Keller 		  info->ena_ports);
23879733cc94SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr_own_map = %u\n",
23889733cc94SJacob Keller 		  info->tmr_own_map);
23899733cc94SJacob Keller }
23909733cc94SJacob Keller 
23919733cc94SJacob Keller /**
2392595b13e2SJacob Keller  * ice_parse_fdir_dev_caps - Parse ICE_AQC_CAPS_FD device caps
2393595b13e2SJacob Keller  * @hw: pointer to the HW struct
2394595b13e2SJacob Keller  * @dev_p: pointer to device capabilities structure
2395595b13e2SJacob Keller  * @cap: capability element to parse
2396595b13e2SJacob Keller  *
2397595b13e2SJacob Keller  * Parse ICE_AQC_CAPS_FD for device capabilities.
2398595b13e2SJacob Keller  */
2399595b13e2SJacob Keller static void
2400595b13e2SJacob Keller ice_parse_fdir_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
2401595b13e2SJacob Keller 			struct ice_aqc_list_caps_elem *cap)
2402595b13e2SJacob Keller {
2403595b13e2SJacob Keller 	u32 number = le32_to_cpu(cap->number);
2404595b13e2SJacob Keller 
2405595b13e2SJacob Keller 	dev_p->num_flow_director_fltr = number;
2406595b13e2SJacob Keller 	ice_debug(hw, ICE_DBG_INIT, "dev caps: num_flow_director_fltr = %d\n",
2407595b13e2SJacob Keller 		  dev_p->num_flow_director_fltr);
2408595b13e2SJacob Keller }
2409595b13e2SJacob Keller 
2410595b13e2SJacob Keller /**
2411595b13e2SJacob Keller  * ice_parse_dev_caps - Parse device capabilities
2412595b13e2SJacob Keller  * @hw: pointer to the HW struct
2413595b13e2SJacob Keller  * @dev_p: pointer to device capabilities structure
2414595b13e2SJacob Keller  * @buf: buffer containing the device capability records
2415595b13e2SJacob Keller  * @cap_count: the number of capabilities
2416595b13e2SJacob Keller  *
2417595b13e2SJacob Keller  * Helper device to parse device (0x000B) capabilities list. For
24187dbc63f0STony Nguyen  * capabilities shared between device and function, this relies on
2419595b13e2SJacob Keller  * ice_parse_common_caps.
2420595b13e2SJacob Keller  *
2421595b13e2SJacob Keller  * Loop through the list of provided capabilities and extract the relevant
2422595b13e2SJacob Keller  * data into the device capabilities structured.
2423595b13e2SJacob Keller  */
2424595b13e2SJacob Keller static void
2425595b13e2SJacob Keller ice_parse_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
2426595b13e2SJacob Keller 		   void *buf, u32 cap_count)
2427595b13e2SJacob Keller {
2428595b13e2SJacob Keller 	struct ice_aqc_list_caps_elem *cap_resp;
2429595b13e2SJacob Keller 	u32 i;
2430595b13e2SJacob Keller 
24317a63dae0SBruce Allan 	cap_resp = buf;
2432595b13e2SJacob Keller 
2433595b13e2SJacob Keller 	memset(dev_p, 0, sizeof(*dev_p));
2434595b13e2SJacob Keller 
2435595b13e2SJacob Keller 	for (i = 0; i < cap_count; i++) {
2436595b13e2SJacob Keller 		u16 cap = le16_to_cpu(cap_resp[i].cap);
2437595b13e2SJacob Keller 		bool found;
2438595b13e2SJacob Keller 
2439595b13e2SJacob Keller 		found = ice_parse_common_caps(hw, &dev_p->common_cap,
2440595b13e2SJacob Keller 					      &cap_resp[i], "dev caps");
2441595b13e2SJacob Keller 
2442595b13e2SJacob Keller 		switch (cap) {
2443595b13e2SJacob Keller 		case ICE_AQC_CAPS_VALID_FUNCTIONS:
2444595b13e2SJacob Keller 			ice_parse_valid_functions_cap(hw, dev_p, &cap_resp[i]);
2445595b13e2SJacob Keller 			break;
2446595b13e2SJacob Keller 		case ICE_AQC_CAPS_VF:
2447595b13e2SJacob Keller 			ice_parse_vf_dev_caps(hw, dev_p, &cap_resp[i]);
2448595b13e2SJacob Keller 			break;
2449595b13e2SJacob Keller 		case ICE_AQC_CAPS_VSI:
2450595b13e2SJacob Keller 			ice_parse_vsi_dev_caps(hw, dev_p, &cap_resp[i]);
2451595b13e2SJacob Keller 			break;
24529733cc94SJacob Keller 		case ICE_AQC_CAPS_1588:
24539733cc94SJacob Keller 			ice_parse_1588_dev_caps(hw, dev_p, &cap_resp[i]);
24549733cc94SJacob Keller 			break;
2455595b13e2SJacob Keller 		case  ICE_AQC_CAPS_FD:
2456595b13e2SJacob Keller 			ice_parse_fdir_dev_caps(hw, dev_p, &cap_resp[i]);
2457595b13e2SJacob Keller 			break;
2458595b13e2SJacob Keller 		default:
2459595b13e2SJacob Keller 			/* Don't list common capabilities as unknown */
2460595b13e2SJacob Keller 			if (!found)
24619228d8b2SJacob Keller 				ice_debug(hw, ICE_DBG_INIT, "dev caps: unknown capability[%d]: 0x%x\n",
2462595b13e2SJacob Keller 					  i, cap);
2463595b13e2SJacob Keller 			break;
2464595b13e2SJacob Keller 		}
2465595b13e2SJacob Keller 	}
2466595b13e2SJacob Keller 
2467595b13e2SJacob Keller 	ice_recalc_port_limited_caps(hw, &dev_p->common_cap);
2468595b13e2SJacob Keller }
2469595b13e2SJacob Keller 
2470595b13e2SJacob Keller /**
24718d7aab35SJacob Keller  * ice_aq_list_caps - query function/device capabilities
2472f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
24738d7aab35SJacob Keller  * @buf: a buffer to hold the capabilities
24748d7aab35SJacob Keller  * @buf_size: size of the buffer
24758d7aab35SJacob Keller  * @cap_count: if not NULL, set to the number of capabilities reported
24768d7aab35SJacob Keller  * @opc: capabilities type to discover, device or function
24779c20346bSAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
24789c20346bSAnirudh Venkataramanan  *
24798d7aab35SJacob Keller  * Get the function (0x000A) or device (0x000B) capabilities description from
24808d7aab35SJacob Keller  * firmware and store it in the buffer.
24818d7aab35SJacob Keller  *
24828d7aab35SJacob Keller  * If the cap_count pointer is not NULL, then it is set to the number of
24838d7aab35SJacob Keller  * capabilities firmware will report. Note that if the buffer size is too
24848d7aab35SJacob Keller  * small, it is possible the command will return ICE_AQ_ERR_ENOMEM. The
24858d7aab35SJacob Keller  * cap_count will still be updated in this case. It is recommended that the
24868d7aab35SJacob Keller  * buffer size be set to ICE_AQ_MAX_BUF_LEN (the largest possible buffer that
24878d7aab35SJacob Keller  * firmware could return) to avoid this.
24889c20346bSAnirudh Venkataramanan  */
2489*5e24d598STony Nguyen int
24908d7aab35SJacob Keller ice_aq_list_caps(struct ice_hw *hw, void *buf, u16 buf_size, u32 *cap_count,
24919c20346bSAnirudh Venkataramanan 		 enum ice_adminq_opc opc, struct ice_sq_cd *cd)
24929c20346bSAnirudh Venkataramanan {
24939c20346bSAnirudh Venkataramanan 	struct ice_aqc_list_caps *cmd;
24949c20346bSAnirudh Venkataramanan 	struct ice_aq_desc desc;
2495*5e24d598STony Nguyen 	int status;
24969c20346bSAnirudh Venkataramanan 
24979c20346bSAnirudh Venkataramanan 	cmd = &desc.params.get_cap;
24989c20346bSAnirudh Venkataramanan 
24999c20346bSAnirudh Venkataramanan 	if (opc != ice_aqc_opc_list_func_caps &&
25009c20346bSAnirudh Venkataramanan 	    opc != ice_aqc_opc_list_dev_caps)
25019c20346bSAnirudh Venkataramanan 		return ICE_ERR_PARAM;
25029c20346bSAnirudh Venkataramanan 
25039c20346bSAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, opc);
25049c20346bSAnirudh Venkataramanan 	status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
25058d7aab35SJacob Keller 
25068d7aab35SJacob Keller 	if (cap_count)
250799189e8bSAnirudh Venkataramanan 		*cap_count = le32_to_cpu(cmd->count);
25088d7aab35SJacob Keller 
25098d7aab35SJacob Keller 	return status;
25108d7aab35SJacob Keller }
25118d7aab35SJacob Keller 
25128d7aab35SJacob Keller /**
251381aed647SJacob Keller  * ice_discover_dev_caps - Read and extract device capabilities
25147d86cf38SAnirudh Venkataramanan  * @hw: pointer to the hardware structure
251581aed647SJacob Keller  * @dev_caps: pointer to device capabilities structure
251681aed647SJacob Keller  *
251781aed647SJacob Keller  * Read the device capabilities and extract them into the dev_caps structure
251881aed647SJacob Keller  * for later use.
25197d86cf38SAnirudh Venkataramanan  */
2520*5e24d598STony Nguyen int
252181aed647SJacob Keller ice_discover_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_caps)
25227d86cf38SAnirudh Venkataramanan {
2523*5e24d598STony Nguyen 	int status;
252481aed647SJacob Keller 	u32 cap_count = 0;
25257d86cf38SAnirudh Venkataramanan 	void *cbuf;
25267d86cf38SAnirudh Venkataramanan 
25271082b360SJacob Keller 	cbuf = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL);
25287d86cf38SAnirudh Venkataramanan 	if (!cbuf)
25297d86cf38SAnirudh Venkataramanan 		return ICE_ERR_NO_MEMORY;
25307d86cf38SAnirudh Venkataramanan 
25311082b360SJacob Keller 	/* Although the driver doesn't know the number of capabilities the
25321082b360SJacob Keller 	 * device will return, we can simply send a 4KB buffer, the maximum
25331082b360SJacob Keller 	 * possible size that firmware can return.
25341082b360SJacob Keller 	 */
25351082b360SJacob Keller 	cap_count = ICE_AQ_MAX_BUF_LEN / sizeof(struct ice_aqc_list_caps_elem);
25361082b360SJacob Keller 
253781aed647SJacob Keller 	status = ice_aq_list_caps(hw, cbuf, ICE_AQ_MAX_BUF_LEN, &cap_count,
253881aed647SJacob Keller 				  ice_aqc_opc_list_dev_caps, NULL);
253981aed647SJacob Keller 	if (!status)
254081aed647SJacob Keller 		ice_parse_dev_caps(hw, dev_caps, cbuf, cap_count);
254181aed647SJacob Keller 	kfree(cbuf);
254281aed647SJacob Keller 
254381aed647SJacob Keller 	return status;
254481aed647SJacob Keller }
254581aed647SJacob Keller 
254681aed647SJacob Keller /**
254781aed647SJacob Keller  * ice_discover_func_caps - Read and extract function capabilities
254881aed647SJacob Keller  * @hw: pointer to the hardware structure
254981aed647SJacob Keller  * @func_caps: pointer to function capabilities structure
255081aed647SJacob Keller  *
255181aed647SJacob Keller  * Read the function capabilities and extract them into the func_caps structure
255281aed647SJacob Keller  * for later use.
255381aed647SJacob Keller  */
2554*5e24d598STony Nguyen static int
255581aed647SJacob Keller ice_discover_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_caps)
255681aed647SJacob Keller {
2557*5e24d598STony Nguyen 	int status;
255881aed647SJacob Keller 	u32 cap_count = 0;
255981aed647SJacob Keller 	void *cbuf;
256081aed647SJacob Keller 
256181aed647SJacob Keller 	cbuf = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL);
256281aed647SJacob Keller 	if (!cbuf)
256381aed647SJacob Keller 		return ICE_ERR_NO_MEMORY;
256481aed647SJacob Keller 
256581aed647SJacob Keller 	/* Although the driver doesn't know the number of capabilities the
256681aed647SJacob Keller 	 * device will return, we can simply send a 4KB buffer, the maximum
256781aed647SJacob Keller 	 * possible size that firmware can return.
256881aed647SJacob Keller 	 */
256981aed647SJacob Keller 	cap_count = ICE_AQ_MAX_BUF_LEN / sizeof(struct ice_aqc_list_caps_elem);
257081aed647SJacob Keller 
257181aed647SJacob Keller 	status = ice_aq_list_caps(hw, cbuf, ICE_AQ_MAX_BUF_LEN, &cap_count,
257281aed647SJacob Keller 				  ice_aqc_opc_list_func_caps, NULL);
257381aed647SJacob Keller 	if (!status)
257481aed647SJacob Keller 		ice_parse_func_caps(hw, func_caps, cbuf, cap_count);
25751082b360SJacob Keller 	kfree(cbuf);
25769c20346bSAnirudh Venkataramanan 
25779c20346bSAnirudh Venkataramanan 	return status;
25789c20346bSAnirudh Venkataramanan }
25799c20346bSAnirudh Venkataramanan 
25809c20346bSAnirudh Venkataramanan /**
2581462acf6aSTony Nguyen  * ice_set_safe_mode_caps - Override dev/func capabilities when in safe mode
2582462acf6aSTony Nguyen  * @hw: pointer to the hardware structure
2583462acf6aSTony Nguyen  */
2584462acf6aSTony Nguyen void ice_set_safe_mode_caps(struct ice_hw *hw)
2585462acf6aSTony Nguyen {
2586462acf6aSTony Nguyen 	struct ice_hw_func_caps *func_caps = &hw->func_caps;
2587462acf6aSTony Nguyen 	struct ice_hw_dev_caps *dev_caps = &hw->dev_caps;
2588be49b1adSJacob Keller 	struct ice_hw_common_caps cached_caps;
2589eae1bbb2SBruce Allan 	u32 num_funcs;
2590462acf6aSTony Nguyen 
2591462acf6aSTony Nguyen 	/* cache some func_caps values that should be restored after memset */
2592be49b1adSJacob Keller 	cached_caps = func_caps->common_cap;
2593462acf6aSTony Nguyen 
2594462acf6aSTony Nguyen 	/* unset func capabilities */
2595462acf6aSTony Nguyen 	memset(func_caps, 0, sizeof(*func_caps));
2596462acf6aSTony Nguyen 
2597be49b1adSJacob Keller #define ICE_RESTORE_FUNC_CAP(name) \
2598be49b1adSJacob Keller 	func_caps->common_cap.name = cached_caps.name
2599be49b1adSJacob Keller 
2600462acf6aSTony Nguyen 	/* restore cached values */
2601be49b1adSJacob Keller 	ICE_RESTORE_FUNC_CAP(valid_functions);
2602be49b1adSJacob Keller 	ICE_RESTORE_FUNC_CAP(txq_first_id);
2603be49b1adSJacob Keller 	ICE_RESTORE_FUNC_CAP(rxq_first_id);
2604be49b1adSJacob Keller 	ICE_RESTORE_FUNC_CAP(msix_vector_first_id);
2605be49b1adSJacob Keller 	ICE_RESTORE_FUNC_CAP(max_mtu);
2606be49b1adSJacob Keller 	ICE_RESTORE_FUNC_CAP(nvm_unified_update);
2607be49b1adSJacob Keller 	ICE_RESTORE_FUNC_CAP(nvm_update_pending_nvm);
2608be49b1adSJacob Keller 	ICE_RESTORE_FUNC_CAP(nvm_update_pending_orom);
2609be49b1adSJacob Keller 	ICE_RESTORE_FUNC_CAP(nvm_update_pending_netlist);
2610462acf6aSTony Nguyen 
2611462acf6aSTony Nguyen 	/* one Tx and one Rx queue in safe mode */
2612462acf6aSTony Nguyen 	func_caps->common_cap.num_rxq = 1;
2613462acf6aSTony Nguyen 	func_caps->common_cap.num_txq = 1;
2614462acf6aSTony Nguyen 
2615462acf6aSTony Nguyen 	/* two MSIX vectors, one for traffic and one for misc causes */
2616462acf6aSTony Nguyen 	func_caps->common_cap.num_msix_vectors = 2;
2617462acf6aSTony Nguyen 	func_caps->guar_num_vsi = 1;
2618462acf6aSTony Nguyen 
2619462acf6aSTony Nguyen 	/* cache some dev_caps values that should be restored after memset */
2620be49b1adSJacob Keller 	cached_caps = dev_caps->common_cap;
2621eae1bbb2SBruce Allan 	num_funcs = dev_caps->num_funcs;
2622462acf6aSTony Nguyen 
2623462acf6aSTony Nguyen 	/* unset dev capabilities */
2624462acf6aSTony Nguyen 	memset(dev_caps, 0, sizeof(*dev_caps));
2625462acf6aSTony Nguyen 
2626be49b1adSJacob Keller #define ICE_RESTORE_DEV_CAP(name) \
2627be49b1adSJacob Keller 	dev_caps->common_cap.name = cached_caps.name
2628be49b1adSJacob Keller 
2629462acf6aSTony Nguyen 	/* restore cached values */
2630be49b1adSJacob Keller 	ICE_RESTORE_DEV_CAP(valid_functions);
2631be49b1adSJacob Keller 	ICE_RESTORE_DEV_CAP(txq_first_id);
2632be49b1adSJacob Keller 	ICE_RESTORE_DEV_CAP(rxq_first_id);
2633be49b1adSJacob Keller 	ICE_RESTORE_DEV_CAP(msix_vector_first_id);
2634be49b1adSJacob Keller 	ICE_RESTORE_DEV_CAP(max_mtu);
2635be49b1adSJacob Keller 	ICE_RESTORE_DEV_CAP(nvm_unified_update);
2636be49b1adSJacob Keller 	ICE_RESTORE_DEV_CAP(nvm_update_pending_nvm);
2637be49b1adSJacob Keller 	ICE_RESTORE_DEV_CAP(nvm_update_pending_orom);
2638be49b1adSJacob Keller 	ICE_RESTORE_DEV_CAP(nvm_update_pending_netlist);
2639eae1bbb2SBruce Allan 	dev_caps->num_funcs = num_funcs;
2640462acf6aSTony Nguyen 
2641462acf6aSTony Nguyen 	/* one Tx and one Rx queue per function in safe mode */
2642eae1bbb2SBruce Allan 	dev_caps->common_cap.num_rxq = num_funcs;
2643eae1bbb2SBruce Allan 	dev_caps->common_cap.num_txq = num_funcs;
2644462acf6aSTony Nguyen 
2645462acf6aSTony Nguyen 	/* two MSIX vectors per function */
2646eae1bbb2SBruce Allan 	dev_caps->common_cap.num_msix_vectors = 2 * num_funcs;
2647462acf6aSTony Nguyen }
2648462acf6aSTony Nguyen 
2649462acf6aSTony Nguyen /**
26509c20346bSAnirudh Venkataramanan  * ice_get_caps - get info about the HW
26519c20346bSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
26529c20346bSAnirudh Venkataramanan  */
2653*5e24d598STony Nguyen int ice_get_caps(struct ice_hw *hw)
26549c20346bSAnirudh Venkataramanan {
2655*5e24d598STony Nguyen 	int status;
26569c20346bSAnirudh Venkataramanan 
265781aed647SJacob Keller 	status = ice_discover_dev_caps(hw, &hw->dev_caps);
265881aed647SJacob Keller 	if (status)
26599c20346bSAnirudh Venkataramanan 		return status;
266081aed647SJacob Keller 
266181aed647SJacob Keller 	return ice_discover_func_caps(hw, &hw->func_caps);
26629c20346bSAnirudh Venkataramanan }
26639c20346bSAnirudh Venkataramanan 
26649c20346bSAnirudh Venkataramanan /**
2665e94d4478SAnirudh Venkataramanan  * ice_aq_manage_mac_write - manage MAC address write command
2666f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
2667e94d4478SAnirudh Venkataramanan  * @mac_addr: MAC address to be written as LAA/LAA+WoL/Port address
2668e94d4478SAnirudh Venkataramanan  * @flags: flags to control write behavior
2669e94d4478SAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
2670e94d4478SAnirudh Venkataramanan  *
2671e94d4478SAnirudh Venkataramanan  * This function is used to write MAC address to the NVM (0x0108).
2672e94d4478SAnirudh Venkataramanan  */
2673*5e24d598STony Nguyen int
2674d671e3e0SJacob Keller ice_aq_manage_mac_write(struct ice_hw *hw, const u8 *mac_addr, u8 flags,
2675e94d4478SAnirudh Venkataramanan 			struct ice_sq_cd *cd)
2676e94d4478SAnirudh Venkataramanan {
2677e94d4478SAnirudh Venkataramanan 	struct ice_aqc_manage_mac_write *cmd;
2678e94d4478SAnirudh Venkataramanan 	struct ice_aq_desc desc;
2679e94d4478SAnirudh Venkataramanan 
2680e94d4478SAnirudh Venkataramanan 	cmd = &desc.params.mac_write;
2681e94d4478SAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_manage_mac_write);
2682e94d4478SAnirudh Venkataramanan 
2683e94d4478SAnirudh Venkataramanan 	cmd->flags = flags;
26845df42c82SJesse Brandeburg 	ether_addr_copy(cmd->mac_addr, mac_addr);
2685e94d4478SAnirudh Venkataramanan 
2686e94d4478SAnirudh Venkataramanan 	return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
2687e94d4478SAnirudh Venkataramanan }
2688e94d4478SAnirudh Venkataramanan 
2689e94d4478SAnirudh Venkataramanan /**
2690f31e4b6fSAnirudh Venkataramanan  * ice_aq_clear_pxe_mode
2691f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
2692f31e4b6fSAnirudh Venkataramanan  *
2693f31e4b6fSAnirudh Venkataramanan  * Tell the firmware that the driver is taking over from PXE (0x0110).
2694f31e4b6fSAnirudh Venkataramanan  */
2695*5e24d598STony Nguyen static int ice_aq_clear_pxe_mode(struct ice_hw *hw)
2696f31e4b6fSAnirudh Venkataramanan {
2697f31e4b6fSAnirudh Venkataramanan 	struct ice_aq_desc desc;
2698f31e4b6fSAnirudh Venkataramanan 
2699f31e4b6fSAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_clear_pxe_mode);
2700f31e4b6fSAnirudh Venkataramanan 	desc.params.clear_pxe.rx_cnt = ICE_AQC_CLEAR_PXE_RX_CNT;
2701f31e4b6fSAnirudh Venkataramanan 
2702f31e4b6fSAnirudh Venkataramanan 	return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
2703f31e4b6fSAnirudh Venkataramanan }
2704f31e4b6fSAnirudh Venkataramanan 
2705f31e4b6fSAnirudh Venkataramanan /**
2706f31e4b6fSAnirudh Venkataramanan  * ice_clear_pxe_mode - clear pxe operations mode
2707f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
2708f31e4b6fSAnirudh Venkataramanan  *
2709f31e4b6fSAnirudh Venkataramanan  * Make sure all PXE mode settings are cleared, including things
2710f31e4b6fSAnirudh Venkataramanan  * like descriptor fetch/write-back mode.
2711f31e4b6fSAnirudh Venkataramanan  */
2712f31e4b6fSAnirudh Venkataramanan void ice_clear_pxe_mode(struct ice_hw *hw)
2713f31e4b6fSAnirudh Venkataramanan {
2714f31e4b6fSAnirudh Venkataramanan 	if (ice_check_sq_alive(hw, &hw->adminq))
2715f31e4b6fSAnirudh Venkataramanan 		ice_aq_clear_pxe_mode(hw);
2716f31e4b6fSAnirudh Venkataramanan }
2717cdedef59SAnirudh Venkataramanan 
2718cdedef59SAnirudh Venkataramanan /**
271948cb27f2SChinh Cao  * ice_get_link_speed_based_on_phy_type - returns link speed
272048cb27f2SChinh Cao  * @phy_type_low: lower part of phy_type
2721aef74145SAnirudh Venkataramanan  * @phy_type_high: higher part of phy_type
272248cb27f2SChinh Cao  *
2723f9867df6SAnirudh Venkataramanan  * This helper function will convert an entry in PHY type structure
2724aef74145SAnirudh Venkataramanan  * [phy_type_low, phy_type_high] to its corresponding link speed.
2725aef74145SAnirudh Venkataramanan  * Note: In the structure of [phy_type_low, phy_type_high], there should
2726f9867df6SAnirudh Venkataramanan  * be one bit set, as this function will convert one PHY type to its
272748cb27f2SChinh Cao  * speed.
272848cb27f2SChinh Cao  * If no bit gets set, ICE_LINK_SPEED_UNKNOWN will be returned
272948cb27f2SChinh Cao  * If more than one bit gets set, ICE_LINK_SPEED_UNKNOWN will be returned
273048cb27f2SChinh Cao  */
2731aef74145SAnirudh Venkataramanan static u16
2732aef74145SAnirudh Venkataramanan ice_get_link_speed_based_on_phy_type(u64 phy_type_low, u64 phy_type_high)
273348cb27f2SChinh Cao {
2734aef74145SAnirudh Venkataramanan 	u16 speed_phy_type_high = ICE_AQ_LINK_SPEED_UNKNOWN;
273548cb27f2SChinh Cao 	u16 speed_phy_type_low = ICE_AQ_LINK_SPEED_UNKNOWN;
273648cb27f2SChinh Cao 
273748cb27f2SChinh Cao 	switch (phy_type_low) {
273848cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_100BASE_TX:
273948cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_100M_SGMII:
274048cb27f2SChinh Cao 		speed_phy_type_low = ICE_AQ_LINK_SPEED_100MB;
274148cb27f2SChinh Cao 		break;
274248cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_1000BASE_T:
274348cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_1000BASE_SX:
274448cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_1000BASE_LX:
274548cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_1000BASE_KX:
274648cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_1G_SGMII:
274748cb27f2SChinh Cao 		speed_phy_type_low = ICE_AQ_LINK_SPEED_1000MB;
274848cb27f2SChinh Cao 		break;
274948cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_2500BASE_T:
275048cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_2500BASE_X:
275148cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_2500BASE_KX:
275248cb27f2SChinh Cao 		speed_phy_type_low = ICE_AQ_LINK_SPEED_2500MB;
275348cb27f2SChinh Cao 		break;
275448cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_5GBASE_T:
275548cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_5GBASE_KR:
275648cb27f2SChinh Cao 		speed_phy_type_low = ICE_AQ_LINK_SPEED_5GB;
275748cb27f2SChinh Cao 		break;
275848cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_10GBASE_T:
275948cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_10G_SFI_DA:
276048cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_10GBASE_SR:
276148cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_10GBASE_LR:
276248cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_10GBASE_KR_CR1:
276348cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_10G_SFI_AOC_ACC:
276448cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_10G_SFI_C2C:
276548cb27f2SChinh Cao 		speed_phy_type_low = ICE_AQ_LINK_SPEED_10GB;
276648cb27f2SChinh Cao 		break;
276748cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_25GBASE_T:
276848cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_25GBASE_CR:
276948cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_25GBASE_CR_S:
277048cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_25GBASE_CR1:
277148cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_25GBASE_SR:
277248cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_25GBASE_LR:
277348cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_25GBASE_KR:
277448cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_25GBASE_KR_S:
277548cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_25GBASE_KR1:
277648cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_25G_AUI_AOC_ACC:
277748cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_25G_AUI_C2C:
277848cb27f2SChinh Cao 		speed_phy_type_low = ICE_AQ_LINK_SPEED_25GB;
277948cb27f2SChinh Cao 		break;
278048cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_40GBASE_CR4:
278148cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_40GBASE_SR4:
278248cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_40GBASE_LR4:
278348cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_40GBASE_KR4:
278448cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_40G_XLAUI_AOC_ACC:
278548cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_40G_XLAUI:
278648cb27f2SChinh Cao 		speed_phy_type_low = ICE_AQ_LINK_SPEED_40GB;
278748cb27f2SChinh Cao 		break;
2788aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50GBASE_CR2:
2789aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50GBASE_SR2:
2790aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50GBASE_LR2:
2791aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50GBASE_KR2:
2792aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50G_LAUI2_AOC_ACC:
2793aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50G_LAUI2:
2794aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50G_AUI2_AOC_ACC:
2795aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50G_AUI2:
2796aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50GBASE_CP:
2797aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50GBASE_SR:
2798aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50GBASE_FR:
2799aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50GBASE_LR:
2800aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50GBASE_KR_PAM4:
2801aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50G_AUI1_AOC_ACC:
2802aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50G_AUI1:
2803aef74145SAnirudh Venkataramanan 		speed_phy_type_low = ICE_AQ_LINK_SPEED_50GB;
2804aef74145SAnirudh Venkataramanan 		break;
2805aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100GBASE_CR4:
2806aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100GBASE_SR4:
2807aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100GBASE_LR4:
2808aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100GBASE_KR4:
2809aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100G_CAUI4_AOC_ACC:
2810aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100G_CAUI4:
2811aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100G_AUI4_AOC_ACC:
2812aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100G_AUI4:
2813aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100GBASE_CR_PAM4:
2814aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100GBASE_KR_PAM4:
2815aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100GBASE_CP2:
2816aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100GBASE_SR2:
2817aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100GBASE_DR:
2818aef74145SAnirudh Venkataramanan 		speed_phy_type_low = ICE_AQ_LINK_SPEED_100GB;
2819aef74145SAnirudh Venkataramanan 		break;
282048cb27f2SChinh Cao 	default:
282148cb27f2SChinh Cao 		speed_phy_type_low = ICE_AQ_LINK_SPEED_UNKNOWN;
282248cb27f2SChinh Cao 		break;
282348cb27f2SChinh Cao 	}
282448cb27f2SChinh Cao 
2825aef74145SAnirudh Venkataramanan 	switch (phy_type_high) {
2826aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_HIGH_100GBASE_KR2_PAM4:
2827aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_HIGH_100G_CAUI2_AOC_ACC:
2828aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_HIGH_100G_CAUI2:
2829aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_HIGH_100G_AUI2_AOC_ACC:
2830aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_HIGH_100G_AUI2:
2831aef74145SAnirudh Venkataramanan 		speed_phy_type_high = ICE_AQ_LINK_SPEED_100GB;
2832aef74145SAnirudh Venkataramanan 		break;
2833aef74145SAnirudh Venkataramanan 	default:
2834aef74145SAnirudh Venkataramanan 		speed_phy_type_high = ICE_AQ_LINK_SPEED_UNKNOWN;
2835aef74145SAnirudh Venkataramanan 		break;
2836aef74145SAnirudh Venkataramanan 	}
2837aef74145SAnirudh Venkataramanan 
2838aef74145SAnirudh Venkataramanan 	if (speed_phy_type_low == ICE_AQ_LINK_SPEED_UNKNOWN &&
2839aef74145SAnirudh Venkataramanan 	    speed_phy_type_high == ICE_AQ_LINK_SPEED_UNKNOWN)
2840aef74145SAnirudh Venkataramanan 		return ICE_AQ_LINK_SPEED_UNKNOWN;
2841aef74145SAnirudh Venkataramanan 	else if (speed_phy_type_low != ICE_AQ_LINK_SPEED_UNKNOWN &&
2842aef74145SAnirudh Venkataramanan 		 speed_phy_type_high != ICE_AQ_LINK_SPEED_UNKNOWN)
2843aef74145SAnirudh Venkataramanan 		return ICE_AQ_LINK_SPEED_UNKNOWN;
2844aef74145SAnirudh Venkataramanan 	else if (speed_phy_type_low != ICE_AQ_LINK_SPEED_UNKNOWN &&
2845aef74145SAnirudh Venkataramanan 		 speed_phy_type_high == ICE_AQ_LINK_SPEED_UNKNOWN)
284648cb27f2SChinh Cao 		return speed_phy_type_low;
2847aef74145SAnirudh Venkataramanan 	else
2848aef74145SAnirudh Venkataramanan 		return speed_phy_type_high;
284948cb27f2SChinh Cao }
285048cb27f2SChinh Cao 
285148cb27f2SChinh Cao /**
285248cb27f2SChinh Cao  * ice_update_phy_type
285348cb27f2SChinh Cao  * @phy_type_low: pointer to the lower part of phy_type
2854aef74145SAnirudh Venkataramanan  * @phy_type_high: pointer to the higher part of phy_type
285548cb27f2SChinh Cao  * @link_speeds_bitmap: targeted link speeds bitmap
285648cb27f2SChinh Cao  *
285748cb27f2SChinh Cao  * Note: For the link_speeds_bitmap structure, you can check it at
285848cb27f2SChinh Cao  * [ice_aqc_get_link_status->link_speed]. Caller can pass in
285948cb27f2SChinh Cao  * link_speeds_bitmap include multiple speeds.
286048cb27f2SChinh Cao  *
2861aef74145SAnirudh Venkataramanan  * Each entry in this [phy_type_low, phy_type_high] structure will
2862aef74145SAnirudh Venkataramanan  * present a certain link speed. This helper function will turn on bits
2863aef74145SAnirudh Venkataramanan  * in [phy_type_low, phy_type_high] structure based on the value of
286448cb27f2SChinh Cao  * link_speeds_bitmap input parameter.
286548cb27f2SChinh Cao  */
2866aef74145SAnirudh Venkataramanan void
2867aef74145SAnirudh Venkataramanan ice_update_phy_type(u64 *phy_type_low, u64 *phy_type_high,
2868aef74145SAnirudh Venkataramanan 		    u16 link_speeds_bitmap)
286948cb27f2SChinh Cao {
2870aef74145SAnirudh Venkataramanan 	u64 pt_high;
287148cb27f2SChinh Cao 	u64 pt_low;
287248cb27f2SChinh Cao 	int index;
2873207e3721SBruce Allan 	u16 speed;
287448cb27f2SChinh Cao 
287548cb27f2SChinh Cao 	/* We first check with low part of phy_type */
287648cb27f2SChinh Cao 	for (index = 0; index <= ICE_PHY_TYPE_LOW_MAX_INDEX; index++) {
287748cb27f2SChinh Cao 		pt_low = BIT_ULL(index);
2878aef74145SAnirudh Venkataramanan 		speed = ice_get_link_speed_based_on_phy_type(pt_low, 0);
287948cb27f2SChinh Cao 
288048cb27f2SChinh Cao 		if (link_speeds_bitmap & speed)
288148cb27f2SChinh Cao 			*phy_type_low |= BIT_ULL(index);
288248cb27f2SChinh Cao 	}
2883aef74145SAnirudh Venkataramanan 
2884aef74145SAnirudh Venkataramanan 	/* We then check with high part of phy_type */
2885aef74145SAnirudh Venkataramanan 	for (index = 0; index <= ICE_PHY_TYPE_HIGH_MAX_INDEX; index++) {
2886aef74145SAnirudh Venkataramanan 		pt_high = BIT_ULL(index);
2887aef74145SAnirudh Venkataramanan 		speed = ice_get_link_speed_based_on_phy_type(0, pt_high);
2888aef74145SAnirudh Venkataramanan 
2889aef74145SAnirudh Venkataramanan 		if (link_speeds_bitmap & speed)
2890aef74145SAnirudh Venkataramanan 			*phy_type_high |= BIT_ULL(index);
2891aef74145SAnirudh Venkataramanan 	}
289248cb27f2SChinh Cao }
289348cb27f2SChinh Cao 
289448cb27f2SChinh Cao /**
2895fcea6f3dSAnirudh Venkataramanan  * ice_aq_set_phy_cfg
2896f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
28971a3571b5SPaul Greenwalt  * @pi: port info structure of the interested logical port
2898fcea6f3dSAnirudh Venkataramanan  * @cfg: structure with PHY configuration data to be set
2899fcea6f3dSAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
2900fcea6f3dSAnirudh Venkataramanan  *
2901fcea6f3dSAnirudh Venkataramanan  * Set the various PHY configuration parameters supported on the Port.
2902fcea6f3dSAnirudh Venkataramanan  * One or more of the Set PHY config parameters may be ignored in an MFP
2903fcea6f3dSAnirudh Venkataramanan  * mode as the PF may not have the privilege to set some of the PHY Config
2904fcea6f3dSAnirudh Venkataramanan  * parameters. This status will be indicated by the command response (0x0601).
2905fcea6f3dSAnirudh Venkataramanan  */
2906*5e24d598STony Nguyen int
29071a3571b5SPaul Greenwalt ice_aq_set_phy_cfg(struct ice_hw *hw, struct ice_port_info *pi,
2908fcea6f3dSAnirudh Venkataramanan 		   struct ice_aqc_set_phy_cfg_data *cfg, struct ice_sq_cd *cd)
2909fcea6f3dSAnirudh Venkataramanan {
2910fcea6f3dSAnirudh Venkataramanan 	struct ice_aq_desc desc;
2911*5e24d598STony Nguyen 	int status;
2912fcea6f3dSAnirudh Venkataramanan 
2913fcea6f3dSAnirudh Venkataramanan 	if (!cfg)
2914fcea6f3dSAnirudh Venkataramanan 		return ICE_ERR_PARAM;
2915fcea6f3dSAnirudh Venkataramanan 
2916d8df260aSChinh T Cao 	/* Ensure that only valid bits of cfg->caps can be turned on. */
2917d8df260aSChinh T Cao 	if (cfg->caps & ~ICE_AQ_PHY_ENA_VALID_MASK) {
29189228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_PHY, "Invalid bit is set in ice_aqc_set_phy_cfg_data->caps : 0x%x\n",
2919d8df260aSChinh T Cao 			  cfg->caps);
2920d8df260aSChinh T Cao 
2921d8df260aSChinh T Cao 		cfg->caps &= ICE_AQ_PHY_ENA_VALID_MASK;
2922d8df260aSChinh T Cao 	}
2923d8df260aSChinh T Cao 
2924fcea6f3dSAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_phy_cfg);
29251a3571b5SPaul Greenwalt 	desc.params.set_phy.lport_num = pi->lport;
292648cb27f2SChinh Cao 	desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
2927fcea6f3dSAnirudh Venkataramanan 
292855df52a0SPaul Greenwalt 	ice_debug(hw, ICE_DBG_LINK, "set phy cfg\n");
2929dc67039bSJesse Brandeburg 	ice_debug(hw, ICE_DBG_LINK, "	phy_type_low = 0x%llx\n",
2930dc67039bSJesse Brandeburg 		  (unsigned long long)le64_to_cpu(cfg->phy_type_low));
2931dc67039bSJesse Brandeburg 	ice_debug(hw, ICE_DBG_LINK, "	phy_type_high = 0x%llx\n",
2932dc67039bSJesse Brandeburg 		  (unsigned long long)le64_to_cpu(cfg->phy_type_high));
2933dc67039bSJesse Brandeburg 	ice_debug(hw, ICE_DBG_LINK, "	caps = 0x%x\n", cfg->caps);
2934bdeff971SLev Faerman 	ice_debug(hw, ICE_DBG_LINK, "	low_power_ctrl_an = 0x%x\n",
2935bdeff971SLev Faerman 		  cfg->low_power_ctrl_an);
2936dc67039bSJesse Brandeburg 	ice_debug(hw, ICE_DBG_LINK, "	eee_cap = 0x%x\n", cfg->eee_cap);
2937dc67039bSJesse Brandeburg 	ice_debug(hw, ICE_DBG_LINK, "	eeer_value = 0x%x\n", cfg->eeer_value);
293855df52a0SPaul Greenwalt 	ice_debug(hw, ICE_DBG_LINK, "	link_fec_opt = 0x%x\n",
293955df52a0SPaul Greenwalt 		  cfg->link_fec_opt);
2940dc67039bSJesse Brandeburg 
2941b5e19a64SChinh T Cao 	status = ice_aq_send_cmd(hw, &desc, cfg, sizeof(*cfg), cd);
2942b5e19a64SChinh T Cao 	if (hw->adminq.sq_last_status == ICE_AQ_RC_EMODE)
2943b5e19a64SChinh T Cao 		status = 0;
2944b5e19a64SChinh T Cao 
29451a3571b5SPaul Greenwalt 	if (!status)
29461a3571b5SPaul Greenwalt 		pi->phy.curr_user_phy_cfg = *cfg;
29471a3571b5SPaul Greenwalt 
2948b5e19a64SChinh T Cao 	return status;
2949fcea6f3dSAnirudh Venkataramanan }
2950fcea6f3dSAnirudh Venkataramanan 
2951fcea6f3dSAnirudh Venkataramanan /**
2952fcea6f3dSAnirudh Venkataramanan  * ice_update_link_info - update status of the HW network link
2953fcea6f3dSAnirudh Venkataramanan  * @pi: port info structure of the interested logical port
2954fcea6f3dSAnirudh Venkataramanan  */
2955*5e24d598STony Nguyen int ice_update_link_info(struct ice_port_info *pi)
2956fcea6f3dSAnirudh Venkataramanan {
2957092a33d4SBruce Allan 	struct ice_link_status *li;
2958*5e24d598STony Nguyen 	int status;
2959fcea6f3dSAnirudh Venkataramanan 
2960fcea6f3dSAnirudh Venkataramanan 	if (!pi)
2961fcea6f3dSAnirudh Venkataramanan 		return ICE_ERR_PARAM;
2962fcea6f3dSAnirudh Venkataramanan 
2963092a33d4SBruce Allan 	li = &pi->phy.link_info;
2964fcea6f3dSAnirudh Venkataramanan 
2965092a33d4SBruce Allan 	status = ice_aq_get_link_info(pi, true, NULL, NULL);
2966092a33d4SBruce Allan 	if (status)
2967092a33d4SBruce Allan 		return status;
2968092a33d4SBruce Allan 
2969092a33d4SBruce Allan 	if (li->link_info & ICE_AQ_MEDIA_AVAILABLE) {
2970092a33d4SBruce Allan 		struct ice_aqc_get_phy_caps_data *pcaps;
2971092a33d4SBruce Allan 		struct ice_hw *hw;
2972092a33d4SBruce Allan 
2973092a33d4SBruce Allan 		hw = pi->hw;
2974092a33d4SBruce Allan 		pcaps = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*pcaps),
2975092a33d4SBruce Allan 				     GFP_KERNEL);
2976fcea6f3dSAnirudh Venkataramanan 		if (!pcaps)
2977fcea6f3dSAnirudh Venkataramanan 			return ICE_ERR_NO_MEMORY;
2978fcea6f3dSAnirudh Venkataramanan 
2979d6730a87SAnirudh Venkataramanan 		status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_TOPO_CAP_MEDIA,
2980fcea6f3dSAnirudh Venkataramanan 					     pcaps, NULL);
2981fcea6f3dSAnirudh Venkataramanan 
2982fcea6f3dSAnirudh Venkataramanan 		devm_kfree(ice_hw_to_dev(hw), pcaps);
2983092a33d4SBruce Allan 	}
2984092a33d4SBruce Allan 
2985fcea6f3dSAnirudh Venkataramanan 	return status;
2986fcea6f3dSAnirudh Venkataramanan }
2987fcea6f3dSAnirudh Venkataramanan 
2988fcea6f3dSAnirudh Venkataramanan /**
29891a3571b5SPaul Greenwalt  * ice_cache_phy_user_req
29901a3571b5SPaul Greenwalt  * @pi: port information structure
29911a3571b5SPaul Greenwalt  * @cache_data: PHY logging data
29921a3571b5SPaul Greenwalt  * @cache_mode: PHY logging mode
29931a3571b5SPaul Greenwalt  *
29941a3571b5SPaul Greenwalt  * Log the user request on (FC, FEC, SPEED) for later use.
29951a3571b5SPaul Greenwalt  */
29961a3571b5SPaul Greenwalt static void
29971a3571b5SPaul Greenwalt ice_cache_phy_user_req(struct ice_port_info *pi,
29981a3571b5SPaul Greenwalt 		       struct ice_phy_cache_mode_data cache_data,
29991a3571b5SPaul Greenwalt 		       enum ice_phy_cache_mode cache_mode)
30001a3571b5SPaul Greenwalt {
30011a3571b5SPaul Greenwalt 	if (!pi)
30021a3571b5SPaul Greenwalt 		return;
30031a3571b5SPaul Greenwalt 
30041a3571b5SPaul Greenwalt 	switch (cache_mode) {
30051a3571b5SPaul Greenwalt 	case ICE_FC_MODE:
30061a3571b5SPaul Greenwalt 		pi->phy.curr_user_fc_req = cache_data.data.curr_user_fc_req;
30071a3571b5SPaul Greenwalt 		break;
30081a3571b5SPaul Greenwalt 	case ICE_SPEED_MODE:
30091a3571b5SPaul Greenwalt 		pi->phy.curr_user_speed_req =
30101a3571b5SPaul Greenwalt 			cache_data.data.curr_user_speed_req;
30111a3571b5SPaul Greenwalt 		break;
30121a3571b5SPaul Greenwalt 	case ICE_FEC_MODE:
30131a3571b5SPaul Greenwalt 		pi->phy.curr_user_fec_req = cache_data.data.curr_user_fec_req;
30141a3571b5SPaul Greenwalt 		break;
30151a3571b5SPaul Greenwalt 	default:
30161a3571b5SPaul Greenwalt 		break;
30171a3571b5SPaul Greenwalt 	}
30181a3571b5SPaul Greenwalt }
30191a3571b5SPaul Greenwalt 
30201a3571b5SPaul Greenwalt /**
30211a3571b5SPaul Greenwalt  * ice_caps_to_fc_mode
30221a3571b5SPaul Greenwalt  * @caps: PHY capabilities
30231a3571b5SPaul Greenwalt  *
30241a3571b5SPaul Greenwalt  * Convert PHY FC capabilities to ice FC mode
30251a3571b5SPaul Greenwalt  */
30261a3571b5SPaul Greenwalt enum ice_fc_mode ice_caps_to_fc_mode(u8 caps)
30271a3571b5SPaul Greenwalt {
30281a3571b5SPaul Greenwalt 	if (caps & ICE_AQC_PHY_EN_TX_LINK_PAUSE &&
30291a3571b5SPaul Greenwalt 	    caps & ICE_AQC_PHY_EN_RX_LINK_PAUSE)
30301a3571b5SPaul Greenwalt 		return ICE_FC_FULL;
30311a3571b5SPaul Greenwalt 
30321a3571b5SPaul Greenwalt 	if (caps & ICE_AQC_PHY_EN_TX_LINK_PAUSE)
30331a3571b5SPaul Greenwalt 		return ICE_FC_TX_PAUSE;
30341a3571b5SPaul Greenwalt 
30351a3571b5SPaul Greenwalt 	if (caps & ICE_AQC_PHY_EN_RX_LINK_PAUSE)
30361a3571b5SPaul Greenwalt 		return ICE_FC_RX_PAUSE;
30371a3571b5SPaul Greenwalt 
30381a3571b5SPaul Greenwalt 	return ICE_FC_NONE;
30391a3571b5SPaul Greenwalt }
30401a3571b5SPaul Greenwalt 
30411a3571b5SPaul Greenwalt /**
30421a3571b5SPaul Greenwalt  * ice_caps_to_fec_mode
30431a3571b5SPaul Greenwalt  * @caps: PHY capabilities
30441a3571b5SPaul Greenwalt  * @fec_options: Link FEC options
30451a3571b5SPaul Greenwalt  *
30461a3571b5SPaul Greenwalt  * Convert PHY FEC capabilities to ice FEC mode
30471a3571b5SPaul Greenwalt  */
30481a3571b5SPaul Greenwalt enum ice_fec_mode ice_caps_to_fec_mode(u8 caps, u8 fec_options)
30491a3571b5SPaul Greenwalt {
30501a3571b5SPaul Greenwalt 	if (caps & ICE_AQC_PHY_EN_AUTO_FEC)
30511a3571b5SPaul Greenwalt 		return ICE_FEC_AUTO;
30521a3571b5SPaul Greenwalt 
30531a3571b5SPaul Greenwalt 	if (fec_options & (ICE_AQC_PHY_FEC_10G_KR_40G_KR4_EN |
30541a3571b5SPaul Greenwalt 			   ICE_AQC_PHY_FEC_10G_KR_40G_KR4_REQ |
30551a3571b5SPaul Greenwalt 			   ICE_AQC_PHY_FEC_25G_KR_CLAUSE74_EN |
30561a3571b5SPaul Greenwalt 			   ICE_AQC_PHY_FEC_25G_KR_REQ))
30571a3571b5SPaul Greenwalt 		return ICE_FEC_BASER;
30581a3571b5SPaul Greenwalt 
30591a3571b5SPaul Greenwalt 	if (fec_options & (ICE_AQC_PHY_FEC_25G_RS_528_REQ |
30601a3571b5SPaul Greenwalt 			   ICE_AQC_PHY_FEC_25G_RS_544_REQ |
30611a3571b5SPaul Greenwalt 			   ICE_AQC_PHY_FEC_25G_RS_CLAUSE91_EN))
30621a3571b5SPaul Greenwalt 		return ICE_FEC_RS;
30631a3571b5SPaul Greenwalt 
30641a3571b5SPaul Greenwalt 	return ICE_FEC_NONE;
30651a3571b5SPaul Greenwalt }
30661a3571b5SPaul Greenwalt 
30671a3571b5SPaul Greenwalt /**
30682ffb6085SPaul Greenwalt  * ice_cfg_phy_fc - Configure PHY FC data based on FC mode
30691a3571b5SPaul Greenwalt  * @pi: port information structure
30702ffb6085SPaul Greenwalt  * @cfg: PHY configuration data to set FC mode
30712ffb6085SPaul Greenwalt  * @req_mode: FC mode to configure
3072fcea6f3dSAnirudh Venkataramanan  */
3073*5e24d598STony Nguyen int
30741a3571b5SPaul Greenwalt ice_cfg_phy_fc(struct ice_port_info *pi, struct ice_aqc_set_phy_cfg_data *cfg,
30751a3571b5SPaul Greenwalt 	       enum ice_fc_mode req_mode)
3076fcea6f3dSAnirudh Venkataramanan {
30771a3571b5SPaul Greenwalt 	struct ice_phy_cache_mode_data cache_data;
3078fcea6f3dSAnirudh Venkataramanan 	u8 pause_mask = 0x0;
3079fcea6f3dSAnirudh Venkataramanan 
30801a3571b5SPaul Greenwalt 	if (!pi || !cfg)
30812ffb6085SPaul Greenwalt 		return ICE_ERR_BAD_PTR;
3082fcea6f3dSAnirudh Venkataramanan 
30832ffb6085SPaul Greenwalt 	switch (req_mode) {
3084fcea6f3dSAnirudh Venkataramanan 	case ICE_FC_FULL:
3085fcea6f3dSAnirudh Venkataramanan 		pause_mask |= ICE_AQC_PHY_EN_TX_LINK_PAUSE;
3086fcea6f3dSAnirudh Venkataramanan 		pause_mask |= ICE_AQC_PHY_EN_RX_LINK_PAUSE;
3087fcea6f3dSAnirudh Venkataramanan 		break;
3088fcea6f3dSAnirudh Venkataramanan 	case ICE_FC_RX_PAUSE:
3089fcea6f3dSAnirudh Venkataramanan 		pause_mask |= ICE_AQC_PHY_EN_RX_LINK_PAUSE;
3090fcea6f3dSAnirudh Venkataramanan 		break;
3091fcea6f3dSAnirudh Venkataramanan 	case ICE_FC_TX_PAUSE:
3092fcea6f3dSAnirudh Venkataramanan 		pause_mask |= ICE_AQC_PHY_EN_TX_LINK_PAUSE;
3093fcea6f3dSAnirudh Venkataramanan 		break;
3094fcea6f3dSAnirudh Venkataramanan 	default:
3095fcea6f3dSAnirudh Venkataramanan 		break;
3096fcea6f3dSAnirudh Venkataramanan 	}
3097fcea6f3dSAnirudh Venkataramanan 
30982ffb6085SPaul Greenwalt 	/* clear the old pause settings */
30992ffb6085SPaul Greenwalt 	cfg->caps &= ~(ICE_AQC_PHY_EN_TX_LINK_PAUSE |
31002ffb6085SPaul Greenwalt 		ICE_AQC_PHY_EN_RX_LINK_PAUSE);
31012ffb6085SPaul Greenwalt 
31022ffb6085SPaul Greenwalt 	/* set the new capabilities */
31032ffb6085SPaul Greenwalt 	cfg->caps |= pause_mask;
31042ffb6085SPaul Greenwalt 
31051a3571b5SPaul Greenwalt 	/* Cache user FC request */
31061a3571b5SPaul Greenwalt 	cache_data.data.curr_user_fc_req = req_mode;
31071a3571b5SPaul Greenwalt 	ice_cache_phy_user_req(pi, cache_data, ICE_FC_MODE);
31081a3571b5SPaul Greenwalt 
31092ffb6085SPaul Greenwalt 	return 0;
31102ffb6085SPaul Greenwalt }
31112ffb6085SPaul Greenwalt 
31122ffb6085SPaul Greenwalt /**
31132ffb6085SPaul Greenwalt  * ice_set_fc
31142ffb6085SPaul Greenwalt  * @pi: port information structure
31152ffb6085SPaul Greenwalt  * @aq_failures: pointer to status code, specific to ice_set_fc routine
31162ffb6085SPaul Greenwalt  * @ena_auto_link_update: enable automatic link update
31172ffb6085SPaul Greenwalt  *
31182ffb6085SPaul Greenwalt  * Set the requested flow control mode.
31192ffb6085SPaul Greenwalt  */
3120*5e24d598STony Nguyen int
31212ffb6085SPaul Greenwalt ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update)
31222ffb6085SPaul Greenwalt {
31232ffb6085SPaul Greenwalt 	struct ice_aqc_set_phy_cfg_data cfg = { 0 };
31242ffb6085SPaul Greenwalt 	struct ice_aqc_get_phy_caps_data *pcaps;
3125*5e24d598STony Nguyen 	int status;
31262ffb6085SPaul Greenwalt 	struct ice_hw *hw;
31272ffb6085SPaul Greenwalt 
31281a3571b5SPaul Greenwalt 	if (!pi || !aq_failures)
31292ffb6085SPaul Greenwalt 		return ICE_ERR_BAD_PTR;
31302ffb6085SPaul Greenwalt 
31312ffb6085SPaul Greenwalt 	*aq_failures = 0;
31322ffb6085SPaul Greenwalt 	hw = pi->hw;
31332ffb6085SPaul Greenwalt 
3134fcea6f3dSAnirudh Venkataramanan 	pcaps = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*pcaps), GFP_KERNEL);
3135fcea6f3dSAnirudh Venkataramanan 	if (!pcaps)
3136fcea6f3dSAnirudh Venkataramanan 		return ICE_ERR_NO_MEMORY;
3137fcea6f3dSAnirudh Venkataramanan 
3138f9867df6SAnirudh Venkataramanan 	/* Get the current PHY config */
3139d6730a87SAnirudh Venkataramanan 	status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_ACTIVE_CFG,
3140d6730a87SAnirudh Venkataramanan 				     pcaps, NULL);
3141fcea6f3dSAnirudh Venkataramanan 	if (status) {
3142fcea6f3dSAnirudh Venkataramanan 		*aq_failures = ICE_SET_FC_AQ_FAIL_GET;
3143fcea6f3dSAnirudh Venkataramanan 		goto out;
3144fcea6f3dSAnirudh Venkataramanan 	}
3145fcea6f3dSAnirudh Venkataramanan 
3146ea78ce4dSPaul Greenwalt 	ice_copy_phy_caps_to_cfg(pi, pcaps, &cfg);
3147d8df260aSChinh T Cao 
31482ffb6085SPaul Greenwalt 	/* Configure the set PHY data */
31491a3571b5SPaul Greenwalt 	status = ice_cfg_phy_fc(pi, &cfg, pi->fc.req_mode);
31502ffb6085SPaul Greenwalt 	if (status)
31512ffb6085SPaul Greenwalt 		goto out;
3152d8df260aSChinh T Cao 
3153fcea6f3dSAnirudh Venkataramanan 	/* If the capabilities have changed, then set the new config */
3154fcea6f3dSAnirudh Venkataramanan 	if (cfg.caps != pcaps->caps) {
3155fcea6f3dSAnirudh Venkataramanan 		int retry_count, retry_max = 10;
3156fcea6f3dSAnirudh Venkataramanan 
3157fcea6f3dSAnirudh Venkataramanan 		/* Auto restart link so settings take effect */
315848cb27f2SChinh Cao 		if (ena_auto_link_update)
315948cb27f2SChinh Cao 			cfg.caps |= ICE_AQ_PHY_ENA_AUTO_LINK_UPDT;
3160fcea6f3dSAnirudh Venkataramanan 
31611a3571b5SPaul Greenwalt 		status = ice_aq_set_phy_cfg(hw, pi, &cfg, NULL);
3162fcea6f3dSAnirudh Venkataramanan 		if (status) {
3163fcea6f3dSAnirudh Venkataramanan 			*aq_failures = ICE_SET_FC_AQ_FAIL_SET;
3164fcea6f3dSAnirudh Venkataramanan 			goto out;
3165fcea6f3dSAnirudh Venkataramanan 		}
3166fcea6f3dSAnirudh Venkataramanan 
3167fcea6f3dSAnirudh Venkataramanan 		/* Update the link info
3168fcea6f3dSAnirudh Venkataramanan 		 * It sometimes takes a really long time for link to
3169fcea6f3dSAnirudh Venkataramanan 		 * come back from the atomic reset. Thus, we wait a
3170fcea6f3dSAnirudh Venkataramanan 		 * little bit.
3171fcea6f3dSAnirudh Venkataramanan 		 */
3172fcea6f3dSAnirudh Venkataramanan 		for (retry_count = 0; retry_count < retry_max; retry_count++) {
3173fcea6f3dSAnirudh Venkataramanan 			status = ice_update_link_info(pi);
3174fcea6f3dSAnirudh Venkataramanan 
3175fcea6f3dSAnirudh Venkataramanan 			if (!status)
3176fcea6f3dSAnirudh Venkataramanan 				break;
3177fcea6f3dSAnirudh Venkataramanan 
3178fcea6f3dSAnirudh Venkataramanan 			mdelay(100);
3179fcea6f3dSAnirudh Venkataramanan 		}
3180fcea6f3dSAnirudh Venkataramanan 
3181fcea6f3dSAnirudh Venkataramanan 		if (status)
3182fcea6f3dSAnirudh Venkataramanan 			*aq_failures = ICE_SET_FC_AQ_FAIL_UPDATE;
3183fcea6f3dSAnirudh Venkataramanan 	}
3184fcea6f3dSAnirudh Venkataramanan 
3185fcea6f3dSAnirudh Venkataramanan out:
3186fcea6f3dSAnirudh Venkataramanan 	devm_kfree(ice_hw_to_dev(hw), pcaps);
3187fcea6f3dSAnirudh Venkataramanan 	return status;
3188fcea6f3dSAnirudh Venkataramanan }
3189fcea6f3dSAnirudh Venkataramanan 
3190fcea6f3dSAnirudh Venkataramanan /**
31911a3571b5SPaul Greenwalt  * ice_phy_caps_equals_cfg
31921a3571b5SPaul Greenwalt  * @phy_caps: PHY capabilities
31931a3571b5SPaul Greenwalt  * @phy_cfg: PHY configuration
31941a3571b5SPaul Greenwalt  *
31951a3571b5SPaul Greenwalt  * Helper function to determine if PHY capabilities matches PHY
31961a3571b5SPaul Greenwalt  * configuration
31971a3571b5SPaul Greenwalt  */
31981a3571b5SPaul Greenwalt bool
31991a3571b5SPaul Greenwalt ice_phy_caps_equals_cfg(struct ice_aqc_get_phy_caps_data *phy_caps,
32001a3571b5SPaul Greenwalt 			struct ice_aqc_set_phy_cfg_data *phy_cfg)
32011a3571b5SPaul Greenwalt {
32021a3571b5SPaul Greenwalt 	u8 caps_mask, cfg_mask;
32031a3571b5SPaul Greenwalt 
32041a3571b5SPaul Greenwalt 	if (!phy_caps || !phy_cfg)
32051a3571b5SPaul Greenwalt 		return false;
32061a3571b5SPaul Greenwalt 
32071a3571b5SPaul Greenwalt 	/* These bits are not common between capabilities and configuration.
32081a3571b5SPaul Greenwalt 	 * Do not use them to determine equality.
32091a3571b5SPaul Greenwalt 	 */
32101a3571b5SPaul Greenwalt 	caps_mask = ICE_AQC_PHY_CAPS_MASK & ~(ICE_AQC_PHY_AN_MODE |
32111a3571b5SPaul Greenwalt 					      ICE_AQC_GET_PHY_EN_MOD_QUAL);
32121a3571b5SPaul Greenwalt 	cfg_mask = ICE_AQ_PHY_ENA_VALID_MASK & ~ICE_AQ_PHY_ENA_AUTO_LINK_UPDT;
32131a3571b5SPaul Greenwalt 
32141a3571b5SPaul Greenwalt 	if (phy_caps->phy_type_low != phy_cfg->phy_type_low ||
32151a3571b5SPaul Greenwalt 	    phy_caps->phy_type_high != phy_cfg->phy_type_high ||
32161a3571b5SPaul Greenwalt 	    ((phy_caps->caps & caps_mask) != (phy_cfg->caps & cfg_mask)) ||
3217bdeff971SLev Faerman 	    phy_caps->low_power_ctrl_an != phy_cfg->low_power_ctrl_an ||
32181a3571b5SPaul Greenwalt 	    phy_caps->eee_cap != phy_cfg->eee_cap ||
32191a3571b5SPaul Greenwalt 	    phy_caps->eeer_value != phy_cfg->eeer_value ||
32201a3571b5SPaul Greenwalt 	    phy_caps->link_fec_options != phy_cfg->link_fec_opt)
32211a3571b5SPaul Greenwalt 		return false;
32221a3571b5SPaul Greenwalt 
32231a3571b5SPaul Greenwalt 	return true;
32241a3571b5SPaul Greenwalt }
32251a3571b5SPaul Greenwalt 
32261a3571b5SPaul Greenwalt /**
3227f776b3acSPaul Greenwalt  * ice_copy_phy_caps_to_cfg - Copy PHY ability data to configuration data
3228ea78ce4dSPaul Greenwalt  * @pi: port information structure
3229f776b3acSPaul Greenwalt  * @caps: PHY ability structure to copy date from
3230f776b3acSPaul Greenwalt  * @cfg: PHY configuration structure to copy data to
3231f776b3acSPaul Greenwalt  *
3232f776b3acSPaul Greenwalt  * Helper function to copy AQC PHY get ability data to PHY set configuration
3233f776b3acSPaul Greenwalt  * data structure
3234f776b3acSPaul Greenwalt  */
3235f776b3acSPaul Greenwalt void
3236ea78ce4dSPaul Greenwalt ice_copy_phy_caps_to_cfg(struct ice_port_info *pi,
3237ea78ce4dSPaul Greenwalt 			 struct ice_aqc_get_phy_caps_data *caps,
3238f776b3acSPaul Greenwalt 			 struct ice_aqc_set_phy_cfg_data *cfg)
3239f776b3acSPaul Greenwalt {
3240ea78ce4dSPaul Greenwalt 	if (!pi || !caps || !cfg)
3241f776b3acSPaul Greenwalt 		return;
3242f776b3acSPaul Greenwalt 
32432ffb6085SPaul Greenwalt 	memset(cfg, 0, sizeof(*cfg));
3244f776b3acSPaul Greenwalt 	cfg->phy_type_low = caps->phy_type_low;
3245f776b3acSPaul Greenwalt 	cfg->phy_type_high = caps->phy_type_high;
3246f776b3acSPaul Greenwalt 	cfg->caps = caps->caps;
3247bdeff971SLev Faerman 	cfg->low_power_ctrl_an = caps->low_power_ctrl_an;
3248f776b3acSPaul Greenwalt 	cfg->eee_cap = caps->eee_cap;
3249f776b3acSPaul Greenwalt 	cfg->eeer_value = caps->eeer_value;
3250f776b3acSPaul Greenwalt 	cfg->link_fec_opt = caps->link_fec_options;
3251ea78ce4dSPaul Greenwalt 	cfg->module_compliance_enforcement =
3252ea78ce4dSPaul Greenwalt 		caps->module_compliance_enforcement;
3253f776b3acSPaul Greenwalt }
3254f776b3acSPaul Greenwalt 
3255f776b3acSPaul Greenwalt /**
3256f776b3acSPaul Greenwalt  * ice_cfg_phy_fec - Configure PHY FEC data based on FEC mode
325761cf42e7SPaul Greenwalt  * @pi: port information structure
3258f776b3acSPaul Greenwalt  * @cfg: PHY configuration data to set FEC mode
3259f776b3acSPaul Greenwalt  * @fec: FEC mode to configure
3260f776b3acSPaul Greenwalt  */
3261*5e24d598STony Nguyen int
326261cf42e7SPaul Greenwalt ice_cfg_phy_fec(struct ice_port_info *pi, struct ice_aqc_set_phy_cfg_data *cfg,
326361cf42e7SPaul Greenwalt 		enum ice_fec_mode fec)
3264f776b3acSPaul Greenwalt {
326561cf42e7SPaul Greenwalt 	struct ice_aqc_get_phy_caps_data *pcaps;
3266*5e24d598STony Nguyen 	int status;
32670a02944fSAnirudh Venkataramanan 	struct ice_hw *hw;
326861cf42e7SPaul Greenwalt 
326961cf42e7SPaul Greenwalt 	if (!pi || !cfg)
327061cf42e7SPaul Greenwalt 		return ICE_ERR_BAD_PTR;
327161cf42e7SPaul Greenwalt 
32720a02944fSAnirudh Venkataramanan 	hw = pi->hw;
32730a02944fSAnirudh Venkataramanan 
327461cf42e7SPaul Greenwalt 	pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL);
327561cf42e7SPaul Greenwalt 	if (!pcaps)
327661cf42e7SPaul Greenwalt 		return ICE_ERR_NO_MEMORY;
327761cf42e7SPaul Greenwalt 
32780a02944fSAnirudh Venkataramanan 	status = ice_aq_get_phy_caps(pi, false,
32790a02944fSAnirudh Venkataramanan 				     (ice_fw_supports_report_dflt_cfg(hw) ?
32800a02944fSAnirudh Venkataramanan 				      ICE_AQC_REPORT_DFLT_CFG :
32810a02944fSAnirudh Venkataramanan 				      ICE_AQC_REPORT_TOPO_CAP_MEDIA), pcaps, NULL);
328261cf42e7SPaul Greenwalt 	if (status)
328361cf42e7SPaul Greenwalt 		goto out;
328461cf42e7SPaul Greenwalt 
328561cf42e7SPaul Greenwalt 	cfg->caps |= pcaps->caps & ICE_AQC_PHY_EN_AUTO_FEC;
328661cf42e7SPaul Greenwalt 	cfg->link_fec_opt = pcaps->link_fec_options;
328761cf42e7SPaul Greenwalt 
3288f776b3acSPaul Greenwalt 	switch (fec) {
3289f776b3acSPaul Greenwalt 	case ICE_FEC_BASER:
32903747f031SChinh T Cao 		/* Clear RS bits, and AND BASE-R ability
3291f776b3acSPaul Greenwalt 		 * bits and OR request bits.
3292f776b3acSPaul Greenwalt 		 */
3293f776b3acSPaul Greenwalt 		cfg->link_fec_opt &= ICE_AQC_PHY_FEC_10G_KR_40G_KR4_EN |
3294f776b3acSPaul Greenwalt 			ICE_AQC_PHY_FEC_25G_KR_CLAUSE74_EN;
3295f776b3acSPaul Greenwalt 		cfg->link_fec_opt |= ICE_AQC_PHY_FEC_10G_KR_40G_KR4_REQ |
3296f776b3acSPaul Greenwalt 			ICE_AQC_PHY_FEC_25G_KR_REQ;
3297f776b3acSPaul Greenwalt 		break;
3298f776b3acSPaul Greenwalt 	case ICE_FEC_RS:
32993747f031SChinh T Cao 		/* Clear BASE-R bits, and AND RS ability
3300f776b3acSPaul Greenwalt 		 * bits and OR request bits.
3301f776b3acSPaul Greenwalt 		 */
3302f776b3acSPaul Greenwalt 		cfg->link_fec_opt &= ICE_AQC_PHY_FEC_25G_RS_CLAUSE91_EN;
3303f776b3acSPaul Greenwalt 		cfg->link_fec_opt |= ICE_AQC_PHY_FEC_25G_RS_528_REQ |
3304f776b3acSPaul Greenwalt 			ICE_AQC_PHY_FEC_25G_RS_544_REQ;
3305f776b3acSPaul Greenwalt 		break;
3306f776b3acSPaul Greenwalt 	case ICE_FEC_NONE:
33073747f031SChinh T Cao 		/* Clear all FEC option bits. */
3308f776b3acSPaul Greenwalt 		cfg->link_fec_opt &= ~ICE_AQC_PHY_FEC_MASK;
3309f776b3acSPaul Greenwalt 		break;
3310f776b3acSPaul Greenwalt 	case ICE_FEC_AUTO:
3311f776b3acSPaul Greenwalt 		/* AND auto FEC bit, and all caps bits. */
3312f776b3acSPaul Greenwalt 		cfg->caps &= ICE_AQC_PHY_CAPS_MASK;
331361cf42e7SPaul Greenwalt 		cfg->link_fec_opt |= pcaps->link_fec_options;
331461cf42e7SPaul Greenwalt 		break;
331561cf42e7SPaul Greenwalt 	default:
331661cf42e7SPaul Greenwalt 		status = ICE_ERR_PARAM;
3317f776b3acSPaul Greenwalt 		break;
3318f776b3acSPaul Greenwalt 	}
331961cf42e7SPaul Greenwalt 
332075751c80SJeb Cramer 	if (fec == ICE_FEC_AUTO && ice_fw_supports_link_override(hw) &&
332175751c80SJeb Cramer 	    !ice_fw_supports_report_dflt_cfg(hw)) {
3322ea78ce4dSPaul Greenwalt 		struct ice_link_default_override_tlv tlv;
3323ea78ce4dSPaul Greenwalt 
3324ea78ce4dSPaul Greenwalt 		if (ice_get_link_default_override(&tlv, pi))
3325ea78ce4dSPaul Greenwalt 			goto out;
3326ea78ce4dSPaul Greenwalt 
3327ea78ce4dSPaul Greenwalt 		if (!(tlv.options & ICE_LINK_OVERRIDE_STRICT_MODE) &&
3328ea78ce4dSPaul Greenwalt 		    (tlv.options & ICE_LINK_OVERRIDE_EN))
3329ea78ce4dSPaul Greenwalt 			cfg->link_fec_opt = tlv.fec_options;
3330ea78ce4dSPaul Greenwalt 	}
3331ea78ce4dSPaul Greenwalt 
333261cf42e7SPaul Greenwalt out:
333361cf42e7SPaul Greenwalt 	kfree(pcaps);
333461cf42e7SPaul Greenwalt 
333561cf42e7SPaul Greenwalt 	return status;
3336f776b3acSPaul Greenwalt }
3337f776b3acSPaul Greenwalt 
3338f776b3acSPaul Greenwalt /**
33390b28b702SAnirudh Venkataramanan  * ice_get_link_status - get status of the HW network link
33400b28b702SAnirudh Venkataramanan  * @pi: port information structure
33410b28b702SAnirudh Venkataramanan  * @link_up: pointer to bool (true/false = linkup/linkdown)
33420b28b702SAnirudh Venkataramanan  *
33430b28b702SAnirudh Venkataramanan  * Variable link_up is true if link is up, false if link is down.
33440b28b702SAnirudh Venkataramanan  * The variable link_up is invalid if status is non zero. As a
33450b28b702SAnirudh Venkataramanan  * result of this call, link status reporting becomes enabled
33460b28b702SAnirudh Venkataramanan  */
3347*5e24d598STony Nguyen int ice_get_link_status(struct ice_port_info *pi, bool *link_up)
33480b28b702SAnirudh Venkataramanan {
33490b28b702SAnirudh Venkataramanan 	struct ice_phy_info *phy_info;
3350*5e24d598STony Nguyen 	int status = 0;
33510b28b702SAnirudh Venkataramanan 
3352c7f2c42bSAnirudh Venkataramanan 	if (!pi || !link_up)
33530b28b702SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
33540b28b702SAnirudh Venkataramanan 
33550b28b702SAnirudh Venkataramanan 	phy_info = &pi->phy;
33560b28b702SAnirudh Venkataramanan 
33570b28b702SAnirudh Venkataramanan 	if (phy_info->get_link_info) {
33580b28b702SAnirudh Venkataramanan 		status = ice_update_link_info(pi);
33590b28b702SAnirudh Venkataramanan 
33600b28b702SAnirudh Venkataramanan 		if (status)
33619228d8b2SJacob Keller 			ice_debug(pi->hw, ICE_DBG_LINK, "get link status error, status = %d\n",
33620b28b702SAnirudh Venkataramanan 				  status);
33630b28b702SAnirudh Venkataramanan 	}
33640b28b702SAnirudh Venkataramanan 
33650b28b702SAnirudh Venkataramanan 	*link_up = phy_info->link_info.link_info & ICE_AQ_LINK_UP;
33660b28b702SAnirudh Venkataramanan 
33670b28b702SAnirudh Venkataramanan 	return status;
33680b28b702SAnirudh Venkataramanan }
33690b28b702SAnirudh Venkataramanan 
33700b28b702SAnirudh Venkataramanan /**
3371fcea6f3dSAnirudh Venkataramanan  * ice_aq_set_link_restart_an
3372fcea6f3dSAnirudh Venkataramanan  * @pi: pointer to the port information structure
3373fcea6f3dSAnirudh Venkataramanan  * @ena_link: if true: enable link, if false: disable link
3374fcea6f3dSAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
3375fcea6f3dSAnirudh Venkataramanan  *
3376fcea6f3dSAnirudh Venkataramanan  * Sets up the link and restarts the Auto-Negotiation over the link.
3377fcea6f3dSAnirudh Venkataramanan  */
3378*5e24d598STony Nguyen int
3379fcea6f3dSAnirudh Venkataramanan ice_aq_set_link_restart_an(struct ice_port_info *pi, bool ena_link,
3380fcea6f3dSAnirudh Venkataramanan 			   struct ice_sq_cd *cd)
3381fcea6f3dSAnirudh Venkataramanan {
3382fcea6f3dSAnirudh Venkataramanan 	struct ice_aqc_restart_an *cmd;
3383fcea6f3dSAnirudh Venkataramanan 	struct ice_aq_desc desc;
3384fcea6f3dSAnirudh Venkataramanan 
3385fcea6f3dSAnirudh Venkataramanan 	cmd = &desc.params.restart_an;
3386fcea6f3dSAnirudh Venkataramanan 
3387fcea6f3dSAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_restart_an);
3388fcea6f3dSAnirudh Venkataramanan 
3389fcea6f3dSAnirudh Venkataramanan 	cmd->cmd_flags = ICE_AQC_RESTART_AN_LINK_RESTART;
3390fcea6f3dSAnirudh Venkataramanan 	cmd->lport_num = pi->lport;
3391fcea6f3dSAnirudh Venkataramanan 	if (ena_link)
3392fcea6f3dSAnirudh Venkataramanan 		cmd->cmd_flags |= ICE_AQC_RESTART_AN_LINK_ENABLE;
3393fcea6f3dSAnirudh Venkataramanan 	else
3394fcea6f3dSAnirudh Venkataramanan 		cmd->cmd_flags &= ~ICE_AQC_RESTART_AN_LINK_ENABLE;
3395fcea6f3dSAnirudh Venkataramanan 
3396fcea6f3dSAnirudh Venkataramanan 	return ice_aq_send_cmd(pi->hw, &desc, NULL, 0, cd);
3397fcea6f3dSAnirudh Venkataramanan }
3398fcea6f3dSAnirudh Venkataramanan 
3399fcea6f3dSAnirudh Venkataramanan /**
3400250c3b3eSBrett Creeley  * ice_aq_set_event_mask
3401250c3b3eSBrett Creeley  * @hw: pointer to the HW struct
3402250c3b3eSBrett Creeley  * @port_num: port number of the physical function
3403250c3b3eSBrett Creeley  * @mask: event mask to be set
3404250c3b3eSBrett Creeley  * @cd: pointer to command details structure or NULL
3405250c3b3eSBrett Creeley  *
3406250c3b3eSBrett Creeley  * Set event mask (0x0613)
3407250c3b3eSBrett Creeley  */
3408*5e24d598STony Nguyen int
3409250c3b3eSBrett Creeley ice_aq_set_event_mask(struct ice_hw *hw, u8 port_num, u16 mask,
3410250c3b3eSBrett Creeley 		      struct ice_sq_cd *cd)
3411250c3b3eSBrett Creeley {
3412250c3b3eSBrett Creeley 	struct ice_aqc_set_event_mask *cmd;
3413250c3b3eSBrett Creeley 	struct ice_aq_desc desc;
3414250c3b3eSBrett Creeley 
3415250c3b3eSBrett Creeley 	cmd = &desc.params.set_event_mask;
3416250c3b3eSBrett Creeley 
3417250c3b3eSBrett Creeley 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_event_mask);
3418250c3b3eSBrett Creeley 
3419250c3b3eSBrett Creeley 	cmd->lport_num = port_num;
3420250c3b3eSBrett Creeley 
3421250c3b3eSBrett Creeley 	cmd->event_mask = cpu_to_le16(mask);
3422250c3b3eSBrett Creeley 	return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
3423250c3b3eSBrett Creeley }
3424250c3b3eSBrett Creeley 
3425250c3b3eSBrett Creeley /**
34260e674aebSAnirudh Venkataramanan  * ice_aq_set_mac_loopback
34270e674aebSAnirudh Venkataramanan  * @hw: pointer to the HW struct
34280e674aebSAnirudh Venkataramanan  * @ena_lpbk: Enable or Disable loopback
34290e674aebSAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
34300e674aebSAnirudh Venkataramanan  *
34310e674aebSAnirudh Venkataramanan  * Enable/disable loopback on a given port
34320e674aebSAnirudh Venkataramanan  */
3433*5e24d598STony Nguyen int
34340e674aebSAnirudh Venkataramanan ice_aq_set_mac_loopback(struct ice_hw *hw, bool ena_lpbk, struct ice_sq_cd *cd)
34350e674aebSAnirudh Venkataramanan {
34360e674aebSAnirudh Venkataramanan 	struct ice_aqc_set_mac_lb *cmd;
34370e674aebSAnirudh Venkataramanan 	struct ice_aq_desc desc;
34380e674aebSAnirudh Venkataramanan 
34390e674aebSAnirudh Venkataramanan 	cmd = &desc.params.set_mac_lb;
34400e674aebSAnirudh Venkataramanan 
34410e674aebSAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_mac_lb);
34420e674aebSAnirudh Venkataramanan 	if (ena_lpbk)
34430e674aebSAnirudh Venkataramanan 		cmd->lb_mode = ICE_AQ_MAC_LB_EN;
34440e674aebSAnirudh Venkataramanan 
34450e674aebSAnirudh Venkataramanan 	return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
34460e674aebSAnirudh Venkataramanan }
34470e674aebSAnirudh Venkataramanan 
34480e674aebSAnirudh Venkataramanan /**
34498e151d50SAnirudh Venkataramanan  * ice_aq_set_port_id_led
34508e151d50SAnirudh Venkataramanan  * @pi: pointer to the port information
34518e151d50SAnirudh Venkataramanan  * @is_orig_mode: is this LED set to original mode (by the net-list)
34528e151d50SAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
34538e151d50SAnirudh Venkataramanan  *
34548e151d50SAnirudh Venkataramanan  * Set LED value for the given port (0x06e9)
34558e151d50SAnirudh Venkataramanan  */
3456*5e24d598STony Nguyen int
34578e151d50SAnirudh Venkataramanan ice_aq_set_port_id_led(struct ice_port_info *pi, bool is_orig_mode,
34588e151d50SAnirudh Venkataramanan 		       struct ice_sq_cd *cd)
34598e151d50SAnirudh Venkataramanan {
34608e151d50SAnirudh Venkataramanan 	struct ice_aqc_set_port_id_led *cmd;
34618e151d50SAnirudh Venkataramanan 	struct ice_hw *hw = pi->hw;
34628e151d50SAnirudh Venkataramanan 	struct ice_aq_desc desc;
34638e151d50SAnirudh Venkataramanan 
34648e151d50SAnirudh Venkataramanan 	cmd = &desc.params.set_port_id_led;
34658e151d50SAnirudh Venkataramanan 
34668e151d50SAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_port_id_led);
34678e151d50SAnirudh Venkataramanan 
34688e151d50SAnirudh Venkataramanan 	if (is_orig_mode)
34698e151d50SAnirudh Venkataramanan 		cmd->ident_mode = ICE_AQC_PORT_IDENT_LED_ORIG;
34708e151d50SAnirudh Venkataramanan 	else
34718e151d50SAnirudh Venkataramanan 		cmd->ident_mode = ICE_AQC_PORT_IDENT_LED_BLINK;
34728e151d50SAnirudh Venkataramanan 
34738e151d50SAnirudh Venkataramanan 	return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
34748e151d50SAnirudh Venkataramanan }
34758e151d50SAnirudh Venkataramanan 
34768e151d50SAnirudh Venkataramanan /**
3477a012dca9SScott W Taylor  * ice_aq_sff_eeprom
3478a012dca9SScott W Taylor  * @hw: pointer to the HW struct
3479a012dca9SScott W Taylor  * @lport: bits [7:0] = logical port, bit [8] = logical port valid
3480a012dca9SScott W Taylor  * @bus_addr: I2C bus address of the eeprom (typically 0xA0, 0=topo default)
3481a012dca9SScott W Taylor  * @mem_addr: I2C offset. lower 8 bits for address, 8 upper bits zero padding.
3482a012dca9SScott W Taylor  * @page: QSFP page
3483a012dca9SScott W Taylor  * @set_page: set or ignore the page
3484a012dca9SScott W Taylor  * @data: pointer to data buffer to be read/written to the I2C device.
3485a012dca9SScott W Taylor  * @length: 1-16 for read, 1 for write.
3486a012dca9SScott W Taylor  * @write: 0 read, 1 for write.
3487a012dca9SScott W Taylor  * @cd: pointer to command details structure or NULL
3488a012dca9SScott W Taylor  *
3489a012dca9SScott W Taylor  * Read/Write SFF EEPROM (0x06EE)
3490a012dca9SScott W Taylor  */
3491*5e24d598STony Nguyen int
3492a012dca9SScott W Taylor ice_aq_sff_eeprom(struct ice_hw *hw, u16 lport, u8 bus_addr,
3493a012dca9SScott W Taylor 		  u16 mem_addr, u8 page, u8 set_page, u8 *data, u8 length,
3494a012dca9SScott W Taylor 		  bool write, struct ice_sq_cd *cd)
3495a012dca9SScott W Taylor {
3496a012dca9SScott W Taylor 	struct ice_aqc_sff_eeprom *cmd;
3497a012dca9SScott W Taylor 	struct ice_aq_desc desc;
3498*5e24d598STony Nguyen 	int status;
3499a012dca9SScott W Taylor 
3500a012dca9SScott W Taylor 	if (!data || (mem_addr & 0xff00))
3501a012dca9SScott W Taylor 		return ICE_ERR_PARAM;
3502a012dca9SScott W Taylor 
3503a012dca9SScott W Taylor 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_sff_eeprom);
3504a012dca9SScott W Taylor 	cmd = &desc.params.read_write_sff_param;
3505800c1443SBruce Allan 	desc.flags = cpu_to_le16(ICE_AQ_FLAG_RD);
3506a012dca9SScott W Taylor 	cmd->lport_num = (u8)(lport & 0xff);
3507a012dca9SScott W Taylor 	cmd->lport_num_valid = (u8)((lport >> 8) & 0x01);
3508a012dca9SScott W Taylor 	cmd->i2c_bus_addr = cpu_to_le16(((bus_addr >> 1) &
3509a012dca9SScott W Taylor 					 ICE_AQC_SFF_I2CBUS_7BIT_M) |
3510a012dca9SScott W Taylor 					((set_page <<
3511a012dca9SScott W Taylor 					  ICE_AQC_SFF_SET_EEPROM_PAGE_S) &
3512a012dca9SScott W Taylor 					 ICE_AQC_SFF_SET_EEPROM_PAGE_M));
3513a012dca9SScott W Taylor 	cmd->i2c_mem_addr = cpu_to_le16(mem_addr & 0xff);
3514a012dca9SScott W Taylor 	cmd->eeprom_page = cpu_to_le16((u16)page << ICE_AQC_SFF_EEPROM_PAGE_S);
3515a012dca9SScott W Taylor 	if (write)
3516a012dca9SScott W Taylor 		cmd->i2c_bus_addr |= cpu_to_le16(ICE_AQC_SFF_IS_WRITE);
3517a012dca9SScott W Taylor 
3518a012dca9SScott W Taylor 	status = ice_aq_send_cmd(hw, &desc, data, length, cd);
3519a012dca9SScott W Taylor 	return status;
3520a012dca9SScott W Taylor }
3521a012dca9SScott W Taylor 
3522a012dca9SScott W Taylor /**
3523d76a60baSAnirudh Venkataramanan  * __ice_aq_get_set_rss_lut
3524d76a60baSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
3525e3c53928SBrett Creeley  * @params: RSS LUT parameters
3526d76a60baSAnirudh Venkataramanan  * @set: set true to set the table, false to get the table
3527d76a60baSAnirudh Venkataramanan  *
3528d76a60baSAnirudh Venkataramanan  * Internal function to get (0x0B05) or set (0x0B03) RSS look up table
3529d76a60baSAnirudh Venkataramanan  */
3530*5e24d598STony Nguyen static int
3531e3c53928SBrett Creeley __ice_aq_get_set_rss_lut(struct ice_hw *hw, struct ice_aq_get_set_rss_lut_params *params, bool set)
3532d76a60baSAnirudh Venkataramanan {
3533e3c53928SBrett Creeley 	u16 flags = 0, vsi_id, lut_type, lut_size, glob_lut_idx, vsi_handle;
3534d76a60baSAnirudh Venkataramanan 	struct ice_aqc_get_set_rss_lut *cmd_resp;
3535d76a60baSAnirudh Venkataramanan 	struct ice_aq_desc desc;
3536*5e24d598STony Nguyen 	int status;
3537e3c53928SBrett Creeley 	u8 *lut;
3538e3c53928SBrett Creeley 
3539e3c53928SBrett Creeley 	if (!params)
3540e3c53928SBrett Creeley 		return ICE_ERR_PARAM;
3541e3c53928SBrett Creeley 
3542e3c53928SBrett Creeley 	vsi_handle = params->vsi_handle;
3543e3c53928SBrett Creeley 	lut = params->lut;
3544e3c53928SBrett Creeley 
3545e3c53928SBrett Creeley 	if (!ice_is_vsi_valid(hw, vsi_handle) || !lut)
3546e3c53928SBrett Creeley 		return ICE_ERR_PARAM;
3547e3c53928SBrett Creeley 
3548e3c53928SBrett Creeley 	lut_size = params->lut_size;
3549e3c53928SBrett Creeley 	lut_type = params->lut_type;
3550e3c53928SBrett Creeley 	glob_lut_idx = params->global_lut_id;
3551e3c53928SBrett Creeley 	vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
3552d76a60baSAnirudh Venkataramanan 
3553d76a60baSAnirudh Venkataramanan 	cmd_resp = &desc.params.get_set_rss_lut;
3554d76a60baSAnirudh Venkataramanan 
3555d76a60baSAnirudh Venkataramanan 	if (set) {
3556d76a60baSAnirudh Venkataramanan 		ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_rss_lut);
3557d76a60baSAnirudh Venkataramanan 		desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
3558d76a60baSAnirudh Venkataramanan 	} else {
3559d76a60baSAnirudh Venkataramanan 		ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_rss_lut);
3560d76a60baSAnirudh Venkataramanan 	}
3561d76a60baSAnirudh Venkataramanan 
3562d76a60baSAnirudh Venkataramanan 	cmd_resp->vsi_id = cpu_to_le16(((vsi_id <<
3563d76a60baSAnirudh Venkataramanan 					 ICE_AQC_GSET_RSS_LUT_VSI_ID_S) &
3564d76a60baSAnirudh Venkataramanan 					ICE_AQC_GSET_RSS_LUT_VSI_ID_M) |
3565d76a60baSAnirudh Venkataramanan 				       ICE_AQC_GSET_RSS_LUT_VSI_VALID);
3566d76a60baSAnirudh Venkataramanan 
3567d76a60baSAnirudh Venkataramanan 	switch (lut_type) {
3568d76a60baSAnirudh Venkataramanan 	case ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_VSI:
3569d76a60baSAnirudh Venkataramanan 	case ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF:
3570d76a60baSAnirudh Venkataramanan 	case ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_GLOBAL:
3571d76a60baSAnirudh Venkataramanan 		flags |= ((lut_type << ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_S) &
3572d76a60baSAnirudh Venkataramanan 			  ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_M);
3573d76a60baSAnirudh Venkataramanan 		break;
3574d76a60baSAnirudh Venkataramanan 	default:
3575d76a60baSAnirudh Venkataramanan 		status = ICE_ERR_PARAM;
3576d76a60baSAnirudh Venkataramanan 		goto ice_aq_get_set_rss_lut_exit;
3577d76a60baSAnirudh Venkataramanan 	}
3578d76a60baSAnirudh Venkataramanan 
3579d76a60baSAnirudh Venkataramanan 	if (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_GLOBAL) {
3580d76a60baSAnirudh Venkataramanan 		flags |= ((glob_lut_idx << ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_S) &
3581d76a60baSAnirudh Venkataramanan 			  ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_M);
3582d76a60baSAnirudh Venkataramanan 
3583d76a60baSAnirudh Venkataramanan 		if (!set)
3584d76a60baSAnirudh Venkataramanan 			goto ice_aq_get_set_rss_lut_send;
3585d76a60baSAnirudh Venkataramanan 	} else if (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF) {
3586d76a60baSAnirudh Venkataramanan 		if (!set)
3587d76a60baSAnirudh Venkataramanan 			goto ice_aq_get_set_rss_lut_send;
3588d76a60baSAnirudh Venkataramanan 	} else {
3589d76a60baSAnirudh Venkataramanan 		goto ice_aq_get_set_rss_lut_send;
3590d76a60baSAnirudh Venkataramanan 	}
3591d76a60baSAnirudh Venkataramanan 
3592d76a60baSAnirudh Venkataramanan 	/* LUT size is only valid for Global and PF table types */
35934381147dSAnirudh Venkataramanan 	switch (lut_size) {
35944381147dSAnirudh Venkataramanan 	case ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_128:
35954381147dSAnirudh Venkataramanan 		break;
35964381147dSAnirudh Venkataramanan 	case ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512:
3597d76a60baSAnirudh Venkataramanan 		flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512_FLAG <<
3598d76a60baSAnirudh Venkataramanan 			  ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) &
3599d76a60baSAnirudh Venkataramanan 			 ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
36004381147dSAnirudh Venkataramanan 		break;
36014381147dSAnirudh Venkataramanan 	case ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K:
36024381147dSAnirudh Venkataramanan 		if (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF) {
3603d76a60baSAnirudh Venkataramanan 			flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K_FLAG <<
3604d76a60baSAnirudh Venkataramanan 				  ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) &
3605d76a60baSAnirudh Venkataramanan 				 ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
36064381147dSAnirudh Venkataramanan 			break;
36074381147dSAnirudh Venkataramanan 		}
36084e83fc93SBruce Allan 		fallthrough;
36094381147dSAnirudh Venkataramanan 	default:
3610d76a60baSAnirudh Venkataramanan 		status = ICE_ERR_PARAM;
3611d76a60baSAnirudh Venkataramanan 		goto ice_aq_get_set_rss_lut_exit;
3612d76a60baSAnirudh Venkataramanan 	}
3613d76a60baSAnirudh Venkataramanan 
3614d76a60baSAnirudh Venkataramanan ice_aq_get_set_rss_lut_send:
3615d76a60baSAnirudh Venkataramanan 	cmd_resp->flags = cpu_to_le16(flags);
3616d76a60baSAnirudh Venkataramanan 	status = ice_aq_send_cmd(hw, &desc, lut, lut_size, NULL);
3617d76a60baSAnirudh Venkataramanan 
3618d76a60baSAnirudh Venkataramanan ice_aq_get_set_rss_lut_exit:
3619d76a60baSAnirudh Venkataramanan 	return status;
3620d76a60baSAnirudh Venkataramanan }
3621d76a60baSAnirudh Venkataramanan 
3622d76a60baSAnirudh Venkataramanan /**
3623d76a60baSAnirudh Venkataramanan  * ice_aq_get_rss_lut
3624d76a60baSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
3625e3c53928SBrett Creeley  * @get_params: RSS LUT parameters used to specify which RSS LUT to get
3626d76a60baSAnirudh Venkataramanan  *
3627d76a60baSAnirudh Venkataramanan  * get the RSS lookup table, PF or VSI type
3628d76a60baSAnirudh Venkataramanan  */
3629*5e24d598STony Nguyen int
3630e3c53928SBrett Creeley ice_aq_get_rss_lut(struct ice_hw *hw, struct ice_aq_get_set_rss_lut_params *get_params)
3631d76a60baSAnirudh Venkataramanan {
3632e3c53928SBrett Creeley 	return __ice_aq_get_set_rss_lut(hw, get_params, false);
3633d76a60baSAnirudh Venkataramanan }
3634d76a60baSAnirudh Venkataramanan 
3635d76a60baSAnirudh Venkataramanan /**
3636d76a60baSAnirudh Venkataramanan  * ice_aq_set_rss_lut
3637d76a60baSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
3638e3c53928SBrett Creeley  * @set_params: RSS LUT parameters used to specify how to set the RSS LUT
3639d76a60baSAnirudh Venkataramanan  *
3640d76a60baSAnirudh Venkataramanan  * set the RSS lookup table, PF or VSI type
3641d76a60baSAnirudh Venkataramanan  */
3642*5e24d598STony Nguyen int
3643e3c53928SBrett Creeley ice_aq_set_rss_lut(struct ice_hw *hw, struct ice_aq_get_set_rss_lut_params *set_params)
3644d76a60baSAnirudh Venkataramanan {
3645e3c53928SBrett Creeley 	return __ice_aq_get_set_rss_lut(hw, set_params, true);
3646d76a60baSAnirudh Venkataramanan }
3647d76a60baSAnirudh Venkataramanan 
3648d76a60baSAnirudh Venkataramanan /**
3649d76a60baSAnirudh Venkataramanan  * __ice_aq_get_set_rss_key
3650f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
3651d76a60baSAnirudh Venkataramanan  * @vsi_id: VSI FW index
3652d76a60baSAnirudh Venkataramanan  * @key: pointer to key info struct
3653d76a60baSAnirudh Venkataramanan  * @set: set true to set the key, false to get the key
3654d76a60baSAnirudh Venkataramanan  *
3655d76a60baSAnirudh Venkataramanan  * get (0x0B04) or set (0x0B02) the RSS key per VSI
3656d76a60baSAnirudh Venkataramanan  */
3657*5e24d598STony Nguyen static int __ice_aq_get_set_rss_key(struct ice_hw *hw, u16 vsi_id,
3658d76a60baSAnirudh Venkataramanan 				    struct ice_aqc_get_set_rss_keys *key,
3659d76a60baSAnirudh Venkataramanan 				    bool set)
3660d76a60baSAnirudh Venkataramanan {
3661d76a60baSAnirudh Venkataramanan 	struct ice_aqc_get_set_rss_key *cmd_resp;
3662d76a60baSAnirudh Venkataramanan 	u16 key_size = sizeof(*key);
3663d76a60baSAnirudh Venkataramanan 	struct ice_aq_desc desc;
3664d76a60baSAnirudh Venkataramanan 
3665d76a60baSAnirudh Venkataramanan 	cmd_resp = &desc.params.get_set_rss_key;
3666d76a60baSAnirudh Venkataramanan 
3667d76a60baSAnirudh Venkataramanan 	if (set) {
3668d76a60baSAnirudh Venkataramanan 		ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_rss_key);
3669d76a60baSAnirudh Venkataramanan 		desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
3670d76a60baSAnirudh Venkataramanan 	} else {
3671d76a60baSAnirudh Venkataramanan 		ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_rss_key);
3672d76a60baSAnirudh Venkataramanan 	}
3673d76a60baSAnirudh Venkataramanan 
3674d76a60baSAnirudh Venkataramanan 	cmd_resp->vsi_id = cpu_to_le16(((vsi_id <<
3675d76a60baSAnirudh Venkataramanan 					 ICE_AQC_GSET_RSS_KEY_VSI_ID_S) &
3676d76a60baSAnirudh Venkataramanan 					ICE_AQC_GSET_RSS_KEY_VSI_ID_M) |
3677d76a60baSAnirudh Venkataramanan 				       ICE_AQC_GSET_RSS_KEY_VSI_VALID);
3678d76a60baSAnirudh Venkataramanan 
3679d76a60baSAnirudh Venkataramanan 	return ice_aq_send_cmd(hw, &desc, key, key_size, NULL);
3680d76a60baSAnirudh Venkataramanan }
3681d76a60baSAnirudh Venkataramanan 
3682d76a60baSAnirudh Venkataramanan /**
3683d76a60baSAnirudh Venkataramanan  * ice_aq_get_rss_key
3684f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
36854fb33f31SAnirudh Venkataramanan  * @vsi_handle: software VSI handle
3686d76a60baSAnirudh Venkataramanan  * @key: pointer to key info struct
3687d76a60baSAnirudh Venkataramanan  *
3688d76a60baSAnirudh Venkataramanan  * get the RSS key per VSI
3689d76a60baSAnirudh Venkataramanan  */
3690*5e24d598STony Nguyen int
36914fb33f31SAnirudh Venkataramanan ice_aq_get_rss_key(struct ice_hw *hw, u16 vsi_handle,
3692d76a60baSAnirudh Venkataramanan 		   struct ice_aqc_get_set_rss_keys *key)
3693d76a60baSAnirudh Venkataramanan {
36944fb33f31SAnirudh Venkataramanan 	if (!ice_is_vsi_valid(hw, vsi_handle) || !key)
36954fb33f31SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
36964fb33f31SAnirudh Venkataramanan 
36974fb33f31SAnirudh Venkataramanan 	return __ice_aq_get_set_rss_key(hw, ice_get_hw_vsi_num(hw, vsi_handle),
36984fb33f31SAnirudh Venkataramanan 					key, false);
3699d76a60baSAnirudh Venkataramanan }
3700d76a60baSAnirudh Venkataramanan 
3701d76a60baSAnirudh Venkataramanan /**
3702d76a60baSAnirudh Venkataramanan  * ice_aq_set_rss_key
3703f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
37044fb33f31SAnirudh Venkataramanan  * @vsi_handle: software VSI handle
3705d76a60baSAnirudh Venkataramanan  * @keys: pointer to key info struct
3706d76a60baSAnirudh Venkataramanan  *
3707d76a60baSAnirudh Venkataramanan  * set the RSS key per VSI
3708d76a60baSAnirudh Venkataramanan  */
3709*5e24d598STony Nguyen int
37104fb33f31SAnirudh Venkataramanan ice_aq_set_rss_key(struct ice_hw *hw, u16 vsi_handle,
3711d76a60baSAnirudh Venkataramanan 		   struct ice_aqc_get_set_rss_keys *keys)
3712d76a60baSAnirudh Venkataramanan {
37134fb33f31SAnirudh Venkataramanan 	if (!ice_is_vsi_valid(hw, vsi_handle) || !keys)
37144fb33f31SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
37154fb33f31SAnirudh Venkataramanan 
37164fb33f31SAnirudh Venkataramanan 	return __ice_aq_get_set_rss_key(hw, ice_get_hw_vsi_num(hw, vsi_handle),
37174fb33f31SAnirudh Venkataramanan 					keys, true);
3718d76a60baSAnirudh Venkataramanan }
3719d76a60baSAnirudh Venkataramanan 
3720d76a60baSAnirudh Venkataramanan /**
3721cdedef59SAnirudh Venkataramanan  * ice_aq_add_lan_txq
3722cdedef59SAnirudh Venkataramanan  * @hw: pointer to the hardware structure
3723cdedef59SAnirudh Venkataramanan  * @num_qgrps: Number of added queue groups
3724cdedef59SAnirudh Venkataramanan  * @qg_list: list of queue groups to be added
3725cdedef59SAnirudh Venkataramanan  * @buf_size: size of buffer for indirect command
3726cdedef59SAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
3727cdedef59SAnirudh Venkataramanan  *
3728cdedef59SAnirudh Venkataramanan  * Add Tx LAN queue (0x0C30)
3729cdedef59SAnirudh Venkataramanan  *
3730cdedef59SAnirudh Venkataramanan  * NOTE:
3731cdedef59SAnirudh Venkataramanan  * Prior to calling add Tx LAN queue:
3732cdedef59SAnirudh Venkataramanan  * Initialize the following as part of the Tx queue context:
3733cdedef59SAnirudh Venkataramanan  * Completion queue ID if the queue uses Completion queue, Quanta profile,
3734cdedef59SAnirudh Venkataramanan  * Cache profile and Packet shaper profile.
3735cdedef59SAnirudh Venkataramanan  *
3736cdedef59SAnirudh Venkataramanan  * After add Tx LAN queue AQ command is completed:
3737cdedef59SAnirudh Venkataramanan  * Interrupts should be associated with specific queues,
3738cdedef59SAnirudh Venkataramanan  * Association of Tx queue to Doorbell queue is not part of Add LAN Tx queue
3739cdedef59SAnirudh Venkataramanan  * flow.
3740cdedef59SAnirudh Venkataramanan  */
3741*5e24d598STony Nguyen static int
3742cdedef59SAnirudh Venkataramanan ice_aq_add_lan_txq(struct ice_hw *hw, u8 num_qgrps,
3743cdedef59SAnirudh Venkataramanan 		   struct ice_aqc_add_tx_qgrp *qg_list, u16 buf_size,
3744cdedef59SAnirudh Venkataramanan 		   struct ice_sq_cd *cd)
3745cdedef59SAnirudh Venkataramanan {
3746cdedef59SAnirudh Venkataramanan 	struct ice_aqc_add_tx_qgrp *list;
3747cdedef59SAnirudh Venkataramanan 	struct ice_aqc_add_txqs *cmd;
3748cdedef59SAnirudh Venkataramanan 	struct ice_aq_desc desc;
374966486d89SBruce Allan 	u16 i, sum_size = 0;
3750cdedef59SAnirudh Venkataramanan 
3751cdedef59SAnirudh Venkataramanan 	cmd = &desc.params.add_txqs;
3752cdedef59SAnirudh Venkataramanan 
3753cdedef59SAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_txqs);
3754cdedef59SAnirudh Venkataramanan 
3755cdedef59SAnirudh Venkataramanan 	if (!qg_list)
3756cdedef59SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
3757cdedef59SAnirudh Venkataramanan 
3758cdedef59SAnirudh Venkataramanan 	if (num_qgrps > ICE_LAN_TXQ_MAX_QGRPS)
3759cdedef59SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
3760cdedef59SAnirudh Venkataramanan 
376166486d89SBruce Allan 	for (i = 0, list = qg_list; i < num_qgrps; i++) {
376266486d89SBruce Allan 		sum_size += struct_size(list, txqs, list->num_txqs);
376366486d89SBruce Allan 		list = (struct ice_aqc_add_tx_qgrp *)(list->txqs +
376466486d89SBruce Allan 						      list->num_txqs);
3765cdedef59SAnirudh Venkataramanan 	}
3766cdedef59SAnirudh Venkataramanan 
376766486d89SBruce Allan 	if (buf_size != sum_size)
3768cdedef59SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
3769cdedef59SAnirudh Venkataramanan 
3770cdedef59SAnirudh Venkataramanan 	desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
3771cdedef59SAnirudh Venkataramanan 
3772cdedef59SAnirudh Venkataramanan 	cmd->num_qgrps = num_qgrps;
3773cdedef59SAnirudh Venkataramanan 
3774cdedef59SAnirudh Venkataramanan 	return ice_aq_send_cmd(hw, &desc, qg_list, buf_size, cd);
3775cdedef59SAnirudh Venkataramanan }
3776cdedef59SAnirudh Venkataramanan 
3777cdedef59SAnirudh Venkataramanan /**
3778cdedef59SAnirudh Venkataramanan  * ice_aq_dis_lan_txq
3779cdedef59SAnirudh Venkataramanan  * @hw: pointer to the hardware structure
3780cdedef59SAnirudh Venkataramanan  * @num_qgrps: number of groups in the list
3781cdedef59SAnirudh Venkataramanan  * @qg_list: the list of groups to disable
3782cdedef59SAnirudh Venkataramanan  * @buf_size: the total size of the qg_list buffer in bytes
378394c4441bSAnirudh Venkataramanan  * @rst_src: if called due to reset, specifies the reset source
3784ddf30f7fSAnirudh Venkataramanan  * @vmvf_num: the relative VM or VF number that is undergoing the reset
3785cdedef59SAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
3786cdedef59SAnirudh Venkataramanan  *
3787cdedef59SAnirudh Venkataramanan  * Disable LAN Tx queue (0x0C31)
3788cdedef59SAnirudh Venkataramanan  */
3789*5e24d598STony Nguyen static int
3790cdedef59SAnirudh Venkataramanan ice_aq_dis_lan_txq(struct ice_hw *hw, u8 num_qgrps,
3791cdedef59SAnirudh Venkataramanan 		   struct ice_aqc_dis_txq_item *qg_list, u16 buf_size,
3792ddf30f7fSAnirudh Venkataramanan 		   enum ice_disq_rst_src rst_src, u16 vmvf_num,
3793cdedef59SAnirudh Venkataramanan 		   struct ice_sq_cd *cd)
3794cdedef59SAnirudh Venkataramanan {
379566486d89SBruce Allan 	struct ice_aqc_dis_txq_item *item;
3796cdedef59SAnirudh Venkataramanan 	struct ice_aqc_dis_txqs *cmd;
3797cdedef59SAnirudh Venkataramanan 	struct ice_aq_desc desc;
3798*5e24d598STony Nguyen 	int status;
3799cdedef59SAnirudh Venkataramanan 	u16 i, sz = 0;
3800cdedef59SAnirudh Venkataramanan 
3801cdedef59SAnirudh Venkataramanan 	cmd = &desc.params.dis_txqs;
3802cdedef59SAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_dis_txqs);
3803cdedef59SAnirudh Venkataramanan 
3804ddf30f7fSAnirudh Venkataramanan 	/* qg_list can be NULL only in VM/VF reset flow */
3805ddf30f7fSAnirudh Venkataramanan 	if (!qg_list && !rst_src)
3806cdedef59SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
3807cdedef59SAnirudh Venkataramanan 
3808cdedef59SAnirudh Venkataramanan 	if (num_qgrps > ICE_LAN_TXQ_MAX_QGRPS)
3809cdedef59SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
3810ddf30f7fSAnirudh Venkataramanan 
3811cdedef59SAnirudh Venkataramanan 	cmd->num_entries = num_qgrps;
3812cdedef59SAnirudh Venkataramanan 
3813ddf30f7fSAnirudh Venkataramanan 	cmd->vmvf_and_timeout = cpu_to_le16((5 << ICE_AQC_Q_DIS_TIMEOUT_S) &
3814ddf30f7fSAnirudh Venkataramanan 					    ICE_AQC_Q_DIS_TIMEOUT_M);
3815ddf30f7fSAnirudh Venkataramanan 
3816ddf30f7fSAnirudh Venkataramanan 	switch (rst_src) {
3817ddf30f7fSAnirudh Venkataramanan 	case ICE_VM_RESET:
3818ddf30f7fSAnirudh Venkataramanan 		cmd->cmd_type = ICE_AQC_Q_DIS_CMD_VM_RESET;
3819ddf30f7fSAnirudh Venkataramanan 		cmd->vmvf_and_timeout |=
3820ddf30f7fSAnirudh Venkataramanan 			cpu_to_le16(vmvf_num & ICE_AQC_Q_DIS_VMVF_NUM_M);
3821ddf30f7fSAnirudh Venkataramanan 		break;
3822ddf30f7fSAnirudh Venkataramanan 	case ICE_VF_RESET:
3823ddf30f7fSAnirudh Venkataramanan 		cmd->cmd_type = ICE_AQC_Q_DIS_CMD_VF_RESET;
3824f9867df6SAnirudh Venkataramanan 		/* In this case, FW expects vmvf_num to be absolute VF ID */
3825ddf30f7fSAnirudh Venkataramanan 		cmd->vmvf_and_timeout |=
3826ddf30f7fSAnirudh Venkataramanan 			cpu_to_le16((vmvf_num + hw->func_caps.vf_base_id) &
3827ddf30f7fSAnirudh Venkataramanan 				    ICE_AQC_Q_DIS_VMVF_NUM_M);
3828ddf30f7fSAnirudh Venkataramanan 		break;
3829ddf30f7fSAnirudh Venkataramanan 	case ICE_NO_RESET:
3830ddf30f7fSAnirudh Venkataramanan 	default:
3831ddf30f7fSAnirudh Venkataramanan 		break;
3832ddf30f7fSAnirudh Venkataramanan 	}
3833ddf30f7fSAnirudh Venkataramanan 
38346e9650d5SVictor Raj 	/* flush pipe on time out */
38356e9650d5SVictor Raj 	cmd->cmd_type |= ICE_AQC_Q_DIS_CMD_FLUSH_PIPE;
3836ddf30f7fSAnirudh Venkataramanan 	/* If no queue group info, we are in a reset flow. Issue the AQ */
3837ddf30f7fSAnirudh Venkataramanan 	if (!qg_list)
3838ddf30f7fSAnirudh Venkataramanan 		goto do_aq;
3839ddf30f7fSAnirudh Venkataramanan 
3840ddf30f7fSAnirudh Venkataramanan 	/* set RD bit to indicate that command buffer is provided by the driver
3841ddf30f7fSAnirudh Venkataramanan 	 * and it needs to be read by the firmware
3842ddf30f7fSAnirudh Venkataramanan 	 */
3843ddf30f7fSAnirudh Venkataramanan 	desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
3844ddf30f7fSAnirudh Venkataramanan 
384566486d89SBruce Allan 	for (i = 0, item = qg_list; i < num_qgrps; i++) {
384666486d89SBruce Allan 		u16 item_size = struct_size(item, q_id, item->num_qs);
3847cdedef59SAnirudh Venkataramanan 
3848cdedef59SAnirudh Venkataramanan 		/* If the num of queues is even, add 2 bytes of padding */
384966486d89SBruce Allan 		if ((item->num_qs % 2) == 0)
385066486d89SBruce Allan 			item_size += 2;
385166486d89SBruce Allan 
385266486d89SBruce Allan 		sz += item_size;
385366486d89SBruce Allan 
385466486d89SBruce Allan 		item = (struct ice_aqc_dis_txq_item *)((u8 *)item + item_size);
3855cdedef59SAnirudh Venkataramanan 	}
3856cdedef59SAnirudh Venkataramanan 
3857cdedef59SAnirudh Venkataramanan 	if (buf_size != sz)
3858cdedef59SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
3859cdedef59SAnirudh Venkataramanan 
3860ddf30f7fSAnirudh Venkataramanan do_aq:
38616e9650d5SVictor Raj 	status = ice_aq_send_cmd(hw, &desc, qg_list, buf_size, cd);
38626e9650d5SVictor Raj 	if (status) {
38636e9650d5SVictor Raj 		if (!qg_list)
38646e9650d5SVictor Raj 			ice_debug(hw, ICE_DBG_SCHED, "VM%d disable failed %d\n",
38656e9650d5SVictor Raj 				  vmvf_num, hw->adminq.sq_last_status);
38666e9650d5SVictor Raj 		else
38672f2da36eSAnirudh Venkataramanan 			ice_debug(hw, ICE_DBG_SCHED, "disable queue %d failed %d\n",
38686e9650d5SVictor Raj 				  le16_to_cpu(qg_list[0].q_id[0]),
38696e9650d5SVictor Raj 				  hw->adminq.sq_last_status);
38706e9650d5SVictor Raj 	}
38716e9650d5SVictor Raj 	return status;
3872cdedef59SAnirudh Venkataramanan }
3873cdedef59SAnirudh Venkataramanan 
3874348048e7SDave Ertman /**
3875348048e7SDave Ertman  * ice_aq_add_rdma_qsets
3876348048e7SDave Ertman  * @hw: pointer to the hardware structure
3877348048e7SDave Ertman  * @num_qset_grps: Number of RDMA Qset groups
3878348048e7SDave Ertman  * @qset_list: list of Qset groups to be added
3879348048e7SDave Ertman  * @buf_size: size of buffer for indirect command
3880348048e7SDave Ertman  * @cd: pointer to command details structure or NULL
3881348048e7SDave Ertman  *
3882348048e7SDave Ertman  * Add Tx RDMA Qsets (0x0C33)
3883348048e7SDave Ertman  */
3884348048e7SDave Ertman static int
3885348048e7SDave Ertman ice_aq_add_rdma_qsets(struct ice_hw *hw, u8 num_qset_grps,
3886348048e7SDave Ertman 		      struct ice_aqc_add_rdma_qset_data *qset_list,
3887348048e7SDave Ertman 		      u16 buf_size, struct ice_sq_cd *cd)
3888348048e7SDave Ertman {
3889348048e7SDave Ertman 	struct ice_aqc_add_rdma_qset_data *list;
3890348048e7SDave Ertman 	struct ice_aqc_add_rdma_qset *cmd;
3891348048e7SDave Ertman 	struct ice_aq_desc desc;
3892348048e7SDave Ertman 	u16 i, sum_size = 0;
3893348048e7SDave Ertman 
3894348048e7SDave Ertman 	cmd = &desc.params.add_rdma_qset;
3895348048e7SDave Ertman 
3896348048e7SDave Ertman 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_rdma_qset);
3897348048e7SDave Ertman 
3898348048e7SDave Ertman 	if (num_qset_grps > ICE_LAN_TXQ_MAX_QGRPS)
3899348048e7SDave Ertman 		return -EINVAL;
3900348048e7SDave Ertman 
3901348048e7SDave Ertman 	for (i = 0, list = qset_list; i < num_qset_grps; i++) {
3902348048e7SDave Ertman 		u16 num_qsets = le16_to_cpu(list->num_qsets);
3903348048e7SDave Ertman 
3904348048e7SDave Ertman 		sum_size += struct_size(list, rdma_qsets, num_qsets);
3905348048e7SDave Ertman 		list = (struct ice_aqc_add_rdma_qset_data *)(list->rdma_qsets +
3906348048e7SDave Ertman 							     num_qsets);
3907348048e7SDave Ertman 	}
3908348048e7SDave Ertman 
3909348048e7SDave Ertman 	if (buf_size != sum_size)
3910348048e7SDave Ertman 		return -EINVAL;
3911348048e7SDave Ertman 
3912348048e7SDave Ertman 	desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
3913348048e7SDave Ertman 
3914348048e7SDave Ertman 	cmd->num_qset_grps = num_qset_grps;
3915348048e7SDave Ertman 
3916348048e7SDave Ertman 	return ice_status_to_errno(ice_aq_send_cmd(hw, &desc, qset_list,
3917348048e7SDave Ertman 						   buf_size, cd));
3918348048e7SDave Ertman }
3919348048e7SDave Ertman 
3920cdedef59SAnirudh Venkataramanan /* End of FW Admin Queue command wrappers */
3921cdedef59SAnirudh Venkataramanan 
3922cdedef59SAnirudh Venkataramanan /**
3923cdedef59SAnirudh Venkataramanan  * ice_write_byte - write a byte to a packed context structure
3924cdedef59SAnirudh Venkataramanan  * @src_ctx:  the context structure to read from
3925cdedef59SAnirudh Venkataramanan  * @dest_ctx: the context to be written to
3926cdedef59SAnirudh Venkataramanan  * @ce_info:  a description of the struct to be filled
3927cdedef59SAnirudh Venkataramanan  */
3928c8b7abddSBruce Allan static void
3929c8b7abddSBruce Allan ice_write_byte(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
3930cdedef59SAnirudh Venkataramanan {
3931cdedef59SAnirudh Venkataramanan 	u8 src_byte, dest_byte, mask;
3932cdedef59SAnirudh Venkataramanan 	u8 *from, *dest;
3933cdedef59SAnirudh Venkataramanan 	u16 shift_width;
3934cdedef59SAnirudh Venkataramanan 
3935cdedef59SAnirudh Venkataramanan 	/* copy from the next struct field */
3936cdedef59SAnirudh Venkataramanan 	from = src_ctx + ce_info->offset;
3937cdedef59SAnirudh Venkataramanan 
3938cdedef59SAnirudh Venkataramanan 	/* prepare the bits and mask */
3939cdedef59SAnirudh Venkataramanan 	shift_width = ce_info->lsb % 8;
3940cdedef59SAnirudh Venkataramanan 	mask = (u8)(BIT(ce_info->width) - 1);
3941cdedef59SAnirudh Venkataramanan 
3942cdedef59SAnirudh Venkataramanan 	src_byte = *from;
3943cdedef59SAnirudh Venkataramanan 	src_byte &= mask;
3944cdedef59SAnirudh Venkataramanan 
3945cdedef59SAnirudh Venkataramanan 	/* shift to correct alignment */
3946cdedef59SAnirudh Venkataramanan 	mask <<= shift_width;
3947cdedef59SAnirudh Venkataramanan 	src_byte <<= shift_width;
3948cdedef59SAnirudh Venkataramanan 
3949cdedef59SAnirudh Venkataramanan 	/* get the current bits from the target bit string */
3950cdedef59SAnirudh Venkataramanan 	dest = dest_ctx + (ce_info->lsb / 8);
3951cdedef59SAnirudh Venkataramanan 
3952cdedef59SAnirudh Venkataramanan 	memcpy(&dest_byte, dest, sizeof(dest_byte));
3953cdedef59SAnirudh Venkataramanan 
3954cdedef59SAnirudh Venkataramanan 	dest_byte &= ~mask;	/* get the bits not changing */
3955cdedef59SAnirudh Venkataramanan 	dest_byte |= src_byte;	/* add in the new bits */
3956cdedef59SAnirudh Venkataramanan 
3957cdedef59SAnirudh Venkataramanan 	/* put it all back */
3958cdedef59SAnirudh Venkataramanan 	memcpy(dest, &dest_byte, sizeof(dest_byte));
3959cdedef59SAnirudh Venkataramanan }
3960cdedef59SAnirudh Venkataramanan 
3961cdedef59SAnirudh Venkataramanan /**
3962cdedef59SAnirudh Venkataramanan  * ice_write_word - write a word to a packed context structure
3963cdedef59SAnirudh Venkataramanan  * @src_ctx:  the context structure to read from
3964cdedef59SAnirudh Venkataramanan  * @dest_ctx: the context to be written to
3965cdedef59SAnirudh Venkataramanan  * @ce_info:  a description of the struct to be filled
3966cdedef59SAnirudh Venkataramanan  */
3967c8b7abddSBruce Allan static void
3968c8b7abddSBruce Allan ice_write_word(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
3969cdedef59SAnirudh Venkataramanan {
3970cdedef59SAnirudh Venkataramanan 	u16 src_word, mask;
3971cdedef59SAnirudh Venkataramanan 	__le16 dest_word;
3972cdedef59SAnirudh Venkataramanan 	u8 *from, *dest;
3973cdedef59SAnirudh Venkataramanan 	u16 shift_width;
3974cdedef59SAnirudh Venkataramanan 
3975cdedef59SAnirudh Venkataramanan 	/* copy from the next struct field */
3976cdedef59SAnirudh Venkataramanan 	from = src_ctx + ce_info->offset;
3977cdedef59SAnirudh Venkataramanan 
3978cdedef59SAnirudh Venkataramanan 	/* prepare the bits and mask */
3979cdedef59SAnirudh Venkataramanan 	shift_width = ce_info->lsb % 8;
3980cdedef59SAnirudh Venkataramanan 	mask = BIT(ce_info->width) - 1;
3981cdedef59SAnirudh Venkataramanan 
3982cdedef59SAnirudh Venkataramanan 	/* don't swizzle the bits until after the mask because the mask bits
3983cdedef59SAnirudh Venkataramanan 	 * will be in a different bit position on big endian machines
3984cdedef59SAnirudh Venkataramanan 	 */
3985cdedef59SAnirudh Venkataramanan 	src_word = *(u16 *)from;
3986cdedef59SAnirudh Venkataramanan 	src_word &= mask;
3987cdedef59SAnirudh Venkataramanan 
3988cdedef59SAnirudh Venkataramanan 	/* shift to correct alignment */
3989cdedef59SAnirudh Venkataramanan 	mask <<= shift_width;
3990cdedef59SAnirudh Venkataramanan 	src_word <<= shift_width;
3991cdedef59SAnirudh Venkataramanan 
3992cdedef59SAnirudh Venkataramanan 	/* get the current bits from the target bit string */
3993cdedef59SAnirudh Venkataramanan 	dest = dest_ctx + (ce_info->lsb / 8);
3994cdedef59SAnirudh Venkataramanan 
3995cdedef59SAnirudh Venkataramanan 	memcpy(&dest_word, dest, sizeof(dest_word));
3996cdedef59SAnirudh Venkataramanan 
3997cdedef59SAnirudh Venkataramanan 	dest_word &= ~(cpu_to_le16(mask));	/* get the bits not changing */
3998cdedef59SAnirudh Venkataramanan 	dest_word |= cpu_to_le16(src_word);	/* add in the new bits */
3999cdedef59SAnirudh Venkataramanan 
4000cdedef59SAnirudh Venkataramanan 	/* put it all back */
4001cdedef59SAnirudh Venkataramanan 	memcpy(dest, &dest_word, sizeof(dest_word));
4002cdedef59SAnirudh Venkataramanan }
4003cdedef59SAnirudh Venkataramanan 
4004cdedef59SAnirudh Venkataramanan /**
4005cdedef59SAnirudh Venkataramanan  * ice_write_dword - write a dword to a packed context structure
4006cdedef59SAnirudh Venkataramanan  * @src_ctx:  the context structure to read from
4007cdedef59SAnirudh Venkataramanan  * @dest_ctx: the context to be written to
4008cdedef59SAnirudh Venkataramanan  * @ce_info:  a description of the struct to be filled
4009cdedef59SAnirudh Venkataramanan  */
4010c8b7abddSBruce Allan static void
4011c8b7abddSBruce Allan ice_write_dword(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
4012cdedef59SAnirudh Venkataramanan {
4013cdedef59SAnirudh Venkataramanan 	u32 src_dword, mask;
4014cdedef59SAnirudh Venkataramanan 	__le32 dest_dword;
4015cdedef59SAnirudh Venkataramanan 	u8 *from, *dest;
4016cdedef59SAnirudh Venkataramanan 	u16 shift_width;
4017cdedef59SAnirudh Venkataramanan 
4018cdedef59SAnirudh Venkataramanan 	/* copy from the next struct field */
4019cdedef59SAnirudh Venkataramanan 	from = src_ctx + ce_info->offset;
4020cdedef59SAnirudh Venkataramanan 
4021cdedef59SAnirudh Venkataramanan 	/* prepare the bits and mask */
4022cdedef59SAnirudh Venkataramanan 	shift_width = ce_info->lsb % 8;
4023cdedef59SAnirudh Venkataramanan 
4024cdedef59SAnirudh Venkataramanan 	/* if the field width is exactly 32 on an x86 machine, then the shift
4025cdedef59SAnirudh Venkataramanan 	 * operation will not work because the SHL instructions count is masked
4026cdedef59SAnirudh Venkataramanan 	 * to 5 bits so the shift will do nothing
4027cdedef59SAnirudh Venkataramanan 	 */
4028cdedef59SAnirudh Venkataramanan 	if (ce_info->width < 32)
4029cdedef59SAnirudh Venkataramanan 		mask = BIT(ce_info->width) - 1;
4030cdedef59SAnirudh Venkataramanan 	else
4031cdedef59SAnirudh Venkataramanan 		mask = (u32)~0;
4032cdedef59SAnirudh Venkataramanan 
4033cdedef59SAnirudh Venkataramanan 	/* don't swizzle the bits until after the mask because the mask bits
4034cdedef59SAnirudh Venkataramanan 	 * will be in a different bit position on big endian machines
4035cdedef59SAnirudh Venkataramanan 	 */
4036cdedef59SAnirudh Venkataramanan 	src_dword = *(u32 *)from;
4037cdedef59SAnirudh Venkataramanan 	src_dword &= mask;
4038cdedef59SAnirudh Venkataramanan 
4039cdedef59SAnirudh Venkataramanan 	/* shift to correct alignment */
4040cdedef59SAnirudh Venkataramanan 	mask <<= shift_width;
4041cdedef59SAnirudh Venkataramanan 	src_dword <<= shift_width;
4042cdedef59SAnirudh Venkataramanan 
4043cdedef59SAnirudh Venkataramanan 	/* get the current bits from the target bit string */
4044cdedef59SAnirudh Venkataramanan 	dest = dest_ctx + (ce_info->lsb / 8);
4045cdedef59SAnirudh Venkataramanan 
4046cdedef59SAnirudh Venkataramanan 	memcpy(&dest_dword, dest, sizeof(dest_dword));
4047cdedef59SAnirudh Venkataramanan 
4048cdedef59SAnirudh Venkataramanan 	dest_dword &= ~(cpu_to_le32(mask));	/* get the bits not changing */
4049cdedef59SAnirudh Venkataramanan 	dest_dword |= cpu_to_le32(src_dword);	/* add in the new bits */
4050cdedef59SAnirudh Venkataramanan 
4051cdedef59SAnirudh Venkataramanan 	/* put it all back */
4052cdedef59SAnirudh Venkataramanan 	memcpy(dest, &dest_dword, sizeof(dest_dword));
4053cdedef59SAnirudh Venkataramanan }
4054cdedef59SAnirudh Venkataramanan 
4055cdedef59SAnirudh Venkataramanan /**
4056cdedef59SAnirudh Venkataramanan  * ice_write_qword - write a qword to a packed context structure
4057cdedef59SAnirudh Venkataramanan  * @src_ctx:  the context structure to read from
4058cdedef59SAnirudh Venkataramanan  * @dest_ctx: the context to be written to
4059cdedef59SAnirudh Venkataramanan  * @ce_info:  a description of the struct to be filled
4060cdedef59SAnirudh Venkataramanan  */
4061c8b7abddSBruce Allan static void
4062c8b7abddSBruce Allan ice_write_qword(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
4063cdedef59SAnirudh Venkataramanan {
4064cdedef59SAnirudh Venkataramanan 	u64 src_qword, mask;
4065cdedef59SAnirudh Venkataramanan 	__le64 dest_qword;
4066cdedef59SAnirudh Venkataramanan 	u8 *from, *dest;
4067cdedef59SAnirudh Venkataramanan 	u16 shift_width;
4068cdedef59SAnirudh Venkataramanan 
4069cdedef59SAnirudh Venkataramanan 	/* copy from the next struct field */
4070cdedef59SAnirudh Venkataramanan 	from = src_ctx + ce_info->offset;
4071cdedef59SAnirudh Venkataramanan 
4072cdedef59SAnirudh Venkataramanan 	/* prepare the bits and mask */
4073cdedef59SAnirudh Venkataramanan 	shift_width = ce_info->lsb % 8;
4074cdedef59SAnirudh Venkataramanan 
4075cdedef59SAnirudh Venkataramanan 	/* if the field width is exactly 64 on an x86 machine, then the shift
4076cdedef59SAnirudh Venkataramanan 	 * operation will not work because the SHL instructions count is masked
4077cdedef59SAnirudh Venkataramanan 	 * to 6 bits so the shift will do nothing
4078cdedef59SAnirudh Venkataramanan 	 */
4079cdedef59SAnirudh Venkataramanan 	if (ce_info->width < 64)
4080cdedef59SAnirudh Venkataramanan 		mask = BIT_ULL(ce_info->width) - 1;
4081cdedef59SAnirudh Venkataramanan 	else
4082cdedef59SAnirudh Venkataramanan 		mask = (u64)~0;
4083cdedef59SAnirudh Venkataramanan 
4084cdedef59SAnirudh Venkataramanan 	/* don't swizzle the bits until after the mask because the mask bits
4085cdedef59SAnirudh Venkataramanan 	 * will be in a different bit position on big endian machines
4086cdedef59SAnirudh Venkataramanan 	 */
4087cdedef59SAnirudh Venkataramanan 	src_qword = *(u64 *)from;
4088cdedef59SAnirudh Venkataramanan 	src_qword &= mask;
4089cdedef59SAnirudh Venkataramanan 
4090cdedef59SAnirudh Venkataramanan 	/* shift to correct alignment */
4091cdedef59SAnirudh Venkataramanan 	mask <<= shift_width;
4092cdedef59SAnirudh Venkataramanan 	src_qword <<= shift_width;
4093cdedef59SAnirudh Venkataramanan 
4094cdedef59SAnirudh Venkataramanan 	/* get the current bits from the target bit string */
4095cdedef59SAnirudh Venkataramanan 	dest = dest_ctx + (ce_info->lsb / 8);
4096cdedef59SAnirudh Venkataramanan 
4097cdedef59SAnirudh Venkataramanan 	memcpy(&dest_qword, dest, sizeof(dest_qword));
4098cdedef59SAnirudh Venkataramanan 
4099cdedef59SAnirudh Venkataramanan 	dest_qword &= ~(cpu_to_le64(mask));	/* get the bits not changing */
4100cdedef59SAnirudh Venkataramanan 	dest_qword |= cpu_to_le64(src_qword);	/* add in the new bits */
4101cdedef59SAnirudh Venkataramanan 
4102cdedef59SAnirudh Venkataramanan 	/* put it all back */
4103cdedef59SAnirudh Venkataramanan 	memcpy(dest, &dest_qword, sizeof(dest_qword));
4104cdedef59SAnirudh Venkataramanan }
4105cdedef59SAnirudh Venkataramanan 
4106cdedef59SAnirudh Venkataramanan /**
4107cdedef59SAnirudh Venkataramanan  * ice_set_ctx - set context bits in packed structure
41087e34786aSBruce Allan  * @hw: pointer to the hardware structure
4109cdedef59SAnirudh Venkataramanan  * @src_ctx:  pointer to a generic non-packed context structure
4110cdedef59SAnirudh Venkataramanan  * @dest_ctx: pointer to memory for the packed structure
4111cdedef59SAnirudh Venkataramanan  * @ce_info:  a description of the structure to be transformed
4112cdedef59SAnirudh Venkataramanan  */
4113*5e24d598STony Nguyen int
41147e34786aSBruce Allan ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx,
41157e34786aSBruce Allan 	    const struct ice_ctx_ele *ce_info)
4116cdedef59SAnirudh Venkataramanan {
4117cdedef59SAnirudh Venkataramanan 	int f;
4118cdedef59SAnirudh Venkataramanan 
4119cdedef59SAnirudh Venkataramanan 	for (f = 0; ce_info[f].width; f++) {
4120cdedef59SAnirudh Venkataramanan 		/* We have to deal with each element of the FW response
4121cdedef59SAnirudh Venkataramanan 		 * using the correct size so that we are correct regardless
4122cdedef59SAnirudh Venkataramanan 		 * of the endianness of the machine.
4123cdedef59SAnirudh Venkataramanan 		 */
41247e34786aSBruce Allan 		if (ce_info[f].width > (ce_info[f].size_of * BITS_PER_BYTE)) {
41259228d8b2SJacob Keller 			ice_debug(hw, ICE_DBG_QCTX, "Field %d width of %d bits larger than size of %d byte(s) ... skipping write\n",
41267e34786aSBruce Allan 				  f, ce_info[f].width, ce_info[f].size_of);
41277e34786aSBruce Allan 			continue;
41287e34786aSBruce Allan 		}
4129cdedef59SAnirudh Venkataramanan 		switch (ce_info[f].size_of) {
4130cdedef59SAnirudh Venkataramanan 		case sizeof(u8):
4131cdedef59SAnirudh Venkataramanan 			ice_write_byte(src_ctx, dest_ctx, &ce_info[f]);
4132cdedef59SAnirudh Venkataramanan 			break;
4133cdedef59SAnirudh Venkataramanan 		case sizeof(u16):
4134cdedef59SAnirudh Venkataramanan 			ice_write_word(src_ctx, dest_ctx, &ce_info[f]);
4135cdedef59SAnirudh Venkataramanan 			break;
4136cdedef59SAnirudh Venkataramanan 		case sizeof(u32):
4137cdedef59SAnirudh Venkataramanan 			ice_write_dword(src_ctx, dest_ctx, &ce_info[f]);
4138cdedef59SAnirudh Venkataramanan 			break;
4139cdedef59SAnirudh Venkataramanan 		case sizeof(u64):
4140cdedef59SAnirudh Venkataramanan 			ice_write_qword(src_ctx, dest_ctx, &ce_info[f]);
4141cdedef59SAnirudh Venkataramanan 			break;
4142cdedef59SAnirudh Venkataramanan 		default:
4143cdedef59SAnirudh Venkataramanan 			return ICE_ERR_INVAL_SIZE;
4144cdedef59SAnirudh Venkataramanan 		}
4145cdedef59SAnirudh Venkataramanan 	}
4146cdedef59SAnirudh Venkataramanan 
4147cdedef59SAnirudh Venkataramanan 	return 0;
4148cdedef59SAnirudh Venkataramanan }
4149cdedef59SAnirudh Venkataramanan 
4150cdedef59SAnirudh Venkataramanan /**
4151bb87ee0eSAnirudh Venkataramanan  * ice_get_lan_q_ctx - get the LAN queue context for the given VSI and TC
4152bb87ee0eSAnirudh Venkataramanan  * @hw: pointer to the HW struct
4153bb87ee0eSAnirudh Venkataramanan  * @vsi_handle: software VSI handle
4154bb87ee0eSAnirudh Venkataramanan  * @tc: TC number
4155bb87ee0eSAnirudh Venkataramanan  * @q_handle: software queue handle
4156bb87ee0eSAnirudh Venkataramanan  */
41571ddef455SUsha Ketineni struct ice_q_ctx *
4158bb87ee0eSAnirudh Venkataramanan ice_get_lan_q_ctx(struct ice_hw *hw, u16 vsi_handle, u8 tc, u16 q_handle)
4159bb87ee0eSAnirudh Venkataramanan {
4160bb87ee0eSAnirudh Venkataramanan 	struct ice_vsi_ctx *vsi;
4161bb87ee0eSAnirudh Venkataramanan 	struct ice_q_ctx *q_ctx;
4162bb87ee0eSAnirudh Venkataramanan 
4163bb87ee0eSAnirudh Venkataramanan 	vsi = ice_get_vsi_ctx(hw, vsi_handle);
4164bb87ee0eSAnirudh Venkataramanan 	if (!vsi)
4165bb87ee0eSAnirudh Venkataramanan 		return NULL;
4166bb87ee0eSAnirudh Venkataramanan 	if (q_handle >= vsi->num_lan_q_entries[tc])
4167bb87ee0eSAnirudh Venkataramanan 		return NULL;
4168bb87ee0eSAnirudh Venkataramanan 	if (!vsi->lan_q_ctx[tc])
4169bb87ee0eSAnirudh Venkataramanan 		return NULL;
4170bb87ee0eSAnirudh Venkataramanan 	q_ctx = vsi->lan_q_ctx[tc];
4171bb87ee0eSAnirudh Venkataramanan 	return &q_ctx[q_handle];
4172bb87ee0eSAnirudh Venkataramanan }
4173bb87ee0eSAnirudh Venkataramanan 
4174bb87ee0eSAnirudh Venkataramanan /**
4175cdedef59SAnirudh Venkataramanan  * ice_ena_vsi_txq
4176cdedef59SAnirudh Venkataramanan  * @pi: port information structure
41774fb33f31SAnirudh Venkataramanan  * @vsi_handle: software VSI handle
4178f9867df6SAnirudh Venkataramanan  * @tc: TC number
4179bb87ee0eSAnirudh Venkataramanan  * @q_handle: software queue handle
4180cdedef59SAnirudh Venkataramanan  * @num_qgrps: Number of added queue groups
4181cdedef59SAnirudh Venkataramanan  * @buf: list of queue groups to be added
4182cdedef59SAnirudh Venkataramanan  * @buf_size: size of buffer for indirect command
4183cdedef59SAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
4184cdedef59SAnirudh Venkataramanan  *
4185f9867df6SAnirudh Venkataramanan  * This function adds one LAN queue
4186cdedef59SAnirudh Venkataramanan  */
4187*5e24d598STony Nguyen int
4188bb87ee0eSAnirudh Venkataramanan ice_ena_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u16 q_handle,
4189bb87ee0eSAnirudh Venkataramanan 		u8 num_qgrps, struct ice_aqc_add_tx_qgrp *buf, u16 buf_size,
4190cdedef59SAnirudh Venkataramanan 		struct ice_sq_cd *cd)
4191cdedef59SAnirudh Venkataramanan {
4192cdedef59SAnirudh Venkataramanan 	struct ice_aqc_txsched_elem_data node = { 0 };
4193cdedef59SAnirudh Venkataramanan 	struct ice_sched_node *parent;
4194bb87ee0eSAnirudh Venkataramanan 	struct ice_q_ctx *q_ctx;
4195*5e24d598STony Nguyen 	int status;
4196cdedef59SAnirudh Venkataramanan 	struct ice_hw *hw;
4197cdedef59SAnirudh Venkataramanan 
4198cdedef59SAnirudh Venkataramanan 	if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY)
4199cdedef59SAnirudh Venkataramanan 		return ICE_ERR_CFG;
4200cdedef59SAnirudh Venkataramanan 
4201cdedef59SAnirudh Venkataramanan 	if (num_qgrps > 1 || buf->num_txqs > 1)
4202cdedef59SAnirudh Venkataramanan 		return ICE_ERR_MAX_LIMIT;
4203cdedef59SAnirudh Venkataramanan 
4204cdedef59SAnirudh Venkataramanan 	hw = pi->hw;
4205cdedef59SAnirudh Venkataramanan 
42064fb33f31SAnirudh Venkataramanan 	if (!ice_is_vsi_valid(hw, vsi_handle))
42074fb33f31SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
42084fb33f31SAnirudh Venkataramanan 
4209cdedef59SAnirudh Venkataramanan 	mutex_lock(&pi->sched_lock);
4210cdedef59SAnirudh Venkataramanan 
4211bb87ee0eSAnirudh Venkataramanan 	q_ctx = ice_get_lan_q_ctx(hw, vsi_handle, tc, q_handle);
4212bb87ee0eSAnirudh Venkataramanan 	if (!q_ctx) {
4213bb87ee0eSAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_SCHED, "Enaq: invalid queue handle %d\n",
4214bb87ee0eSAnirudh Venkataramanan 			  q_handle);
4215bb87ee0eSAnirudh Venkataramanan 		status = ICE_ERR_PARAM;
4216bb87ee0eSAnirudh Venkataramanan 		goto ena_txq_exit;
4217bb87ee0eSAnirudh Venkataramanan 	}
4218bb87ee0eSAnirudh Venkataramanan 
4219cdedef59SAnirudh Venkataramanan 	/* find a parent node */
42204fb33f31SAnirudh Venkataramanan 	parent = ice_sched_get_free_qparent(pi, vsi_handle, tc,
4221cdedef59SAnirudh Venkataramanan 					    ICE_SCHED_NODE_OWNER_LAN);
4222cdedef59SAnirudh Venkataramanan 	if (!parent) {
4223cdedef59SAnirudh Venkataramanan 		status = ICE_ERR_PARAM;
4224cdedef59SAnirudh Venkataramanan 		goto ena_txq_exit;
4225cdedef59SAnirudh Venkataramanan 	}
42264fb33f31SAnirudh Venkataramanan 
4227cdedef59SAnirudh Venkataramanan 	buf->parent_teid = parent->info.node_teid;
4228cdedef59SAnirudh Venkataramanan 	node.parent_teid = parent->info.node_teid;
4229cdedef59SAnirudh Venkataramanan 	/* Mark that the values in the "generic" section as valid. The default
4230cdedef59SAnirudh Venkataramanan 	 * value in the "generic" section is zero. This means that :
4231cdedef59SAnirudh Venkataramanan 	 * - Scheduling mode is Bytes Per Second (BPS), indicated by Bit 0.
4232cdedef59SAnirudh Venkataramanan 	 * - 0 priority among siblings, indicated by Bit 1-3.
4233cdedef59SAnirudh Venkataramanan 	 * - WFQ, indicated by Bit 4.
4234cdedef59SAnirudh Venkataramanan 	 * - 0 Adjustment value is used in PSM credit update flow, indicated by
4235cdedef59SAnirudh Venkataramanan 	 * Bit 5-6.
4236cdedef59SAnirudh Venkataramanan 	 * - Bit 7 is reserved.
4237cdedef59SAnirudh Venkataramanan 	 * Without setting the generic section as valid in valid_sections, the
4238f9867df6SAnirudh Venkataramanan 	 * Admin queue command will fail with error code ICE_AQ_RC_EINVAL.
4239cdedef59SAnirudh Venkataramanan 	 */
4240984824a2STarun Singh 	buf->txqs[0].info.valid_sections =
4241984824a2STarun Singh 		ICE_AQC_ELEM_VALID_GENERIC | ICE_AQC_ELEM_VALID_CIR |
4242984824a2STarun Singh 		ICE_AQC_ELEM_VALID_EIR;
4243984824a2STarun Singh 	buf->txqs[0].info.generic = 0;
4244984824a2STarun Singh 	buf->txqs[0].info.cir_bw.bw_profile_idx =
4245984824a2STarun Singh 		cpu_to_le16(ICE_SCHED_DFLT_RL_PROF_ID);
4246984824a2STarun Singh 	buf->txqs[0].info.cir_bw.bw_alloc =
4247984824a2STarun Singh 		cpu_to_le16(ICE_SCHED_DFLT_BW_WT);
4248984824a2STarun Singh 	buf->txqs[0].info.eir_bw.bw_profile_idx =
4249984824a2STarun Singh 		cpu_to_le16(ICE_SCHED_DFLT_RL_PROF_ID);
4250984824a2STarun Singh 	buf->txqs[0].info.eir_bw.bw_alloc =
4251984824a2STarun Singh 		cpu_to_le16(ICE_SCHED_DFLT_BW_WT);
4252cdedef59SAnirudh Venkataramanan 
4253f9867df6SAnirudh Venkataramanan 	/* add the LAN queue */
4254cdedef59SAnirudh Venkataramanan 	status = ice_aq_add_lan_txq(hw, num_qgrps, buf, buf_size, cd);
42556e9650d5SVictor Raj 	if (status) {
4256bb87ee0eSAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_SCHED, "enable queue %d failed %d\n",
42576e9650d5SVictor Raj 			  le16_to_cpu(buf->txqs[0].txq_id),
42586e9650d5SVictor Raj 			  hw->adminq.sq_last_status);
4259cdedef59SAnirudh Venkataramanan 		goto ena_txq_exit;
42606e9650d5SVictor Raj 	}
4261cdedef59SAnirudh Venkataramanan 
4262cdedef59SAnirudh Venkataramanan 	node.node_teid = buf->txqs[0].q_teid;
4263cdedef59SAnirudh Venkataramanan 	node.data.elem_type = ICE_AQC_ELEM_TYPE_LEAF;
4264bb87ee0eSAnirudh Venkataramanan 	q_ctx->q_handle = q_handle;
42651ddef455SUsha Ketineni 	q_ctx->q_teid = le32_to_cpu(node.node_teid);
4266cdedef59SAnirudh Venkataramanan 
42671ddef455SUsha Ketineni 	/* add a leaf node into scheduler tree queue layer */
4268cdedef59SAnirudh Venkataramanan 	status = ice_sched_add_node(pi, hw->num_tx_sched_layers - 1, &node);
42691ddef455SUsha Ketineni 	if (!status)
42701ddef455SUsha Ketineni 		status = ice_sched_replay_q_bw(pi, q_ctx);
4271cdedef59SAnirudh Venkataramanan 
4272cdedef59SAnirudh Venkataramanan ena_txq_exit:
4273cdedef59SAnirudh Venkataramanan 	mutex_unlock(&pi->sched_lock);
4274cdedef59SAnirudh Venkataramanan 	return status;
4275cdedef59SAnirudh Venkataramanan }
4276cdedef59SAnirudh Venkataramanan 
4277cdedef59SAnirudh Venkataramanan /**
4278cdedef59SAnirudh Venkataramanan  * ice_dis_vsi_txq
4279cdedef59SAnirudh Venkataramanan  * @pi: port information structure
4280bb87ee0eSAnirudh Venkataramanan  * @vsi_handle: software VSI handle
4281bb87ee0eSAnirudh Venkataramanan  * @tc: TC number
4282cdedef59SAnirudh Venkataramanan  * @num_queues: number of queues
4283bb87ee0eSAnirudh Venkataramanan  * @q_handles: pointer to software queue handle array
4284cdedef59SAnirudh Venkataramanan  * @q_ids: pointer to the q_id array
4285cdedef59SAnirudh Venkataramanan  * @q_teids: pointer to queue node teids
428694c4441bSAnirudh Venkataramanan  * @rst_src: if called due to reset, specifies the reset source
4287ddf30f7fSAnirudh Venkataramanan  * @vmvf_num: the relative VM or VF number that is undergoing the reset
4288cdedef59SAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
4289cdedef59SAnirudh Venkataramanan  *
4290cdedef59SAnirudh Venkataramanan  * This function removes queues and their corresponding nodes in SW DB
4291cdedef59SAnirudh Venkataramanan  */
4292*5e24d598STony Nguyen int
4293bb87ee0eSAnirudh Venkataramanan ice_dis_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u8 num_queues,
4294bb87ee0eSAnirudh Venkataramanan 		u16 *q_handles, u16 *q_ids, u32 *q_teids,
4295bb87ee0eSAnirudh Venkataramanan 		enum ice_disq_rst_src rst_src, u16 vmvf_num,
4296ddf30f7fSAnirudh Venkataramanan 		struct ice_sq_cd *cd)
4297cdedef59SAnirudh Venkataramanan {
4298*5e24d598STony Nguyen 	int status = ICE_ERR_DOES_NOT_EXIST;
429966486d89SBruce Allan 	struct ice_aqc_dis_txq_item *qg_list;
4300bb87ee0eSAnirudh Venkataramanan 	struct ice_q_ctx *q_ctx;
430166486d89SBruce Allan 	struct ice_hw *hw;
430266486d89SBruce Allan 	u16 i, buf_size;
4303cdedef59SAnirudh Venkataramanan 
4304cdedef59SAnirudh Venkataramanan 	if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY)
4305cdedef59SAnirudh Venkataramanan 		return ICE_ERR_CFG;
4306cdedef59SAnirudh Venkataramanan 
430766486d89SBruce Allan 	hw = pi->hw;
430866486d89SBruce Allan 
430985796d6eSAkeem G Abodunrin 	if (!num_queues) {
431085796d6eSAkeem G Abodunrin 		/* if queue is disabled already yet the disable queue command
431185796d6eSAkeem G Abodunrin 		 * has to be sent to complete the VF reset, then call
431285796d6eSAkeem G Abodunrin 		 * ice_aq_dis_lan_txq without any queue information
431385796d6eSAkeem G Abodunrin 		 */
431485796d6eSAkeem G Abodunrin 		if (rst_src)
431566486d89SBruce Allan 			return ice_aq_dis_lan_txq(hw, 0, NULL, 0, rst_src,
431685796d6eSAkeem G Abodunrin 						  vmvf_num, NULL);
431785796d6eSAkeem G Abodunrin 		return ICE_ERR_CFG;
431885796d6eSAkeem G Abodunrin 	}
4319ddf30f7fSAnirudh Venkataramanan 
432066486d89SBruce Allan 	buf_size = struct_size(qg_list, q_id, 1);
432166486d89SBruce Allan 	qg_list = kzalloc(buf_size, GFP_KERNEL);
432266486d89SBruce Allan 	if (!qg_list)
432366486d89SBruce Allan 		return ICE_ERR_NO_MEMORY;
432466486d89SBruce Allan 
4325cdedef59SAnirudh Venkataramanan 	mutex_lock(&pi->sched_lock);
4326cdedef59SAnirudh Venkataramanan 
4327cdedef59SAnirudh Venkataramanan 	for (i = 0; i < num_queues; i++) {
4328cdedef59SAnirudh Venkataramanan 		struct ice_sched_node *node;
4329cdedef59SAnirudh Venkataramanan 
4330cdedef59SAnirudh Venkataramanan 		node = ice_sched_find_node_by_teid(pi->root, q_teids[i]);
4331cdedef59SAnirudh Venkataramanan 		if (!node)
4332cdedef59SAnirudh Venkataramanan 			continue;
433366486d89SBruce Allan 		q_ctx = ice_get_lan_q_ctx(hw, vsi_handle, tc, q_handles[i]);
4334bb87ee0eSAnirudh Venkataramanan 		if (!q_ctx) {
433566486d89SBruce Allan 			ice_debug(hw, ICE_DBG_SCHED, "invalid queue handle%d\n",
4336bb87ee0eSAnirudh Venkataramanan 				  q_handles[i]);
4337bb87ee0eSAnirudh Venkataramanan 			continue;
4338bb87ee0eSAnirudh Venkataramanan 		}
4339bb87ee0eSAnirudh Venkataramanan 		if (q_ctx->q_handle != q_handles[i]) {
434066486d89SBruce Allan 			ice_debug(hw, ICE_DBG_SCHED, "Err:handles %d %d\n",
4341bb87ee0eSAnirudh Venkataramanan 				  q_ctx->q_handle, q_handles[i]);
4342bb87ee0eSAnirudh Venkataramanan 			continue;
4343bb87ee0eSAnirudh Venkataramanan 		}
434466486d89SBruce Allan 		qg_list->parent_teid = node->info.parent_teid;
434566486d89SBruce Allan 		qg_list->num_qs = 1;
434666486d89SBruce Allan 		qg_list->q_id[0] = cpu_to_le16(q_ids[i]);
434766486d89SBruce Allan 		status = ice_aq_dis_lan_txq(hw, 1, qg_list, buf_size, rst_src,
434866486d89SBruce Allan 					    vmvf_num, cd);
4349cdedef59SAnirudh Venkataramanan 
4350cdedef59SAnirudh Venkataramanan 		if (status)
4351cdedef59SAnirudh Venkataramanan 			break;
4352cdedef59SAnirudh Venkataramanan 		ice_free_sched_node(pi, node);
4353bb87ee0eSAnirudh Venkataramanan 		q_ctx->q_handle = ICE_INVAL_Q_HANDLE;
4354cdedef59SAnirudh Venkataramanan 	}
4355cdedef59SAnirudh Venkataramanan 	mutex_unlock(&pi->sched_lock);
435666486d89SBruce Allan 	kfree(qg_list);
4357cdedef59SAnirudh Venkataramanan 	return status;
4358cdedef59SAnirudh Venkataramanan }
43595513b920SAnirudh Venkataramanan 
43605513b920SAnirudh Venkataramanan /**
436194c4441bSAnirudh Venkataramanan  * ice_cfg_vsi_qs - configure the new/existing VSI queues
43625513b920SAnirudh Venkataramanan  * @pi: port information structure
43634fb33f31SAnirudh Venkataramanan  * @vsi_handle: software VSI handle
43645513b920SAnirudh Venkataramanan  * @tc_bitmap: TC bitmap
43655513b920SAnirudh Venkataramanan  * @maxqs: max queues array per TC
4366f9867df6SAnirudh Venkataramanan  * @owner: LAN or RDMA
43675513b920SAnirudh Venkataramanan  *
43685513b920SAnirudh Venkataramanan  * This function adds/updates the VSI queues per TC.
43695513b920SAnirudh Venkataramanan  */
4370*5e24d598STony Nguyen static int
43714fb33f31SAnirudh Venkataramanan ice_cfg_vsi_qs(struct ice_port_info *pi, u16 vsi_handle, u8 tc_bitmap,
43725513b920SAnirudh Venkataramanan 	       u16 *maxqs, u8 owner)
43735513b920SAnirudh Venkataramanan {
4374*5e24d598STony Nguyen 	int status = 0;
43755513b920SAnirudh Venkataramanan 	u8 i;
43765513b920SAnirudh Venkataramanan 
43775513b920SAnirudh Venkataramanan 	if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY)
43785513b920SAnirudh Venkataramanan 		return ICE_ERR_CFG;
43795513b920SAnirudh Venkataramanan 
43804fb33f31SAnirudh Venkataramanan 	if (!ice_is_vsi_valid(pi->hw, vsi_handle))
43814fb33f31SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
43824fb33f31SAnirudh Venkataramanan 
43835513b920SAnirudh Venkataramanan 	mutex_lock(&pi->sched_lock);
43845513b920SAnirudh Venkataramanan 
43852bdc97beSBruce Allan 	ice_for_each_traffic_class(i) {
43865513b920SAnirudh Venkataramanan 		/* configuration is possible only if TC node is present */
43875513b920SAnirudh Venkataramanan 		if (!ice_sched_get_tc_node(pi, i))
43885513b920SAnirudh Venkataramanan 			continue;
43895513b920SAnirudh Venkataramanan 
43904fb33f31SAnirudh Venkataramanan 		status = ice_sched_cfg_vsi(pi, vsi_handle, i, maxqs[i], owner,
43915513b920SAnirudh Venkataramanan 					   ice_is_tc_ena(tc_bitmap, i));
43925513b920SAnirudh Venkataramanan 		if (status)
43935513b920SAnirudh Venkataramanan 			break;
43945513b920SAnirudh Venkataramanan 	}
43955513b920SAnirudh Venkataramanan 
43965513b920SAnirudh Venkataramanan 	mutex_unlock(&pi->sched_lock);
43975513b920SAnirudh Venkataramanan 	return status;
43985513b920SAnirudh Venkataramanan }
43995513b920SAnirudh Venkataramanan 
44005513b920SAnirudh Venkataramanan /**
4401f9867df6SAnirudh Venkataramanan  * ice_cfg_vsi_lan - configure VSI LAN queues
44025513b920SAnirudh Venkataramanan  * @pi: port information structure
44034fb33f31SAnirudh Venkataramanan  * @vsi_handle: software VSI handle
44045513b920SAnirudh Venkataramanan  * @tc_bitmap: TC bitmap
4405f9867df6SAnirudh Venkataramanan  * @max_lanqs: max LAN queues array per TC
44065513b920SAnirudh Venkataramanan  *
4407f9867df6SAnirudh Venkataramanan  * This function adds/updates the VSI LAN queues per TC.
44085513b920SAnirudh Venkataramanan  */
4409*5e24d598STony Nguyen int
44104fb33f31SAnirudh Venkataramanan ice_cfg_vsi_lan(struct ice_port_info *pi, u16 vsi_handle, u8 tc_bitmap,
44115513b920SAnirudh Venkataramanan 		u16 *max_lanqs)
44125513b920SAnirudh Venkataramanan {
44134fb33f31SAnirudh Venkataramanan 	return ice_cfg_vsi_qs(pi, vsi_handle, tc_bitmap, max_lanqs,
44145513b920SAnirudh Venkataramanan 			      ICE_SCHED_NODE_OWNER_LAN);
44155513b920SAnirudh Venkataramanan }
441645d3d428SAnirudh Venkataramanan 
441745d3d428SAnirudh Venkataramanan /**
4418348048e7SDave Ertman  * ice_cfg_vsi_rdma - configure the VSI RDMA queues
4419348048e7SDave Ertman  * @pi: port information structure
4420348048e7SDave Ertman  * @vsi_handle: software VSI handle
4421348048e7SDave Ertman  * @tc_bitmap: TC bitmap
4422348048e7SDave Ertman  * @max_rdmaqs: max RDMA queues array per TC
4423348048e7SDave Ertman  *
4424348048e7SDave Ertman  * This function adds/updates the VSI RDMA queues per TC.
4425348048e7SDave Ertman  */
4426348048e7SDave Ertman int
4427348048e7SDave Ertman ice_cfg_vsi_rdma(struct ice_port_info *pi, u16 vsi_handle, u16 tc_bitmap,
4428348048e7SDave Ertman 		 u16 *max_rdmaqs)
4429348048e7SDave Ertman {
4430348048e7SDave Ertman 	return ice_status_to_errno(ice_cfg_vsi_qs(pi, vsi_handle, tc_bitmap,
4431348048e7SDave Ertman 						  max_rdmaqs,
4432348048e7SDave Ertman 						  ICE_SCHED_NODE_OWNER_RDMA));
4433348048e7SDave Ertman }
4434348048e7SDave Ertman 
4435348048e7SDave Ertman /**
4436348048e7SDave Ertman  * ice_ena_vsi_rdma_qset
4437348048e7SDave Ertman  * @pi: port information structure
4438348048e7SDave Ertman  * @vsi_handle: software VSI handle
4439348048e7SDave Ertman  * @tc: TC number
4440348048e7SDave Ertman  * @rdma_qset: pointer to RDMA Qset
4441348048e7SDave Ertman  * @num_qsets: number of RDMA Qsets
4442348048e7SDave Ertman  * @qset_teid: pointer to Qset node TEIDs
4443348048e7SDave Ertman  *
4444348048e7SDave Ertman  * This function adds RDMA Qset
4445348048e7SDave Ertman  */
4446348048e7SDave Ertman int
4447348048e7SDave Ertman ice_ena_vsi_rdma_qset(struct ice_port_info *pi, u16 vsi_handle, u8 tc,
4448348048e7SDave Ertman 		      u16 *rdma_qset, u16 num_qsets, u32 *qset_teid)
4449348048e7SDave Ertman {
4450348048e7SDave Ertman 	struct ice_aqc_txsched_elem_data node = { 0 };
4451348048e7SDave Ertman 	struct ice_aqc_add_rdma_qset_data *buf;
4452348048e7SDave Ertman 	struct ice_sched_node *parent;
4453*5e24d598STony Nguyen 	int status;
4454348048e7SDave Ertman 	struct ice_hw *hw;
4455348048e7SDave Ertman 	u16 i, buf_size;
4456348048e7SDave Ertman 	int ret;
4457348048e7SDave Ertman 
4458348048e7SDave Ertman 	if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY)
4459348048e7SDave Ertman 		return -EIO;
4460348048e7SDave Ertman 	hw = pi->hw;
4461348048e7SDave Ertman 
4462348048e7SDave Ertman 	if (!ice_is_vsi_valid(hw, vsi_handle))
4463348048e7SDave Ertman 		return -EINVAL;
4464348048e7SDave Ertman 
4465348048e7SDave Ertman 	buf_size = struct_size(buf, rdma_qsets, num_qsets);
4466348048e7SDave Ertman 	buf = kzalloc(buf_size, GFP_KERNEL);
4467348048e7SDave Ertman 	if (!buf)
4468348048e7SDave Ertman 		return -ENOMEM;
4469348048e7SDave Ertman 	mutex_lock(&pi->sched_lock);
4470348048e7SDave Ertman 
4471348048e7SDave Ertman 	parent = ice_sched_get_free_qparent(pi, vsi_handle, tc,
4472348048e7SDave Ertman 					    ICE_SCHED_NODE_OWNER_RDMA);
4473348048e7SDave Ertman 	if (!parent) {
4474348048e7SDave Ertman 		ret = -EINVAL;
4475348048e7SDave Ertman 		goto rdma_error_exit;
4476348048e7SDave Ertman 	}
4477348048e7SDave Ertman 	buf->parent_teid = parent->info.node_teid;
4478348048e7SDave Ertman 	node.parent_teid = parent->info.node_teid;
4479348048e7SDave Ertman 
4480348048e7SDave Ertman 	buf->num_qsets = cpu_to_le16(num_qsets);
4481348048e7SDave Ertman 	for (i = 0; i < num_qsets; i++) {
4482348048e7SDave Ertman 		buf->rdma_qsets[i].tx_qset_id = cpu_to_le16(rdma_qset[i]);
4483348048e7SDave Ertman 		buf->rdma_qsets[i].info.valid_sections =
4484348048e7SDave Ertman 			ICE_AQC_ELEM_VALID_GENERIC | ICE_AQC_ELEM_VALID_CIR |
4485348048e7SDave Ertman 			ICE_AQC_ELEM_VALID_EIR;
4486348048e7SDave Ertman 		buf->rdma_qsets[i].info.generic = 0;
4487348048e7SDave Ertman 		buf->rdma_qsets[i].info.cir_bw.bw_profile_idx =
4488348048e7SDave Ertman 			cpu_to_le16(ICE_SCHED_DFLT_RL_PROF_ID);
4489348048e7SDave Ertman 		buf->rdma_qsets[i].info.cir_bw.bw_alloc =
4490348048e7SDave Ertman 			cpu_to_le16(ICE_SCHED_DFLT_BW_WT);
4491348048e7SDave Ertman 		buf->rdma_qsets[i].info.eir_bw.bw_profile_idx =
4492348048e7SDave Ertman 			cpu_to_le16(ICE_SCHED_DFLT_RL_PROF_ID);
4493348048e7SDave Ertman 		buf->rdma_qsets[i].info.eir_bw.bw_alloc =
4494348048e7SDave Ertman 			cpu_to_le16(ICE_SCHED_DFLT_BW_WT);
4495348048e7SDave Ertman 	}
4496348048e7SDave Ertman 	ret = ice_aq_add_rdma_qsets(hw, 1, buf, buf_size, NULL);
4497348048e7SDave Ertman 	if (ret) {
4498348048e7SDave Ertman 		ice_debug(hw, ICE_DBG_RDMA, "add RDMA qset failed\n");
4499348048e7SDave Ertman 		goto rdma_error_exit;
4500348048e7SDave Ertman 	}
4501348048e7SDave Ertman 	node.data.elem_type = ICE_AQC_ELEM_TYPE_LEAF;
4502348048e7SDave Ertman 	for (i = 0; i < num_qsets; i++) {
4503348048e7SDave Ertman 		node.node_teid = buf->rdma_qsets[i].qset_teid;
4504348048e7SDave Ertman 		status = ice_sched_add_node(pi, hw->num_tx_sched_layers - 1,
4505348048e7SDave Ertman 					    &node);
4506348048e7SDave Ertman 		if (status) {
4507348048e7SDave Ertman 			ret = ice_status_to_errno(status);
4508348048e7SDave Ertman 			break;
4509348048e7SDave Ertman 		}
4510348048e7SDave Ertman 		qset_teid[i] = le32_to_cpu(node.node_teid);
4511348048e7SDave Ertman 	}
4512348048e7SDave Ertman rdma_error_exit:
4513348048e7SDave Ertman 	mutex_unlock(&pi->sched_lock);
4514348048e7SDave Ertman 	kfree(buf);
4515348048e7SDave Ertman 	return ret;
4516348048e7SDave Ertman }
4517348048e7SDave Ertman 
4518348048e7SDave Ertman /**
4519348048e7SDave Ertman  * ice_dis_vsi_rdma_qset - free RDMA resources
4520348048e7SDave Ertman  * @pi: port_info struct
4521348048e7SDave Ertman  * @count: number of RDMA Qsets to free
4522348048e7SDave Ertman  * @qset_teid: TEID of Qset node
4523348048e7SDave Ertman  * @q_id: list of queue IDs being disabled
4524348048e7SDave Ertman  */
4525348048e7SDave Ertman int
4526348048e7SDave Ertman ice_dis_vsi_rdma_qset(struct ice_port_info *pi, u16 count, u32 *qset_teid,
4527348048e7SDave Ertman 		      u16 *q_id)
4528348048e7SDave Ertman {
4529348048e7SDave Ertman 	struct ice_aqc_dis_txq_item *qg_list;
4530*5e24d598STony Nguyen 	int status = 0;
4531348048e7SDave Ertman 	struct ice_hw *hw;
4532348048e7SDave Ertman 	u16 qg_size;
4533348048e7SDave Ertman 	int i;
4534348048e7SDave Ertman 
4535348048e7SDave Ertman 	if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY)
4536348048e7SDave Ertman 		return -EIO;
4537348048e7SDave Ertman 
4538348048e7SDave Ertman 	hw = pi->hw;
4539348048e7SDave Ertman 
4540348048e7SDave Ertman 	qg_size = struct_size(qg_list, q_id, 1);
4541348048e7SDave Ertman 	qg_list = kzalloc(qg_size, GFP_KERNEL);
4542348048e7SDave Ertman 	if (!qg_list)
4543348048e7SDave Ertman 		return -ENOMEM;
4544348048e7SDave Ertman 
4545348048e7SDave Ertman 	mutex_lock(&pi->sched_lock);
4546348048e7SDave Ertman 
4547348048e7SDave Ertman 	for (i = 0; i < count; i++) {
4548348048e7SDave Ertman 		struct ice_sched_node *node;
4549348048e7SDave Ertman 
4550348048e7SDave Ertman 		node = ice_sched_find_node_by_teid(pi->root, qset_teid[i]);
4551348048e7SDave Ertman 		if (!node)
4552348048e7SDave Ertman 			continue;
4553348048e7SDave Ertman 
4554348048e7SDave Ertman 		qg_list->parent_teid = node->info.parent_teid;
4555348048e7SDave Ertman 		qg_list->num_qs = 1;
4556348048e7SDave Ertman 		qg_list->q_id[0] =
4557348048e7SDave Ertman 			cpu_to_le16(q_id[i] |
4558348048e7SDave Ertman 				    ICE_AQC_Q_DIS_BUF_ELEM_TYPE_RDMA_QSET);
4559348048e7SDave Ertman 
4560348048e7SDave Ertman 		status = ice_aq_dis_lan_txq(hw, 1, qg_list, qg_size,
4561348048e7SDave Ertman 					    ICE_NO_RESET, 0, NULL);
4562348048e7SDave Ertman 		if (status)
4563348048e7SDave Ertman 			break;
4564348048e7SDave Ertman 
4565348048e7SDave Ertman 		ice_free_sched_node(pi, node);
4566348048e7SDave Ertman 	}
4567348048e7SDave Ertman 
4568348048e7SDave Ertman 	mutex_unlock(&pi->sched_lock);
4569348048e7SDave Ertman 	kfree(qg_list);
4570348048e7SDave Ertman 	return ice_status_to_errno(status);
4571348048e7SDave Ertman }
4572348048e7SDave Ertman 
4573348048e7SDave Ertman /**
4574334cb062SAnirudh Venkataramanan  * ice_replay_pre_init - replay pre initialization
4575f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
4576334cb062SAnirudh Venkataramanan  *
4577334cb062SAnirudh Venkataramanan  * Initializes required config data for VSI, FD, ACL, and RSS before replay.
4578334cb062SAnirudh Venkataramanan  */
4579*5e24d598STony Nguyen static int ice_replay_pre_init(struct ice_hw *hw)
4580334cb062SAnirudh Venkataramanan {
4581334cb062SAnirudh Venkataramanan 	struct ice_switch_info *sw = hw->switch_info;
4582334cb062SAnirudh Venkataramanan 	u8 i;
4583334cb062SAnirudh Venkataramanan 
4584334cb062SAnirudh Venkataramanan 	/* Delete old entries from replay filter list head if there is any */
4585334cb062SAnirudh Venkataramanan 	ice_rm_all_sw_replay_rule_info(hw);
4586334cb062SAnirudh Venkataramanan 	/* In start of replay, move entries into replay_rules list, it
4587334cb062SAnirudh Venkataramanan 	 * will allow adding rules entries back to filt_rules list,
4588334cb062SAnirudh Venkataramanan 	 * which is operational list.
4589334cb062SAnirudh Venkataramanan 	 */
4590334cb062SAnirudh Venkataramanan 	for (i = 0; i < ICE_SW_LKUP_LAST; i++)
4591334cb062SAnirudh Venkataramanan 		list_replace_init(&sw->recp_list[i].filt_rules,
4592334cb062SAnirudh Venkataramanan 				  &sw->recp_list[i].filt_replay_rules);
4593b126bd6bSKiran Patil 	ice_sched_replay_agg_vsi_preinit(hw);
4594334cb062SAnirudh Venkataramanan 
4595334cb062SAnirudh Venkataramanan 	return 0;
4596334cb062SAnirudh Venkataramanan }
4597334cb062SAnirudh Venkataramanan 
4598334cb062SAnirudh Venkataramanan /**
4599334cb062SAnirudh Venkataramanan  * ice_replay_vsi - replay VSI configuration
4600f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
4601334cb062SAnirudh Venkataramanan  * @vsi_handle: driver VSI handle
4602334cb062SAnirudh Venkataramanan  *
4603334cb062SAnirudh Venkataramanan  * Restore all VSI configuration after reset. It is required to call this
4604334cb062SAnirudh Venkataramanan  * function with main VSI first.
4605334cb062SAnirudh Venkataramanan  */
4606*5e24d598STony Nguyen int ice_replay_vsi(struct ice_hw *hw, u16 vsi_handle)
4607334cb062SAnirudh Venkataramanan {
4608*5e24d598STony Nguyen 	int status;
4609334cb062SAnirudh Venkataramanan 
4610334cb062SAnirudh Venkataramanan 	if (!ice_is_vsi_valid(hw, vsi_handle))
4611334cb062SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
4612334cb062SAnirudh Venkataramanan 
4613334cb062SAnirudh Venkataramanan 	/* Replay pre-initialization if there is any */
4614334cb062SAnirudh Venkataramanan 	if (vsi_handle == ICE_MAIN_VSI_HANDLE) {
4615334cb062SAnirudh Venkataramanan 		status = ice_replay_pre_init(hw);
4616334cb062SAnirudh Venkataramanan 		if (status)
4617334cb062SAnirudh Venkataramanan 			return status;
4618334cb062SAnirudh Venkataramanan 	}
4619c90ed40cSTony Nguyen 	/* Replay per VSI all RSS configurations */
4620c90ed40cSTony Nguyen 	status = ice_replay_rss_cfg(hw, vsi_handle);
4621c90ed40cSTony Nguyen 	if (status)
4622c90ed40cSTony Nguyen 		return status;
4623334cb062SAnirudh Venkataramanan 	/* Replay per VSI all filters */
4624334cb062SAnirudh Venkataramanan 	status = ice_replay_vsi_all_fltr(hw, vsi_handle);
4625b126bd6bSKiran Patil 	if (!status)
4626b126bd6bSKiran Patil 		status = ice_replay_vsi_agg(hw, vsi_handle);
4627334cb062SAnirudh Venkataramanan 	return status;
4628334cb062SAnirudh Venkataramanan }
4629334cb062SAnirudh Venkataramanan 
4630334cb062SAnirudh Venkataramanan /**
4631334cb062SAnirudh Venkataramanan  * ice_replay_post - post replay configuration cleanup
4632f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
4633334cb062SAnirudh Venkataramanan  *
4634334cb062SAnirudh Venkataramanan  * Post replay cleanup.
4635334cb062SAnirudh Venkataramanan  */
4636334cb062SAnirudh Venkataramanan void ice_replay_post(struct ice_hw *hw)
4637334cb062SAnirudh Venkataramanan {
4638334cb062SAnirudh Venkataramanan 	/* Delete old entries from replay filter list head */
4639334cb062SAnirudh Venkataramanan 	ice_rm_all_sw_replay_rule_info(hw);
4640b126bd6bSKiran Patil 	ice_sched_replay_agg(hw);
4641334cb062SAnirudh Venkataramanan }
4642334cb062SAnirudh Venkataramanan 
4643334cb062SAnirudh Venkataramanan /**
464445d3d428SAnirudh Venkataramanan  * ice_stat_update40 - read 40 bit stat from the chip and update stat values
464545d3d428SAnirudh Venkataramanan  * @hw: ptr to the hardware info
464636517fd3SJacob Keller  * @reg: offset of 64 bit HW register to read from
464745d3d428SAnirudh Venkataramanan  * @prev_stat_loaded: bool to specify if previous stats are loaded
464845d3d428SAnirudh Venkataramanan  * @prev_stat: ptr to previous loaded stat value
464945d3d428SAnirudh Venkataramanan  * @cur_stat: ptr to current stat value
465045d3d428SAnirudh Venkataramanan  */
4651c8b7abddSBruce Allan void
465236517fd3SJacob Keller ice_stat_update40(struct ice_hw *hw, u32 reg, bool prev_stat_loaded,
465336517fd3SJacob Keller 		  u64 *prev_stat, u64 *cur_stat)
465445d3d428SAnirudh Venkataramanan {
465536517fd3SJacob Keller 	u64 new_data = rd64(hw, reg) & (BIT_ULL(40) - 1);
465645d3d428SAnirudh Venkataramanan 
465745d3d428SAnirudh Venkataramanan 	/* device stats are not reset at PFR, they likely will not be zeroed
465836517fd3SJacob Keller 	 * when the driver starts. Thus, save the value from the first read
465936517fd3SJacob Keller 	 * without adding to the statistic value so that we report stats which
466036517fd3SJacob Keller 	 * count up from zero.
466145d3d428SAnirudh Venkataramanan 	 */
466236517fd3SJacob Keller 	if (!prev_stat_loaded) {
466345d3d428SAnirudh Venkataramanan 		*prev_stat = new_data;
466436517fd3SJacob Keller 		return;
466536517fd3SJacob Keller 	}
466636517fd3SJacob Keller 
466736517fd3SJacob Keller 	/* Calculate the difference between the new and old values, and then
466836517fd3SJacob Keller 	 * add it to the software stat value.
466936517fd3SJacob Keller 	 */
467045d3d428SAnirudh Venkataramanan 	if (new_data >= *prev_stat)
467136517fd3SJacob Keller 		*cur_stat += new_data - *prev_stat;
467245d3d428SAnirudh Venkataramanan 	else
467345d3d428SAnirudh Venkataramanan 		/* to manage the potential roll-over */
467436517fd3SJacob Keller 		*cur_stat += (new_data + BIT_ULL(40)) - *prev_stat;
467536517fd3SJacob Keller 
467636517fd3SJacob Keller 	/* Update the previously stored value to prepare for next read */
467736517fd3SJacob Keller 	*prev_stat = new_data;
467845d3d428SAnirudh Venkataramanan }
467945d3d428SAnirudh Venkataramanan 
468045d3d428SAnirudh Venkataramanan /**
468145d3d428SAnirudh Venkataramanan  * ice_stat_update32 - read 32 bit stat from the chip and update stat values
468245d3d428SAnirudh Venkataramanan  * @hw: ptr to the hardware info
468336517fd3SJacob Keller  * @reg: offset of HW register to read from
468445d3d428SAnirudh Venkataramanan  * @prev_stat_loaded: bool to specify if previous stats are loaded
468545d3d428SAnirudh Venkataramanan  * @prev_stat: ptr to previous loaded stat value
468645d3d428SAnirudh Venkataramanan  * @cur_stat: ptr to current stat value
468745d3d428SAnirudh Venkataramanan  */
4688c8b7abddSBruce Allan void
4689c8b7abddSBruce Allan ice_stat_update32(struct ice_hw *hw, u32 reg, bool prev_stat_loaded,
469045d3d428SAnirudh Venkataramanan 		  u64 *prev_stat, u64 *cur_stat)
469145d3d428SAnirudh Venkataramanan {
469245d3d428SAnirudh Venkataramanan 	u32 new_data;
469345d3d428SAnirudh Venkataramanan 
469445d3d428SAnirudh Venkataramanan 	new_data = rd32(hw, reg);
469545d3d428SAnirudh Venkataramanan 
469645d3d428SAnirudh Venkataramanan 	/* device stats are not reset at PFR, they likely will not be zeroed
469736517fd3SJacob Keller 	 * when the driver starts. Thus, save the value from the first read
469836517fd3SJacob Keller 	 * without adding to the statistic value so that we report stats which
469936517fd3SJacob Keller 	 * count up from zero.
470045d3d428SAnirudh Venkataramanan 	 */
470136517fd3SJacob Keller 	if (!prev_stat_loaded) {
470245d3d428SAnirudh Venkataramanan 		*prev_stat = new_data;
470336517fd3SJacob Keller 		return;
470436517fd3SJacob Keller 	}
470536517fd3SJacob Keller 
470636517fd3SJacob Keller 	/* Calculate the difference between the new and old values, and then
470736517fd3SJacob Keller 	 * add it to the software stat value.
470836517fd3SJacob Keller 	 */
470945d3d428SAnirudh Venkataramanan 	if (new_data >= *prev_stat)
471036517fd3SJacob Keller 		*cur_stat += new_data - *prev_stat;
471145d3d428SAnirudh Venkataramanan 	else
471245d3d428SAnirudh Venkataramanan 		/* to manage the potential roll-over */
471336517fd3SJacob Keller 		*cur_stat += (new_data + BIT_ULL(32)) - *prev_stat;
471436517fd3SJacob Keller 
471536517fd3SJacob Keller 	/* Update the previously stored value to prepare for next read */
471636517fd3SJacob Keller 	*prev_stat = new_data;
471745d3d428SAnirudh Venkataramanan }
47187b9ffc76SAnirudh Venkataramanan 
47197b9ffc76SAnirudh Venkataramanan /**
47207b9ffc76SAnirudh Venkataramanan  * ice_sched_query_elem - query element information from HW
47217b9ffc76SAnirudh Venkataramanan  * @hw: pointer to the HW struct
47227b9ffc76SAnirudh Venkataramanan  * @node_teid: node TEID to be queried
47237b9ffc76SAnirudh Venkataramanan  * @buf: buffer to element information
47247b9ffc76SAnirudh Venkataramanan  *
47257b9ffc76SAnirudh Venkataramanan  * This function queries HW element information
47267b9ffc76SAnirudh Venkataramanan  */
4727*5e24d598STony Nguyen int
47287b9ffc76SAnirudh Venkataramanan ice_sched_query_elem(struct ice_hw *hw, u32 node_teid,
4729b3c38904SBruce Allan 		     struct ice_aqc_txsched_elem_data *buf)
47307b9ffc76SAnirudh Venkataramanan {
47317b9ffc76SAnirudh Venkataramanan 	u16 buf_size, num_elem_ret = 0;
4732*5e24d598STony Nguyen 	int status;
47337b9ffc76SAnirudh Venkataramanan 
47347b9ffc76SAnirudh Venkataramanan 	buf_size = sizeof(*buf);
47357b9ffc76SAnirudh Venkataramanan 	memset(buf, 0, buf_size);
4736b3c38904SBruce Allan 	buf->node_teid = cpu_to_le32(node_teid);
47377b9ffc76SAnirudh Venkataramanan 	status = ice_aq_query_sched_elems(hw, 1, buf, buf_size, &num_elem_ret,
47387b9ffc76SAnirudh Venkataramanan 					  NULL);
47397b9ffc76SAnirudh Venkataramanan 	if (status || num_elem_ret != 1)
47407b9ffc76SAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_SCHED, "query element failed\n");
47417b9ffc76SAnirudh Venkataramanan 	return status;
47427b9ffc76SAnirudh Venkataramanan }
4743ea78ce4dSPaul Greenwalt 
4744ea78ce4dSPaul Greenwalt /**
47457f9ab54dSJacob Keller  * ice_aq_set_driver_param - Set driver parameter to share via firmware
47467f9ab54dSJacob Keller  * @hw: pointer to the HW struct
47477f9ab54dSJacob Keller  * @idx: parameter index to set
47487f9ab54dSJacob Keller  * @value: the value to set the parameter to
47497f9ab54dSJacob Keller  * @cd: pointer to command details structure or NULL
47507f9ab54dSJacob Keller  *
47517f9ab54dSJacob Keller  * Set the value of one of the software defined parameters. All PFs connected
47527f9ab54dSJacob Keller  * to this device can read the value using ice_aq_get_driver_param.
47537f9ab54dSJacob Keller  *
47547f9ab54dSJacob Keller  * Note that firmware provides no synchronization or locking, and will not
47557f9ab54dSJacob Keller  * save the parameter value during a device reset. It is expected that
47567f9ab54dSJacob Keller  * a single PF will write the parameter value, while all other PFs will only
47577f9ab54dSJacob Keller  * read it.
47587f9ab54dSJacob Keller  */
47597f9ab54dSJacob Keller int
47607f9ab54dSJacob Keller ice_aq_set_driver_param(struct ice_hw *hw, enum ice_aqc_driver_params idx,
47617f9ab54dSJacob Keller 			u32 value, struct ice_sq_cd *cd)
47627f9ab54dSJacob Keller {
47637f9ab54dSJacob Keller 	struct ice_aqc_driver_shared_params *cmd;
47647f9ab54dSJacob Keller 	struct ice_aq_desc desc;
47657f9ab54dSJacob Keller 
47667f9ab54dSJacob Keller 	if (idx >= ICE_AQC_DRIVER_PARAM_MAX)
47677f9ab54dSJacob Keller 		return -EIO;
47687f9ab54dSJacob Keller 
47697f9ab54dSJacob Keller 	cmd = &desc.params.drv_shared_params;
47707f9ab54dSJacob Keller 
47717f9ab54dSJacob Keller 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_driver_shared_params);
47727f9ab54dSJacob Keller 
47737f9ab54dSJacob Keller 	cmd->set_or_get_op = ICE_AQC_DRIVER_PARAM_SET;
47747f9ab54dSJacob Keller 	cmd->param_indx = idx;
47757f9ab54dSJacob Keller 	cmd->param_val = cpu_to_le32(value);
47767f9ab54dSJacob Keller 
47777f9ab54dSJacob Keller 	return ice_status_to_errno(ice_aq_send_cmd(hw, &desc, NULL, 0, cd));
47787f9ab54dSJacob Keller }
47797f9ab54dSJacob Keller 
47807f9ab54dSJacob Keller /**
47817f9ab54dSJacob Keller  * ice_aq_get_driver_param - Get driver parameter shared via firmware
47827f9ab54dSJacob Keller  * @hw: pointer to the HW struct
47837f9ab54dSJacob Keller  * @idx: parameter index to set
47847f9ab54dSJacob Keller  * @value: storage to return the shared parameter
47857f9ab54dSJacob Keller  * @cd: pointer to command details structure or NULL
47867f9ab54dSJacob Keller  *
47877f9ab54dSJacob Keller  * Get the value of one of the software defined parameters.
47887f9ab54dSJacob Keller  *
47897f9ab54dSJacob Keller  * Note that firmware provides no synchronization or locking. It is expected
47907f9ab54dSJacob Keller  * that only a single PF will write a given parameter.
47917f9ab54dSJacob Keller  */
47927f9ab54dSJacob Keller int
47937f9ab54dSJacob Keller ice_aq_get_driver_param(struct ice_hw *hw, enum ice_aqc_driver_params idx,
47947f9ab54dSJacob Keller 			u32 *value, struct ice_sq_cd *cd)
47957f9ab54dSJacob Keller {
47967f9ab54dSJacob Keller 	struct ice_aqc_driver_shared_params *cmd;
47977f9ab54dSJacob Keller 	struct ice_aq_desc desc;
4798*5e24d598STony Nguyen 	int status;
47997f9ab54dSJacob Keller 
48007f9ab54dSJacob Keller 	if (idx >= ICE_AQC_DRIVER_PARAM_MAX)
48017f9ab54dSJacob Keller 		return -EIO;
48027f9ab54dSJacob Keller 
48037f9ab54dSJacob Keller 	cmd = &desc.params.drv_shared_params;
48047f9ab54dSJacob Keller 
48057f9ab54dSJacob Keller 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_driver_shared_params);
48067f9ab54dSJacob Keller 
48077f9ab54dSJacob Keller 	cmd->set_or_get_op = ICE_AQC_DRIVER_PARAM_GET;
48087f9ab54dSJacob Keller 	cmd->param_indx = idx;
48097f9ab54dSJacob Keller 
48107f9ab54dSJacob Keller 	status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
48117f9ab54dSJacob Keller 	if (status)
48127f9ab54dSJacob Keller 		return ice_status_to_errno(status);
48137f9ab54dSJacob Keller 
48147f9ab54dSJacob Keller 	*value = le32_to_cpu(cmd->param_val);
48157f9ab54dSJacob Keller 
48167f9ab54dSJacob Keller 	return 0;
48177f9ab54dSJacob Keller }
48187f9ab54dSJacob Keller 
48197f9ab54dSJacob Keller /**
48203bb6324bSMaciej Machnikowski  * ice_aq_set_gpio
48213bb6324bSMaciej Machnikowski  * @hw: pointer to the hw struct
48223bb6324bSMaciej Machnikowski  * @gpio_ctrl_handle: GPIO controller node handle
48233bb6324bSMaciej Machnikowski  * @pin_idx: IO Number of the GPIO that needs to be set
48243bb6324bSMaciej Machnikowski  * @value: SW provide IO value to set in the LSB
48253bb6324bSMaciej Machnikowski  * @cd: pointer to command details structure or NULL
48263bb6324bSMaciej Machnikowski  *
48273bb6324bSMaciej Machnikowski  * Sends 0x06EC AQ command to set the GPIO pin state that's part of the topology
48283bb6324bSMaciej Machnikowski  */
48293bb6324bSMaciej Machnikowski int
48303bb6324bSMaciej Machnikowski ice_aq_set_gpio(struct ice_hw *hw, u16 gpio_ctrl_handle, u8 pin_idx, bool value,
48313bb6324bSMaciej Machnikowski 		struct ice_sq_cd *cd)
48323bb6324bSMaciej Machnikowski {
48333bb6324bSMaciej Machnikowski 	struct ice_aqc_gpio *cmd;
48343bb6324bSMaciej Machnikowski 	struct ice_aq_desc desc;
48353bb6324bSMaciej Machnikowski 
48363bb6324bSMaciej Machnikowski 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_gpio);
48373bb6324bSMaciej Machnikowski 	cmd = &desc.params.read_write_gpio;
48383bb6324bSMaciej Machnikowski 	cmd->gpio_ctrl_handle = cpu_to_le16(gpio_ctrl_handle);
48393bb6324bSMaciej Machnikowski 	cmd->gpio_num = pin_idx;
48403bb6324bSMaciej Machnikowski 	cmd->gpio_val = value ? 1 : 0;
48413bb6324bSMaciej Machnikowski 
48423bb6324bSMaciej Machnikowski 	return ice_status_to_errno(ice_aq_send_cmd(hw, &desc, NULL, 0, cd));
48433bb6324bSMaciej Machnikowski }
48443bb6324bSMaciej Machnikowski 
48453bb6324bSMaciej Machnikowski /**
48463bb6324bSMaciej Machnikowski  * ice_aq_get_gpio
48473bb6324bSMaciej Machnikowski  * @hw: pointer to the hw struct
48483bb6324bSMaciej Machnikowski  * @gpio_ctrl_handle: GPIO controller node handle
48493bb6324bSMaciej Machnikowski  * @pin_idx: IO Number of the GPIO that needs to be set
48503bb6324bSMaciej Machnikowski  * @value: IO value read
48513bb6324bSMaciej Machnikowski  * @cd: pointer to command details structure or NULL
48523bb6324bSMaciej Machnikowski  *
48533bb6324bSMaciej Machnikowski  * Sends 0x06ED AQ command to get the value of a GPIO signal which is part of
48543bb6324bSMaciej Machnikowski  * the topology
48553bb6324bSMaciej Machnikowski  */
48563bb6324bSMaciej Machnikowski int
48573bb6324bSMaciej Machnikowski ice_aq_get_gpio(struct ice_hw *hw, u16 gpio_ctrl_handle, u8 pin_idx,
48583bb6324bSMaciej Machnikowski 		bool *value, struct ice_sq_cd *cd)
48593bb6324bSMaciej Machnikowski {
48603bb6324bSMaciej Machnikowski 	struct ice_aqc_gpio *cmd;
48613bb6324bSMaciej Machnikowski 	struct ice_aq_desc desc;
4862*5e24d598STony Nguyen 	int status;
48633bb6324bSMaciej Machnikowski 
48643bb6324bSMaciej Machnikowski 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_gpio);
48653bb6324bSMaciej Machnikowski 	cmd = &desc.params.read_write_gpio;
48663bb6324bSMaciej Machnikowski 	cmd->gpio_ctrl_handle = cpu_to_le16(gpio_ctrl_handle);
48673bb6324bSMaciej Machnikowski 	cmd->gpio_num = pin_idx;
48683bb6324bSMaciej Machnikowski 
48693bb6324bSMaciej Machnikowski 	status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
48703bb6324bSMaciej Machnikowski 	if (status)
48713bb6324bSMaciej Machnikowski 		return ice_status_to_errno(status);
48723bb6324bSMaciej Machnikowski 
48733bb6324bSMaciej Machnikowski 	*value = !!cmd->gpio_val;
48743bb6324bSMaciej Machnikowski 	return 0;
48753bb6324bSMaciej Machnikowski }
48763bb6324bSMaciej Machnikowski 
48773bb6324bSMaciej Machnikowski /**
4878ea78ce4dSPaul Greenwalt  * ice_fw_supports_link_override
4879ea78ce4dSPaul Greenwalt  * @hw: pointer to the hardware structure
4880ea78ce4dSPaul Greenwalt  *
4881ea78ce4dSPaul Greenwalt  * Checks if the firmware supports link override
4882ea78ce4dSPaul Greenwalt  */
4883ea78ce4dSPaul Greenwalt bool ice_fw_supports_link_override(struct ice_hw *hw)
4884ea78ce4dSPaul Greenwalt {
4885ea78ce4dSPaul Greenwalt 	if (hw->api_maj_ver == ICE_FW_API_LINK_OVERRIDE_MAJ) {
4886ea78ce4dSPaul Greenwalt 		if (hw->api_min_ver > ICE_FW_API_LINK_OVERRIDE_MIN)
4887ea78ce4dSPaul Greenwalt 			return true;
4888ea78ce4dSPaul Greenwalt 		if (hw->api_min_ver == ICE_FW_API_LINK_OVERRIDE_MIN &&
4889ea78ce4dSPaul Greenwalt 		    hw->api_patch >= ICE_FW_API_LINK_OVERRIDE_PATCH)
4890ea78ce4dSPaul Greenwalt 			return true;
4891ea78ce4dSPaul Greenwalt 	} else if (hw->api_maj_ver > ICE_FW_API_LINK_OVERRIDE_MAJ) {
4892ea78ce4dSPaul Greenwalt 		return true;
4893ea78ce4dSPaul Greenwalt 	}
4894ea78ce4dSPaul Greenwalt 
4895ea78ce4dSPaul Greenwalt 	return false;
4896ea78ce4dSPaul Greenwalt }
4897ea78ce4dSPaul Greenwalt 
4898ea78ce4dSPaul Greenwalt /**
4899ea78ce4dSPaul Greenwalt  * ice_get_link_default_override
4900ea78ce4dSPaul Greenwalt  * @ldo: pointer to the link default override struct
4901ea78ce4dSPaul Greenwalt  * @pi: pointer to the port info struct
4902ea78ce4dSPaul Greenwalt  *
4903ea78ce4dSPaul Greenwalt  * Gets the link default override for a port
4904ea78ce4dSPaul Greenwalt  */
4905*5e24d598STony Nguyen int
4906ea78ce4dSPaul Greenwalt ice_get_link_default_override(struct ice_link_default_override_tlv *ldo,
4907ea78ce4dSPaul Greenwalt 			      struct ice_port_info *pi)
4908ea78ce4dSPaul Greenwalt {
4909ea78ce4dSPaul Greenwalt 	u16 i, tlv, tlv_len, tlv_start, buf, offset;
4910ea78ce4dSPaul Greenwalt 	struct ice_hw *hw = pi->hw;
4911*5e24d598STony Nguyen 	int status;
4912ea78ce4dSPaul Greenwalt 
4913ea78ce4dSPaul Greenwalt 	status = ice_get_pfa_module_tlv(hw, &tlv, &tlv_len,
4914ea78ce4dSPaul Greenwalt 					ICE_SR_LINK_DEFAULT_OVERRIDE_PTR);
4915ea78ce4dSPaul Greenwalt 	if (status) {
49169228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "Failed to read link override TLV.\n");
4917ea78ce4dSPaul Greenwalt 		return status;
4918ea78ce4dSPaul Greenwalt 	}
4919ea78ce4dSPaul Greenwalt 
4920ea78ce4dSPaul Greenwalt 	/* Each port has its own config; calculate for our port */
4921ea78ce4dSPaul Greenwalt 	tlv_start = tlv + pi->lport * ICE_SR_PFA_LINK_OVERRIDE_WORDS +
4922ea78ce4dSPaul Greenwalt 		ICE_SR_PFA_LINK_OVERRIDE_OFFSET;
4923ea78ce4dSPaul Greenwalt 
4924ea78ce4dSPaul Greenwalt 	/* link options first */
4925ea78ce4dSPaul Greenwalt 	status = ice_read_sr_word(hw, tlv_start, &buf);
4926ea78ce4dSPaul Greenwalt 	if (status) {
49279228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "Failed to read override link options.\n");
4928ea78ce4dSPaul Greenwalt 		return status;
4929ea78ce4dSPaul Greenwalt 	}
4930ea78ce4dSPaul Greenwalt 	ldo->options = buf & ICE_LINK_OVERRIDE_OPT_M;
4931ea78ce4dSPaul Greenwalt 	ldo->phy_config = (buf & ICE_LINK_OVERRIDE_PHY_CFG_M) >>
4932ea78ce4dSPaul Greenwalt 		ICE_LINK_OVERRIDE_PHY_CFG_S;
4933ea78ce4dSPaul Greenwalt 
4934ea78ce4dSPaul Greenwalt 	/* link PHY config */
4935ea78ce4dSPaul Greenwalt 	offset = tlv_start + ICE_SR_PFA_LINK_OVERRIDE_FEC_OFFSET;
4936ea78ce4dSPaul Greenwalt 	status = ice_read_sr_word(hw, offset, &buf);
4937ea78ce4dSPaul Greenwalt 	if (status) {
49389228d8b2SJacob Keller 		ice_debug(hw, ICE_DBG_INIT, "Failed to read override phy config.\n");
4939ea78ce4dSPaul Greenwalt 		return status;
4940ea78ce4dSPaul Greenwalt 	}
4941ea78ce4dSPaul Greenwalt 	ldo->fec_options = buf & ICE_LINK_OVERRIDE_FEC_OPT_M;
4942ea78ce4dSPaul Greenwalt 
4943ea78ce4dSPaul Greenwalt 	/* PHY types low */
4944ea78ce4dSPaul Greenwalt 	offset = tlv_start + ICE_SR_PFA_LINK_OVERRIDE_PHY_OFFSET;
4945ea78ce4dSPaul Greenwalt 	for (i = 0; i < ICE_SR_PFA_LINK_OVERRIDE_PHY_WORDS; i++) {
4946ea78ce4dSPaul Greenwalt 		status = ice_read_sr_word(hw, (offset + i), &buf);
4947ea78ce4dSPaul Greenwalt 		if (status) {
49489228d8b2SJacob Keller 			ice_debug(hw, ICE_DBG_INIT, "Failed to read override link options.\n");
4949ea78ce4dSPaul Greenwalt 			return status;
4950ea78ce4dSPaul Greenwalt 		}
4951ea78ce4dSPaul Greenwalt 		/* shift 16 bits at a time to fill 64 bits */
4952ea78ce4dSPaul Greenwalt 		ldo->phy_type_low |= ((u64)buf << (i * 16));
4953ea78ce4dSPaul Greenwalt 	}
4954ea78ce4dSPaul Greenwalt 
4955ea78ce4dSPaul Greenwalt 	/* PHY types high */
4956ea78ce4dSPaul Greenwalt 	offset = tlv_start + ICE_SR_PFA_LINK_OVERRIDE_PHY_OFFSET +
4957ea78ce4dSPaul Greenwalt 		ICE_SR_PFA_LINK_OVERRIDE_PHY_WORDS;
4958ea78ce4dSPaul Greenwalt 	for (i = 0; i < ICE_SR_PFA_LINK_OVERRIDE_PHY_WORDS; i++) {
4959ea78ce4dSPaul Greenwalt 		status = ice_read_sr_word(hw, (offset + i), &buf);
4960ea78ce4dSPaul Greenwalt 		if (status) {
49619228d8b2SJacob Keller 			ice_debug(hw, ICE_DBG_INIT, "Failed to read override link options.\n");
4962ea78ce4dSPaul Greenwalt 			return status;
4963ea78ce4dSPaul Greenwalt 		}
4964ea78ce4dSPaul Greenwalt 		/* shift 16 bits at a time to fill 64 bits */
4965ea78ce4dSPaul Greenwalt 		ldo->phy_type_high |= ((u64)buf << (i * 16));
4966ea78ce4dSPaul Greenwalt 	}
4967ea78ce4dSPaul Greenwalt 
4968ea78ce4dSPaul Greenwalt 	return status;
4969ea78ce4dSPaul Greenwalt }
49705ee30564SPaul Greenwalt 
49715ee30564SPaul Greenwalt /**
49725ee30564SPaul Greenwalt  * ice_is_phy_caps_an_enabled - check if PHY capabilities autoneg is enabled
49735ee30564SPaul Greenwalt  * @caps: get PHY capability data
49745ee30564SPaul Greenwalt  */
49755ee30564SPaul Greenwalt bool ice_is_phy_caps_an_enabled(struct ice_aqc_get_phy_caps_data *caps)
49765ee30564SPaul Greenwalt {
49775ee30564SPaul Greenwalt 	if (caps->caps & ICE_AQC_PHY_AN_MODE ||
4978bdeff971SLev Faerman 	    caps->low_power_ctrl_an & (ICE_AQC_PHY_AN_EN_CLAUSE28 |
49795ee30564SPaul Greenwalt 				       ICE_AQC_PHY_AN_EN_CLAUSE73 |
49805ee30564SPaul Greenwalt 				       ICE_AQC_PHY_AN_EN_CLAUSE37))
49815ee30564SPaul Greenwalt 		return true;
49825ee30564SPaul Greenwalt 
49835ee30564SPaul Greenwalt 	return false;
49845ee30564SPaul Greenwalt }
49857d9c9b79SDave Ertman 
49867d9c9b79SDave Ertman /**
49877d9c9b79SDave Ertman  * ice_aq_set_lldp_mib - Set the LLDP MIB
49887d9c9b79SDave Ertman  * @hw: pointer to the HW struct
49897d9c9b79SDave Ertman  * @mib_type: Local, Remote or both Local and Remote MIBs
49907d9c9b79SDave Ertman  * @buf: pointer to the caller-supplied buffer to store the MIB block
49917d9c9b79SDave Ertman  * @buf_size: size of the buffer (in bytes)
49927d9c9b79SDave Ertman  * @cd: pointer to command details structure or NULL
49937d9c9b79SDave Ertman  *
49947d9c9b79SDave Ertman  * Set the LLDP MIB. (0x0A08)
49957d9c9b79SDave Ertman  */
4996*5e24d598STony Nguyen int
49977d9c9b79SDave Ertman ice_aq_set_lldp_mib(struct ice_hw *hw, u8 mib_type, void *buf, u16 buf_size,
49987d9c9b79SDave Ertman 		    struct ice_sq_cd *cd)
49997d9c9b79SDave Ertman {
50007d9c9b79SDave Ertman 	struct ice_aqc_lldp_set_local_mib *cmd;
50017d9c9b79SDave Ertman 	struct ice_aq_desc desc;
50027d9c9b79SDave Ertman 
50037d9c9b79SDave Ertman 	cmd = &desc.params.lldp_set_mib;
50047d9c9b79SDave Ertman 
50057d9c9b79SDave Ertman 	if (buf_size == 0 || !buf)
50067d9c9b79SDave Ertman 		return ICE_ERR_PARAM;
50077d9c9b79SDave Ertman 
50087d9c9b79SDave Ertman 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_lldp_set_local_mib);
50097d9c9b79SDave Ertman 
50107d9c9b79SDave Ertman 	desc.flags |= cpu_to_le16((u16)ICE_AQ_FLAG_RD);
50117d9c9b79SDave Ertman 	desc.datalen = cpu_to_le16(buf_size);
50127d9c9b79SDave Ertman 
50137d9c9b79SDave Ertman 	cmd->type = mib_type;
50147d9c9b79SDave Ertman 	cmd->length = cpu_to_le16(buf_size);
50157d9c9b79SDave Ertman 
50167d9c9b79SDave Ertman 	return ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
50177d9c9b79SDave Ertman }
501834295a36SDave Ertman 
501934295a36SDave Ertman /**
5020ef860480STony Nguyen  * ice_fw_supports_lldp_fltr_ctrl - check NVM version supports lldp_fltr_ctrl
502134295a36SDave Ertman  * @hw: pointer to HW struct
502234295a36SDave Ertman  */
502334295a36SDave Ertman bool ice_fw_supports_lldp_fltr_ctrl(struct ice_hw *hw)
502434295a36SDave Ertman {
502534295a36SDave Ertman 	if (hw->mac_type != ICE_MAC_E810)
502634295a36SDave Ertman 		return false;
502734295a36SDave Ertman 
502834295a36SDave Ertman 	if (hw->api_maj_ver == ICE_FW_API_LLDP_FLTR_MAJ) {
502934295a36SDave Ertman 		if (hw->api_min_ver > ICE_FW_API_LLDP_FLTR_MIN)
503034295a36SDave Ertman 			return true;
503134295a36SDave Ertman 		if (hw->api_min_ver == ICE_FW_API_LLDP_FLTR_MIN &&
503234295a36SDave Ertman 		    hw->api_patch >= ICE_FW_API_LLDP_FLTR_PATCH)
503334295a36SDave Ertman 			return true;
503434295a36SDave Ertman 	} else if (hw->api_maj_ver > ICE_FW_API_LLDP_FLTR_MAJ) {
503534295a36SDave Ertman 		return true;
503634295a36SDave Ertman 	}
503734295a36SDave Ertman 	return false;
503834295a36SDave Ertman }
503934295a36SDave Ertman 
504034295a36SDave Ertman /**
504134295a36SDave Ertman  * ice_lldp_fltr_add_remove - add or remove a LLDP Rx switch filter
504234295a36SDave Ertman  * @hw: pointer to HW struct
504334295a36SDave Ertman  * @vsi_num: absolute HW index for VSI
504434295a36SDave Ertman  * @add: boolean for if adding or removing a filter
504534295a36SDave Ertman  */
5046*5e24d598STony Nguyen int
504734295a36SDave Ertman ice_lldp_fltr_add_remove(struct ice_hw *hw, u16 vsi_num, bool add)
504834295a36SDave Ertman {
504934295a36SDave Ertman 	struct ice_aqc_lldp_filter_ctrl *cmd;
505034295a36SDave Ertman 	struct ice_aq_desc desc;
505134295a36SDave Ertman 
505234295a36SDave Ertman 	cmd = &desc.params.lldp_filter_ctrl;
505334295a36SDave Ertman 
505434295a36SDave Ertman 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_lldp_filter_ctrl);
505534295a36SDave Ertman 
505634295a36SDave Ertman 	if (add)
505734295a36SDave Ertman 		cmd->cmd_flags = ICE_AQC_LLDP_FILTER_ACTION_ADD;
505834295a36SDave Ertman 	else
505934295a36SDave Ertman 		cmd->cmd_flags = ICE_AQC_LLDP_FILTER_ACTION_DELETE;
506034295a36SDave Ertman 
506134295a36SDave Ertman 	cmd->vsi_num = cpu_to_le16(vsi_num);
506234295a36SDave Ertman 
506334295a36SDave Ertman 	return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
506434295a36SDave Ertman }
50650a02944fSAnirudh Venkataramanan 
50660a02944fSAnirudh Venkataramanan /**
50670a02944fSAnirudh Venkataramanan  * ice_fw_supports_report_dflt_cfg
50680a02944fSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
50690a02944fSAnirudh Venkataramanan  *
50700a02944fSAnirudh Venkataramanan  * Checks if the firmware supports report default configuration
50710a02944fSAnirudh Venkataramanan  */
50720a02944fSAnirudh Venkataramanan bool ice_fw_supports_report_dflt_cfg(struct ice_hw *hw)
50730a02944fSAnirudh Venkataramanan {
50740a02944fSAnirudh Venkataramanan 	if (hw->api_maj_ver == ICE_FW_API_REPORT_DFLT_CFG_MAJ) {
50750a02944fSAnirudh Venkataramanan 		if (hw->api_min_ver > ICE_FW_API_REPORT_DFLT_CFG_MIN)
50760a02944fSAnirudh Venkataramanan 			return true;
50770a02944fSAnirudh Venkataramanan 		if (hw->api_min_ver == ICE_FW_API_REPORT_DFLT_CFG_MIN &&
50780a02944fSAnirudh Venkataramanan 		    hw->api_patch >= ICE_FW_API_REPORT_DFLT_CFG_PATCH)
50790a02944fSAnirudh Venkataramanan 			return true;
50800a02944fSAnirudh Venkataramanan 	} else if (hw->api_maj_ver > ICE_FW_API_REPORT_DFLT_CFG_MAJ) {
50810a02944fSAnirudh Venkataramanan 		return true;
50820a02944fSAnirudh Venkataramanan 	}
50830a02944fSAnirudh Venkataramanan 	return false;
50840a02944fSAnirudh Venkataramanan }
5085