17ec59eeaSAnirudh Venkataramanan // SPDX-License-Identifier: GPL-2.0
27ec59eeaSAnirudh Venkataramanan /* Copyright (c) 2018, Intel Corporation. */
37ec59eeaSAnirudh Venkataramanan 
47ec59eeaSAnirudh Venkataramanan #include "ice_common.h"
59c20346bSAnirudh Venkataramanan #include "ice_sched.h"
67ec59eeaSAnirudh Venkataramanan #include "ice_adminq_cmd.h"
77ec59eeaSAnirudh Venkataramanan 
8f31e4b6fSAnirudh Venkataramanan #define ICE_PF_RESET_WAIT_COUNT	200
9f31e4b6fSAnirudh Venkataramanan 
1022ef683bSAnirudh Venkataramanan #define ICE_PROG_FLEX_ENTRY(hw, rxdid, mdid, idx) \
1122ef683bSAnirudh Venkataramanan 	wr32((hw), GLFLXP_RXDID_FLX_WRD_##idx(rxdid), \
12cdedef59SAnirudh Venkataramanan 	     ((ICE_RX_OPC_MDID << \
13cdedef59SAnirudh Venkataramanan 	       GLFLXP_RXDID_FLX_WRD_##idx##_RXDID_OPCODE_S) & \
14cdedef59SAnirudh Venkataramanan 	      GLFLXP_RXDID_FLX_WRD_##idx##_RXDID_OPCODE_M) | \
15cdedef59SAnirudh Venkataramanan 	     (((mdid) << GLFLXP_RXDID_FLX_WRD_##idx##_PROT_MDID_S) & \
16cdedef59SAnirudh Venkataramanan 	      GLFLXP_RXDID_FLX_WRD_##idx##_PROT_MDID_M))
17cdedef59SAnirudh Venkataramanan 
1822ef683bSAnirudh Venkataramanan #define ICE_PROG_FLG_ENTRY(hw, rxdid, flg_0, flg_1, flg_2, flg_3, idx) \
1922ef683bSAnirudh Venkataramanan 	wr32((hw), GLFLXP_RXDID_FLAGS(rxdid, idx), \
20cdedef59SAnirudh Venkataramanan 	     (((flg_0) << GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_S) & \
21cdedef59SAnirudh Venkataramanan 	      GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_M) | \
22cdedef59SAnirudh Venkataramanan 	     (((flg_1) << GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_1_S) & \
23cdedef59SAnirudh Venkataramanan 	      GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_1_M) | \
24cdedef59SAnirudh Venkataramanan 	     (((flg_2) << GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_2_S) & \
25cdedef59SAnirudh Venkataramanan 	      GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_2_M) | \
26cdedef59SAnirudh Venkataramanan 	     (((flg_3) << GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_3_S) & \
27cdedef59SAnirudh Venkataramanan 	      GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_3_M))
28cdedef59SAnirudh Venkataramanan 
29f31e4b6fSAnirudh Venkataramanan /**
30f31e4b6fSAnirudh Venkataramanan  * ice_set_mac_type - Sets MAC type
31f31e4b6fSAnirudh Venkataramanan  * @hw: pointer to the HW structure
32f31e4b6fSAnirudh Venkataramanan  *
33f31e4b6fSAnirudh Venkataramanan  * This function sets the MAC type of the adapter based on the
34f9867df6SAnirudh Venkataramanan  * vendor ID and device ID stored in the HW structure.
35f31e4b6fSAnirudh Venkataramanan  */
36f31e4b6fSAnirudh Venkataramanan static enum ice_status ice_set_mac_type(struct ice_hw *hw)
37f31e4b6fSAnirudh Venkataramanan {
38f31e4b6fSAnirudh Venkataramanan 	if (hw->vendor_id != PCI_VENDOR_ID_INTEL)
39f31e4b6fSAnirudh Venkataramanan 		return ICE_ERR_DEVICE_NOT_SUPPORTED;
40f31e4b6fSAnirudh Venkataramanan 
41f31e4b6fSAnirudh Venkataramanan 	hw->mac_type = ICE_MAC_GENERIC;
42f31e4b6fSAnirudh Venkataramanan 	return 0;
43f31e4b6fSAnirudh Venkataramanan }
44f31e4b6fSAnirudh Venkataramanan 
45f31e4b6fSAnirudh Venkataramanan /**
46f203dca3SAnirudh Venkataramanan  * ice_dev_onetime_setup - Temporary HW/FW workarounds
47f203dca3SAnirudh Venkataramanan  * @hw: pointer to the HW structure
48f203dca3SAnirudh Venkataramanan  *
49f203dca3SAnirudh Venkataramanan  * This function provides temporary workarounds for certain issues
50f203dca3SAnirudh Venkataramanan  * that are expected to be fixed in the HW/FW.
51f203dca3SAnirudh Venkataramanan  */
52f203dca3SAnirudh Venkataramanan void ice_dev_onetime_setup(struct ice_hw *hw)
53f203dca3SAnirudh Venkataramanan {
54f203dca3SAnirudh Venkataramanan 	/* configure Rx - set non pxe mode */
55f203dca3SAnirudh Venkataramanan 	wr32(hw, GLLAN_RCTL_0, 0x1);
56f203dca3SAnirudh Venkataramanan 
57f203dca3SAnirudh Venkataramanan #define MBX_PF_VT_PFALLOC	0x00231E80
58f203dca3SAnirudh Venkataramanan 	/* set VFs per PF */
59f203dca3SAnirudh Venkataramanan 	wr32(hw, MBX_PF_VT_PFALLOC, rd32(hw, PF_VT_PFALLOC_HIF));
60f203dca3SAnirudh Venkataramanan }
61f203dca3SAnirudh Venkataramanan 
62f203dca3SAnirudh Venkataramanan /**
63f31e4b6fSAnirudh Venkataramanan  * ice_clear_pf_cfg - Clear PF configuration
64f31e4b6fSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
653968540bSAnirudh Venkataramanan  *
663968540bSAnirudh Venkataramanan  * Clears any existing PF configuration (VSIs, VSI lists, switch rules, port
673968540bSAnirudh Venkataramanan  * configuration, flow director filters, etc.).
68f31e4b6fSAnirudh Venkataramanan  */
69f31e4b6fSAnirudh Venkataramanan enum ice_status ice_clear_pf_cfg(struct ice_hw *hw)
70f31e4b6fSAnirudh Venkataramanan {
71f31e4b6fSAnirudh Venkataramanan 	struct ice_aq_desc desc;
72f31e4b6fSAnirudh Venkataramanan 
73f31e4b6fSAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_clear_pf_cfg);
74f31e4b6fSAnirudh Venkataramanan 
75f31e4b6fSAnirudh Venkataramanan 	return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
76f31e4b6fSAnirudh Venkataramanan }
77f31e4b6fSAnirudh Venkataramanan 
78f31e4b6fSAnirudh Venkataramanan /**
79dc49c772SAnirudh Venkataramanan  * ice_aq_manage_mac_read - manage MAC address read command
80f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
81dc49c772SAnirudh Venkataramanan  * @buf: a virtual buffer to hold the manage MAC read response
82dc49c772SAnirudh Venkataramanan  * @buf_size: Size of the virtual buffer
83dc49c772SAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
84dc49c772SAnirudh Venkataramanan  *
85dc49c772SAnirudh Venkataramanan  * This function is used to return per PF station MAC address (0x0107).
86dc49c772SAnirudh Venkataramanan  * NOTE: Upon successful completion of this command, MAC address information
87dc49c772SAnirudh Venkataramanan  * is returned in user specified buffer. Please interpret user specified
88dc49c772SAnirudh Venkataramanan  * buffer as "manage_mac_read" response.
89dc49c772SAnirudh Venkataramanan  * Response such as various MAC addresses are stored in HW struct (port.mac)
90dc49c772SAnirudh Venkataramanan  * ice_aq_discover_caps is expected to be called before this function is called.
91dc49c772SAnirudh Venkataramanan  */
92dc49c772SAnirudh Venkataramanan static enum ice_status
93dc49c772SAnirudh Venkataramanan ice_aq_manage_mac_read(struct ice_hw *hw, void *buf, u16 buf_size,
94dc49c772SAnirudh Venkataramanan 		       struct ice_sq_cd *cd)
95dc49c772SAnirudh Venkataramanan {
96dc49c772SAnirudh Venkataramanan 	struct ice_aqc_manage_mac_read_resp *resp;
97dc49c772SAnirudh Venkataramanan 	struct ice_aqc_manage_mac_read *cmd;
98dc49c772SAnirudh Venkataramanan 	struct ice_aq_desc desc;
99dc49c772SAnirudh Venkataramanan 	enum ice_status status;
100dc49c772SAnirudh Venkataramanan 	u16 flags;
101d6fef10cSMd Fahad Iqbal Polash 	u8 i;
102dc49c772SAnirudh Venkataramanan 
103dc49c772SAnirudh Venkataramanan 	cmd = &desc.params.mac_read;
104dc49c772SAnirudh Venkataramanan 
105dc49c772SAnirudh Venkataramanan 	if (buf_size < sizeof(*resp))
106dc49c772SAnirudh Venkataramanan 		return ICE_ERR_BUF_TOO_SHORT;
107dc49c772SAnirudh Venkataramanan 
108dc49c772SAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_manage_mac_read);
109dc49c772SAnirudh Venkataramanan 
110dc49c772SAnirudh Venkataramanan 	status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
111dc49c772SAnirudh Venkataramanan 	if (status)
112dc49c772SAnirudh Venkataramanan 		return status;
113dc49c772SAnirudh Venkataramanan 
114dc49c772SAnirudh Venkataramanan 	resp = (struct ice_aqc_manage_mac_read_resp *)buf;
115dc49c772SAnirudh Venkataramanan 	flags = le16_to_cpu(cmd->flags) & ICE_AQC_MAN_MAC_READ_M;
116dc49c772SAnirudh Venkataramanan 
117dc49c772SAnirudh Venkataramanan 	if (!(flags & ICE_AQC_MAN_MAC_LAN_ADDR_VALID)) {
118dc49c772SAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_LAN, "got invalid MAC address\n");
119dc49c772SAnirudh Venkataramanan 		return ICE_ERR_CFG;
120dc49c772SAnirudh Venkataramanan 	}
121dc49c772SAnirudh Venkataramanan 
122d6fef10cSMd Fahad Iqbal Polash 	/* A single port can report up to two (LAN and WoL) addresses */
123d6fef10cSMd Fahad Iqbal Polash 	for (i = 0; i < cmd->num_addr; i++)
124d6fef10cSMd Fahad Iqbal Polash 		if (resp[i].addr_type == ICE_AQC_MAN_MAC_ADDR_TYPE_LAN) {
125d6fef10cSMd Fahad Iqbal Polash 			ether_addr_copy(hw->port_info->mac.lan_addr,
126d6fef10cSMd Fahad Iqbal Polash 					resp[i].mac_addr);
127d6fef10cSMd Fahad Iqbal Polash 			ether_addr_copy(hw->port_info->mac.perm_addr,
128d6fef10cSMd Fahad Iqbal Polash 					resp[i].mac_addr);
129d6fef10cSMd Fahad Iqbal Polash 			break;
130d6fef10cSMd Fahad Iqbal Polash 		}
131d6fef10cSMd Fahad Iqbal Polash 
132dc49c772SAnirudh Venkataramanan 	return 0;
133dc49c772SAnirudh Venkataramanan }
134dc49c772SAnirudh Venkataramanan 
135dc49c772SAnirudh Venkataramanan /**
136dc49c772SAnirudh Venkataramanan  * ice_aq_get_phy_caps - returns PHY capabilities
137dc49c772SAnirudh Venkataramanan  * @pi: port information structure
138dc49c772SAnirudh Venkataramanan  * @qual_mods: report qualified modules
139dc49c772SAnirudh Venkataramanan  * @report_mode: report mode capabilities
140dc49c772SAnirudh Venkataramanan  * @pcaps: structure for PHY capabilities to be filled
141dc49c772SAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
142dc49c772SAnirudh Venkataramanan  *
143dc49c772SAnirudh Venkataramanan  * Returns the various PHY capabilities supported on the Port (0x0600)
144dc49c772SAnirudh Venkataramanan  */
14548cb27f2SChinh Cao enum ice_status
146dc49c772SAnirudh Venkataramanan ice_aq_get_phy_caps(struct ice_port_info *pi, bool qual_mods, u8 report_mode,
147dc49c772SAnirudh Venkataramanan 		    struct ice_aqc_get_phy_caps_data *pcaps,
148dc49c772SAnirudh Venkataramanan 		    struct ice_sq_cd *cd)
149dc49c772SAnirudh Venkataramanan {
150dc49c772SAnirudh Venkataramanan 	struct ice_aqc_get_phy_caps *cmd;
151dc49c772SAnirudh Venkataramanan 	u16 pcaps_size = sizeof(*pcaps);
152dc49c772SAnirudh Venkataramanan 	struct ice_aq_desc desc;
153dc49c772SAnirudh Venkataramanan 	enum ice_status status;
154dc49c772SAnirudh Venkataramanan 
155dc49c772SAnirudh Venkataramanan 	cmd = &desc.params.get_phy;
156dc49c772SAnirudh Venkataramanan 
157dc49c772SAnirudh Venkataramanan 	if (!pcaps || (report_mode & ~ICE_AQC_REPORT_MODE_M) || !pi)
158dc49c772SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
159dc49c772SAnirudh Venkataramanan 
160dc49c772SAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_phy_caps);
161dc49c772SAnirudh Venkataramanan 
162dc49c772SAnirudh Venkataramanan 	if (qual_mods)
163dc49c772SAnirudh Venkataramanan 		cmd->param0 |= cpu_to_le16(ICE_AQC_GET_PHY_RQM);
164dc49c772SAnirudh Venkataramanan 
165dc49c772SAnirudh Venkataramanan 	cmd->param0 |= cpu_to_le16(report_mode);
166dc49c772SAnirudh Venkataramanan 	status = ice_aq_send_cmd(pi->hw, &desc, pcaps, pcaps_size, cd);
167dc49c772SAnirudh Venkataramanan 
168aef74145SAnirudh Venkataramanan 	if (!status && report_mode == ICE_AQC_REPORT_TOPO_CAP) {
169dc49c772SAnirudh Venkataramanan 		pi->phy.phy_type_low = le64_to_cpu(pcaps->phy_type_low);
170aef74145SAnirudh Venkataramanan 		pi->phy.phy_type_high = le64_to_cpu(pcaps->phy_type_high);
171aef74145SAnirudh Venkataramanan 	}
172dc49c772SAnirudh Venkataramanan 
173dc49c772SAnirudh Venkataramanan 	return status;
174dc49c772SAnirudh Venkataramanan }
175dc49c772SAnirudh Venkataramanan 
176dc49c772SAnirudh Venkataramanan /**
177dc49c772SAnirudh Venkataramanan  * ice_get_media_type - Gets media type
178dc49c772SAnirudh Venkataramanan  * @pi: port information structure
179dc49c772SAnirudh Venkataramanan  */
180dc49c772SAnirudh Venkataramanan static enum ice_media_type ice_get_media_type(struct ice_port_info *pi)
181dc49c772SAnirudh Venkataramanan {
182dc49c772SAnirudh Venkataramanan 	struct ice_link_status *hw_link_info;
183dc49c772SAnirudh Venkataramanan 
184dc49c772SAnirudh Venkataramanan 	if (!pi)
185dc49c772SAnirudh Venkataramanan 		return ICE_MEDIA_UNKNOWN;
186dc49c772SAnirudh Venkataramanan 
187dc49c772SAnirudh Venkataramanan 	hw_link_info = &pi->phy.link_info;
188aef74145SAnirudh Venkataramanan 	if (hw_link_info->phy_type_low && hw_link_info->phy_type_high)
189aef74145SAnirudh Venkataramanan 		/* If more than one media type is selected, report unknown */
190aef74145SAnirudh Venkataramanan 		return ICE_MEDIA_UNKNOWN;
191dc49c772SAnirudh Venkataramanan 
192dc49c772SAnirudh Venkataramanan 	if (hw_link_info->phy_type_low) {
193dc49c772SAnirudh Venkataramanan 		switch (hw_link_info->phy_type_low) {
194dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_1000BASE_SX:
195dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_1000BASE_LX:
196dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_10GBASE_SR:
197dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_10GBASE_LR:
198dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_10G_SFI_C2C:
199dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_25GBASE_SR:
200dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_25GBASE_LR:
201dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_25G_AUI_C2C:
202dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_40GBASE_SR4:
203dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_40GBASE_LR4:
204aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_50GBASE_SR2:
205aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_50GBASE_LR2:
206aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_50GBASE_SR:
207aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_50GBASE_FR:
208aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_50GBASE_LR:
209aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_100GBASE_SR4:
210aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_100GBASE_LR4:
211aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_100GBASE_SR2:
212aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_100GBASE_DR:
213dc49c772SAnirudh Venkataramanan 			return ICE_MEDIA_FIBER;
214dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_100BASE_TX:
215dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_1000BASE_T:
216dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_2500BASE_T:
217dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_5GBASE_T:
218dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_10GBASE_T:
219dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_25GBASE_T:
220dc49c772SAnirudh Venkataramanan 			return ICE_MEDIA_BASET;
221dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_10G_SFI_DA:
222dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_25GBASE_CR:
223dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_25GBASE_CR_S:
224dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_25GBASE_CR1:
225dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_40GBASE_CR4:
226aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_50GBASE_CR2:
227aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_50GBASE_CP:
228aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_100GBASE_CR4:
229aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_100GBASE_CR_PAM4:
230aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_100GBASE_CP2:
231dc49c772SAnirudh Venkataramanan 			return ICE_MEDIA_DA;
232dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_1000BASE_KX:
233dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_2500BASE_KX:
234dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_2500BASE_X:
235dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_5GBASE_KR:
236dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_10GBASE_KR_CR1:
237dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_25GBASE_KR:
238dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_25GBASE_KR1:
239dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_25GBASE_KR_S:
240dc49c772SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_40GBASE_KR4:
241aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_50GBASE_KR_PAM4:
242aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_50GBASE_KR2:
243aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_100GBASE_KR4:
244aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_LOW_100GBASE_KR_PAM4:
245aef74145SAnirudh Venkataramanan 			return ICE_MEDIA_BACKPLANE;
246aef74145SAnirudh Venkataramanan 		}
247aef74145SAnirudh Venkataramanan 	} else {
248aef74145SAnirudh Venkataramanan 		switch (hw_link_info->phy_type_high) {
249aef74145SAnirudh Venkataramanan 		case ICE_PHY_TYPE_HIGH_100GBASE_KR2_PAM4:
250dc49c772SAnirudh Venkataramanan 			return ICE_MEDIA_BACKPLANE;
251dc49c772SAnirudh Venkataramanan 		}
252dc49c772SAnirudh Venkataramanan 	}
253dc49c772SAnirudh Venkataramanan 	return ICE_MEDIA_UNKNOWN;
254dc49c772SAnirudh Venkataramanan }
255dc49c772SAnirudh Venkataramanan 
256dc49c772SAnirudh Venkataramanan /**
257dc49c772SAnirudh Venkataramanan  * ice_aq_get_link_info
258dc49c772SAnirudh Venkataramanan  * @pi: port information structure
259dc49c772SAnirudh Venkataramanan  * @ena_lse: enable/disable LinkStatusEvent reporting
260dc49c772SAnirudh Venkataramanan  * @link: pointer to link status structure - optional
261dc49c772SAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
262dc49c772SAnirudh Venkataramanan  *
263dc49c772SAnirudh Venkataramanan  * Get Link Status (0x607). Returns the link status of the adapter.
264dc49c772SAnirudh Venkataramanan  */
265250c3b3eSBrett Creeley enum ice_status
266dc49c772SAnirudh Venkataramanan ice_aq_get_link_info(struct ice_port_info *pi, bool ena_lse,
267dc49c772SAnirudh Venkataramanan 		     struct ice_link_status *link, struct ice_sq_cd *cd)
268dc49c772SAnirudh Venkataramanan {
269dc49c772SAnirudh Venkataramanan 	struct ice_link_status *hw_link_info_old, *hw_link_info;
270dc49c772SAnirudh Venkataramanan 	struct ice_aqc_get_link_status_data link_data = { 0 };
271dc49c772SAnirudh Venkataramanan 	struct ice_aqc_get_link_status *resp;
272dc49c772SAnirudh Venkataramanan 	enum ice_media_type *hw_media_type;
273dc49c772SAnirudh Venkataramanan 	struct ice_fc_info *hw_fc_info;
274dc49c772SAnirudh Venkataramanan 	bool tx_pause, rx_pause;
275dc49c772SAnirudh Venkataramanan 	struct ice_aq_desc desc;
276dc49c772SAnirudh Venkataramanan 	enum ice_status status;
277dc49c772SAnirudh Venkataramanan 	u16 cmd_flags;
278dc49c772SAnirudh Venkataramanan 
279dc49c772SAnirudh Venkataramanan 	if (!pi)
280dc49c772SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
281dc49c772SAnirudh Venkataramanan 	hw_link_info_old = &pi->phy.link_info_old;
282dc49c772SAnirudh Venkataramanan 	hw_media_type = &pi->phy.media_type;
283dc49c772SAnirudh Venkataramanan 	hw_link_info = &pi->phy.link_info;
284dc49c772SAnirudh Venkataramanan 	hw_fc_info = &pi->fc;
285dc49c772SAnirudh Venkataramanan 
286dc49c772SAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_status);
287dc49c772SAnirudh Venkataramanan 	cmd_flags = (ena_lse) ? ICE_AQ_LSE_ENA : ICE_AQ_LSE_DIS;
288dc49c772SAnirudh Venkataramanan 	resp = &desc.params.get_link_status;
289dc49c772SAnirudh Venkataramanan 	resp->cmd_flags = cpu_to_le16(cmd_flags);
290dc49c772SAnirudh Venkataramanan 	resp->lport_num = pi->lport;
291dc49c772SAnirudh Venkataramanan 
292dc49c772SAnirudh Venkataramanan 	status = ice_aq_send_cmd(pi->hw, &desc, &link_data, sizeof(link_data),
293dc49c772SAnirudh Venkataramanan 				 cd);
294dc49c772SAnirudh Venkataramanan 
295dc49c772SAnirudh Venkataramanan 	if (status)
296dc49c772SAnirudh Venkataramanan 		return status;
297dc49c772SAnirudh Venkataramanan 
298dc49c772SAnirudh Venkataramanan 	/* save off old link status information */
299dc49c772SAnirudh Venkataramanan 	*hw_link_info_old = *hw_link_info;
300dc49c772SAnirudh Venkataramanan 
301dc49c772SAnirudh Venkataramanan 	/* update current link status information */
302dc49c772SAnirudh Venkataramanan 	hw_link_info->link_speed = le16_to_cpu(link_data.link_speed);
303dc49c772SAnirudh Venkataramanan 	hw_link_info->phy_type_low = le64_to_cpu(link_data.phy_type_low);
304aef74145SAnirudh Venkataramanan 	hw_link_info->phy_type_high = le64_to_cpu(link_data.phy_type_high);
305dc49c772SAnirudh Venkataramanan 	*hw_media_type = ice_get_media_type(pi);
306dc49c772SAnirudh Venkataramanan 	hw_link_info->link_info = link_data.link_info;
307dc49c772SAnirudh Venkataramanan 	hw_link_info->an_info = link_data.an_info;
308dc49c772SAnirudh Venkataramanan 	hw_link_info->ext_info = link_data.ext_info;
309dc49c772SAnirudh Venkataramanan 	hw_link_info->max_frame_size = le16_to_cpu(link_data.max_frame_size);
310dc49c772SAnirudh Venkataramanan 	hw_link_info->pacing = link_data.cfg & ICE_AQ_CFG_PACING_M;
311dc49c772SAnirudh Venkataramanan 
312dc49c772SAnirudh Venkataramanan 	/* update fc info */
313dc49c772SAnirudh Venkataramanan 	tx_pause = !!(link_data.an_info & ICE_AQ_LINK_PAUSE_TX);
314dc49c772SAnirudh Venkataramanan 	rx_pause = !!(link_data.an_info & ICE_AQ_LINK_PAUSE_RX);
315dc49c772SAnirudh Venkataramanan 	if (tx_pause && rx_pause)
316dc49c772SAnirudh Venkataramanan 		hw_fc_info->current_mode = ICE_FC_FULL;
317dc49c772SAnirudh Venkataramanan 	else if (tx_pause)
318dc49c772SAnirudh Venkataramanan 		hw_fc_info->current_mode = ICE_FC_TX_PAUSE;
319dc49c772SAnirudh Venkataramanan 	else if (rx_pause)
320dc49c772SAnirudh Venkataramanan 		hw_fc_info->current_mode = ICE_FC_RX_PAUSE;
321dc49c772SAnirudh Venkataramanan 	else
322dc49c772SAnirudh Venkataramanan 		hw_fc_info->current_mode = ICE_FC_NONE;
323dc49c772SAnirudh Venkataramanan 
324dc49c772SAnirudh Venkataramanan 	hw_link_info->lse_ena =
325dc49c772SAnirudh Venkataramanan 		!!(resp->cmd_flags & cpu_to_le16(ICE_AQ_LSE_IS_ENABLED));
326dc49c772SAnirudh Venkataramanan 
327dc49c772SAnirudh Venkataramanan 	/* save link status information */
328dc49c772SAnirudh Venkataramanan 	if (link)
329dc49c772SAnirudh Venkataramanan 		*link = *hw_link_info;
330dc49c772SAnirudh Venkataramanan 
331dc49c772SAnirudh Venkataramanan 	/* flag cleared so calling functions don't call AQ again */
332dc49c772SAnirudh Venkataramanan 	pi->phy.get_link_info = false;
333dc49c772SAnirudh Venkataramanan 
3341b5c19c7SBruce Allan 	return 0;
335dc49c772SAnirudh Venkataramanan }
336dc49c772SAnirudh Venkataramanan 
337dc49c772SAnirudh Venkataramanan /**
33822ef683bSAnirudh Venkataramanan  * ice_init_flex_flags
339cdedef59SAnirudh Venkataramanan  * @hw: pointer to the hardware structure
34022ef683bSAnirudh Venkataramanan  * @prof_id: Rx Descriptor Builder profile ID
341cdedef59SAnirudh Venkataramanan  *
34222ef683bSAnirudh Venkataramanan  * Function to initialize Rx flex flags
343cdedef59SAnirudh Venkataramanan  */
34422ef683bSAnirudh Venkataramanan static void ice_init_flex_flags(struct ice_hw *hw, enum ice_rxdid prof_id)
345cdedef59SAnirudh Venkataramanan {
346cdedef59SAnirudh Venkataramanan 	u8 idx = 0;
347cdedef59SAnirudh Venkataramanan 
34822ef683bSAnirudh Venkataramanan 	/* Flex-flag fields (0-2) are programmed with FLG64 bits with layout:
34922ef683bSAnirudh Venkataramanan 	 * flexiflags0[5:0] - TCP flags, is_packet_fragmented, is_packet_UDP_GRE
35022ef683bSAnirudh Venkataramanan 	 * flexiflags1[3:0] - Not used for flag programming
35122ef683bSAnirudh Venkataramanan 	 * flexiflags2[7:0] - Tunnel and VLAN types
35222ef683bSAnirudh Venkataramanan 	 * 2 invalid fields in last index
35322ef683bSAnirudh Venkataramanan 	 */
35422ef683bSAnirudh Venkataramanan 	switch (prof_id) {
35522ef683bSAnirudh Venkataramanan 	/* Rx flex flags are currently programmed for the NIC profiles only.
35622ef683bSAnirudh Venkataramanan 	 * Different flag bit programming configurations can be added per
35722ef683bSAnirudh Venkataramanan 	 * profile as needed.
35822ef683bSAnirudh Venkataramanan 	 */
35922ef683bSAnirudh Venkataramanan 	case ICE_RXDID_FLEX_NIC:
36022ef683bSAnirudh Venkataramanan 	case ICE_RXDID_FLEX_NIC_2:
36186e81794SChinh T Cao 		ICE_PROG_FLG_ENTRY(hw, prof_id, ICE_FLG_PKT_FRG,
36286e81794SChinh T Cao 				   ICE_FLG_UDP_GRE, ICE_FLG_PKT_DSI,
36386e81794SChinh T Cao 				   ICE_FLG_FIN, idx++);
36422ef683bSAnirudh Venkataramanan 		/* flex flag 1 is not used for flexi-flag programming, skipping
36522ef683bSAnirudh Venkataramanan 		 * these four FLG64 bits.
36622ef683bSAnirudh Venkataramanan 		 */
36786e81794SChinh T Cao 		ICE_PROG_FLG_ENTRY(hw, prof_id, ICE_FLG_SYN, ICE_FLG_RST,
36886e81794SChinh T Cao 				   ICE_FLG_PKT_DSI, ICE_FLG_PKT_DSI, idx++);
36986e81794SChinh T Cao 		ICE_PROG_FLG_ENTRY(hw, prof_id, ICE_FLG_PKT_DSI,
37086e81794SChinh T Cao 				   ICE_FLG_PKT_DSI, ICE_FLG_EVLAN_x8100,
37186e81794SChinh T Cao 				   ICE_FLG_EVLAN_x9100, idx++);
37286e81794SChinh T Cao 		ICE_PROG_FLG_ENTRY(hw, prof_id, ICE_FLG_VLAN_x8100,
37386e81794SChinh T Cao 				   ICE_FLG_TNL_VLAN, ICE_FLG_TNL_MAC,
37486e81794SChinh T Cao 				   ICE_FLG_TNL0, idx++);
37586e81794SChinh T Cao 		ICE_PROG_FLG_ENTRY(hw, prof_id, ICE_FLG_TNL1, ICE_FLG_TNL2,
37686e81794SChinh T Cao 				   ICE_FLG_PKT_DSI, ICE_FLG_PKT_DSI, idx);
37722ef683bSAnirudh Venkataramanan 		break;
37822ef683bSAnirudh Venkataramanan 
37922ef683bSAnirudh Venkataramanan 	default:
38022ef683bSAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_INIT,
38122ef683bSAnirudh Venkataramanan 			  "Flag programming for profile ID %d not supported\n",
38222ef683bSAnirudh Venkataramanan 			  prof_id);
38322ef683bSAnirudh Venkataramanan 	}
38422ef683bSAnirudh Venkataramanan }
38522ef683bSAnirudh Venkataramanan 
38622ef683bSAnirudh Venkataramanan /**
38722ef683bSAnirudh Venkataramanan  * ice_init_flex_flds
38822ef683bSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
38922ef683bSAnirudh Venkataramanan  * @prof_id: Rx Descriptor Builder profile ID
39022ef683bSAnirudh Venkataramanan  *
39122ef683bSAnirudh Venkataramanan  * Function to initialize flex descriptors
39222ef683bSAnirudh Venkataramanan  */
39322ef683bSAnirudh Venkataramanan static void ice_init_flex_flds(struct ice_hw *hw, enum ice_rxdid prof_id)
39422ef683bSAnirudh Venkataramanan {
39522ef683bSAnirudh Venkataramanan 	enum ice_flex_rx_mdid mdid;
39622ef683bSAnirudh Venkataramanan 
39722ef683bSAnirudh Venkataramanan 	switch (prof_id) {
39822ef683bSAnirudh Venkataramanan 	case ICE_RXDID_FLEX_NIC:
39922ef683bSAnirudh Venkataramanan 	case ICE_RXDID_FLEX_NIC_2:
40022ef683bSAnirudh Venkataramanan 		ICE_PROG_FLEX_ENTRY(hw, prof_id, ICE_RX_MDID_HASH_LOW, 0);
40122ef683bSAnirudh Venkataramanan 		ICE_PROG_FLEX_ENTRY(hw, prof_id, ICE_RX_MDID_HASH_HIGH, 1);
40222ef683bSAnirudh Venkataramanan 		ICE_PROG_FLEX_ENTRY(hw, prof_id, ICE_RX_MDID_FLOW_ID_LOWER, 2);
40322ef683bSAnirudh Venkataramanan 
40422ef683bSAnirudh Venkataramanan 		mdid = (prof_id == ICE_RXDID_FLEX_NIC_2) ?
40522ef683bSAnirudh Venkataramanan 			ICE_RX_MDID_SRC_VSI : ICE_RX_MDID_FLOW_ID_HIGH;
40622ef683bSAnirudh Venkataramanan 
40722ef683bSAnirudh Venkataramanan 		ICE_PROG_FLEX_ENTRY(hw, prof_id, mdid, 3);
40822ef683bSAnirudh Venkataramanan 
40922ef683bSAnirudh Venkataramanan 		ice_init_flex_flags(hw, prof_id);
41022ef683bSAnirudh Venkataramanan 		break;
41122ef683bSAnirudh Venkataramanan 
41222ef683bSAnirudh Venkataramanan 	default:
41322ef683bSAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_INIT,
41422ef683bSAnirudh Venkataramanan 			  "Field init for profile ID %d not supported\n",
41522ef683bSAnirudh Venkataramanan 			  prof_id);
41622ef683bSAnirudh Venkataramanan 	}
417cdedef59SAnirudh Venkataramanan }
418cdedef59SAnirudh Venkataramanan 
419cdedef59SAnirudh Venkataramanan /**
4209daf8208SAnirudh Venkataramanan  * ice_init_fltr_mgmt_struct - initializes filter management list and locks
421f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
4229daf8208SAnirudh Venkataramanan  */
4239daf8208SAnirudh Venkataramanan static enum ice_status ice_init_fltr_mgmt_struct(struct ice_hw *hw)
4249daf8208SAnirudh Venkataramanan {
4259daf8208SAnirudh Venkataramanan 	struct ice_switch_info *sw;
4269daf8208SAnirudh Venkataramanan 
4279daf8208SAnirudh Venkataramanan 	hw->switch_info = devm_kzalloc(ice_hw_to_dev(hw),
4289daf8208SAnirudh Venkataramanan 				       sizeof(*hw->switch_info), GFP_KERNEL);
4299daf8208SAnirudh Venkataramanan 	sw = hw->switch_info;
4309daf8208SAnirudh Venkataramanan 
4319daf8208SAnirudh Venkataramanan 	if (!sw)
4329daf8208SAnirudh Venkataramanan 		return ICE_ERR_NO_MEMORY;
4339daf8208SAnirudh Venkataramanan 
4349daf8208SAnirudh Venkataramanan 	INIT_LIST_HEAD(&sw->vsi_list_map_head);
4359daf8208SAnirudh Venkataramanan 
4365fb597d7SJaroslaw Ilgiewicz 	return ice_init_def_sw_recp(hw);
4379daf8208SAnirudh Venkataramanan }
4389daf8208SAnirudh Venkataramanan 
4399daf8208SAnirudh Venkataramanan /**
4409daf8208SAnirudh Venkataramanan  * ice_cleanup_fltr_mgmt_struct - cleanup filter management list and locks
441f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
4429daf8208SAnirudh Venkataramanan  */
4439daf8208SAnirudh Venkataramanan static void ice_cleanup_fltr_mgmt_struct(struct ice_hw *hw)
4449daf8208SAnirudh Venkataramanan {
4459daf8208SAnirudh Venkataramanan 	struct ice_switch_info *sw = hw->switch_info;
4469daf8208SAnirudh Venkataramanan 	struct ice_vsi_list_map_info *v_pos_map;
4479daf8208SAnirudh Venkataramanan 	struct ice_vsi_list_map_info *v_tmp_map;
44880d144c9SAnirudh Venkataramanan 	struct ice_sw_recipe *recps;
44980d144c9SAnirudh Venkataramanan 	u8 i;
4509daf8208SAnirudh Venkataramanan 
4519daf8208SAnirudh Venkataramanan 	list_for_each_entry_safe(v_pos_map, v_tmp_map, &sw->vsi_list_map_head,
4529daf8208SAnirudh Venkataramanan 				 list_entry) {
4539daf8208SAnirudh Venkataramanan 		list_del(&v_pos_map->list_entry);
4549daf8208SAnirudh Venkataramanan 		devm_kfree(ice_hw_to_dev(hw), v_pos_map);
4559daf8208SAnirudh Venkataramanan 	}
45680d144c9SAnirudh Venkataramanan 	recps = hw->switch_info->recp_list;
45780d144c9SAnirudh Venkataramanan 	for (i = 0; i < ICE_SW_LKUP_LAST; i++) {
45880d144c9SAnirudh Venkataramanan 		struct ice_fltr_mgmt_list_entry *lst_itr, *tmp_entry;
4599daf8208SAnirudh Venkataramanan 
46080d144c9SAnirudh Venkataramanan 		recps[i].root_rid = i;
46180d144c9SAnirudh Venkataramanan 		mutex_destroy(&recps[i].filt_rule_lock);
46280d144c9SAnirudh Venkataramanan 		list_for_each_entry_safe(lst_itr, tmp_entry,
46380d144c9SAnirudh Venkataramanan 					 &recps[i].filt_rules, list_entry) {
46480d144c9SAnirudh Venkataramanan 			list_del(&lst_itr->list_entry);
46580d144c9SAnirudh Venkataramanan 			devm_kfree(ice_hw_to_dev(hw), lst_itr);
46680d144c9SAnirudh Venkataramanan 		}
46780d144c9SAnirudh Venkataramanan 	}
468334cb062SAnirudh Venkataramanan 	ice_rm_all_sw_replay_rule_info(hw);
46980d144c9SAnirudh Venkataramanan 	devm_kfree(ice_hw_to_dev(hw), sw->recp_list);
4709daf8208SAnirudh Venkataramanan 	devm_kfree(ice_hw_to_dev(hw), sw);
4719daf8208SAnirudh Venkataramanan }
4729daf8208SAnirudh Venkataramanan 
4738b97ceb1SHieu Tran #define ICE_FW_LOG_DESC_SIZE(n)	(sizeof(struct ice_aqc_fw_logging_data) + \
4748b97ceb1SHieu Tran 	(((n) - 1) * sizeof(((struct ice_aqc_fw_logging_data *)0)->entry)))
4758b97ceb1SHieu Tran #define ICE_FW_LOG_DESC_SIZE_MAX	\
4768b97ceb1SHieu Tran 	ICE_FW_LOG_DESC_SIZE(ICE_AQC_FW_LOG_ID_MAX)
4778b97ceb1SHieu Tran 
4788b97ceb1SHieu Tran /**
4798b97ceb1SHieu Tran  * ice_cfg_fw_log - configure FW logging
480f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
4818b97ceb1SHieu Tran  * @enable: enable certain FW logging events if true, disable all if false
4828b97ceb1SHieu Tran  *
4838b97ceb1SHieu Tran  * This function enables/disables the FW logging via Rx CQ events and a UART
4848b97ceb1SHieu Tran  * port based on predetermined configurations. FW logging via the Rx CQ can be
4858b97ceb1SHieu Tran  * enabled/disabled for individual PF's. However, FW logging via the UART can
4868b97ceb1SHieu Tran  * only be enabled/disabled for all PFs on the same device.
4878b97ceb1SHieu Tran  *
4888b97ceb1SHieu Tran  * To enable overall FW logging, the "cq_en" and "uart_en" enable bits in
4898b97ceb1SHieu Tran  * hw->fw_log need to be set accordingly, e.g. based on user-provided input,
4908b97ceb1SHieu Tran  * before initializing the device.
4918b97ceb1SHieu Tran  *
4928b97ceb1SHieu Tran  * When re/configuring FW logging, callers need to update the "cfg" elements of
4938b97ceb1SHieu Tran  * the hw->fw_log.evnts array with the desired logging event configurations for
4948b97ceb1SHieu Tran  * modules of interest. When disabling FW logging completely, the callers can
4958b97ceb1SHieu Tran  * just pass false in the "enable" parameter. On completion, the function will
4968b97ceb1SHieu Tran  * update the "cur" element of the hw->fw_log.evnts array with the resulting
4978b97ceb1SHieu Tran  * logging event configurations of the modules that are being re/configured. FW
4988b97ceb1SHieu Tran  * logging modules that are not part of a reconfiguration operation retain their
4998b97ceb1SHieu Tran  * previous states.
5008b97ceb1SHieu Tran  *
5018b97ceb1SHieu Tran  * Before resetting the device, it is recommended that the driver disables FW
5028b97ceb1SHieu Tran  * logging before shutting down the control queue. When disabling FW logging
5038b97ceb1SHieu Tran  * ("enable" = false), the latest configurations of FW logging events stored in
5048b97ceb1SHieu Tran  * hw->fw_log.evnts[] are not overridden to allow them to be reconfigured after
5058b97ceb1SHieu Tran  * a device reset.
5068b97ceb1SHieu Tran  *
5078b97ceb1SHieu Tran  * When enabling FW logging to emit log messages via the Rx CQ during the
5088b97ceb1SHieu Tran  * device's initialization phase, a mechanism alternative to interrupt handlers
5098b97ceb1SHieu Tran  * needs to be used to extract FW log messages from the Rx CQ periodically and
5108b97ceb1SHieu Tran  * to prevent the Rx CQ from being full and stalling other types of control
5118b97ceb1SHieu Tran  * messages from FW to SW. Interrupts are typically disabled during the device's
5128b97ceb1SHieu Tran  * initialization phase.
5138b97ceb1SHieu Tran  */
5148b97ceb1SHieu Tran static enum ice_status ice_cfg_fw_log(struct ice_hw *hw, bool enable)
5158b97ceb1SHieu Tran {
5168b97ceb1SHieu Tran 	struct ice_aqc_fw_logging_data *data = NULL;
5178b97ceb1SHieu Tran 	struct ice_aqc_fw_logging *cmd;
5188b97ceb1SHieu Tran 	enum ice_status status = 0;
5198b97ceb1SHieu Tran 	u16 i, chgs = 0, len = 0;
5208b97ceb1SHieu Tran 	struct ice_aq_desc desc;
5218b97ceb1SHieu Tran 	u8 actv_evnts = 0;
5228b97ceb1SHieu Tran 	void *buf = NULL;
5238b97ceb1SHieu Tran 
5248b97ceb1SHieu Tran 	if (!hw->fw_log.cq_en && !hw->fw_log.uart_en)
5258b97ceb1SHieu Tran 		return 0;
5268b97ceb1SHieu Tran 
5278b97ceb1SHieu Tran 	/* Disable FW logging only when the control queue is still responsive */
5288b97ceb1SHieu Tran 	if (!enable &&
5298b97ceb1SHieu Tran 	    (!hw->fw_log.actv_evnts || !ice_check_sq_alive(hw, &hw->adminq)))
5308b97ceb1SHieu Tran 		return 0;
5318b97ceb1SHieu Tran 
5328b97ceb1SHieu Tran 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_fw_logging);
5338b97ceb1SHieu Tran 	cmd = &desc.params.fw_logging;
5348b97ceb1SHieu Tran 
5358b97ceb1SHieu Tran 	/* Indicate which controls are valid */
5368b97ceb1SHieu Tran 	if (hw->fw_log.cq_en)
5378b97ceb1SHieu Tran 		cmd->log_ctrl_valid |= ICE_AQC_FW_LOG_AQ_VALID;
5388b97ceb1SHieu Tran 
5398b97ceb1SHieu Tran 	if (hw->fw_log.uart_en)
5408b97ceb1SHieu Tran 		cmd->log_ctrl_valid |= ICE_AQC_FW_LOG_UART_VALID;
5418b97ceb1SHieu Tran 
5428b97ceb1SHieu Tran 	if (enable) {
5438b97ceb1SHieu Tran 		/* Fill in an array of entries with FW logging modules and
5448b97ceb1SHieu Tran 		 * logging events being reconfigured.
5458b97ceb1SHieu Tran 		 */
5468b97ceb1SHieu Tran 		for (i = 0; i < ICE_AQC_FW_LOG_ID_MAX; i++) {
5478b97ceb1SHieu Tran 			u16 val;
5488b97ceb1SHieu Tran 
5498b97ceb1SHieu Tran 			/* Keep track of enabled event types */
5508b97ceb1SHieu Tran 			actv_evnts |= hw->fw_log.evnts[i].cfg;
5518b97ceb1SHieu Tran 
5528b97ceb1SHieu Tran 			if (hw->fw_log.evnts[i].cfg == hw->fw_log.evnts[i].cur)
5538b97ceb1SHieu Tran 				continue;
5548b97ceb1SHieu Tran 
5558b97ceb1SHieu Tran 			if (!data) {
5568b97ceb1SHieu Tran 				data = devm_kzalloc(ice_hw_to_dev(hw),
5578b97ceb1SHieu Tran 						    ICE_FW_LOG_DESC_SIZE_MAX,
5588b97ceb1SHieu Tran 						    GFP_KERNEL);
5598b97ceb1SHieu Tran 				if (!data)
5608b97ceb1SHieu Tran 					return ICE_ERR_NO_MEMORY;
5618b97ceb1SHieu Tran 			}
5628b97ceb1SHieu Tran 
5638b97ceb1SHieu Tran 			val = i << ICE_AQC_FW_LOG_ID_S;
5648b97ceb1SHieu Tran 			val |= hw->fw_log.evnts[i].cfg << ICE_AQC_FW_LOG_EN_S;
5658b97ceb1SHieu Tran 			data->entry[chgs++] = cpu_to_le16(val);
5668b97ceb1SHieu Tran 		}
5678b97ceb1SHieu Tran 
5688b97ceb1SHieu Tran 		/* Only enable FW logging if at least one module is specified.
5698b97ceb1SHieu Tran 		 * If FW logging is currently enabled but all modules are not
5708b97ceb1SHieu Tran 		 * enabled to emit log messages, disable FW logging altogether.
5718b97ceb1SHieu Tran 		 */
5728b97ceb1SHieu Tran 		if (actv_evnts) {
5738b97ceb1SHieu Tran 			/* Leave if there is effectively no change */
5748b97ceb1SHieu Tran 			if (!chgs)
5758b97ceb1SHieu Tran 				goto out;
5768b97ceb1SHieu Tran 
5778b97ceb1SHieu Tran 			if (hw->fw_log.cq_en)
5788b97ceb1SHieu Tran 				cmd->log_ctrl |= ICE_AQC_FW_LOG_AQ_EN;
5798b97ceb1SHieu Tran 
5808b97ceb1SHieu Tran 			if (hw->fw_log.uart_en)
5818b97ceb1SHieu Tran 				cmd->log_ctrl |= ICE_AQC_FW_LOG_UART_EN;
5828b97ceb1SHieu Tran 
5838b97ceb1SHieu Tran 			buf = data;
5848b97ceb1SHieu Tran 			len = ICE_FW_LOG_DESC_SIZE(chgs);
5858b97ceb1SHieu Tran 			desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
5868b97ceb1SHieu Tran 		}
5878b97ceb1SHieu Tran 	}
5888b97ceb1SHieu Tran 
5898b97ceb1SHieu Tran 	status = ice_aq_send_cmd(hw, &desc, buf, len, NULL);
5908b97ceb1SHieu Tran 	if (!status) {
5918b97ceb1SHieu Tran 		/* Update the current configuration to reflect events enabled.
5928b97ceb1SHieu Tran 		 * hw->fw_log.cq_en and hw->fw_log.uart_en indicate if the FW
5938b97ceb1SHieu Tran 		 * logging mode is enabled for the device. They do not reflect
5948b97ceb1SHieu Tran 		 * actual modules being enabled to emit log messages. So, their
5958b97ceb1SHieu Tran 		 * values remain unchanged even when all modules are disabled.
5968b97ceb1SHieu Tran 		 */
5978b97ceb1SHieu Tran 		u16 cnt = enable ? chgs : (u16)ICE_AQC_FW_LOG_ID_MAX;
5988b97ceb1SHieu Tran 
5998b97ceb1SHieu Tran 		hw->fw_log.actv_evnts = actv_evnts;
6008b97ceb1SHieu Tran 		for (i = 0; i < cnt; i++) {
6018b97ceb1SHieu Tran 			u16 v, m;
6028b97ceb1SHieu Tran 
6038b97ceb1SHieu Tran 			if (!enable) {
6048b97ceb1SHieu Tran 				/* When disabling all FW logging events as part
6058b97ceb1SHieu Tran 				 * of device's de-initialization, the original
6068b97ceb1SHieu Tran 				 * configurations are retained, and can be used
6078b97ceb1SHieu Tran 				 * to reconfigure FW logging later if the device
6088b97ceb1SHieu Tran 				 * is re-initialized.
6098b97ceb1SHieu Tran 				 */
6108b97ceb1SHieu Tran 				hw->fw_log.evnts[i].cur = 0;
6118b97ceb1SHieu Tran 				continue;
6128b97ceb1SHieu Tran 			}
6138b97ceb1SHieu Tran 
6148b97ceb1SHieu Tran 			v = le16_to_cpu(data->entry[i]);
6158b97ceb1SHieu Tran 			m = (v & ICE_AQC_FW_LOG_ID_M) >> ICE_AQC_FW_LOG_ID_S;
6168b97ceb1SHieu Tran 			hw->fw_log.evnts[m].cur = hw->fw_log.evnts[m].cfg;
6178b97ceb1SHieu Tran 		}
6188b97ceb1SHieu Tran 	}
6198b97ceb1SHieu Tran 
6208b97ceb1SHieu Tran out:
6218b97ceb1SHieu Tran 	if (data)
6228b97ceb1SHieu Tran 		devm_kfree(ice_hw_to_dev(hw), data);
6238b97ceb1SHieu Tran 
6248b97ceb1SHieu Tran 	return status;
6258b97ceb1SHieu Tran }
6268b97ceb1SHieu Tran 
6278b97ceb1SHieu Tran /**
6288b97ceb1SHieu Tran  * ice_output_fw_log
629f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
6308b97ceb1SHieu Tran  * @desc: pointer to the AQ message descriptor
6318b97ceb1SHieu Tran  * @buf: pointer to the buffer accompanying the AQ message
6328b97ceb1SHieu Tran  *
6338b97ceb1SHieu Tran  * Formats a FW Log message and outputs it via the standard driver logs.
6348b97ceb1SHieu Tran  */
6358b97ceb1SHieu Tran void ice_output_fw_log(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf)
6368b97ceb1SHieu Tran {
6378b97ceb1SHieu Tran 	ice_debug(hw, ICE_DBG_AQ_MSG, "[ FW Log Msg Start ]\n");
6388b97ceb1SHieu Tran 	ice_debug_array(hw, ICE_DBG_AQ_MSG, 16, 1, (u8 *)buf,
6398b97ceb1SHieu Tran 			le16_to_cpu(desc->datalen));
6408b97ceb1SHieu Tran 	ice_debug(hw, ICE_DBG_AQ_MSG, "[ FW Log Msg End ]\n");
6418b97ceb1SHieu Tran }
6428b97ceb1SHieu Tran 
6439daf8208SAnirudh Venkataramanan /**
6449e4ab4c2SBrett Creeley  * ice_get_itr_intrl_gran - determine int/intrl granularity
645f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
6469e4ab4c2SBrett Creeley  *
6479e4ab4c2SBrett Creeley  * Determines the itr/intrl granularities based on the maximum aggregate
6489e4ab4c2SBrett Creeley  * bandwidth according to the device's configuration during power-on.
6499e4ab4c2SBrett Creeley  */
6509e4ab4c2SBrett Creeley static enum ice_status ice_get_itr_intrl_gran(struct ice_hw *hw)
6519e4ab4c2SBrett Creeley {
6529e4ab4c2SBrett Creeley 	u8 max_agg_bw = (rd32(hw, GL_PWR_MODE_CTL) &
6539e4ab4c2SBrett Creeley 			 GL_PWR_MODE_CTL_CAR_MAX_BW_M) >>
6549e4ab4c2SBrett Creeley 			GL_PWR_MODE_CTL_CAR_MAX_BW_S;
6559e4ab4c2SBrett Creeley 
6569e4ab4c2SBrett Creeley 	switch (max_agg_bw) {
6579e4ab4c2SBrett Creeley 	case ICE_MAX_AGG_BW_200G:
6589e4ab4c2SBrett Creeley 	case ICE_MAX_AGG_BW_100G:
6599e4ab4c2SBrett Creeley 	case ICE_MAX_AGG_BW_50G:
6609e4ab4c2SBrett Creeley 		hw->itr_gran = ICE_ITR_GRAN_ABOVE_25;
6619e4ab4c2SBrett Creeley 		hw->intrl_gran = ICE_INTRL_GRAN_ABOVE_25;
6629e4ab4c2SBrett Creeley 		break;
6639e4ab4c2SBrett Creeley 	case ICE_MAX_AGG_BW_25G:
6649e4ab4c2SBrett Creeley 		hw->itr_gran = ICE_ITR_GRAN_MAX_25;
6659e4ab4c2SBrett Creeley 		hw->intrl_gran = ICE_INTRL_GRAN_MAX_25;
6669e4ab4c2SBrett Creeley 		break;
6679e4ab4c2SBrett Creeley 	default:
6689e4ab4c2SBrett Creeley 		ice_debug(hw, ICE_DBG_INIT,
6699e4ab4c2SBrett Creeley 			  "Failed to determine itr/intrl granularity\n");
6709e4ab4c2SBrett Creeley 		return ICE_ERR_CFG;
6719e4ab4c2SBrett Creeley 	}
6729e4ab4c2SBrett Creeley 
6739e4ab4c2SBrett Creeley 	return 0;
6749e4ab4c2SBrett Creeley }
6759e4ab4c2SBrett Creeley 
6769e4ab4c2SBrett Creeley /**
677f31e4b6fSAnirudh Venkataramanan  * ice_init_hw - main hardware initialization routine
678f31e4b6fSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
679f31e4b6fSAnirudh Venkataramanan  */
680f31e4b6fSAnirudh Venkataramanan enum ice_status ice_init_hw(struct ice_hw *hw)
681f31e4b6fSAnirudh Venkataramanan {
682dc49c772SAnirudh Venkataramanan 	struct ice_aqc_get_phy_caps_data *pcaps;
683f31e4b6fSAnirudh Venkataramanan 	enum ice_status status;
684dc49c772SAnirudh Venkataramanan 	u16 mac_buf_len;
685dc49c772SAnirudh Venkataramanan 	void *mac_buf;
686f31e4b6fSAnirudh Venkataramanan 
687f31e4b6fSAnirudh Venkataramanan 	/* Set MAC type based on DeviceID */
688f31e4b6fSAnirudh Venkataramanan 	status = ice_set_mac_type(hw);
689f31e4b6fSAnirudh Venkataramanan 	if (status)
690f31e4b6fSAnirudh Venkataramanan 		return status;
691f31e4b6fSAnirudh Venkataramanan 
692f31e4b6fSAnirudh Venkataramanan 	hw->pf_id = (u8)(rd32(hw, PF_FUNC_RID) &
693f31e4b6fSAnirudh Venkataramanan 			 PF_FUNC_RID_FUNC_NUM_M) >>
694f31e4b6fSAnirudh Venkataramanan 		PF_FUNC_RID_FUNC_NUM_S;
695f31e4b6fSAnirudh Venkataramanan 
696f31e4b6fSAnirudh Venkataramanan 	status = ice_reset(hw, ICE_RESET_PFR);
697f31e4b6fSAnirudh Venkataramanan 	if (status)
698f31e4b6fSAnirudh Venkataramanan 		return status;
699f31e4b6fSAnirudh Venkataramanan 
7009e4ab4c2SBrett Creeley 	status = ice_get_itr_intrl_gran(hw);
7019e4ab4c2SBrett Creeley 	if (status)
7029e4ab4c2SBrett Creeley 		return status;
703940b61afSAnirudh Venkataramanan 
704f31e4b6fSAnirudh Venkataramanan 	status = ice_init_all_ctrlq(hw);
705f31e4b6fSAnirudh Venkataramanan 	if (status)
706f31e4b6fSAnirudh Venkataramanan 		goto err_unroll_cqinit;
707f31e4b6fSAnirudh Venkataramanan 
7088b97ceb1SHieu Tran 	/* Enable FW logging. Not fatal if this fails. */
7098b97ceb1SHieu Tran 	status = ice_cfg_fw_log(hw, true);
7108b97ceb1SHieu Tran 	if (status)
7118b97ceb1SHieu Tran 		ice_debug(hw, ICE_DBG_INIT, "Failed to enable FW logging.\n");
7128b97ceb1SHieu Tran 
713f31e4b6fSAnirudh Venkataramanan 	status = ice_clear_pf_cfg(hw);
714f31e4b6fSAnirudh Venkataramanan 	if (status)
715f31e4b6fSAnirudh Venkataramanan 		goto err_unroll_cqinit;
716f31e4b6fSAnirudh Venkataramanan 
717f31e4b6fSAnirudh Venkataramanan 	ice_clear_pxe_mode(hw);
718f31e4b6fSAnirudh Venkataramanan 
719f31e4b6fSAnirudh Venkataramanan 	status = ice_init_nvm(hw);
720f31e4b6fSAnirudh Venkataramanan 	if (status)
721f31e4b6fSAnirudh Venkataramanan 		goto err_unroll_cqinit;
722f31e4b6fSAnirudh Venkataramanan 
7239c20346bSAnirudh Venkataramanan 	status = ice_get_caps(hw);
7249c20346bSAnirudh Venkataramanan 	if (status)
7259c20346bSAnirudh Venkataramanan 		goto err_unroll_cqinit;
7269c20346bSAnirudh Venkataramanan 
7279c20346bSAnirudh Venkataramanan 	hw->port_info = devm_kzalloc(ice_hw_to_dev(hw),
7289c20346bSAnirudh Venkataramanan 				     sizeof(*hw->port_info), GFP_KERNEL);
7299c20346bSAnirudh Venkataramanan 	if (!hw->port_info) {
7309c20346bSAnirudh Venkataramanan 		status = ICE_ERR_NO_MEMORY;
7319c20346bSAnirudh Venkataramanan 		goto err_unroll_cqinit;
7329c20346bSAnirudh Venkataramanan 	}
7339c20346bSAnirudh Venkataramanan 
734f9867df6SAnirudh Venkataramanan 	/* set the back pointer to HW */
7359c20346bSAnirudh Venkataramanan 	hw->port_info->hw = hw;
7369c20346bSAnirudh Venkataramanan 
7379c20346bSAnirudh Venkataramanan 	/* Initialize port_info struct with switch configuration data */
7389c20346bSAnirudh Venkataramanan 	status = ice_get_initial_sw_cfg(hw);
7399c20346bSAnirudh Venkataramanan 	if (status)
7409c20346bSAnirudh Venkataramanan 		goto err_unroll_alloc;
7419c20346bSAnirudh Venkataramanan 
7429daf8208SAnirudh Venkataramanan 	hw->evb_veb = true;
7439daf8208SAnirudh Venkataramanan 
744d337f2afSAnirudh Venkataramanan 	/* Query the allocated resources for Tx scheduler */
7459c20346bSAnirudh Venkataramanan 	status = ice_sched_query_res_alloc(hw);
7469c20346bSAnirudh Venkataramanan 	if (status) {
7479c20346bSAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_SCHED,
7489c20346bSAnirudh Venkataramanan 			  "Failed to get scheduler allocated resources\n");
7499c20346bSAnirudh Venkataramanan 		goto err_unroll_alloc;
7509c20346bSAnirudh Venkataramanan 	}
7519c20346bSAnirudh Venkataramanan 
752dc49c772SAnirudh Venkataramanan 	/* Initialize port_info struct with scheduler data */
753dc49c772SAnirudh Venkataramanan 	status = ice_sched_init_port(hw->port_info);
754dc49c772SAnirudh Venkataramanan 	if (status)
755dc49c772SAnirudh Venkataramanan 		goto err_unroll_sched;
756dc49c772SAnirudh Venkataramanan 
757dc49c772SAnirudh Venkataramanan 	pcaps = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*pcaps), GFP_KERNEL);
758dc49c772SAnirudh Venkataramanan 	if (!pcaps) {
759dc49c772SAnirudh Venkataramanan 		status = ICE_ERR_NO_MEMORY;
760dc49c772SAnirudh Venkataramanan 		goto err_unroll_sched;
761dc49c772SAnirudh Venkataramanan 	}
762dc49c772SAnirudh Venkataramanan 
763dc49c772SAnirudh Venkataramanan 	/* Initialize port_info struct with PHY capabilities */
764dc49c772SAnirudh Venkataramanan 	status = ice_aq_get_phy_caps(hw->port_info, false,
765dc49c772SAnirudh Venkataramanan 				     ICE_AQC_REPORT_TOPO_CAP, pcaps, NULL);
766dc49c772SAnirudh Venkataramanan 	devm_kfree(ice_hw_to_dev(hw), pcaps);
767dc49c772SAnirudh Venkataramanan 	if (status)
768dc49c772SAnirudh Venkataramanan 		goto err_unroll_sched;
769dc49c772SAnirudh Venkataramanan 
770dc49c772SAnirudh Venkataramanan 	/* Initialize port_info struct with link information */
771dc49c772SAnirudh Venkataramanan 	status = ice_aq_get_link_info(hw->port_info, false, NULL, NULL);
772dc49c772SAnirudh Venkataramanan 	if (status)
773dc49c772SAnirudh Venkataramanan 		goto err_unroll_sched;
774dc49c772SAnirudh Venkataramanan 
775b36c598cSAnirudh Venkataramanan 	/* need a valid SW entry point to build a Tx tree */
776b36c598cSAnirudh Venkataramanan 	if (!hw->sw_entry_point_layer) {
777b36c598cSAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_SCHED, "invalid sw entry point\n");
778b36c598cSAnirudh Venkataramanan 		status = ICE_ERR_CFG;
779b36c598cSAnirudh Venkataramanan 		goto err_unroll_sched;
780b36c598cSAnirudh Venkataramanan 	}
7819be1d6f8SAnirudh Venkataramanan 	INIT_LIST_HEAD(&hw->agg_list);
782b36c598cSAnirudh Venkataramanan 
7839daf8208SAnirudh Venkataramanan 	status = ice_init_fltr_mgmt_struct(hw);
7849daf8208SAnirudh Venkataramanan 	if (status)
7859daf8208SAnirudh Venkataramanan 		goto err_unroll_sched;
7869daf8208SAnirudh Venkataramanan 
787f203dca3SAnirudh Venkataramanan 	ice_dev_onetime_setup(hw);
788f203dca3SAnirudh Venkataramanan 
789d6fef10cSMd Fahad Iqbal Polash 	/* Get MAC information */
790d6fef10cSMd Fahad Iqbal Polash 	/* A single port can report up to two (LAN and WoL) addresses */
791d6fef10cSMd Fahad Iqbal Polash 	mac_buf = devm_kcalloc(ice_hw_to_dev(hw), 2,
792d6fef10cSMd Fahad Iqbal Polash 			       sizeof(struct ice_aqc_manage_mac_read_resp),
793d6fef10cSMd Fahad Iqbal Polash 			       GFP_KERNEL);
794d6fef10cSMd Fahad Iqbal Polash 	mac_buf_len = 2 * sizeof(struct ice_aqc_manage_mac_read_resp);
795dc49c772SAnirudh Venkataramanan 
79663bb4e1eSWei Yongjun 	if (!mac_buf) {
79763bb4e1eSWei Yongjun 		status = ICE_ERR_NO_MEMORY;
7989daf8208SAnirudh Venkataramanan 		goto err_unroll_fltr_mgmt_struct;
79963bb4e1eSWei Yongjun 	}
800dc49c772SAnirudh Venkataramanan 
801dc49c772SAnirudh Venkataramanan 	status = ice_aq_manage_mac_read(hw, mac_buf, mac_buf_len, NULL);
802dc49c772SAnirudh Venkataramanan 	devm_kfree(ice_hw_to_dev(hw), mac_buf);
803dc49c772SAnirudh Venkataramanan 
804dc49c772SAnirudh Venkataramanan 	if (status)
8059daf8208SAnirudh Venkataramanan 		goto err_unroll_fltr_mgmt_struct;
806dc49c772SAnirudh Venkataramanan 
80722ef683bSAnirudh Venkataramanan 	ice_init_flex_flds(hw, ICE_RXDID_FLEX_NIC);
80822ef683bSAnirudh Venkataramanan 	ice_init_flex_flds(hw, ICE_RXDID_FLEX_NIC_2);
809cdedef59SAnirudh Venkataramanan 
810f31e4b6fSAnirudh Venkataramanan 	return 0;
811f31e4b6fSAnirudh Venkataramanan 
8129daf8208SAnirudh Venkataramanan err_unroll_fltr_mgmt_struct:
8139daf8208SAnirudh Venkataramanan 	ice_cleanup_fltr_mgmt_struct(hw);
814dc49c772SAnirudh Venkataramanan err_unroll_sched:
815dc49c772SAnirudh Venkataramanan 	ice_sched_cleanup_all(hw);
8169c20346bSAnirudh Venkataramanan err_unroll_alloc:
8179c20346bSAnirudh Venkataramanan 	devm_kfree(ice_hw_to_dev(hw), hw->port_info);
818f31e4b6fSAnirudh Venkataramanan err_unroll_cqinit:
819f31e4b6fSAnirudh Venkataramanan 	ice_shutdown_all_ctrlq(hw);
820f31e4b6fSAnirudh Venkataramanan 	return status;
821f31e4b6fSAnirudh Venkataramanan }
822f31e4b6fSAnirudh Venkataramanan 
823f31e4b6fSAnirudh Venkataramanan /**
824f31e4b6fSAnirudh Venkataramanan  * ice_deinit_hw - unroll initialization operations done by ice_init_hw
825f31e4b6fSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
826f31e4b6fSAnirudh Venkataramanan  */
827f31e4b6fSAnirudh Venkataramanan void ice_deinit_hw(struct ice_hw *hw)
828f31e4b6fSAnirudh Venkataramanan {
8298b97ceb1SHieu Tran 	ice_cleanup_fltr_mgmt_struct(hw);
8308b97ceb1SHieu Tran 
8319c20346bSAnirudh Venkataramanan 	ice_sched_cleanup_all(hw);
8329be1d6f8SAnirudh Venkataramanan 	ice_sched_clear_agg(hw);
833dc49c772SAnirudh Venkataramanan 
8349c20346bSAnirudh Venkataramanan 	if (hw->port_info) {
8359c20346bSAnirudh Venkataramanan 		devm_kfree(ice_hw_to_dev(hw), hw->port_info);
8369c20346bSAnirudh Venkataramanan 		hw->port_info = NULL;
8379c20346bSAnirudh Venkataramanan 	}
8389daf8208SAnirudh Venkataramanan 
8398b97ceb1SHieu Tran 	/* Attempt to disable FW logging before shutting down control queues */
8408b97ceb1SHieu Tran 	ice_cfg_fw_log(hw, false);
8418b97ceb1SHieu Tran 	ice_shutdown_all_ctrlq(hw);
84233e055fcSVictor Raj 
84333e055fcSVictor Raj 	/* Clear VSI contexts if not already cleared */
84433e055fcSVictor Raj 	ice_clear_all_vsi_ctx(hw);
845f31e4b6fSAnirudh Venkataramanan }
846f31e4b6fSAnirudh Venkataramanan 
847f31e4b6fSAnirudh Venkataramanan /**
848f31e4b6fSAnirudh Venkataramanan  * ice_check_reset - Check to see if a global reset is complete
849f31e4b6fSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
850f31e4b6fSAnirudh Venkataramanan  */
851f31e4b6fSAnirudh Venkataramanan enum ice_status ice_check_reset(struct ice_hw *hw)
852f31e4b6fSAnirudh Venkataramanan {
853f31e4b6fSAnirudh Venkataramanan 	u32 cnt, reg = 0, grst_delay;
854f31e4b6fSAnirudh Venkataramanan 
855f31e4b6fSAnirudh Venkataramanan 	/* Poll for Device Active state in case a recent CORER, GLOBR,
856f31e4b6fSAnirudh Venkataramanan 	 * or EMPR has occurred. The grst delay value is in 100ms units.
857f31e4b6fSAnirudh Venkataramanan 	 * Add 1sec for outstanding AQ commands that can take a long time.
858f31e4b6fSAnirudh Venkataramanan 	 */
859f31e4b6fSAnirudh Venkataramanan 	grst_delay = ((rd32(hw, GLGEN_RSTCTL) & GLGEN_RSTCTL_GRSTDEL_M) >>
860f31e4b6fSAnirudh Venkataramanan 		      GLGEN_RSTCTL_GRSTDEL_S) + 10;
861f31e4b6fSAnirudh Venkataramanan 
862f31e4b6fSAnirudh Venkataramanan 	for (cnt = 0; cnt < grst_delay; cnt++) {
863f31e4b6fSAnirudh Venkataramanan 		mdelay(100);
864f31e4b6fSAnirudh Venkataramanan 		reg = rd32(hw, GLGEN_RSTAT);
865f31e4b6fSAnirudh Venkataramanan 		if (!(reg & GLGEN_RSTAT_DEVSTATE_M))
866f31e4b6fSAnirudh Venkataramanan 			break;
867f31e4b6fSAnirudh Venkataramanan 	}
868f31e4b6fSAnirudh Venkataramanan 
869f31e4b6fSAnirudh Venkataramanan 	if (cnt == grst_delay) {
870f31e4b6fSAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_INIT,
871f31e4b6fSAnirudh Venkataramanan 			  "Global reset polling failed to complete.\n");
872f31e4b6fSAnirudh Venkataramanan 		return ICE_ERR_RESET_FAILED;
873f31e4b6fSAnirudh Venkataramanan 	}
874f31e4b6fSAnirudh Venkataramanan 
875f31e4b6fSAnirudh Venkataramanan #define ICE_RESET_DONE_MASK	(GLNVM_ULD_CORER_DONE_M | \
876f31e4b6fSAnirudh Venkataramanan 				 GLNVM_ULD_GLOBR_DONE_M)
877f31e4b6fSAnirudh Venkataramanan 
878f31e4b6fSAnirudh Venkataramanan 	/* Device is Active; check Global Reset processes are done */
879f31e4b6fSAnirudh Venkataramanan 	for (cnt = 0; cnt < ICE_PF_RESET_WAIT_COUNT; cnt++) {
880f31e4b6fSAnirudh Venkataramanan 		reg = rd32(hw, GLNVM_ULD) & ICE_RESET_DONE_MASK;
881f31e4b6fSAnirudh Venkataramanan 		if (reg == ICE_RESET_DONE_MASK) {
882f31e4b6fSAnirudh Venkataramanan 			ice_debug(hw, ICE_DBG_INIT,
883f31e4b6fSAnirudh Venkataramanan 				  "Global reset processes done. %d\n", cnt);
884f31e4b6fSAnirudh Venkataramanan 			break;
885f31e4b6fSAnirudh Venkataramanan 		}
886f31e4b6fSAnirudh Venkataramanan 		mdelay(10);
887f31e4b6fSAnirudh Venkataramanan 	}
888f31e4b6fSAnirudh Venkataramanan 
889f31e4b6fSAnirudh Venkataramanan 	if (cnt == ICE_PF_RESET_WAIT_COUNT) {
890f31e4b6fSAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_INIT,
891f31e4b6fSAnirudh Venkataramanan 			  "Wait for Reset Done timed out. GLNVM_ULD = 0x%x\n",
892f31e4b6fSAnirudh Venkataramanan 			  reg);
893f31e4b6fSAnirudh Venkataramanan 		return ICE_ERR_RESET_FAILED;
894f31e4b6fSAnirudh Venkataramanan 	}
895f31e4b6fSAnirudh Venkataramanan 
896f31e4b6fSAnirudh Venkataramanan 	return 0;
897f31e4b6fSAnirudh Venkataramanan }
898f31e4b6fSAnirudh Venkataramanan 
899f31e4b6fSAnirudh Venkataramanan /**
900f31e4b6fSAnirudh Venkataramanan  * ice_pf_reset - Reset the PF
901f31e4b6fSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
902f31e4b6fSAnirudh Venkataramanan  *
903f31e4b6fSAnirudh Venkataramanan  * If a global reset has been triggered, this function checks
904f31e4b6fSAnirudh Venkataramanan  * for its completion and then issues the PF reset
905f31e4b6fSAnirudh Venkataramanan  */
906f31e4b6fSAnirudh Venkataramanan static enum ice_status ice_pf_reset(struct ice_hw *hw)
907f31e4b6fSAnirudh Venkataramanan {
908f31e4b6fSAnirudh Venkataramanan 	u32 cnt, reg;
909f31e4b6fSAnirudh Venkataramanan 
910f31e4b6fSAnirudh Venkataramanan 	/* If at function entry a global reset was already in progress, i.e.
911f31e4b6fSAnirudh Venkataramanan 	 * state is not 'device active' or any of the reset done bits are not
912f31e4b6fSAnirudh Venkataramanan 	 * set in GLNVM_ULD, there is no need for a PF Reset; poll until the
913f31e4b6fSAnirudh Venkataramanan 	 * global reset is done.
914f31e4b6fSAnirudh Venkataramanan 	 */
915f31e4b6fSAnirudh Venkataramanan 	if ((rd32(hw, GLGEN_RSTAT) & GLGEN_RSTAT_DEVSTATE_M) ||
916f31e4b6fSAnirudh Venkataramanan 	    (rd32(hw, GLNVM_ULD) & ICE_RESET_DONE_MASK) ^ ICE_RESET_DONE_MASK) {
917f31e4b6fSAnirudh Venkataramanan 		/* poll on global reset currently in progress until done */
918f31e4b6fSAnirudh Venkataramanan 		if (ice_check_reset(hw))
919f31e4b6fSAnirudh Venkataramanan 			return ICE_ERR_RESET_FAILED;
920f31e4b6fSAnirudh Venkataramanan 
921f31e4b6fSAnirudh Venkataramanan 		return 0;
922f31e4b6fSAnirudh Venkataramanan 	}
923f31e4b6fSAnirudh Venkataramanan 
924f31e4b6fSAnirudh Venkataramanan 	/* Reset the PF */
925f31e4b6fSAnirudh Venkataramanan 	reg = rd32(hw, PFGEN_CTRL);
926f31e4b6fSAnirudh Venkataramanan 
927f31e4b6fSAnirudh Venkataramanan 	wr32(hw, PFGEN_CTRL, (reg | PFGEN_CTRL_PFSWR_M));
928f31e4b6fSAnirudh Venkataramanan 
929f31e4b6fSAnirudh Venkataramanan 	for (cnt = 0; cnt < ICE_PF_RESET_WAIT_COUNT; cnt++) {
930f31e4b6fSAnirudh Venkataramanan 		reg = rd32(hw, PFGEN_CTRL);
931f31e4b6fSAnirudh Venkataramanan 		if (!(reg & PFGEN_CTRL_PFSWR_M))
932f31e4b6fSAnirudh Venkataramanan 			break;
933f31e4b6fSAnirudh Venkataramanan 
934f31e4b6fSAnirudh Venkataramanan 		mdelay(1);
935f31e4b6fSAnirudh Venkataramanan 	}
936f31e4b6fSAnirudh Venkataramanan 
937f31e4b6fSAnirudh Venkataramanan 	if (cnt == ICE_PF_RESET_WAIT_COUNT) {
938f31e4b6fSAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_INIT,
939f31e4b6fSAnirudh Venkataramanan 			  "PF reset polling failed to complete.\n");
940f31e4b6fSAnirudh Venkataramanan 		return ICE_ERR_RESET_FAILED;
941f31e4b6fSAnirudh Venkataramanan 	}
942f31e4b6fSAnirudh Venkataramanan 
943f31e4b6fSAnirudh Venkataramanan 	return 0;
944f31e4b6fSAnirudh Venkataramanan }
945f31e4b6fSAnirudh Venkataramanan 
946f31e4b6fSAnirudh Venkataramanan /**
947f31e4b6fSAnirudh Venkataramanan  * ice_reset - Perform different types of reset
948f31e4b6fSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
949f31e4b6fSAnirudh Venkataramanan  * @req: reset request
950f31e4b6fSAnirudh Venkataramanan  *
951f31e4b6fSAnirudh Venkataramanan  * This function triggers a reset as specified by the req parameter.
952f31e4b6fSAnirudh Venkataramanan  *
953f31e4b6fSAnirudh Venkataramanan  * Note:
954f31e4b6fSAnirudh Venkataramanan  * If anything other than a PF reset is triggered, PXE mode is restored.
955f31e4b6fSAnirudh Venkataramanan  * This has to be cleared using ice_clear_pxe_mode again, once the AQ
956f31e4b6fSAnirudh Venkataramanan  * interface has been restored in the rebuild flow.
957f31e4b6fSAnirudh Venkataramanan  */
958f31e4b6fSAnirudh Venkataramanan enum ice_status ice_reset(struct ice_hw *hw, enum ice_reset_req req)
959f31e4b6fSAnirudh Venkataramanan {
960f31e4b6fSAnirudh Venkataramanan 	u32 val = 0;
961f31e4b6fSAnirudh Venkataramanan 
962f31e4b6fSAnirudh Venkataramanan 	switch (req) {
963f31e4b6fSAnirudh Venkataramanan 	case ICE_RESET_PFR:
964f31e4b6fSAnirudh Venkataramanan 		return ice_pf_reset(hw);
965f31e4b6fSAnirudh Venkataramanan 	case ICE_RESET_CORER:
966f31e4b6fSAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_INIT, "CoreR requested\n");
967f31e4b6fSAnirudh Venkataramanan 		val = GLGEN_RTRIG_CORER_M;
968f31e4b6fSAnirudh Venkataramanan 		break;
969f31e4b6fSAnirudh Venkataramanan 	case ICE_RESET_GLOBR:
970f31e4b6fSAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_INIT, "GlobalR requested\n");
971f31e4b6fSAnirudh Venkataramanan 		val = GLGEN_RTRIG_GLOBR_M;
972f31e4b6fSAnirudh Venkataramanan 		break;
9730f9d5027SAnirudh Venkataramanan 	default:
9740f9d5027SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
975f31e4b6fSAnirudh Venkataramanan 	}
976f31e4b6fSAnirudh Venkataramanan 
977f31e4b6fSAnirudh Venkataramanan 	val |= rd32(hw, GLGEN_RTRIG);
978f31e4b6fSAnirudh Venkataramanan 	wr32(hw, GLGEN_RTRIG, val);
979f31e4b6fSAnirudh Venkataramanan 	ice_flush(hw);
980f31e4b6fSAnirudh Venkataramanan 
981f31e4b6fSAnirudh Venkataramanan 	/* wait for the FW to be ready */
982f31e4b6fSAnirudh Venkataramanan 	return ice_check_reset(hw);
983f31e4b6fSAnirudh Venkataramanan }
984f31e4b6fSAnirudh Venkataramanan 
9857ec59eeaSAnirudh Venkataramanan /**
986cdedef59SAnirudh Venkataramanan  * ice_copy_rxq_ctx_to_hw
987cdedef59SAnirudh Venkataramanan  * @hw: pointer to the hardware structure
988cdedef59SAnirudh Venkataramanan  * @ice_rxq_ctx: pointer to the rxq context
989d337f2afSAnirudh Venkataramanan  * @rxq_index: the index of the Rx queue
990cdedef59SAnirudh Venkataramanan  *
991f9867df6SAnirudh Venkataramanan  * Copies rxq context from dense structure to HW register space
992cdedef59SAnirudh Venkataramanan  */
993cdedef59SAnirudh Venkataramanan static enum ice_status
994cdedef59SAnirudh Venkataramanan ice_copy_rxq_ctx_to_hw(struct ice_hw *hw, u8 *ice_rxq_ctx, u32 rxq_index)
995cdedef59SAnirudh Venkataramanan {
996cdedef59SAnirudh Venkataramanan 	u8 i;
997cdedef59SAnirudh Venkataramanan 
998cdedef59SAnirudh Venkataramanan 	if (!ice_rxq_ctx)
999cdedef59SAnirudh Venkataramanan 		return ICE_ERR_BAD_PTR;
1000cdedef59SAnirudh Venkataramanan 
1001cdedef59SAnirudh Venkataramanan 	if (rxq_index > QRX_CTRL_MAX_INDEX)
1002cdedef59SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
1003cdedef59SAnirudh Venkataramanan 
1004f9867df6SAnirudh Venkataramanan 	/* Copy each dword separately to HW */
1005cdedef59SAnirudh Venkataramanan 	for (i = 0; i < ICE_RXQ_CTX_SIZE_DWORDS; i++) {
1006cdedef59SAnirudh Venkataramanan 		wr32(hw, QRX_CONTEXT(i, rxq_index),
1007cdedef59SAnirudh Venkataramanan 		     *((u32 *)(ice_rxq_ctx + (i * sizeof(u32)))));
1008cdedef59SAnirudh Venkataramanan 
1009cdedef59SAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_QCTX, "qrxdata[%d]: %08X\n", i,
1010cdedef59SAnirudh Venkataramanan 			  *((u32 *)(ice_rxq_ctx + (i * sizeof(u32)))));
1011cdedef59SAnirudh Venkataramanan 	}
1012cdedef59SAnirudh Venkataramanan 
1013cdedef59SAnirudh Venkataramanan 	return 0;
1014cdedef59SAnirudh Venkataramanan }
1015cdedef59SAnirudh Venkataramanan 
1016cdedef59SAnirudh Venkataramanan /* LAN Rx Queue Context */
1017cdedef59SAnirudh Venkataramanan static const struct ice_ctx_ele ice_rlan_ctx_info[] = {
1018cdedef59SAnirudh Venkataramanan 	/* Field		Width	LSB */
1019cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, head,		13,	0),
1020cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, cpuid,		8,	13),
1021cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, base,		57,	32),
1022cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, qlen,		13,	89),
1023cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, dbuf,		7,	102),
1024cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, hbuf,		5,	109),
1025cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, dtype,		2,	114),
1026cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, dsize,		1,	116),
1027cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, crcstrip,		1,	117),
1028cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, l2tsel,		1,	119),
1029cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, hsplit_0,		4,	120),
1030cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, hsplit_1,		2,	124),
1031cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, showiv,		1,	127),
1032cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, rxmax,		14,	174),
1033cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, tphrdesc_ena,	1,	193),
1034cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, tphwdesc_ena,	1,	194),
1035cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, tphdata_ena,	1,	195),
1036cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, tphhead_ena,	1,	196),
1037cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_rlan_ctx, lrxqthresh,		3,	198),
1038cdedef59SAnirudh Venkataramanan 	{ 0 }
1039cdedef59SAnirudh Venkataramanan };
1040cdedef59SAnirudh Venkataramanan 
1041cdedef59SAnirudh Venkataramanan /**
1042cdedef59SAnirudh Venkataramanan  * ice_write_rxq_ctx
1043cdedef59SAnirudh Venkataramanan  * @hw: pointer to the hardware structure
1044cdedef59SAnirudh Venkataramanan  * @rlan_ctx: pointer to the rxq context
1045d337f2afSAnirudh Venkataramanan  * @rxq_index: the index of the Rx queue
1046cdedef59SAnirudh Venkataramanan  *
1047cdedef59SAnirudh Venkataramanan  * Converts rxq context from sparse to dense structure and then writes
1048f9867df6SAnirudh Venkataramanan  * it to HW register space
1049cdedef59SAnirudh Venkataramanan  */
1050cdedef59SAnirudh Venkataramanan enum ice_status
1051cdedef59SAnirudh Venkataramanan ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx,
1052cdedef59SAnirudh Venkataramanan 		  u32 rxq_index)
1053cdedef59SAnirudh Venkataramanan {
1054cdedef59SAnirudh Venkataramanan 	u8 ctx_buf[ICE_RXQ_CTX_SZ] = { 0 };
1055cdedef59SAnirudh Venkataramanan 
1056cdedef59SAnirudh Venkataramanan 	ice_set_ctx((u8 *)rlan_ctx, ctx_buf, ice_rlan_ctx_info);
1057cdedef59SAnirudh Venkataramanan 	return ice_copy_rxq_ctx_to_hw(hw, ctx_buf, rxq_index);
1058cdedef59SAnirudh Venkataramanan }
1059cdedef59SAnirudh Venkataramanan 
1060cdedef59SAnirudh Venkataramanan /* LAN Tx Queue Context */
1061cdedef59SAnirudh Venkataramanan const struct ice_ctx_ele ice_tlan_ctx_info[] = {
1062cdedef59SAnirudh Venkataramanan 				    /* Field			Width	LSB */
1063cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, base,			57,	0),
1064cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, port_num,			3,	57),
1065cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, cgd_num,			5,	60),
1066cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, pf_num,			3,	65),
1067cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, vmvf_num,			10,	68),
1068cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, vmvf_type,			2,	78),
1069cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, src_vsi,			10,	80),
1070cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, tsyn_ena,			1,	90),
1071cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, alt_vlan,			1,	92),
1072cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, cpuid,			8,	93),
1073cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, wb_mode,			1,	101),
1074cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, tphrd_desc,			1,	102),
1075cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, tphrd,			1,	103),
1076cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, tphwr_desc,			1,	104),
1077cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, cmpq_id,			9,	105),
1078cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, qnum_in_func,		14,	114),
1079cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, itr_notification_mode,	1,	128),
1080cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, adjust_prof_id,		6,	129),
1081cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, qlen,			13,	135),
1082cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, quanta_prof_idx,		4,	148),
1083cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, tso_ena,			1,	152),
1084cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, tso_qnum,			11,	153),
1085cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, legacy_int,			1,	164),
1086cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, drop_ena,			1,	165),
1087cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, cache_prof_idx,		2,	166),
1088cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, pkt_shaper_prof_idx,	3,	168),
1089cdedef59SAnirudh Venkataramanan 	ICE_CTX_STORE(ice_tlan_ctx, int_q_state,		110,	171),
1090cdedef59SAnirudh Venkataramanan 	{ 0 }
1091cdedef59SAnirudh Venkataramanan };
1092cdedef59SAnirudh Venkataramanan 
1093cdedef59SAnirudh Venkataramanan /**
10947ec59eeaSAnirudh Venkataramanan  * ice_debug_cq
10957ec59eeaSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
10967ec59eeaSAnirudh Venkataramanan  * @mask: debug mask
10977ec59eeaSAnirudh Venkataramanan  * @desc: pointer to control queue descriptor
10987ec59eeaSAnirudh Venkataramanan  * @buf: pointer to command buffer
10997ec59eeaSAnirudh Venkataramanan  * @buf_len: max length of buf
11007ec59eeaSAnirudh Venkataramanan  *
11017ec59eeaSAnirudh Venkataramanan  * Dumps debug log about control command with descriptor contents.
11027ec59eeaSAnirudh Venkataramanan  */
1103c8b7abddSBruce Allan void
1104c8b7abddSBruce Allan ice_debug_cq(struct ice_hw *hw, u32 __maybe_unused mask, void *desc, void *buf,
1105c8b7abddSBruce Allan 	     u16 buf_len)
11067ec59eeaSAnirudh Venkataramanan {
11077ec59eeaSAnirudh Venkataramanan 	struct ice_aq_desc *cq_desc = (struct ice_aq_desc *)desc;
11087ec59eeaSAnirudh Venkataramanan 	u16 len;
11097ec59eeaSAnirudh Venkataramanan 
11107ec59eeaSAnirudh Venkataramanan #ifndef CONFIG_DYNAMIC_DEBUG
11117ec59eeaSAnirudh Venkataramanan 	if (!(mask & hw->debug_mask))
11127ec59eeaSAnirudh Venkataramanan 		return;
11137ec59eeaSAnirudh Venkataramanan #endif
11147ec59eeaSAnirudh Venkataramanan 
11157ec59eeaSAnirudh Venkataramanan 	if (!desc)
11167ec59eeaSAnirudh Venkataramanan 		return;
11177ec59eeaSAnirudh Venkataramanan 
11187ec59eeaSAnirudh Venkataramanan 	len = le16_to_cpu(cq_desc->datalen);
11197ec59eeaSAnirudh Venkataramanan 
11207ec59eeaSAnirudh Venkataramanan 	ice_debug(hw, mask,
11217ec59eeaSAnirudh Venkataramanan 		  "CQ CMD: opcode 0x%04X, flags 0x%04X, datalen 0x%04X, retval 0x%04X\n",
11227ec59eeaSAnirudh Venkataramanan 		  le16_to_cpu(cq_desc->opcode),
11237ec59eeaSAnirudh Venkataramanan 		  le16_to_cpu(cq_desc->flags),
11247ec59eeaSAnirudh Venkataramanan 		  le16_to_cpu(cq_desc->datalen), le16_to_cpu(cq_desc->retval));
11257ec59eeaSAnirudh Venkataramanan 	ice_debug(hw, mask, "\tcookie (h,l) 0x%08X 0x%08X\n",
11267ec59eeaSAnirudh Venkataramanan 		  le32_to_cpu(cq_desc->cookie_high),
11277ec59eeaSAnirudh Venkataramanan 		  le32_to_cpu(cq_desc->cookie_low));
11287ec59eeaSAnirudh Venkataramanan 	ice_debug(hw, mask, "\tparam (0,1)  0x%08X 0x%08X\n",
11297ec59eeaSAnirudh Venkataramanan 		  le32_to_cpu(cq_desc->params.generic.param0),
11307ec59eeaSAnirudh Venkataramanan 		  le32_to_cpu(cq_desc->params.generic.param1));
11317ec59eeaSAnirudh Venkataramanan 	ice_debug(hw, mask, "\taddr (h,l)   0x%08X 0x%08X\n",
11327ec59eeaSAnirudh Venkataramanan 		  le32_to_cpu(cq_desc->params.generic.addr_high),
11337ec59eeaSAnirudh Venkataramanan 		  le32_to_cpu(cq_desc->params.generic.addr_low));
11347ec59eeaSAnirudh Venkataramanan 	if (buf && cq_desc->datalen != 0) {
11357ec59eeaSAnirudh Venkataramanan 		ice_debug(hw, mask, "Buffer:\n");
11367ec59eeaSAnirudh Venkataramanan 		if (buf_len < len)
11377ec59eeaSAnirudh Venkataramanan 			len = buf_len;
11387ec59eeaSAnirudh Venkataramanan 
11397ec59eeaSAnirudh Venkataramanan 		ice_debug_array(hw, mask, 16, 1, (u8 *)buf, len);
11407ec59eeaSAnirudh Venkataramanan 	}
11417ec59eeaSAnirudh Venkataramanan }
11427ec59eeaSAnirudh Venkataramanan 
11437ec59eeaSAnirudh Venkataramanan /* FW Admin Queue command wrappers */
11447ec59eeaSAnirudh Venkataramanan 
11457ec59eeaSAnirudh Venkataramanan /**
11467ec59eeaSAnirudh Venkataramanan  * ice_aq_send_cmd - send FW Admin Queue command to FW Admin Queue
1147f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
11487ec59eeaSAnirudh Venkataramanan  * @desc: descriptor describing the command
11497ec59eeaSAnirudh Venkataramanan  * @buf: buffer to use for indirect commands (NULL for direct commands)
11507ec59eeaSAnirudh Venkataramanan  * @buf_size: size of buffer for indirect commands (0 for direct commands)
11517ec59eeaSAnirudh Venkataramanan  * @cd: pointer to command details structure
11527ec59eeaSAnirudh Venkataramanan  *
11537ec59eeaSAnirudh Venkataramanan  * Helper function to send FW Admin Queue commands to the FW Admin Queue.
11547ec59eeaSAnirudh Venkataramanan  */
11557ec59eeaSAnirudh Venkataramanan enum ice_status
11567ec59eeaSAnirudh Venkataramanan ice_aq_send_cmd(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf,
11577ec59eeaSAnirudh Venkataramanan 		u16 buf_size, struct ice_sq_cd *cd)
11587ec59eeaSAnirudh Venkataramanan {
11597ec59eeaSAnirudh Venkataramanan 	return ice_sq_send_cmd(hw, &hw->adminq, desc, buf, buf_size, cd);
11607ec59eeaSAnirudh Venkataramanan }
11617ec59eeaSAnirudh Venkataramanan 
11627ec59eeaSAnirudh Venkataramanan /**
11637ec59eeaSAnirudh Venkataramanan  * ice_aq_get_fw_ver
1164f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
11657ec59eeaSAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
11667ec59eeaSAnirudh Venkataramanan  *
11677ec59eeaSAnirudh Venkataramanan  * Get the firmware version (0x0001) from the admin queue commands
11687ec59eeaSAnirudh Venkataramanan  */
11697ec59eeaSAnirudh Venkataramanan enum ice_status ice_aq_get_fw_ver(struct ice_hw *hw, struct ice_sq_cd *cd)
11707ec59eeaSAnirudh Venkataramanan {
11717ec59eeaSAnirudh Venkataramanan 	struct ice_aqc_get_ver *resp;
11727ec59eeaSAnirudh Venkataramanan 	struct ice_aq_desc desc;
11737ec59eeaSAnirudh Venkataramanan 	enum ice_status status;
11747ec59eeaSAnirudh Venkataramanan 
11757ec59eeaSAnirudh Venkataramanan 	resp = &desc.params.get_ver;
11767ec59eeaSAnirudh Venkataramanan 
11777ec59eeaSAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_ver);
11787ec59eeaSAnirudh Venkataramanan 
11797ec59eeaSAnirudh Venkataramanan 	status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
11807ec59eeaSAnirudh Venkataramanan 
11817ec59eeaSAnirudh Venkataramanan 	if (!status) {
11827ec59eeaSAnirudh Venkataramanan 		hw->fw_branch = resp->fw_branch;
11837ec59eeaSAnirudh Venkataramanan 		hw->fw_maj_ver = resp->fw_major;
11847ec59eeaSAnirudh Venkataramanan 		hw->fw_min_ver = resp->fw_minor;
11857ec59eeaSAnirudh Venkataramanan 		hw->fw_patch = resp->fw_patch;
11867ec59eeaSAnirudh Venkataramanan 		hw->fw_build = le32_to_cpu(resp->fw_build);
11877ec59eeaSAnirudh Venkataramanan 		hw->api_branch = resp->api_branch;
11887ec59eeaSAnirudh Venkataramanan 		hw->api_maj_ver = resp->api_major;
11897ec59eeaSAnirudh Venkataramanan 		hw->api_min_ver = resp->api_minor;
11907ec59eeaSAnirudh Venkataramanan 		hw->api_patch = resp->api_patch;
11917ec59eeaSAnirudh Venkataramanan 	}
11927ec59eeaSAnirudh Venkataramanan 
11937ec59eeaSAnirudh Venkataramanan 	return status;
11947ec59eeaSAnirudh Venkataramanan }
11957ec59eeaSAnirudh Venkataramanan 
11967ec59eeaSAnirudh Venkataramanan /**
11977ec59eeaSAnirudh Venkataramanan  * ice_aq_q_shutdown
1198f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
11997ec59eeaSAnirudh Venkataramanan  * @unloading: is the driver unloading itself
12007ec59eeaSAnirudh Venkataramanan  *
12017ec59eeaSAnirudh Venkataramanan  * Tell the Firmware that we're shutting down the AdminQ and whether
12027ec59eeaSAnirudh Venkataramanan  * or not the driver is unloading as well (0x0003).
12037ec59eeaSAnirudh Venkataramanan  */
12047ec59eeaSAnirudh Venkataramanan enum ice_status ice_aq_q_shutdown(struct ice_hw *hw, bool unloading)
12057ec59eeaSAnirudh Venkataramanan {
12067ec59eeaSAnirudh Venkataramanan 	struct ice_aqc_q_shutdown *cmd;
12077ec59eeaSAnirudh Venkataramanan 	struct ice_aq_desc desc;
12087ec59eeaSAnirudh Venkataramanan 
12097ec59eeaSAnirudh Venkataramanan 	cmd = &desc.params.q_shutdown;
12107ec59eeaSAnirudh Venkataramanan 
12117ec59eeaSAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_q_shutdown);
12127ec59eeaSAnirudh Venkataramanan 
12137ec59eeaSAnirudh Venkataramanan 	if (unloading)
12147ec59eeaSAnirudh Venkataramanan 		cmd->driver_unloading = cpu_to_le32(ICE_AQC_DRIVER_UNLOADING);
12157ec59eeaSAnirudh Venkataramanan 
12167ec59eeaSAnirudh Venkataramanan 	return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
12177ec59eeaSAnirudh Venkataramanan }
1218f31e4b6fSAnirudh Venkataramanan 
1219f31e4b6fSAnirudh Venkataramanan /**
1220f31e4b6fSAnirudh Venkataramanan  * ice_aq_req_res
1221f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
1222f9867df6SAnirudh Venkataramanan  * @res: resource ID
1223f31e4b6fSAnirudh Venkataramanan  * @access: access type
1224f31e4b6fSAnirudh Venkataramanan  * @sdp_number: resource number
1225f31e4b6fSAnirudh Venkataramanan  * @timeout: the maximum time in ms that the driver may hold the resource
1226f31e4b6fSAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
1227f31e4b6fSAnirudh Venkataramanan  *
1228ff2b1321SDan Nowlin  * Requests common resource using the admin queue commands (0x0008).
1229ff2b1321SDan Nowlin  * When attempting to acquire the Global Config Lock, the driver can
1230ff2b1321SDan Nowlin  * learn of three states:
1231ff2b1321SDan Nowlin  *  1) ICE_SUCCESS -        acquired lock, and can perform download package
1232ff2b1321SDan Nowlin  *  2) ICE_ERR_AQ_ERROR -   did not get lock, driver should fail to load
1233ff2b1321SDan Nowlin  *  3) ICE_ERR_AQ_NO_WORK - did not get lock, but another driver has
1234ff2b1321SDan Nowlin  *                          successfully downloaded the package; the driver does
1235ff2b1321SDan Nowlin  *                          not have to download the package and can continue
1236ff2b1321SDan Nowlin  *                          loading
1237ff2b1321SDan Nowlin  *
1238ff2b1321SDan Nowlin  * Note that if the caller is in an acquire lock, perform action, release lock
1239ff2b1321SDan Nowlin  * phase of operation, it is possible that the FW may detect a timeout and issue
1240ff2b1321SDan Nowlin  * a CORER. In this case, the driver will receive a CORER interrupt and will
1241ff2b1321SDan Nowlin  * have to determine its cause. The calling thread that is handling this flow
1242ff2b1321SDan Nowlin  * will likely get an error propagated back to it indicating the Download
1243ff2b1321SDan Nowlin  * Package, Update Package or the Release Resource AQ commands timed out.
1244f31e4b6fSAnirudh Venkataramanan  */
1245f31e4b6fSAnirudh Venkataramanan static enum ice_status
1246f31e4b6fSAnirudh Venkataramanan ice_aq_req_res(struct ice_hw *hw, enum ice_aq_res_ids res,
1247f31e4b6fSAnirudh Venkataramanan 	       enum ice_aq_res_access_type access, u8 sdp_number, u32 *timeout,
1248f31e4b6fSAnirudh Venkataramanan 	       struct ice_sq_cd *cd)
1249f31e4b6fSAnirudh Venkataramanan {
1250f31e4b6fSAnirudh Venkataramanan 	struct ice_aqc_req_res *cmd_resp;
1251f31e4b6fSAnirudh Venkataramanan 	struct ice_aq_desc desc;
1252f31e4b6fSAnirudh Venkataramanan 	enum ice_status status;
1253f31e4b6fSAnirudh Venkataramanan 
1254f31e4b6fSAnirudh Venkataramanan 	cmd_resp = &desc.params.res_owner;
1255f31e4b6fSAnirudh Venkataramanan 
1256f31e4b6fSAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_req_res);
1257f31e4b6fSAnirudh Venkataramanan 
1258f31e4b6fSAnirudh Venkataramanan 	cmd_resp->res_id = cpu_to_le16(res);
1259f31e4b6fSAnirudh Venkataramanan 	cmd_resp->access_type = cpu_to_le16(access);
1260f31e4b6fSAnirudh Venkataramanan 	cmd_resp->res_number = cpu_to_le32(sdp_number);
1261ff2b1321SDan Nowlin 	cmd_resp->timeout = cpu_to_le32(*timeout);
1262ff2b1321SDan Nowlin 	*timeout = 0;
1263f31e4b6fSAnirudh Venkataramanan 
1264f31e4b6fSAnirudh Venkataramanan 	status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
1265ff2b1321SDan Nowlin 
1266f31e4b6fSAnirudh Venkataramanan 	/* The completion specifies the maximum time in ms that the driver
1267f31e4b6fSAnirudh Venkataramanan 	 * may hold the resource in the Timeout field.
1268ff2b1321SDan Nowlin 	 */
1269ff2b1321SDan Nowlin 
1270ff2b1321SDan Nowlin 	/* Global config lock response utilizes an additional status field.
1271ff2b1321SDan Nowlin 	 *
1272ff2b1321SDan Nowlin 	 * If the Global config lock resource is held by some other driver, the
1273ff2b1321SDan Nowlin 	 * command completes with ICE_AQ_RES_GLBL_IN_PROG in the status field
1274ff2b1321SDan Nowlin 	 * and the timeout field indicates the maximum time the current owner
1275ff2b1321SDan Nowlin 	 * of the resource has to free it.
1276ff2b1321SDan Nowlin 	 */
1277ff2b1321SDan Nowlin 	if (res == ICE_GLOBAL_CFG_LOCK_RES_ID) {
1278ff2b1321SDan Nowlin 		if (le16_to_cpu(cmd_resp->status) == ICE_AQ_RES_GLBL_SUCCESS) {
1279ff2b1321SDan Nowlin 			*timeout = le32_to_cpu(cmd_resp->timeout);
1280ff2b1321SDan Nowlin 			return 0;
1281ff2b1321SDan Nowlin 		} else if (le16_to_cpu(cmd_resp->status) ==
1282ff2b1321SDan Nowlin 			   ICE_AQ_RES_GLBL_IN_PROG) {
1283ff2b1321SDan Nowlin 			*timeout = le32_to_cpu(cmd_resp->timeout);
1284ff2b1321SDan Nowlin 			return ICE_ERR_AQ_ERROR;
1285ff2b1321SDan Nowlin 		} else if (le16_to_cpu(cmd_resp->status) ==
1286ff2b1321SDan Nowlin 			   ICE_AQ_RES_GLBL_DONE) {
1287ff2b1321SDan Nowlin 			return ICE_ERR_AQ_NO_WORK;
1288ff2b1321SDan Nowlin 		}
1289ff2b1321SDan Nowlin 
1290ff2b1321SDan Nowlin 		/* invalid FW response, force a timeout immediately */
1291ff2b1321SDan Nowlin 		*timeout = 0;
1292ff2b1321SDan Nowlin 		return ICE_ERR_AQ_ERROR;
1293ff2b1321SDan Nowlin 	}
1294ff2b1321SDan Nowlin 
1295ff2b1321SDan Nowlin 	/* If the resource is held by some other driver, the command completes
1296ff2b1321SDan Nowlin 	 * with a busy return value and the timeout field indicates the maximum
1297ff2b1321SDan Nowlin 	 * time the current owner of the resource has to free it.
1298f31e4b6fSAnirudh Venkataramanan 	 */
1299f31e4b6fSAnirudh Venkataramanan 	if (!status || hw->adminq.sq_last_status == ICE_AQ_RC_EBUSY)
1300f31e4b6fSAnirudh Venkataramanan 		*timeout = le32_to_cpu(cmd_resp->timeout);
1301f31e4b6fSAnirudh Venkataramanan 
1302f31e4b6fSAnirudh Venkataramanan 	return status;
1303f31e4b6fSAnirudh Venkataramanan }
1304f31e4b6fSAnirudh Venkataramanan 
1305f31e4b6fSAnirudh Venkataramanan /**
1306f31e4b6fSAnirudh Venkataramanan  * ice_aq_release_res
1307f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
1308f9867df6SAnirudh Venkataramanan  * @res: resource ID
1309f31e4b6fSAnirudh Venkataramanan  * @sdp_number: resource number
1310f31e4b6fSAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
1311f31e4b6fSAnirudh Venkataramanan  *
1312f31e4b6fSAnirudh Venkataramanan  * release common resource using the admin queue commands (0x0009)
1313f31e4b6fSAnirudh Venkataramanan  */
1314f31e4b6fSAnirudh Venkataramanan static enum ice_status
1315f31e4b6fSAnirudh Venkataramanan ice_aq_release_res(struct ice_hw *hw, enum ice_aq_res_ids res, u8 sdp_number,
1316f31e4b6fSAnirudh Venkataramanan 		   struct ice_sq_cd *cd)
1317f31e4b6fSAnirudh Venkataramanan {
1318f31e4b6fSAnirudh Venkataramanan 	struct ice_aqc_req_res *cmd;
1319f31e4b6fSAnirudh Venkataramanan 	struct ice_aq_desc desc;
1320f31e4b6fSAnirudh Venkataramanan 
1321f31e4b6fSAnirudh Venkataramanan 	cmd = &desc.params.res_owner;
1322f31e4b6fSAnirudh Venkataramanan 
1323f31e4b6fSAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_release_res);
1324f31e4b6fSAnirudh Venkataramanan 
1325f31e4b6fSAnirudh Venkataramanan 	cmd->res_id = cpu_to_le16(res);
1326f31e4b6fSAnirudh Venkataramanan 	cmd->res_number = cpu_to_le32(sdp_number);
1327f31e4b6fSAnirudh Venkataramanan 
1328f31e4b6fSAnirudh Venkataramanan 	return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
1329f31e4b6fSAnirudh Venkataramanan }
1330f31e4b6fSAnirudh Venkataramanan 
1331f31e4b6fSAnirudh Venkataramanan /**
1332f31e4b6fSAnirudh Venkataramanan  * ice_acquire_res
1333f31e4b6fSAnirudh Venkataramanan  * @hw: pointer to the HW structure
1334f9867df6SAnirudh Venkataramanan  * @res: resource ID
1335f31e4b6fSAnirudh Venkataramanan  * @access: access type (read or write)
1336ff2b1321SDan Nowlin  * @timeout: timeout in milliseconds
1337f31e4b6fSAnirudh Venkataramanan  *
1338f31e4b6fSAnirudh Venkataramanan  * This function will attempt to acquire the ownership of a resource.
1339f31e4b6fSAnirudh Venkataramanan  */
1340f31e4b6fSAnirudh Venkataramanan enum ice_status
1341f31e4b6fSAnirudh Venkataramanan ice_acquire_res(struct ice_hw *hw, enum ice_aq_res_ids res,
1342ff2b1321SDan Nowlin 		enum ice_aq_res_access_type access, u32 timeout)
1343f31e4b6fSAnirudh Venkataramanan {
1344f31e4b6fSAnirudh Venkataramanan #define ICE_RES_POLLING_DELAY_MS	10
1345f31e4b6fSAnirudh Venkataramanan 	u32 delay = ICE_RES_POLLING_DELAY_MS;
1346ff2b1321SDan Nowlin 	u32 time_left = timeout;
1347f31e4b6fSAnirudh Venkataramanan 	enum ice_status status;
1348f31e4b6fSAnirudh Venkataramanan 
1349f31e4b6fSAnirudh Venkataramanan 	status = ice_aq_req_res(hw, res, access, 0, &time_left, NULL);
1350f31e4b6fSAnirudh Venkataramanan 
1351ff2b1321SDan Nowlin 	/* A return code of ICE_ERR_AQ_NO_WORK means that another driver has
1352ff2b1321SDan Nowlin 	 * previously acquired the resource and performed any necessary updates;
1353ff2b1321SDan Nowlin 	 * in this case the caller does not obtain the resource and has no
1354ff2b1321SDan Nowlin 	 * further work to do.
1355f31e4b6fSAnirudh Venkataramanan 	 */
1356ff2b1321SDan Nowlin 	if (status == ICE_ERR_AQ_NO_WORK)
1357f31e4b6fSAnirudh Venkataramanan 		goto ice_acquire_res_exit;
1358f31e4b6fSAnirudh Venkataramanan 
1359f31e4b6fSAnirudh Venkataramanan 	if (status)
1360f31e4b6fSAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_RES,
1361f31e4b6fSAnirudh Venkataramanan 			  "resource %d acquire type %d failed.\n", res, access);
1362f31e4b6fSAnirudh Venkataramanan 
1363f31e4b6fSAnirudh Venkataramanan 	/* If necessary, poll until the current lock owner timeouts */
1364f31e4b6fSAnirudh Venkataramanan 	timeout = time_left;
1365f31e4b6fSAnirudh Venkataramanan 	while (status && timeout && time_left) {
1366f31e4b6fSAnirudh Venkataramanan 		mdelay(delay);
1367f31e4b6fSAnirudh Venkataramanan 		timeout = (timeout > delay) ? timeout - delay : 0;
1368f31e4b6fSAnirudh Venkataramanan 		status = ice_aq_req_res(hw, res, access, 0, &time_left, NULL);
1369f31e4b6fSAnirudh Venkataramanan 
1370ff2b1321SDan Nowlin 		if (status == ICE_ERR_AQ_NO_WORK)
1371f31e4b6fSAnirudh Venkataramanan 			/* lock free, but no work to do */
1372f31e4b6fSAnirudh Venkataramanan 			break;
1373f31e4b6fSAnirudh Venkataramanan 
1374f31e4b6fSAnirudh Venkataramanan 		if (!status)
1375f31e4b6fSAnirudh Venkataramanan 			/* lock acquired */
1376f31e4b6fSAnirudh Venkataramanan 			break;
1377f31e4b6fSAnirudh Venkataramanan 	}
1378f31e4b6fSAnirudh Venkataramanan 	if (status && status != ICE_ERR_AQ_NO_WORK)
1379f31e4b6fSAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_RES, "resource acquire timed out.\n");
1380f31e4b6fSAnirudh Venkataramanan 
1381f31e4b6fSAnirudh Venkataramanan ice_acquire_res_exit:
1382f31e4b6fSAnirudh Venkataramanan 	if (status == ICE_ERR_AQ_NO_WORK) {
1383f31e4b6fSAnirudh Venkataramanan 		if (access == ICE_RES_WRITE)
1384f31e4b6fSAnirudh Venkataramanan 			ice_debug(hw, ICE_DBG_RES,
1385f31e4b6fSAnirudh Venkataramanan 				  "resource indicates no work to do.\n");
1386f31e4b6fSAnirudh Venkataramanan 		else
1387f31e4b6fSAnirudh Venkataramanan 			ice_debug(hw, ICE_DBG_RES,
1388f31e4b6fSAnirudh Venkataramanan 				  "Warning: ICE_ERR_AQ_NO_WORK not expected\n");
1389f31e4b6fSAnirudh Venkataramanan 	}
1390f31e4b6fSAnirudh Venkataramanan 	return status;
1391f31e4b6fSAnirudh Venkataramanan }
1392f31e4b6fSAnirudh Venkataramanan 
1393f31e4b6fSAnirudh Venkataramanan /**
1394f31e4b6fSAnirudh Venkataramanan  * ice_release_res
1395f31e4b6fSAnirudh Venkataramanan  * @hw: pointer to the HW structure
1396f9867df6SAnirudh Venkataramanan  * @res: resource ID
1397f31e4b6fSAnirudh Venkataramanan  *
1398f31e4b6fSAnirudh Venkataramanan  * This function will release a resource using the proper Admin Command.
1399f31e4b6fSAnirudh Venkataramanan  */
1400f31e4b6fSAnirudh Venkataramanan void ice_release_res(struct ice_hw *hw, enum ice_aq_res_ids res)
1401f31e4b6fSAnirudh Venkataramanan {
1402f31e4b6fSAnirudh Venkataramanan 	enum ice_status status;
1403f31e4b6fSAnirudh Venkataramanan 	u32 total_delay = 0;
1404f31e4b6fSAnirudh Venkataramanan 
1405f31e4b6fSAnirudh Venkataramanan 	status = ice_aq_release_res(hw, res, 0, NULL);
1406f31e4b6fSAnirudh Venkataramanan 
1407f31e4b6fSAnirudh Venkataramanan 	/* there are some rare cases when trying to release the resource
1408f9867df6SAnirudh Venkataramanan 	 * results in an admin queue timeout, so handle them correctly
1409f31e4b6fSAnirudh Venkataramanan 	 */
1410f31e4b6fSAnirudh Venkataramanan 	while ((status == ICE_ERR_AQ_TIMEOUT) &&
1411f31e4b6fSAnirudh Venkataramanan 	       (total_delay < hw->adminq.sq_cmd_timeout)) {
1412f31e4b6fSAnirudh Venkataramanan 		mdelay(1);
1413f31e4b6fSAnirudh Venkataramanan 		status = ice_aq_release_res(hw, res, 0, NULL);
1414f31e4b6fSAnirudh Venkataramanan 		total_delay++;
1415f31e4b6fSAnirudh Venkataramanan 	}
1416f31e4b6fSAnirudh Venkataramanan }
1417f31e4b6fSAnirudh Venkataramanan 
1418f31e4b6fSAnirudh Venkataramanan /**
14197a1f7111SBrett Creeley  * ice_get_num_per_func - determine number of resources per PF
1420f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW structure
14217a1f7111SBrett Creeley  * @max: value to be evenly split between each PF
1422995c90f2SAnirudh Venkataramanan  *
1423995c90f2SAnirudh Venkataramanan  * Determine the number of valid functions by going through the bitmap returned
14247a1f7111SBrett Creeley  * from parsing capabilities and use this to calculate the number of resources
14257a1f7111SBrett Creeley  * per PF based on the max value passed in.
1426995c90f2SAnirudh Venkataramanan  */
14277a1f7111SBrett Creeley static u32 ice_get_num_per_func(struct ice_hw *hw, u32 max)
1428995c90f2SAnirudh Venkataramanan {
1429995c90f2SAnirudh Venkataramanan 	u8 funcs;
1430995c90f2SAnirudh Venkataramanan 
1431995c90f2SAnirudh Venkataramanan #define ICE_CAPS_VALID_FUNCS_M	0xFF
1432995c90f2SAnirudh Venkataramanan 	funcs = hweight8(hw->dev_caps.common_cap.valid_functions &
1433995c90f2SAnirudh Venkataramanan 			 ICE_CAPS_VALID_FUNCS_M);
1434995c90f2SAnirudh Venkataramanan 
1435995c90f2SAnirudh Venkataramanan 	if (!funcs)
1436995c90f2SAnirudh Venkataramanan 		return 0;
1437995c90f2SAnirudh Venkataramanan 
14387a1f7111SBrett Creeley 	return max / funcs;
1439995c90f2SAnirudh Venkataramanan }
1440995c90f2SAnirudh Venkataramanan 
1441995c90f2SAnirudh Venkataramanan /**
14429c20346bSAnirudh Venkataramanan  * ice_parse_caps - parse function/device capabilities
1443f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
14449c20346bSAnirudh Venkataramanan  * @buf: pointer to a buffer containing function/device capability records
14459c20346bSAnirudh Venkataramanan  * @cap_count: number of capability records in the list
14469c20346bSAnirudh Venkataramanan  * @opc: type of capabilities list to parse
14479c20346bSAnirudh Venkataramanan  *
14489c20346bSAnirudh Venkataramanan  * Helper function to parse function(0x000a)/device(0x000b) capabilities list.
14499c20346bSAnirudh Venkataramanan  */
14509c20346bSAnirudh Venkataramanan static void
14519c20346bSAnirudh Venkataramanan ice_parse_caps(struct ice_hw *hw, void *buf, u32 cap_count,
14529c20346bSAnirudh Venkataramanan 	       enum ice_adminq_opc opc)
14539c20346bSAnirudh Venkataramanan {
14549c20346bSAnirudh Venkataramanan 	struct ice_aqc_list_caps_elem *cap_resp;
14559c20346bSAnirudh Venkataramanan 	struct ice_hw_func_caps *func_p = NULL;
14569c20346bSAnirudh Venkataramanan 	struct ice_hw_dev_caps *dev_p = NULL;
14579c20346bSAnirudh Venkataramanan 	struct ice_hw_common_caps *caps;
14589c20346bSAnirudh Venkataramanan 	u32 i;
14599c20346bSAnirudh Venkataramanan 
14609c20346bSAnirudh Venkataramanan 	if (!buf)
14619c20346bSAnirudh Venkataramanan 		return;
14629c20346bSAnirudh Venkataramanan 
14639c20346bSAnirudh Venkataramanan 	cap_resp = (struct ice_aqc_list_caps_elem *)buf;
14649c20346bSAnirudh Venkataramanan 
14659c20346bSAnirudh Venkataramanan 	if (opc == ice_aqc_opc_list_dev_caps) {
14669c20346bSAnirudh Venkataramanan 		dev_p = &hw->dev_caps;
14679c20346bSAnirudh Venkataramanan 		caps = &dev_p->common_cap;
14689c20346bSAnirudh Venkataramanan 	} else if (opc == ice_aqc_opc_list_func_caps) {
14699c20346bSAnirudh Venkataramanan 		func_p = &hw->func_caps;
14709c20346bSAnirudh Venkataramanan 		caps = &func_p->common_cap;
14719c20346bSAnirudh Venkataramanan 	} else {
14729c20346bSAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_INIT, "wrong opcode\n");
14739c20346bSAnirudh Venkataramanan 		return;
14749c20346bSAnirudh Venkataramanan 	}
14759c20346bSAnirudh Venkataramanan 
14769c20346bSAnirudh Venkataramanan 	for (i = 0; caps && i < cap_count; i++, cap_resp++) {
14779c20346bSAnirudh Venkataramanan 		u32 logical_id = le32_to_cpu(cap_resp->logical_id);
14789c20346bSAnirudh Venkataramanan 		u32 phys_id = le32_to_cpu(cap_resp->phys_id);
14799c20346bSAnirudh Venkataramanan 		u32 number = le32_to_cpu(cap_resp->number);
14809c20346bSAnirudh Venkataramanan 		u16 cap = le16_to_cpu(cap_resp->cap);
14819c20346bSAnirudh Venkataramanan 
14829c20346bSAnirudh Venkataramanan 		switch (cap) {
1483995c90f2SAnirudh Venkataramanan 		case ICE_AQC_CAPS_VALID_FUNCTIONS:
1484995c90f2SAnirudh Venkataramanan 			caps->valid_functions = number;
1485995c90f2SAnirudh Venkataramanan 			ice_debug(hw, ICE_DBG_INIT,
1486995c90f2SAnirudh Venkataramanan 				  "HW caps: Valid Functions = %d\n",
1487995c90f2SAnirudh Venkataramanan 				  caps->valid_functions);
1488995c90f2SAnirudh Venkataramanan 			break;
148975d2b253SAnirudh Venkataramanan 		case ICE_AQC_CAPS_SRIOV:
149075d2b253SAnirudh Venkataramanan 			caps->sr_iov_1_1 = (number == 1);
149175d2b253SAnirudh Venkataramanan 			ice_debug(hw, ICE_DBG_INIT,
149275d2b253SAnirudh Venkataramanan 				  "HW caps: SR-IOV = %d\n", caps->sr_iov_1_1);
149375d2b253SAnirudh Venkataramanan 			break;
149475d2b253SAnirudh Venkataramanan 		case ICE_AQC_CAPS_VF:
149575d2b253SAnirudh Venkataramanan 			if (dev_p) {
149675d2b253SAnirudh Venkataramanan 				dev_p->num_vfs_exposed = number;
149775d2b253SAnirudh Venkataramanan 				ice_debug(hw, ICE_DBG_INIT,
149875d2b253SAnirudh Venkataramanan 					  "HW caps: VFs exposed = %d\n",
149975d2b253SAnirudh Venkataramanan 					  dev_p->num_vfs_exposed);
150075d2b253SAnirudh Venkataramanan 			} else if (func_p) {
150175d2b253SAnirudh Venkataramanan 				func_p->num_allocd_vfs = number;
150275d2b253SAnirudh Venkataramanan 				func_p->vf_base_id = logical_id;
150375d2b253SAnirudh Venkataramanan 				ice_debug(hw, ICE_DBG_INIT,
150475d2b253SAnirudh Venkataramanan 					  "HW caps: VFs allocated = %d\n",
150575d2b253SAnirudh Venkataramanan 					  func_p->num_allocd_vfs);
150675d2b253SAnirudh Venkataramanan 				ice_debug(hw, ICE_DBG_INIT,
150775d2b253SAnirudh Venkataramanan 					  "HW caps: VF base_id = %d\n",
150875d2b253SAnirudh Venkataramanan 					  func_p->vf_base_id);
150975d2b253SAnirudh Venkataramanan 			}
151075d2b253SAnirudh Venkataramanan 			break;
15119c20346bSAnirudh Venkataramanan 		case ICE_AQC_CAPS_VSI:
15129c20346bSAnirudh Venkataramanan 			if (dev_p) {
15139c20346bSAnirudh Venkataramanan 				dev_p->num_vsi_allocd_to_host = number;
15149c20346bSAnirudh Venkataramanan 				ice_debug(hw, ICE_DBG_INIT,
15159c20346bSAnirudh Venkataramanan 					  "HW caps: Dev.VSI cnt = %d\n",
15169c20346bSAnirudh Venkataramanan 					  dev_p->num_vsi_allocd_to_host);
15179c20346bSAnirudh Venkataramanan 			} else if (func_p) {
15187a1f7111SBrett Creeley 				func_p->guar_num_vsi =
15197a1f7111SBrett Creeley 					ice_get_num_per_func(hw, ICE_MAX_VSI);
15209c20346bSAnirudh Venkataramanan 				ice_debug(hw, ICE_DBG_INIT,
15219c20346bSAnirudh Venkataramanan 					  "HW caps: Func.VSI cnt = %d\n",
1522995c90f2SAnirudh Venkataramanan 					  number);
15239c20346bSAnirudh Venkataramanan 			}
15249c20346bSAnirudh Venkataramanan 			break;
15259c20346bSAnirudh Venkataramanan 		case ICE_AQC_CAPS_RSS:
15269c20346bSAnirudh Venkataramanan 			caps->rss_table_size = number;
15279c20346bSAnirudh Venkataramanan 			caps->rss_table_entry_width = logical_id;
15289c20346bSAnirudh Venkataramanan 			ice_debug(hw, ICE_DBG_INIT,
15299c20346bSAnirudh Venkataramanan 				  "HW caps: RSS table size = %d\n",
15309c20346bSAnirudh Venkataramanan 				  caps->rss_table_size);
15319c20346bSAnirudh Venkataramanan 			ice_debug(hw, ICE_DBG_INIT,
15329c20346bSAnirudh Venkataramanan 				  "HW caps: RSS table width = %d\n",
15339c20346bSAnirudh Venkataramanan 				  caps->rss_table_entry_width);
15349c20346bSAnirudh Venkataramanan 			break;
15359c20346bSAnirudh Venkataramanan 		case ICE_AQC_CAPS_RXQS:
15369c20346bSAnirudh Venkataramanan 			caps->num_rxq = number;
15379c20346bSAnirudh Venkataramanan 			caps->rxq_first_id = phys_id;
15389c20346bSAnirudh Venkataramanan 			ice_debug(hw, ICE_DBG_INIT,
15399c20346bSAnirudh Venkataramanan 				  "HW caps: Num Rx Qs = %d\n", caps->num_rxq);
15409c20346bSAnirudh Venkataramanan 			ice_debug(hw, ICE_DBG_INIT,
15419c20346bSAnirudh Venkataramanan 				  "HW caps: Rx first queue ID = %d\n",
15429c20346bSAnirudh Venkataramanan 				  caps->rxq_first_id);
15439c20346bSAnirudh Venkataramanan 			break;
15449c20346bSAnirudh Venkataramanan 		case ICE_AQC_CAPS_TXQS:
15459c20346bSAnirudh Venkataramanan 			caps->num_txq = number;
15469c20346bSAnirudh Venkataramanan 			caps->txq_first_id = phys_id;
15479c20346bSAnirudh Venkataramanan 			ice_debug(hw, ICE_DBG_INIT,
15489c20346bSAnirudh Venkataramanan 				  "HW caps: Num Tx Qs = %d\n", caps->num_txq);
15499c20346bSAnirudh Venkataramanan 			ice_debug(hw, ICE_DBG_INIT,
15509c20346bSAnirudh Venkataramanan 				  "HW caps: Tx first queue ID = %d\n",
15519c20346bSAnirudh Venkataramanan 				  caps->txq_first_id);
15529c20346bSAnirudh Venkataramanan 			break;
15539c20346bSAnirudh Venkataramanan 		case ICE_AQC_CAPS_MSIX:
15549c20346bSAnirudh Venkataramanan 			caps->num_msix_vectors = number;
15559c20346bSAnirudh Venkataramanan 			caps->msix_vector_first_id = phys_id;
15569c20346bSAnirudh Venkataramanan 			ice_debug(hw, ICE_DBG_INIT,
15579c20346bSAnirudh Venkataramanan 				  "HW caps: MSIX vector count = %d\n",
15589c20346bSAnirudh Venkataramanan 				  caps->num_msix_vectors);
15599c20346bSAnirudh Venkataramanan 			ice_debug(hw, ICE_DBG_INIT,
15609c20346bSAnirudh Venkataramanan 				  "HW caps: MSIX first vector index = %d\n",
15619c20346bSAnirudh Venkataramanan 				  caps->msix_vector_first_id);
15629c20346bSAnirudh Venkataramanan 			break;
15639c20346bSAnirudh Venkataramanan 		case ICE_AQC_CAPS_MAX_MTU:
15649c20346bSAnirudh Venkataramanan 			caps->max_mtu = number;
15659c20346bSAnirudh Venkataramanan 			if (dev_p)
15669c20346bSAnirudh Venkataramanan 				ice_debug(hw, ICE_DBG_INIT,
15679c20346bSAnirudh Venkataramanan 					  "HW caps: Dev.MaxMTU = %d\n",
15689c20346bSAnirudh Venkataramanan 					  caps->max_mtu);
15699c20346bSAnirudh Venkataramanan 			else if (func_p)
15709c20346bSAnirudh Venkataramanan 				ice_debug(hw, ICE_DBG_INIT,
15719c20346bSAnirudh Venkataramanan 					  "HW caps: func.MaxMTU = %d\n",
15729c20346bSAnirudh Venkataramanan 					  caps->max_mtu);
15739c20346bSAnirudh Venkataramanan 			break;
15749c20346bSAnirudh Venkataramanan 		default:
15759c20346bSAnirudh Venkataramanan 			ice_debug(hw, ICE_DBG_INIT,
15769c20346bSAnirudh Venkataramanan 				  "HW caps: Unknown capability[%d]: 0x%x\n", i,
15779c20346bSAnirudh Venkataramanan 				  cap);
15789c20346bSAnirudh Venkataramanan 			break;
15799c20346bSAnirudh Venkataramanan 		}
15809c20346bSAnirudh Venkataramanan 	}
15819c20346bSAnirudh Venkataramanan }
15829c20346bSAnirudh Venkataramanan 
15839c20346bSAnirudh Venkataramanan /**
15849c20346bSAnirudh Venkataramanan  * ice_aq_discover_caps - query function/device capabilities
1585f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
15869c20346bSAnirudh Venkataramanan  * @buf: a virtual buffer to hold the capabilities
15879c20346bSAnirudh Venkataramanan  * @buf_size: Size of the virtual buffer
15887d86cf38SAnirudh Venkataramanan  * @cap_count: cap count needed if AQ err==ENOMEM
15899c20346bSAnirudh Venkataramanan  * @opc: capabilities type to discover - pass in the command opcode
15909c20346bSAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
15919c20346bSAnirudh Venkataramanan  *
15929c20346bSAnirudh Venkataramanan  * Get the function(0x000a)/device(0x000b) capabilities description from
15939c20346bSAnirudh Venkataramanan  * the firmware.
15949c20346bSAnirudh Venkataramanan  */
15959c20346bSAnirudh Venkataramanan static enum ice_status
15967d86cf38SAnirudh Venkataramanan ice_aq_discover_caps(struct ice_hw *hw, void *buf, u16 buf_size, u32 *cap_count,
15979c20346bSAnirudh Venkataramanan 		     enum ice_adminq_opc opc, struct ice_sq_cd *cd)
15989c20346bSAnirudh Venkataramanan {
15999c20346bSAnirudh Venkataramanan 	struct ice_aqc_list_caps *cmd;
16009c20346bSAnirudh Venkataramanan 	struct ice_aq_desc desc;
16019c20346bSAnirudh Venkataramanan 	enum ice_status status;
16029c20346bSAnirudh Venkataramanan 
16039c20346bSAnirudh Venkataramanan 	cmd = &desc.params.get_cap;
16049c20346bSAnirudh Venkataramanan 
16059c20346bSAnirudh Venkataramanan 	if (opc != ice_aqc_opc_list_func_caps &&
16069c20346bSAnirudh Venkataramanan 	    opc != ice_aqc_opc_list_dev_caps)
16079c20346bSAnirudh Venkataramanan 		return ICE_ERR_PARAM;
16089c20346bSAnirudh Venkataramanan 
16099c20346bSAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, opc);
16109c20346bSAnirudh Venkataramanan 
16119c20346bSAnirudh Venkataramanan 	status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
16129c20346bSAnirudh Venkataramanan 	if (!status)
16139c20346bSAnirudh Venkataramanan 		ice_parse_caps(hw, buf, le32_to_cpu(cmd->count), opc);
16147d86cf38SAnirudh Venkataramanan 	else if (hw->adminq.sq_last_status == ICE_AQ_RC_ENOMEM)
161599189e8bSAnirudh Venkataramanan 		*cap_count = le32_to_cpu(cmd->count);
16167d86cf38SAnirudh Venkataramanan 	return status;
16177d86cf38SAnirudh Venkataramanan }
16187d86cf38SAnirudh Venkataramanan 
16197d86cf38SAnirudh Venkataramanan /**
16207d86cf38SAnirudh Venkataramanan  * ice_discover_caps - get info about the HW
16217d86cf38SAnirudh Venkataramanan  * @hw: pointer to the hardware structure
16227d86cf38SAnirudh Venkataramanan  * @opc: capabilities type to discover - pass in the command opcode
16237d86cf38SAnirudh Venkataramanan  */
1624c8b7abddSBruce Allan static enum ice_status
1625c8b7abddSBruce Allan ice_discover_caps(struct ice_hw *hw, enum ice_adminq_opc opc)
16267d86cf38SAnirudh Venkataramanan {
16277d86cf38SAnirudh Venkataramanan 	enum ice_status status;
16287d86cf38SAnirudh Venkataramanan 	u32 cap_count;
16297d86cf38SAnirudh Venkataramanan 	u16 cbuf_len;
16307d86cf38SAnirudh Venkataramanan 	u8 retries;
16317d86cf38SAnirudh Venkataramanan 
16327d86cf38SAnirudh Venkataramanan 	/* The driver doesn't know how many capabilities the device will return
16337d86cf38SAnirudh Venkataramanan 	 * so the buffer size required isn't known ahead of time. The driver
16347d86cf38SAnirudh Venkataramanan 	 * starts with cbuf_len and if this turns out to be insufficient, the
16357d86cf38SAnirudh Venkataramanan 	 * device returns ICE_AQ_RC_ENOMEM and also the cap_count it needs.
16367d86cf38SAnirudh Venkataramanan 	 * The driver then allocates the buffer based on the count and retries
16377d86cf38SAnirudh Venkataramanan 	 * the operation. So it follows that the retry count is 2.
16387d86cf38SAnirudh Venkataramanan 	 */
16397d86cf38SAnirudh Venkataramanan #define ICE_GET_CAP_BUF_COUNT	40
16407d86cf38SAnirudh Venkataramanan #define ICE_GET_CAP_RETRY_COUNT	2
16417d86cf38SAnirudh Venkataramanan 
16427d86cf38SAnirudh Venkataramanan 	cap_count = ICE_GET_CAP_BUF_COUNT;
16437d86cf38SAnirudh Venkataramanan 	retries = ICE_GET_CAP_RETRY_COUNT;
16447d86cf38SAnirudh Venkataramanan 
16457d86cf38SAnirudh Venkataramanan 	do {
16467d86cf38SAnirudh Venkataramanan 		void *cbuf;
16477d86cf38SAnirudh Venkataramanan 
16487d86cf38SAnirudh Venkataramanan 		cbuf_len = (u16)(cap_count *
16497d86cf38SAnirudh Venkataramanan 				 sizeof(struct ice_aqc_list_caps_elem));
16507d86cf38SAnirudh Venkataramanan 		cbuf = devm_kzalloc(ice_hw_to_dev(hw), cbuf_len, GFP_KERNEL);
16517d86cf38SAnirudh Venkataramanan 		if (!cbuf)
16527d86cf38SAnirudh Venkataramanan 			return ICE_ERR_NO_MEMORY;
16537d86cf38SAnirudh Venkataramanan 
16547d86cf38SAnirudh Venkataramanan 		status = ice_aq_discover_caps(hw, cbuf, cbuf_len, &cap_count,
16557d86cf38SAnirudh Venkataramanan 					      opc, NULL);
16567d86cf38SAnirudh Venkataramanan 		devm_kfree(ice_hw_to_dev(hw), cbuf);
16577d86cf38SAnirudh Venkataramanan 
16587d86cf38SAnirudh Venkataramanan 		if (!status || hw->adminq.sq_last_status != ICE_AQ_RC_ENOMEM)
16597d86cf38SAnirudh Venkataramanan 			break;
16607d86cf38SAnirudh Venkataramanan 
16617d86cf38SAnirudh Venkataramanan 		/* If ENOMEM is returned, try again with bigger buffer */
16627d86cf38SAnirudh Venkataramanan 	} while (--retries);
16639c20346bSAnirudh Venkataramanan 
16649c20346bSAnirudh Venkataramanan 	return status;
16659c20346bSAnirudh Venkataramanan }
16669c20346bSAnirudh Venkataramanan 
16679c20346bSAnirudh Venkataramanan /**
16689c20346bSAnirudh Venkataramanan  * ice_get_caps - get info about the HW
16699c20346bSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
16709c20346bSAnirudh Venkataramanan  */
16719c20346bSAnirudh Venkataramanan enum ice_status ice_get_caps(struct ice_hw *hw)
16729c20346bSAnirudh Venkataramanan {
16739c20346bSAnirudh Venkataramanan 	enum ice_status status;
16749c20346bSAnirudh Venkataramanan 
16757d86cf38SAnirudh Venkataramanan 	status = ice_discover_caps(hw, ice_aqc_opc_list_dev_caps);
16767d86cf38SAnirudh Venkataramanan 	if (!status)
16777d86cf38SAnirudh Venkataramanan 		status = ice_discover_caps(hw, ice_aqc_opc_list_func_caps);
16789c20346bSAnirudh Venkataramanan 
16799c20346bSAnirudh Venkataramanan 	return status;
16809c20346bSAnirudh Venkataramanan }
16819c20346bSAnirudh Venkataramanan 
16829c20346bSAnirudh Venkataramanan /**
1683e94d4478SAnirudh Venkataramanan  * ice_aq_manage_mac_write - manage MAC address write command
1684f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
1685e94d4478SAnirudh Venkataramanan  * @mac_addr: MAC address to be written as LAA/LAA+WoL/Port address
1686e94d4478SAnirudh Venkataramanan  * @flags: flags to control write behavior
1687e94d4478SAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
1688e94d4478SAnirudh Venkataramanan  *
1689e94d4478SAnirudh Venkataramanan  * This function is used to write MAC address to the NVM (0x0108).
1690e94d4478SAnirudh Venkataramanan  */
1691e94d4478SAnirudh Venkataramanan enum ice_status
1692d671e3e0SJacob Keller ice_aq_manage_mac_write(struct ice_hw *hw, const u8 *mac_addr, u8 flags,
1693e94d4478SAnirudh Venkataramanan 			struct ice_sq_cd *cd)
1694e94d4478SAnirudh Venkataramanan {
1695e94d4478SAnirudh Venkataramanan 	struct ice_aqc_manage_mac_write *cmd;
1696e94d4478SAnirudh Venkataramanan 	struct ice_aq_desc desc;
1697e94d4478SAnirudh Venkataramanan 
1698e94d4478SAnirudh Venkataramanan 	cmd = &desc.params.mac_write;
1699e94d4478SAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_manage_mac_write);
1700e94d4478SAnirudh Venkataramanan 
1701e94d4478SAnirudh Venkataramanan 	cmd->flags = flags;
1702e94d4478SAnirudh Venkataramanan 
1703e94d4478SAnirudh Venkataramanan 	/* Prep values for flags, sah, sal */
1704d671e3e0SJacob Keller 	cmd->sah = htons(*((const u16 *)mac_addr));
1705d671e3e0SJacob Keller 	cmd->sal = htonl(*((const u32 *)(mac_addr + 2)));
1706e94d4478SAnirudh Venkataramanan 
1707e94d4478SAnirudh Venkataramanan 	return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
1708e94d4478SAnirudh Venkataramanan }
1709e94d4478SAnirudh Venkataramanan 
1710e94d4478SAnirudh Venkataramanan /**
1711f31e4b6fSAnirudh Venkataramanan  * ice_aq_clear_pxe_mode
1712f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
1713f31e4b6fSAnirudh Venkataramanan  *
1714f31e4b6fSAnirudh Venkataramanan  * Tell the firmware that the driver is taking over from PXE (0x0110).
1715f31e4b6fSAnirudh Venkataramanan  */
1716f31e4b6fSAnirudh Venkataramanan static enum ice_status ice_aq_clear_pxe_mode(struct ice_hw *hw)
1717f31e4b6fSAnirudh Venkataramanan {
1718f31e4b6fSAnirudh Venkataramanan 	struct ice_aq_desc desc;
1719f31e4b6fSAnirudh Venkataramanan 
1720f31e4b6fSAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_clear_pxe_mode);
1721f31e4b6fSAnirudh Venkataramanan 	desc.params.clear_pxe.rx_cnt = ICE_AQC_CLEAR_PXE_RX_CNT;
1722f31e4b6fSAnirudh Venkataramanan 
1723f31e4b6fSAnirudh Venkataramanan 	return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
1724f31e4b6fSAnirudh Venkataramanan }
1725f31e4b6fSAnirudh Venkataramanan 
1726f31e4b6fSAnirudh Venkataramanan /**
1727f31e4b6fSAnirudh Venkataramanan  * ice_clear_pxe_mode - clear pxe operations mode
1728f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
1729f31e4b6fSAnirudh Venkataramanan  *
1730f31e4b6fSAnirudh Venkataramanan  * Make sure all PXE mode settings are cleared, including things
1731f31e4b6fSAnirudh Venkataramanan  * like descriptor fetch/write-back mode.
1732f31e4b6fSAnirudh Venkataramanan  */
1733f31e4b6fSAnirudh Venkataramanan void ice_clear_pxe_mode(struct ice_hw *hw)
1734f31e4b6fSAnirudh Venkataramanan {
1735f31e4b6fSAnirudh Venkataramanan 	if (ice_check_sq_alive(hw, &hw->adminq))
1736f31e4b6fSAnirudh Venkataramanan 		ice_aq_clear_pxe_mode(hw);
1737f31e4b6fSAnirudh Venkataramanan }
1738cdedef59SAnirudh Venkataramanan 
1739cdedef59SAnirudh Venkataramanan /**
174048cb27f2SChinh Cao  * ice_get_link_speed_based_on_phy_type - returns link speed
174148cb27f2SChinh Cao  * @phy_type_low: lower part of phy_type
1742aef74145SAnirudh Venkataramanan  * @phy_type_high: higher part of phy_type
174348cb27f2SChinh Cao  *
1744f9867df6SAnirudh Venkataramanan  * This helper function will convert an entry in PHY type structure
1745aef74145SAnirudh Venkataramanan  * [phy_type_low, phy_type_high] to its corresponding link speed.
1746aef74145SAnirudh Venkataramanan  * Note: In the structure of [phy_type_low, phy_type_high], there should
1747f9867df6SAnirudh Venkataramanan  * be one bit set, as this function will convert one PHY type to its
174848cb27f2SChinh Cao  * speed.
174948cb27f2SChinh Cao  * If no bit gets set, ICE_LINK_SPEED_UNKNOWN will be returned
175048cb27f2SChinh Cao  * If more than one bit gets set, ICE_LINK_SPEED_UNKNOWN will be returned
175148cb27f2SChinh Cao  */
1752aef74145SAnirudh Venkataramanan static u16
1753aef74145SAnirudh Venkataramanan ice_get_link_speed_based_on_phy_type(u64 phy_type_low, u64 phy_type_high)
175448cb27f2SChinh Cao {
1755aef74145SAnirudh Venkataramanan 	u16 speed_phy_type_high = ICE_AQ_LINK_SPEED_UNKNOWN;
175648cb27f2SChinh Cao 	u16 speed_phy_type_low = ICE_AQ_LINK_SPEED_UNKNOWN;
175748cb27f2SChinh Cao 
175848cb27f2SChinh Cao 	switch (phy_type_low) {
175948cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_100BASE_TX:
176048cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_100M_SGMII:
176148cb27f2SChinh Cao 		speed_phy_type_low = ICE_AQ_LINK_SPEED_100MB;
176248cb27f2SChinh Cao 		break;
176348cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_1000BASE_T:
176448cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_1000BASE_SX:
176548cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_1000BASE_LX:
176648cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_1000BASE_KX:
176748cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_1G_SGMII:
176848cb27f2SChinh Cao 		speed_phy_type_low = ICE_AQ_LINK_SPEED_1000MB;
176948cb27f2SChinh Cao 		break;
177048cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_2500BASE_T:
177148cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_2500BASE_X:
177248cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_2500BASE_KX:
177348cb27f2SChinh Cao 		speed_phy_type_low = ICE_AQ_LINK_SPEED_2500MB;
177448cb27f2SChinh Cao 		break;
177548cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_5GBASE_T:
177648cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_5GBASE_KR:
177748cb27f2SChinh Cao 		speed_phy_type_low = ICE_AQ_LINK_SPEED_5GB;
177848cb27f2SChinh Cao 		break;
177948cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_10GBASE_T:
178048cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_10G_SFI_DA:
178148cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_10GBASE_SR:
178248cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_10GBASE_LR:
178348cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_10GBASE_KR_CR1:
178448cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_10G_SFI_AOC_ACC:
178548cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_10G_SFI_C2C:
178648cb27f2SChinh Cao 		speed_phy_type_low = ICE_AQ_LINK_SPEED_10GB;
178748cb27f2SChinh Cao 		break;
178848cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_25GBASE_T:
178948cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_25GBASE_CR:
179048cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_25GBASE_CR_S:
179148cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_25GBASE_CR1:
179248cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_25GBASE_SR:
179348cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_25GBASE_LR:
179448cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_25GBASE_KR:
179548cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_25GBASE_KR_S:
179648cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_25GBASE_KR1:
179748cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_25G_AUI_AOC_ACC:
179848cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_25G_AUI_C2C:
179948cb27f2SChinh Cao 		speed_phy_type_low = ICE_AQ_LINK_SPEED_25GB;
180048cb27f2SChinh Cao 		break;
180148cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_40GBASE_CR4:
180248cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_40GBASE_SR4:
180348cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_40GBASE_LR4:
180448cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_40GBASE_KR4:
180548cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_40G_XLAUI_AOC_ACC:
180648cb27f2SChinh Cao 	case ICE_PHY_TYPE_LOW_40G_XLAUI:
180748cb27f2SChinh Cao 		speed_phy_type_low = ICE_AQ_LINK_SPEED_40GB;
180848cb27f2SChinh Cao 		break;
1809aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50GBASE_CR2:
1810aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50GBASE_SR2:
1811aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50GBASE_LR2:
1812aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50GBASE_KR2:
1813aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50G_LAUI2_AOC_ACC:
1814aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50G_LAUI2:
1815aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50G_AUI2_AOC_ACC:
1816aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50G_AUI2:
1817aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50GBASE_CP:
1818aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50GBASE_SR:
1819aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50GBASE_FR:
1820aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50GBASE_LR:
1821aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50GBASE_KR_PAM4:
1822aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50G_AUI1_AOC_ACC:
1823aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_50G_AUI1:
1824aef74145SAnirudh Venkataramanan 		speed_phy_type_low = ICE_AQ_LINK_SPEED_50GB;
1825aef74145SAnirudh Venkataramanan 		break;
1826aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100GBASE_CR4:
1827aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100GBASE_SR4:
1828aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100GBASE_LR4:
1829aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100GBASE_KR4:
1830aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100G_CAUI4_AOC_ACC:
1831aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100G_CAUI4:
1832aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100G_AUI4_AOC_ACC:
1833aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100G_AUI4:
1834aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100GBASE_CR_PAM4:
1835aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100GBASE_KR_PAM4:
1836aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100GBASE_CP2:
1837aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100GBASE_SR2:
1838aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_LOW_100GBASE_DR:
1839aef74145SAnirudh Venkataramanan 		speed_phy_type_low = ICE_AQ_LINK_SPEED_100GB;
1840aef74145SAnirudh Venkataramanan 		break;
184148cb27f2SChinh Cao 	default:
184248cb27f2SChinh Cao 		speed_phy_type_low = ICE_AQ_LINK_SPEED_UNKNOWN;
184348cb27f2SChinh Cao 		break;
184448cb27f2SChinh Cao 	}
184548cb27f2SChinh Cao 
1846aef74145SAnirudh Venkataramanan 	switch (phy_type_high) {
1847aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_HIGH_100GBASE_KR2_PAM4:
1848aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_HIGH_100G_CAUI2_AOC_ACC:
1849aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_HIGH_100G_CAUI2:
1850aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_HIGH_100G_AUI2_AOC_ACC:
1851aef74145SAnirudh Venkataramanan 	case ICE_PHY_TYPE_HIGH_100G_AUI2:
1852aef74145SAnirudh Venkataramanan 		speed_phy_type_high = ICE_AQ_LINK_SPEED_100GB;
1853aef74145SAnirudh Venkataramanan 		break;
1854aef74145SAnirudh Venkataramanan 	default:
1855aef74145SAnirudh Venkataramanan 		speed_phy_type_high = ICE_AQ_LINK_SPEED_UNKNOWN;
1856aef74145SAnirudh Venkataramanan 		break;
1857aef74145SAnirudh Venkataramanan 	}
1858aef74145SAnirudh Venkataramanan 
1859aef74145SAnirudh Venkataramanan 	if (speed_phy_type_low == ICE_AQ_LINK_SPEED_UNKNOWN &&
1860aef74145SAnirudh Venkataramanan 	    speed_phy_type_high == ICE_AQ_LINK_SPEED_UNKNOWN)
1861aef74145SAnirudh Venkataramanan 		return ICE_AQ_LINK_SPEED_UNKNOWN;
1862aef74145SAnirudh Venkataramanan 	else if (speed_phy_type_low != ICE_AQ_LINK_SPEED_UNKNOWN &&
1863aef74145SAnirudh Venkataramanan 		 speed_phy_type_high != ICE_AQ_LINK_SPEED_UNKNOWN)
1864aef74145SAnirudh Venkataramanan 		return ICE_AQ_LINK_SPEED_UNKNOWN;
1865aef74145SAnirudh Venkataramanan 	else if (speed_phy_type_low != ICE_AQ_LINK_SPEED_UNKNOWN &&
1866aef74145SAnirudh Venkataramanan 		 speed_phy_type_high == ICE_AQ_LINK_SPEED_UNKNOWN)
186748cb27f2SChinh Cao 		return speed_phy_type_low;
1868aef74145SAnirudh Venkataramanan 	else
1869aef74145SAnirudh Venkataramanan 		return speed_phy_type_high;
187048cb27f2SChinh Cao }
187148cb27f2SChinh Cao 
187248cb27f2SChinh Cao /**
187348cb27f2SChinh Cao  * ice_update_phy_type
187448cb27f2SChinh Cao  * @phy_type_low: pointer to the lower part of phy_type
1875aef74145SAnirudh Venkataramanan  * @phy_type_high: pointer to the higher part of phy_type
187648cb27f2SChinh Cao  * @link_speeds_bitmap: targeted link speeds bitmap
187748cb27f2SChinh Cao  *
187848cb27f2SChinh Cao  * Note: For the link_speeds_bitmap structure, you can check it at
187948cb27f2SChinh Cao  * [ice_aqc_get_link_status->link_speed]. Caller can pass in
188048cb27f2SChinh Cao  * link_speeds_bitmap include multiple speeds.
188148cb27f2SChinh Cao  *
1882aef74145SAnirudh Venkataramanan  * Each entry in this [phy_type_low, phy_type_high] structure will
1883aef74145SAnirudh Venkataramanan  * present a certain link speed. This helper function will turn on bits
1884aef74145SAnirudh Venkataramanan  * in [phy_type_low, phy_type_high] structure based on the value of
188548cb27f2SChinh Cao  * link_speeds_bitmap input parameter.
188648cb27f2SChinh Cao  */
1887aef74145SAnirudh Venkataramanan void
1888aef74145SAnirudh Venkataramanan ice_update_phy_type(u64 *phy_type_low, u64 *phy_type_high,
1889aef74145SAnirudh Venkataramanan 		    u16 link_speeds_bitmap)
189048cb27f2SChinh Cao {
189148cb27f2SChinh Cao 	u16 speed = ICE_AQ_LINK_SPEED_UNKNOWN;
1892aef74145SAnirudh Venkataramanan 	u64 pt_high;
189348cb27f2SChinh Cao 	u64 pt_low;
189448cb27f2SChinh Cao 	int index;
189548cb27f2SChinh Cao 
189648cb27f2SChinh Cao 	/* We first check with low part of phy_type */
189748cb27f2SChinh Cao 	for (index = 0; index <= ICE_PHY_TYPE_LOW_MAX_INDEX; index++) {
189848cb27f2SChinh Cao 		pt_low = BIT_ULL(index);
1899aef74145SAnirudh Venkataramanan 		speed = ice_get_link_speed_based_on_phy_type(pt_low, 0);
190048cb27f2SChinh Cao 
190148cb27f2SChinh Cao 		if (link_speeds_bitmap & speed)
190248cb27f2SChinh Cao 			*phy_type_low |= BIT_ULL(index);
190348cb27f2SChinh Cao 	}
1904aef74145SAnirudh Venkataramanan 
1905aef74145SAnirudh Venkataramanan 	/* We then check with high part of phy_type */
1906aef74145SAnirudh Venkataramanan 	for (index = 0; index <= ICE_PHY_TYPE_HIGH_MAX_INDEX; index++) {
1907aef74145SAnirudh Venkataramanan 		pt_high = BIT_ULL(index);
1908aef74145SAnirudh Venkataramanan 		speed = ice_get_link_speed_based_on_phy_type(0, pt_high);
1909aef74145SAnirudh Venkataramanan 
1910aef74145SAnirudh Venkataramanan 		if (link_speeds_bitmap & speed)
1911aef74145SAnirudh Venkataramanan 			*phy_type_high |= BIT_ULL(index);
1912aef74145SAnirudh Venkataramanan 	}
191348cb27f2SChinh Cao }
191448cb27f2SChinh Cao 
191548cb27f2SChinh Cao /**
1916fcea6f3dSAnirudh Venkataramanan  * ice_aq_set_phy_cfg
1917f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
1918fcea6f3dSAnirudh Venkataramanan  * @lport: logical port number
1919fcea6f3dSAnirudh Venkataramanan  * @cfg: structure with PHY configuration data to be set
1920fcea6f3dSAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
1921fcea6f3dSAnirudh Venkataramanan  *
1922fcea6f3dSAnirudh Venkataramanan  * Set the various PHY configuration parameters supported on the Port.
1923fcea6f3dSAnirudh Venkataramanan  * One or more of the Set PHY config parameters may be ignored in an MFP
1924fcea6f3dSAnirudh Venkataramanan  * mode as the PF may not have the privilege to set some of the PHY Config
1925fcea6f3dSAnirudh Venkataramanan  * parameters. This status will be indicated by the command response (0x0601).
1926fcea6f3dSAnirudh Venkataramanan  */
192748cb27f2SChinh Cao enum ice_status
1928fcea6f3dSAnirudh Venkataramanan ice_aq_set_phy_cfg(struct ice_hw *hw, u8 lport,
1929fcea6f3dSAnirudh Venkataramanan 		   struct ice_aqc_set_phy_cfg_data *cfg, struct ice_sq_cd *cd)
1930fcea6f3dSAnirudh Venkataramanan {
1931fcea6f3dSAnirudh Venkataramanan 	struct ice_aq_desc desc;
1932fcea6f3dSAnirudh Venkataramanan 
1933fcea6f3dSAnirudh Venkataramanan 	if (!cfg)
1934fcea6f3dSAnirudh Venkataramanan 		return ICE_ERR_PARAM;
1935fcea6f3dSAnirudh Venkataramanan 
1936d8df260aSChinh T Cao 	/* Ensure that only valid bits of cfg->caps can be turned on. */
1937d8df260aSChinh T Cao 	if (cfg->caps & ~ICE_AQ_PHY_ENA_VALID_MASK) {
1938d8df260aSChinh T Cao 		ice_debug(hw, ICE_DBG_PHY,
1939d8df260aSChinh T Cao 			  "Invalid bit is set in ice_aqc_set_phy_cfg_data->caps : 0x%x\n",
1940d8df260aSChinh T Cao 			  cfg->caps);
1941d8df260aSChinh T Cao 
1942d8df260aSChinh T Cao 		cfg->caps &= ICE_AQ_PHY_ENA_VALID_MASK;
1943d8df260aSChinh T Cao 	}
1944d8df260aSChinh T Cao 
1945fcea6f3dSAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_phy_cfg);
194648cb27f2SChinh Cao 	desc.params.set_phy.lport_num = lport;
194748cb27f2SChinh Cao 	desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
1948fcea6f3dSAnirudh Venkataramanan 
1949fcea6f3dSAnirudh Venkataramanan 	return ice_aq_send_cmd(hw, &desc, cfg, sizeof(*cfg), cd);
1950fcea6f3dSAnirudh Venkataramanan }
1951fcea6f3dSAnirudh Venkataramanan 
1952fcea6f3dSAnirudh Venkataramanan /**
1953fcea6f3dSAnirudh Venkataramanan  * ice_update_link_info - update status of the HW network link
1954fcea6f3dSAnirudh Venkataramanan  * @pi: port info structure of the interested logical port
1955fcea6f3dSAnirudh Venkataramanan  */
19565755143dSDave Ertman enum ice_status ice_update_link_info(struct ice_port_info *pi)
1957fcea6f3dSAnirudh Venkataramanan {
1958fcea6f3dSAnirudh Venkataramanan 	struct ice_aqc_get_phy_caps_data *pcaps;
1959fcea6f3dSAnirudh Venkataramanan 	struct ice_phy_info *phy_info;
1960fcea6f3dSAnirudh Venkataramanan 	enum ice_status status;
1961fcea6f3dSAnirudh Venkataramanan 	struct ice_hw *hw;
1962fcea6f3dSAnirudh Venkataramanan 
1963fcea6f3dSAnirudh Venkataramanan 	if (!pi)
1964fcea6f3dSAnirudh Venkataramanan 		return ICE_ERR_PARAM;
1965fcea6f3dSAnirudh Venkataramanan 
1966fcea6f3dSAnirudh Venkataramanan 	hw = pi->hw;
1967fcea6f3dSAnirudh Venkataramanan 
1968fcea6f3dSAnirudh Venkataramanan 	pcaps = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*pcaps), GFP_KERNEL);
1969fcea6f3dSAnirudh Venkataramanan 	if (!pcaps)
1970fcea6f3dSAnirudh Venkataramanan 		return ICE_ERR_NO_MEMORY;
1971fcea6f3dSAnirudh Venkataramanan 
1972fcea6f3dSAnirudh Venkataramanan 	phy_info = &pi->phy;
1973fcea6f3dSAnirudh Venkataramanan 	status = ice_aq_get_link_info(pi, true, NULL, NULL);
1974fcea6f3dSAnirudh Venkataramanan 	if (status)
1975fcea6f3dSAnirudh Venkataramanan 		goto out;
1976fcea6f3dSAnirudh Venkataramanan 
1977fcea6f3dSAnirudh Venkataramanan 	if (phy_info->link_info.link_info & ICE_AQ_MEDIA_AVAILABLE) {
1978fcea6f3dSAnirudh Venkataramanan 		status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_SW_CFG,
1979fcea6f3dSAnirudh Venkataramanan 					     pcaps, NULL);
1980fcea6f3dSAnirudh Venkataramanan 		if (status)
1981fcea6f3dSAnirudh Venkataramanan 			goto out;
1982fcea6f3dSAnirudh Venkataramanan 
1983fcea6f3dSAnirudh Venkataramanan 		memcpy(phy_info->link_info.module_type, &pcaps->module_type,
1984fcea6f3dSAnirudh Venkataramanan 		       sizeof(phy_info->link_info.module_type));
1985fcea6f3dSAnirudh Venkataramanan 	}
1986fcea6f3dSAnirudh Venkataramanan out:
1987fcea6f3dSAnirudh Venkataramanan 	devm_kfree(ice_hw_to_dev(hw), pcaps);
1988fcea6f3dSAnirudh Venkataramanan 	return status;
1989fcea6f3dSAnirudh Venkataramanan }
1990fcea6f3dSAnirudh Venkataramanan 
1991fcea6f3dSAnirudh Venkataramanan /**
1992fcea6f3dSAnirudh Venkataramanan  * ice_set_fc
1993fcea6f3dSAnirudh Venkataramanan  * @pi: port information structure
1994fcea6f3dSAnirudh Venkataramanan  * @aq_failures: pointer to status code, specific to ice_set_fc routine
199548cb27f2SChinh Cao  * @ena_auto_link_update: enable automatic link update
1996fcea6f3dSAnirudh Venkataramanan  *
1997fcea6f3dSAnirudh Venkataramanan  * Set the requested flow control mode.
1998fcea6f3dSAnirudh Venkataramanan  */
1999fcea6f3dSAnirudh Venkataramanan enum ice_status
200048cb27f2SChinh Cao ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update)
2001fcea6f3dSAnirudh Venkataramanan {
2002fcea6f3dSAnirudh Venkataramanan 	struct ice_aqc_set_phy_cfg_data cfg = { 0 };
2003fcea6f3dSAnirudh Venkataramanan 	struct ice_aqc_get_phy_caps_data *pcaps;
2004fcea6f3dSAnirudh Venkataramanan 	enum ice_status status;
2005fcea6f3dSAnirudh Venkataramanan 	u8 pause_mask = 0x0;
2006fcea6f3dSAnirudh Venkataramanan 	struct ice_hw *hw;
2007fcea6f3dSAnirudh Venkataramanan 
2008fcea6f3dSAnirudh Venkataramanan 	if (!pi)
2009fcea6f3dSAnirudh Venkataramanan 		return ICE_ERR_PARAM;
2010fcea6f3dSAnirudh Venkataramanan 	hw = pi->hw;
2011fcea6f3dSAnirudh Venkataramanan 	*aq_failures = ICE_SET_FC_AQ_FAIL_NONE;
2012fcea6f3dSAnirudh Venkataramanan 
2013fcea6f3dSAnirudh Venkataramanan 	switch (pi->fc.req_mode) {
2014fcea6f3dSAnirudh Venkataramanan 	case ICE_FC_FULL:
2015fcea6f3dSAnirudh Venkataramanan 		pause_mask |= ICE_AQC_PHY_EN_TX_LINK_PAUSE;
2016fcea6f3dSAnirudh Venkataramanan 		pause_mask |= ICE_AQC_PHY_EN_RX_LINK_PAUSE;
2017fcea6f3dSAnirudh Venkataramanan 		break;
2018fcea6f3dSAnirudh Venkataramanan 	case ICE_FC_RX_PAUSE:
2019fcea6f3dSAnirudh Venkataramanan 		pause_mask |= ICE_AQC_PHY_EN_RX_LINK_PAUSE;
2020fcea6f3dSAnirudh Venkataramanan 		break;
2021fcea6f3dSAnirudh Venkataramanan 	case ICE_FC_TX_PAUSE:
2022fcea6f3dSAnirudh Venkataramanan 		pause_mask |= ICE_AQC_PHY_EN_TX_LINK_PAUSE;
2023fcea6f3dSAnirudh Venkataramanan 		break;
2024fcea6f3dSAnirudh Venkataramanan 	default:
2025fcea6f3dSAnirudh Venkataramanan 		break;
2026fcea6f3dSAnirudh Venkataramanan 	}
2027fcea6f3dSAnirudh Venkataramanan 
2028fcea6f3dSAnirudh Venkataramanan 	pcaps = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*pcaps), GFP_KERNEL);
2029fcea6f3dSAnirudh Venkataramanan 	if (!pcaps)
2030fcea6f3dSAnirudh Venkataramanan 		return ICE_ERR_NO_MEMORY;
2031fcea6f3dSAnirudh Venkataramanan 
2032f9867df6SAnirudh Venkataramanan 	/* Get the current PHY config */
2033fcea6f3dSAnirudh Venkataramanan 	status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_SW_CFG, pcaps,
2034fcea6f3dSAnirudh Venkataramanan 				     NULL);
2035fcea6f3dSAnirudh Venkataramanan 	if (status) {
2036fcea6f3dSAnirudh Venkataramanan 		*aq_failures = ICE_SET_FC_AQ_FAIL_GET;
2037fcea6f3dSAnirudh Venkataramanan 		goto out;
2038fcea6f3dSAnirudh Venkataramanan 	}
2039fcea6f3dSAnirudh Venkataramanan 
2040fcea6f3dSAnirudh Venkataramanan 	/* clear the old pause settings */
2041fcea6f3dSAnirudh Venkataramanan 	cfg.caps = pcaps->caps & ~(ICE_AQC_PHY_EN_TX_LINK_PAUSE |
2042fcea6f3dSAnirudh Venkataramanan 				   ICE_AQC_PHY_EN_RX_LINK_PAUSE);
2043d8df260aSChinh T Cao 
2044fcea6f3dSAnirudh Venkataramanan 	/* set the new capabilities */
2045fcea6f3dSAnirudh Venkataramanan 	cfg.caps |= pause_mask;
2046d8df260aSChinh T Cao 
2047fcea6f3dSAnirudh Venkataramanan 	/* If the capabilities have changed, then set the new config */
2048fcea6f3dSAnirudh Venkataramanan 	if (cfg.caps != pcaps->caps) {
2049fcea6f3dSAnirudh Venkataramanan 		int retry_count, retry_max = 10;
2050fcea6f3dSAnirudh Venkataramanan 
2051fcea6f3dSAnirudh Venkataramanan 		/* Auto restart link so settings take effect */
205248cb27f2SChinh Cao 		if (ena_auto_link_update)
205348cb27f2SChinh Cao 			cfg.caps |= ICE_AQ_PHY_ENA_AUTO_LINK_UPDT;
2054fcea6f3dSAnirudh Venkataramanan 		/* Copy over all the old settings */
2055aef74145SAnirudh Venkataramanan 		cfg.phy_type_high = pcaps->phy_type_high;
2056fcea6f3dSAnirudh Venkataramanan 		cfg.phy_type_low = pcaps->phy_type_low;
2057fcea6f3dSAnirudh Venkataramanan 		cfg.low_power_ctrl = pcaps->low_power_ctrl;
2058fcea6f3dSAnirudh Venkataramanan 		cfg.eee_cap = pcaps->eee_cap;
2059fcea6f3dSAnirudh Venkataramanan 		cfg.eeer_value = pcaps->eeer_value;
2060fcea6f3dSAnirudh Venkataramanan 		cfg.link_fec_opt = pcaps->link_fec_options;
2061fcea6f3dSAnirudh Venkataramanan 
2062fcea6f3dSAnirudh Venkataramanan 		status = ice_aq_set_phy_cfg(hw, pi->lport, &cfg, NULL);
2063fcea6f3dSAnirudh Venkataramanan 		if (status) {
2064fcea6f3dSAnirudh Venkataramanan 			*aq_failures = ICE_SET_FC_AQ_FAIL_SET;
2065fcea6f3dSAnirudh Venkataramanan 			goto out;
2066fcea6f3dSAnirudh Venkataramanan 		}
2067fcea6f3dSAnirudh Venkataramanan 
2068fcea6f3dSAnirudh Venkataramanan 		/* Update the link info
2069fcea6f3dSAnirudh Venkataramanan 		 * It sometimes takes a really long time for link to
2070fcea6f3dSAnirudh Venkataramanan 		 * come back from the atomic reset. Thus, we wait a
2071fcea6f3dSAnirudh Venkataramanan 		 * little bit.
2072fcea6f3dSAnirudh Venkataramanan 		 */
2073fcea6f3dSAnirudh Venkataramanan 		for (retry_count = 0; retry_count < retry_max; retry_count++) {
2074fcea6f3dSAnirudh Venkataramanan 			status = ice_update_link_info(pi);
2075fcea6f3dSAnirudh Venkataramanan 
2076fcea6f3dSAnirudh Venkataramanan 			if (!status)
2077fcea6f3dSAnirudh Venkataramanan 				break;
2078fcea6f3dSAnirudh Venkataramanan 
2079fcea6f3dSAnirudh Venkataramanan 			mdelay(100);
2080fcea6f3dSAnirudh Venkataramanan 		}
2081fcea6f3dSAnirudh Venkataramanan 
2082fcea6f3dSAnirudh Venkataramanan 		if (status)
2083fcea6f3dSAnirudh Venkataramanan 			*aq_failures = ICE_SET_FC_AQ_FAIL_UPDATE;
2084fcea6f3dSAnirudh Venkataramanan 	}
2085fcea6f3dSAnirudh Venkataramanan 
2086fcea6f3dSAnirudh Venkataramanan out:
2087fcea6f3dSAnirudh Venkataramanan 	devm_kfree(ice_hw_to_dev(hw), pcaps);
2088fcea6f3dSAnirudh Venkataramanan 	return status;
2089fcea6f3dSAnirudh Venkataramanan }
2090fcea6f3dSAnirudh Venkataramanan 
2091fcea6f3dSAnirudh Venkataramanan /**
20920b28b702SAnirudh Venkataramanan  * ice_get_link_status - get status of the HW network link
20930b28b702SAnirudh Venkataramanan  * @pi: port information structure
20940b28b702SAnirudh Venkataramanan  * @link_up: pointer to bool (true/false = linkup/linkdown)
20950b28b702SAnirudh Venkataramanan  *
20960b28b702SAnirudh Venkataramanan  * Variable link_up is true if link is up, false if link is down.
20970b28b702SAnirudh Venkataramanan  * The variable link_up is invalid if status is non zero. As a
20980b28b702SAnirudh Venkataramanan  * result of this call, link status reporting becomes enabled
20990b28b702SAnirudh Venkataramanan  */
21000b28b702SAnirudh Venkataramanan enum ice_status ice_get_link_status(struct ice_port_info *pi, bool *link_up)
21010b28b702SAnirudh Venkataramanan {
21020b28b702SAnirudh Venkataramanan 	struct ice_phy_info *phy_info;
21030b28b702SAnirudh Venkataramanan 	enum ice_status status = 0;
21040b28b702SAnirudh Venkataramanan 
2105c7f2c42bSAnirudh Venkataramanan 	if (!pi || !link_up)
21060b28b702SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
21070b28b702SAnirudh Venkataramanan 
21080b28b702SAnirudh Venkataramanan 	phy_info = &pi->phy;
21090b28b702SAnirudh Venkataramanan 
21100b28b702SAnirudh Venkataramanan 	if (phy_info->get_link_info) {
21110b28b702SAnirudh Venkataramanan 		status = ice_update_link_info(pi);
21120b28b702SAnirudh Venkataramanan 
21130b28b702SAnirudh Venkataramanan 		if (status)
21140b28b702SAnirudh Venkataramanan 			ice_debug(pi->hw, ICE_DBG_LINK,
21150b28b702SAnirudh Venkataramanan 				  "get link status error, status = %d\n",
21160b28b702SAnirudh Venkataramanan 				  status);
21170b28b702SAnirudh Venkataramanan 	}
21180b28b702SAnirudh Venkataramanan 
21190b28b702SAnirudh Venkataramanan 	*link_up = phy_info->link_info.link_info & ICE_AQ_LINK_UP;
21200b28b702SAnirudh Venkataramanan 
21210b28b702SAnirudh Venkataramanan 	return status;
21220b28b702SAnirudh Venkataramanan }
21230b28b702SAnirudh Venkataramanan 
21240b28b702SAnirudh Venkataramanan /**
2125fcea6f3dSAnirudh Venkataramanan  * ice_aq_set_link_restart_an
2126fcea6f3dSAnirudh Venkataramanan  * @pi: pointer to the port information structure
2127fcea6f3dSAnirudh Venkataramanan  * @ena_link: if true: enable link, if false: disable link
2128fcea6f3dSAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
2129fcea6f3dSAnirudh Venkataramanan  *
2130fcea6f3dSAnirudh Venkataramanan  * Sets up the link and restarts the Auto-Negotiation over the link.
2131fcea6f3dSAnirudh Venkataramanan  */
2132fcea6f3dSAnirudh Venkataramanan enum ice_status
2133fcea6f3dSAnirudh Venkataramanan ice_aq_set_link_restart_an(struct ice_port_info *pi, bool ena_link,
2134fcea6f3dSAnirudh Venkataramanan 			   struct ice_sq_cd *cd)
2135fcea6f3dSAnirudh Venkataramanan {
2136fcea6f3dSAnirudh Venkataramanan 	struct ice_aqc_restart_an *cmd;
2137fcea6f3dSAnirudh Venkataramanan 	struct ice_aq_desc desc;
2138fcea6f3dSAnirudh Venkataramanan 
2139fcea6f3dSAnirudh Venkataramanan 	cmd = &desc.params.restart_an;
2140fcea6f3dSAnirudh Venkataramanan 
2141fcea6f3dSAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_restart_an);
2142fcea6f3dSAnirudh Venkataramanan 
2143fcea6f3dSAnirudh Venkataramanan 	cmd->cmd_flags = ICE_AQC_RESTART_AN_LINK_RESTART;
2144fcea6f3dSAnirudh Venkataramanan 	cmd->lport_num = pi->lport;
2145fcea6f3dSAnirudh Venkataramanan 	if (ena_link)
2146fcea6f3dSAnirudh Venkataramanan 		cmd->cmd_flags |= ICE_AQC_RESTART_AN_LINK_ENABLE;
2147fcea6f3dSAnirudh Venkataramanan 	else
2148fcea6f3dSAnirudh Venkataramanan 		cmd->cmd_flags &= ~ICE_AQC_RESTART_AN_LINK_ENABLE;
2149fcea6f3dSAnirudh Venkataramanan 
2150fcea6f3dSAnirudh Venkataramanan 	return ice_aq_send_cmd(pi->hw, &desc, NULL, 0, cd);
2151fcea6f3dSAnirudh Venkataramanan }
2152fcea6f3dSAnirudh Venkataramanan 
2153fcea6f3dSAnirudh Venkataramanan /**
2154250c3b3eSBrett Creeley  * ice_aq_set_event_mask
2155250c3b3eSBrett Creeley  * @hw: pointer to the HW struct
2156250c3b3eSBrett Creeley  * @port_num: port number of the physical function
2157250c3b3eSBrett Creeley  * @mask: event mask to be set
2158250c3b3eSBrett Creeley  * @cd: pointer to command details structure or NULL
2159250c3b3eSBrett Creeley  *
2160250c3b3eSBrett Creeley  * Set event mask (0x0613)
2161250c3b3eSBrett Creeley  */
2162250c3b3eSBrett Creeley enum ice_status
2163250c3b3eSBrett Creeley ice_aq_set_event_mask(struct ice_hw *hw, u8 port_num, u16 mask,
2164250c3b3eSBrett Creeley 		      struct ice_sq_cd *cd)
2165250c3b3eSBrett Creeley {
2166250c3b3eSBrett Creeley 	struct ice_aqc_set_event_mask *cmd;
2167250c3b3eSBrett Creeley 	struct ice_aq_desc desc;
2168250c3b3eSBrett Creeley 
2169250c3b3eSBrett Creeley 	cmd = &desc.params.set_event_mask;
2170250c3b3eSBrett Creeley 
2171250c3b3eSBrett Creeley 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_event_mask);
2172250c3b3eSBrett Creeley 
2173250c3b3eSBrett Creeley 	cmd->lport_num = port_num;
2174250c3b3eSBrett Creeley 
2175250c3b3eSBrett Creeley 	cmd->event_mask = cpu_to_le16(mask);
2176250c3b3eSBrett Creeley 	return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
2177250c3b3eSBrett Creeley }
2178250c3b3eSBrett Creeley 
2179250c3b3eSBrett Creeley /**
21808e151d50SAnirudh Venkataramanan  * ice_aq_set_port_id_led
21818e151d50SAnirudh Venkataramanan  * @pi: pointer to the port information
21828e151d50SAnirudh Venkataramanan  * @is_orig_mode: is this LED set to original mode (by the net-list)
21838e151d50SAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
21848e151d50SAnirudh Venkataramanan  *
21858e151d50SAnirudh Venkataramanan  * Set LED value for the given port (0x06e9)
21868e151d50SAnirudh Venkataramanan  */
21878e151d50SAnirudh Venkataramanan enum ice_status
21888e151d50SAnirudh Venkataramanan ice_aq_set_port_id_led(struct ice_port_info *pi, bool is_orig_mode,
21898e151d50SAnirudh Venkataramanan 		       struct ice_sq_cd *cd)
21908e151d50SAnirudh Venkataramanan {
21918e151d50SAnirudh Venkataramanan 	struct ice_aqc_set_port_id_led *cmd;
21928e151d50SAnirudh Venkataramanan 	struct ice_hw *hw = pi->hw;
21938e151d50SAnirudh Venkataramanan 	struct ice_aq_desc desc;
21948e151d50SAnirudh Venkataramanan 
21958e151d50SAnirudh Venkataramanan 	cmd = &desc.params.set_port_id_led;
21968e151d50SAnirudh Venkataramanan 
21978e151d50SAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_port_id_led);
21988e151d50SAnirudh Venkataramanan 
21998e151d50SAnirudh Venkataramanan 	if (is_orig_mode)
22008e151d50SAnirudh Venkataramanan 		cmd->ident_mode = ICE_AQC_PORT_IDENT_LED_ORIG;
22018e151d50SAnirudh Venkataramanan 	else
22028e151d50SAnirudh Venkataramanan 		cmd->ident_mode = ICE_AQC_PORT_IDENT_LED_BLINK;
22038e151d50SAnirudh Venkataramanan 
22048e151d50SAnirudh Venkataramanan 	return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
22058e151d50SAnirudh Venkataramanan }
22068e151d50SAnirudh Venkataramanan 
22078e151d50SAnirudh Venkataramanan /**
2208d76a60baSAnirudh Venkataramanan  * __ice_aq_get_set_rss_lut
2209d76a60baSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
2210d76a60baSAnirudh Venkataramanan  * @vsi_id: VSI FW index
2211d76a60baSAnirudh Venkataramanan  * @lut_type: LUT table type
2212d76a60baSAnirudh Venkataramanan  * @lut: pointer to the LUT buffer provided by the caller
2213d76a60baSAnirudh Venkataramanan  * @lut_size: size of the LUT buffer
2214d76a60baSAnirudh Venkataramanan  * @glob_lut_idx: global LUT index
2215d76a60baSAnirudh Venkataramanan  * @set: set true to set the table, false to get the table
2216d76a60baSAnirudh Venkataramanan  *
2217d76a60baSAnirudh Venkataramanan  * Internal function to get (0x0B05) or set (0x0B03) RSS look up table
2218d76a60baSAnirudh Venkataramanan  */
2219d76a60baSAnirudh Venkataramanan static enum ice_status
2220d76a60baSAnirudh Venkataramanan __ice_aq_get_set_rss_lut(struct ice_hw *hw, u16 vsi_id, u8 lut_type, u8 *lut,
2221d76a60baSAnirudh Venkataramanan 			 u16 lut_size, u8 glob_lut_idx, bool set)
2222d76a60baSAnirudh Venkataramanan {
2223d76a60baSAnirudh Venkataramanan 	struct ice_aqc_get_set_rss_lut *cmd_resp;
2224d76a60baSAnirudh Venkataramanan 	struct ice_aq_desc desc;
2225d76a60baSAnirudh Venkataramanan 	enum ice_status status;
2226d76a60baSAnirudh Venkataramanan 	u16 flags = 0;
2227d76a60baSAnirudh Venkataramanan 
2228d76a60baSAnirudh Venkataramanan 	cmd_resp = &desc.params.get_set_rss_lut;
2229d76a60baSAnirudh Venkataramanan 
2230d76a60baSAnirudh Venkataramanan 	if (set) {
2231d76a60baSAnirudh Venkataramanan 		ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_rss_lut);
2232d76a60baSAnirudh Venkataramanan 		desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
2233d76a60baSAnirudh Venkataramanan 	} else {
2234d76a60baSAnirudh Venkataramanan 		ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_rss_lut);
2235d76a60baSAnirudh Venkataramanan 	}
2236d76a60baSAnirudh Venkataramanan 
2237d76a60baSAnirudh Venkataramanan 	cmd_resp->vsi_id = cpu_to_le16(((vsi_id <<
2238d76a60baSAnirudh Venkataramanan 					 ICE_AQC_GSET_RSS_LUT_VSI_ID_S) &
2239d76a60baSAnirudh Venkataramanan 					ICE_AQC_GSET_RSS_LUT_VSI_ID_M) |
2240d76a60baSAnirudh Venkataramanan 				       ICE_AQC_GSET_RSS_LUT_VSI_VALID);
2241d76a60baSAnirudh Venkataramanan 
2242d76a60baSAnirudh Venkataramanan 	switch (lut_type) {
2243d76a60baSAnirudh Venkataramanan 	case ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_VSI:
2244d76a60baSAnirudh Venkataramanan 	case ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF:
2245d76a60baSAnirudh Venkataramanan 	case ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_GLOBAL:
2246d76a60baSAnirudh Venkataramanan 		flags |= ((lut_type << ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_S) &
2247d76a60baSAnirudh Venkataramanan 			  ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_M);
2248d76a60baSAnirudh Venkataramanan 		break;
2249d76a60baSAnirudh Venkataramanan 	default:
2250d76a60baSAnirudh Venkataramanan 		status = ICE_ERR_PARAM;
2251d76a60baSAnirudh Venkataramanan 		goto ice_aq_get_set_rss_lut_exit;
2252d76a60baSAnirudh Venkataramanan 	}
2253d76a60baSAnirudh Venkataramanan 
2254d76a60baSAnirudh Venkataramanan 	if (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_GLOBAL) {
2255d76a60baSAnirudh Venkataramanan 		flags |= ((glob_lut_idx << ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_S) &
2256d76a60baSAnirudh Venkataramanan 			  ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_M);
2257d76a60baSAnirudh Venkataramanan 
2258d76a60baSAnirudh Venkataramanan 		if (!set)
2259d76a60baSAnirudh Venkataramanan 			goto ice_aq_get_set_rss_lut_send;
2260d76a60baSAnirudh Venkataramanan 	} else if (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF) {
2261d76a60baSAnirudh Venkataramanan 		if (!set)
2262d76a60baSAnirudh Venkataramanan 			goto ice_aq_get_set_rss_lut_send;
2263d76a60baSAnirudh Venkataramanan 	} else {
2264d76a60baSAnirudh Venkataramanan 		goto ice_aq_get_set_rss_lut_send;
2265d76a60baSAnirudh Venkataramanan 	}
2266d76a60baSAnirudh Venkataramanan 
2267d76a60baSAnirudh Venkataramanan 	/* LUT size is only valid for Global and PF table types */
22684381147dSAnirudh Venkataramanan 	switch (lut_size) {
22694381147dSAnirudh Venkataramanan 	case ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_128:
22704381147dSAnirudh Venkataramanan 		break;
22714381147dSAnirudh Venkataramanan 	case ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512:
2272d76a60baSAnirudh Venkataramanan 		flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512_FLAG <<
2273d76a60baSAnirudh Venkataramanan 			  ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) &
2274d76a60baSAnirudh Venkataramanan 			 ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
22754381147dSAnirudh Venkataramanan 		break;
22764381147dSAnirudh Venkataramanan 	case ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K:
22774381147dSAnirudh Venkataramanan 		if (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF) {
2278d76a60baSAnirudh Venkataramanan 			flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K_FLAG <<
2279d76a60baSAnirudh Venkataramanan 				  ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) &
2280d76a60baSAnirudh Venkataramanan 				 ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
22814381147dSAnirudh Venkataramanan 			break;
22824381147dSAnirudh Venkataramanan 		}
22834381147dSAnirudh Venkataramanan 		/* fall-through */
22844381147dSAnirudh Venkataramanan 	default:
2285d76a60baSAnirudh Venkataramanan 		status = ICE_ERR_PARAM;
2286d76a60baSAnirudh Venkataramanan 		goto ice_aq_get_set_rss_lut_exit;
2287d76a60baSAnirudh Venkataramanan 	}
2288d76a60baSAnirudh Venkataramanan 
2289d76a60baSAnirudh Venkataramanan ice_aq_get_set_rss_lut_send:
2290d76a60baSAnirudh Venkataramanan 	cmd_resp->flags = cpu_to_le16(flags);
2291d76a60baSAnirudh Venkataramanan 	status = ice_aq_send_cmd(hw, &desc, lut, lut_size, NULL);
2292d76a60baSAnirudh Venkataramanan 
2293d76a60baSAnirudh Venkataramanan ice_aq_get_set_rss_lut_exit:
2294d76a60baSAnirudh Venkataramanan 	return status;
2295d76a60baSAnirudh Venkataramanan }
2296d76a60baSAnirudh Venkataramanan 
2297d76a60baSAnirudh Venkataramanan /**
2298d76a60baSAnirudh Venkataramanan  * ice_aq_get_rss_lut
2299d76a60baSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
23004fb33f31SAnirudh Venkataramanan  * @vsi_handle: software VSI handle
2301d76a60baSAnirudh Venkataramanan  * @lut_type: LUT table type
2302d76a60baSAnirudh Venkataramanan  * @lut: pointer to the LUT buffer provided by the caller
2303d76a60baSAnirudh Venkataramanan  * @lut_size: size of the LUT buffer
2304d76a60baSAnirudh Venkataramanan  *
2305d76a60baSAnirudh Venkataramanan  * get the RSS lookup table, PF or VSI type
2306d76a60baSAnirudh Venkataramanan  */
2307d76a60baSAnirudh Venkataramanan enum ice_status
23084fb33f31SAnirudh Venkataramanan ice_aq_get_rss_lut(struct ice_hw *hw, u16 vsi_handle, u8 lut_type,
23094fb33f31SAnirudh Venkataramanan 		   u8 *lut, u16 lut_size)
2310d76a60baSAnirudh Venkataramanan {
23114fb33f31SAnirudh Venkataramanan 	if (!ice_is_vsi_valid(hw, vsi_handle) || !lut)
23124fb33f31SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
23134fb33f31SAnirudh Venkataramanan 
23144fb33f31SAnirudh Venkataramanan 	return __ice_aq_get_set_rss_lut(hw, ice_get_hw_vsi_num(hw, vsi_handle),
23154fb33f31SAnirudh Venkataramanan 					lut_type, lut, lut_size, 0, false);
2316d76a60baSAnirudh Venkataramanan }
2317d76a60baSAnirudh Venkataramanan 
2318d76a60baSAnirudh Venkataramanan /**
2319d76a60baSAnirudh Venkataramanan  * ice_aq_set_rss_lut
2320d76a60baSAnirudh Venkataramanan  * @hw: pointer to the hardware structure
23214fb33f31SAnirudh Venkataramanan  * @vsi_handle: software VSI handle
2322d76a60baSAnirudh Venkataramanan  * @lut_type: LUT table type
2323d76a60baSAnirudh Venkataramanan  * @lut: pointer to the LUT buffer provided by the caller
2324d76a60baSAnirudh Venkataramanan  * @lut_size: size of the LUT buffer
2325d76a60baSAnirudh Venkataramanan  *
2326d76a60baSAnirudh Venkataramanan  * set the RSS lookup table, PF or VSI type
2327d76a60baSAnirudh Venkataramanan  */
2328d76a60baSAnirudh Venkataramanan enum ice_status
23294fb33f31SAnirudh Venkataramanan ice_aq_set_rss_lut(struct ice_hw *hw, u16 vsi_handle, u8 lut_type,
23304fb33f31SAnirudh Venkataramanan 		   u8 *lut, u16 lut_size)
2331d76a60baSAnirudh Venkataramanan {
23324fb33f31SAnirudh Venkataramanan 	if (!ice_is_vsi_valid(hw, vsi_handle) || !lut)
23334fb33f31SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
23344fb33f31SAnirudh Venkataramanan 
23354fb33f31SAnirudh Venkataramanan 	return __ice_aq_get_set_rss_lut(hw, ice_get_hw_vsi_num(hw, vsi_handle),
23364fb33f31SAnirudh Venkataramanan 					lut_type, lut, lut_size, 0, true);
2337d76a60baSAnirudh Venkataramanan }
2338d76a60baSAnirudh Venkataramanan 
2339d76a60baSAnirudh Venkataramanan /**
2340d76a60baSAnirudh Venkataramanan  * __ice_aq_get_set_rss_key
2341f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
2342d76a60baSAnirudh Venkataramanan  * @vsi_id: VSI FW index
2343d76a60baSAnirudh Venkataramanan  * @key: pointer to key info struct
2344d76a60baSAnirudh Venkataramanan  * @set: set true to set the key, false to get the key
2345d76a60baSAnirudh Venkataramanan  *
2346d76a60baSAnirudh Venkataramanan  * get (0x0B04) or set (0x0B02) the RSS key per VSI
2347d76a60baSAnirudh Venkataramanan  */
2348d76a60baSAnirudh Venkataramanan static enum
2349d76a60baSAnirudh Venkataramanan ice_status __ice_aq_get_set_rss_key(struct ice_hw *hw, u16 vsi_id,
2350d76a60baSAnirudh Venkataramanan 				    struct ice_aqc_get_set_rss_keys *key,
2351d76a60baSAnirudh Venkataramanan 				    bool set)
2352d76a60baSAnirudh Venkataramanan {
2353d76a60baSAnirudh Venkataramanan 	struct ice_aqc_get_set_rss_key *cmd_resp;
2354d76a60baSAnirudh Venkataramanan 	u16 key_size = sizeof(*key);
2355d76a60baSAnirudh Venkataramanan 	struct ice_aq_desc desc;
2356d76a60baSAnirudh Venkataramanan 
2357d76a60baSAnirudh Venkataramanan 	cmd_resp = &desc.params.get_set_rss_key;
2358d76a60baSAnirudh Venkataramanan 
2359d76a60baSAnirudh Venkataramanan 	if (set) {
2360d76a60baSAnirudh Venkataramanan 		ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_rss_key);
2361d76a60baSAnirudh Venkataramanan 		desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
2362d76a60baSAnirudh Venkataramanan 	} else {
2363d76a60baSAnirudh Venkataramanan 		ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_rss_key);
2364d76a60baSAnirudh Venkataramanan 	}
2365d76a60baSAnirudh Venkataramanan 
2366d76a60baSAnirudh Venkataramanan 	cmd_resp->vsi_id = cpu_to_le16(((vsi_id <<
2367d76a60baSAnirudh Venkataramanan 					 ICE_AQC_GSET_RSS_KEY_VSI_ID_S) &
2368d76a60baSAnirudh Venkataramanan 					ICE_AQC_GSET_RSS_KEY_VSI_ID_M) |
2369d76a60baSAnirudh Venkataramanan 				       ICE_AQC_GSET_RSS_KEY_VSI_VALID);
2370d76a60baSAnirudh Venkataramanan 
2371d76a60baSAnirudh Venkataramanan 	return ice_aq_send_cmd(hw, &desc, key, key_size, NULL);
2372d76a60baSAnirudh Venkataramanan }
2373d76a60baSAnirudh Venkataramanan 
2374d76a60baSAnirudh Venkataramanan /**
2375d76a60baSAnirudh Venkataramanan  * ice_aq_get_rss_key
2376f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
23774fb33f31SAnirudh Venkataramanan  * @vsi_handle: software VSI handle
2378d76a60baSAnirudh Venkataramanan  * @key: pointer to key info struct
2379d76a60baSAnirudh Venkataramanan  *
2380d76a60baSAnirudh Venkataramanan  * get the RSS key per VSI
2381d76a60baSAnirudh Venkataramanan  */
2382d76a60baSAnirudh Venkataramanan enum ice_status
23834fb33f31SAnirudh Venkataramanan ice_aq_get_rss_key(struct ice_hw *hw, u16 vsi_handle,
2384d76a60baSAnirudh Venkataramanan 		   struct ice_aqc_get_set_rss_keys *key)
2385d76a60baSAnirudh Venkataramanan {
23864fb33f31SAnirudh Venkataramanan 	if (!ice_is_vsi_valid(hw, vsi_handle) || !key)
23874fb33f31SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
23884fb33f31SAnirudh Venkataramanan 
23894fb33f31SAnirudh Venkataramanan 	return __ice_aq_get_set_rss_key(hw, ice_get_hw_vsi_num(hw, vsi_handle),
23904fb33f31SAnirudh Venkataramanan 					key, false);
2391d76a60baSAnirudh Venkataramanan }
2392d76a60baSAnirudh Venkataramanan 
2393d76a60baSAnirudh Venkataramanan /**
2394d76a60baSAnirudh Venkataramanan  * ice_aq_set_rss_key
2395f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
23964fb33f31SAnirudh Venkataramanan  * @vsi_handle: software VSI handle
2397d76a60baSAnirudh Venkataramanan  * @keys: pointer to key info struct
2398d76a60baSAnirudh Venkataramanan  *
2399d76a60baSAnirudh Venkataramanan  * set the RSS key per VSI
2400d76a60baSAnirudh Venkataramanan  */
2401d76a60baSAnirudh Venkataramanan enum ice_status
24024fb33f31SAnirudh Venkataramanan ice_aq_set_rss_key(struct ice_hw *hw, u16 vsi_handle,
2403d76a60baSAnirudh Venkataramanan 		   struct ice_aqc_get_set_rss_keys *keys)
2404d76a60baSAnirudh Venkataramanan {
24054fb33f31SAnirudh Venkataramanan 	if (!ice_is_vsi_valid(hw, vsi_handle) || !keys)
24064fb33f31SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
24074fb33f31SAnirudh Venkataramanan 
24084fb33f31SAnirudh Venkataramanan 	return __ice_aq_get_set_rss_key(hw, ice_get_hw_vsi_num(hw, vsi_handle),
24094fb33f31SAnirudh Venkataramanan 					keys, true);
2410d76a60baSAnirudh Venkataramanan }
2411d76a60baSAnirudh Venkataramanan 
2412d76a60baSAnirudh Venkataramanan /**
2413cdedef59SAnirudh Venkataramanan  * ice_aq_add_lan_txq
2414cdedef59SAnirudh Venkataramanan  * @hw: pointer to the hardware structure
2415cdedef59SAnirudh Venkataramanan  * @num_qgrps: Number of added queue groups
2416cdedef59SAnirudh Venkataramanan  * @qg_list: list of queue groups to be added
2417cdedef59SAnirudh Venkataramanan  * @buf_size: size of buffer for indirect command
2418cdedef59SAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
2419cdedef59SAnirudh Venkataramanan  *
2420cdedef59SAnirudh Venkataramanan  * Add Tx LAN queue (0x0C30)
2421cdedef59SAnirudh Venkataramanan  *
2422cdedef59SAnirudh Venkataramanan  * NOTE:
2423cdedef59SAnirudh Venkataramanan  * Prior to calling add Tx LAN queue:
2424cdedef59SAnirudh Venkataramanan  * Initialize the following as part of the Tx queue context:
2425cdedef59SAnirudh Venkataramanan  * Completion queue ID if the queue uses Completion queue, Quanta profile,
2426cdedef59SAnirudh Venkataramanan  * Cache profile and Packet shaper profile.
2427cdedef59SAnirudh Venkataramanan  *
2428cdedef59SAnirudh Venkataramanan  * After add Tx LAN queue AQ command is completed:
2429cdedef59SAnirudh Venkataramanan  * Interrupts should be associated with specific queues,
2430cdedef59SAnirudh Venkataramanan  * Association of Tx queue to Doorbell queue is not part of Add LAN Tx queue
2431cdedef59SAnirudh Venkataramanan  * flow.
2432cdedef59SAnirudh Venkataramanan  */
2433cdedef59SAnirudh Venkataramanan static enum ice_status
2434cdedef59SAnirudh Venkataramanan ice_aq_add_lan_txq(struct ice_hw *hw, u8 num_qgrps,
2435cdedef59SAnirudh Venkataramanan 		   struct ice_aqc_add_tx_qgrp *qg_list, u16 buf_size,
2436cdedef59SAnirudh Venkataramanan 		   struct ice_sq_cd *cd)
2437cdedef59SAnirudh Venkataramanan {
2438cdedef59SAnirudh Venkataramanan 	u16 i, sum_header_size, sum_q_size = 0;
2439cdedef59SAnirudh Venkataramanan 	struct ice_aqc_add_tx_qgrp *list;
2440cdedef59SAnirudh Venkataramanan 	struct ice_aqc_add_txqs *cmd;
2441cdedef59SAnirudh Venkataramanan 	struct ice_aq_desc desc;
2442cdedef59SAnirudh Venkataramanan 
2443cdedef59SAnirudh Venkataramanan 	cmd = &desc.params.add_txqs;
2444cdedef59SAnirudh Venkataramanan 
2445cdedef59SAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_txqs);
2446cdedef59SAnirudh Venkataramanan 
2447cdedef59SAnirudh Venkataramanan 	if (!qg_list)
2448cdedef59SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
2449cdedef59SAnirudh Venkataramanan 
2450cdedef59SAnirudh Venkataramanan 	if (num_qgrps > ICE_LAN_TXQ_MAX_QGRPS)
2451cdedef59SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
2452cdedef59SAnirudh Venkataramanan 
2453cdedef59SAnirudh Venkataramanan 	sum_header_size = num_qgrps *
2454cdedef59SAnirudh Venkataramanan 		(sizeof(*qg_list) - sizeof(*qg_list->txqs));
2455cdedef59SAnirudh Venkataramanan 
2456cdedef59SAnirudh Venkataramanan 	list = qg_list;
2457cdedef59SAnirudh Venkataramanan 	for (i = 0; i < num_qgrps; i++) {
2458cdedef59SAnirudh Venkataramanan 		struct ice_aqc_add_txqs_perq *q = list->txqs;
2459cdedef59SAnirudh Venkataramanan 
2460cdedef59SAnirudh Venkataramanan 		sum_q_size += list->num_txqs * sizeof(*q);
2461cdedef59SAnirudh Venkataramanan 		list = (struct ice_aqc_add_tx_qgrp *)(q + list->num_txqs);
2462cdedef59SAnirudh Venkataramanan 	}
2463cdedef59SAnirudh Venkataramanan 
2464cdedef59SAnirudh Venkataramanan 	if (buf_size != (sum_header_size + sum_q_size))
2465cdedef59SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
2466cdedef59SAnirudh Venkataramanan 
2467cdedef59SAnirudh Venkataramanan 	desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
2468cdedef59SAnirudh Venkataramanan 
2469cdedef59SAnirudh Venkataramanan 	cmd->num_qgrps = num_qgrps;
2470cdedef59SAnirudh Venkataramanan 
2471cdedef59SAnirudh Venkataramanan 	return ice_aq_send_cmd(hw, &desc, qg_list, buf_size, cd);
2472cdedef59SAnirudh Venkataramanan }
2473cdedef59SAnirudh Venkataramanan 
2474cdedef59SAnirudh Venkataramanan /**
2475cdedef59SAnirudh Venkataramanan  * ice_aq_dis_lan_txq
2476cdedef59SAnirudh Venkataramanan  * @hw: pointer to the hardware structure
2477cdedef59SAnirudh Venkataramanan  * @num_qgrps: number of groups in the list
2478cdedef59SAnirudh Venkataramanan  * @qg_list: the list of groups to disable
2479cdedef59SAnirudh Venkataramanan  * @buf_size: the total size of the qg_list buffer in bytes
248094c4441bSAnirudh Venkataramanan  * @rst_src: if called due to reset, specifies the reset source
2481ddf30f7fSAnirudh Venkataramanan  * @vmvf_num: the relative VM or VF number that is undergoing the reset
2482cdedef59SAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
2483cdedef59SAnirudh Venkataramanan  *
2484cdedef59SAnirudh Venkataramanan  * Disable LAN Tx queue (0x0C31)
2485cdedef59SAnirudh Venkataramanan  */
2486cdedef59SAnirudh Venkataramanan static enum ice_status
2487cdedef59SAnirudh Venkataramanan ice_aq_dis_lan_txq(struct ice_hw *hw, u8 num_qgrps,
2488cdedef59SAnirudh Venkataramanan 		   struct ice_aqc_dis_txq_item *qg_list, u16 buf_size,
2489ddf30f7fSAnirudh Venkataramanan 		   enum ice_disq_rst_src rst_src, u16 vmvf_num,
2490cdedef59SAnirudh Venkataramanan 		   struct ice_sq_cd *cd)
2491cdedef59SAnirudh Venkataramanan {
2492cdedef59SAnirudh Venkataramanan 	struct ice_aqc_dis_txqs *cmd;
2493cdedef59SAnirudh Venkataramanan 	struct ice_aq_desc desc;
24946e9650d5SVictor Raj 	enum ice_status status;
2495cdedef59SAnirudh Venkataramanan 	u16 i, sz = 0;
2496cdedef59SAnirudh Venkataramanan 
2497cdedef59SAnirudh Venkataramanan 	cmd = &desc.params.dis_txqs;
2498cdedef59SAnirudh Venkataramanan 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_dis_txqs);
2499cdedef59SAnirudh Venkataramanan 
2500ddf30f7fSAnirudh Venkataramanan 	/* qg_list can be NULL only in VM/VF reset flow */
2501ddf30f7fSAnirudh Venkataramanan 	if (!qg_list && !rst_src)
2502cdedef59SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
2503cdedef59SAnirudh Venkataramanan 
2504cdedef59SAnirudh Venkataramanan 	if (num_qgrps > ICE_LAN_TXQ_MAX_QGRPS)
2505cdedef59SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
2506ddf30f7fSAnirudh Venkataramanan 
2507cdedef59SAnirudh Venkataramanan 	cmd->num_entries = num_qgrps;
2508cdedef59SAnirudh Venkataramanan 
2509ddf30f7fSAnirudh Venkataramanan 	cmd->vmvf_and_timeout = cpu_to_le16((5 << ICE_AQC_Q_DIS_TIMEOUT_S) &
2510ddf30f7fSAnirudh Venkataramanan 					    ICE_AQC_Q_DIS_TIMEOUT_M);
2511ddf30f7fSAnirudh Venkataramanan 
2512ddf30f7fSAnirudh Venkataramanan 	switch (rst_src) {
2513ddf30f7fSAnirudh Venkataramanan 	case ICE_VM_RESET:
2514ddf30f7fSAnirudh Venkataramanan 		cmd->cmd_type = ICE_AQC_Q_DIS_CMD_VM_RESET;
2515ddf30f7fSAnirudh Venkataramanan 		cmd->vmvf_and_timeout |=
2516ddf30f7fSAnirudh Venkataramanan 			cpu_to_le16(vmvf_num & ICE_AQC_Q_DIS_VMVF_NUM_M);
2517ddf30f7fSAnirudh Venkataramanan 		break;
2518ddf30f7fSAnirudh Venkataramanan 	case ICE_VF_RESET:
2519ddf30f7fSAnirudh Venkataramanan 		cmd->cmd_type = ICE_AQC_Q_DIS_CMD_VF_RESET;
2520f9867df6SAnirudh Venkataramanan 		/* In this case, FW expects vmvf_num to be absolute VF ID */
2521ddf30f7fSAnirudh Venkataramanan 		cmd->vmvf_and_timeout |=
2522ddf30f7fSAnirudh Venkataramanan 			cpu_to_le16((vmvf_num + hw->func_caps.vf_base_id) &
2523ddf30f7fSAnirudh Venkataramanan 				    ICE_AQC_Q_DIS_VMVF_NUM_M);
2524ddf30f7fSAnirudh Venkataramanan 		break;
2525ddf30f7fSAnirudh Venkataramanan 	case ICE_NO_RESET:
2526ddf30f7fSAnirudh Venkataramanan 	default:
2527ddf30f7fSAnirudh Venkataramanan 		break;
2528ddf30f7fSAnirudh Venkataramanan 	}
2529ddf30f7fSAnirudh Venkataramanan 
25306e9650d5SVictor Raj 	/* flush pipe on time out */
25316e9650d5SVictor Raj 	cmd->cmd_type |= ICE_AQC_Q_DIS_CMD_FLUSH_PIPE;
2532ddf30f7fSAnirudh Venkataramanan 	/* If no queue group info, we are in a reset flow. Issue the AQ */
2533ddf30f7fSAnirudh Venkataramanan 	if (!qg_list)
2534ddf30f7fSAnirudh Venkataramanan 		goto do_aq;
2535ddf30f7fSAnirudh Venkataramanan 
2536ddf30f7fSAnirudh Venkataramanan 	/* set RD bit to indicate that command buffer is provided by the driver
2537ddf30f7fSAnirudh Venkataramanan 	 * and it needs to be read by the firmware
2538ddf30f7fSAnirudh Venkataramanan 	 */
2539ddf30f7fSAnirudh Venkataramanan 	desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
2540ddf30f7fSAnirudh Venkataramanan 
2541cdedef59SAnirudh Venkataramanan 	for (i = 0; i < num_qgrps; ++i) {
2542cdedef59SAnirudh Venkataramanan 		/* Calculate the size taken up by the queue IDs in this group */
2543cdedef59SAnirudh Venkataramanan 		sz += qg_list[i].num_qs * sizeof(qg_list[i].q_id);
2544cdedef59SAnirudh Venkataramanan 
2545cdedef59SAnirudh Venkataramanan 		/* Add the size of the group header */
2546cdedef59SAnirudh Venkataramanan 		sz += sizeof(qg_list[i]) - sizeof(qg_list[i].q_id);
2547cdedef59SAnirudh Venkataramanan 
2548cdedef59SAnirudh Venkataramanan 		/* If the num of queues is even, add 2 bytes of padding */
2549cdedef59SAnirudh Venkataramanan 		if ((qg_list[i].num_qs % 2) == 0)
2550cdedef59SAnirudh Venkataramanan 			sz += 2;
2551cdedef59SAnirudh Venkataramanan 	}
2552cdedef59SAnirudh Venkataramanan 
2553cdedef59SAnirudh Venkataramanan 	if (buf_size != sz)
2554cdedef59SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
2555cdedef59SAnirudh Venkataramanan 
2556ddf30f7fSAnirudh Venkataramanan do_aq:
25576e9650d5SVictor Raj 	status = ice_aq_send_cmd(hw, &desc, qg_list, buf_size, cd);
25586e9650d5SVictor Raj 	if (status) {
25596e9650d5SVictor Raj 		if (!qg_list)
25606e9650d5SVictor Raj 			ice_debug(hw, ICE_DBG_SCHED, "VM%d disable failed %d\n",
25616e9650d5SVictor Raj 				  vmvf_num, hw->adminq.sq_last_status);
25626e9650d5SVictor Raj 		else
25636e9650d5SVictor Raj 			ice_debug(hw, ICE_DBG_SCHED, "disable Q %d failed %d\n",
25646e9650d5SVictor Raj 				  le16_to_cpu(qg_list[0].q_id[0]),
25656e9650d5SVictor Raj 				  hw->adminq.sq_last_status);
25666e9650d5SVictor Raj 	}
25676e9650d5SVictor Raj 	return status;
2568cdedef59SAnirudh Venkataramanan }
2569cdedef59SAnirudh Venkataramanan 
2570cdedef59SAnirudh Venkataramanan /* End of FW Admin Queue command wrappers */
2571cdedef59SAnirudh Venkataramanan 
2572cdedef59SAnirudh Venkataramanan /**
2573cdedef59SAnirudh Venkataramanan  * ice_write_byte - write a byte to a packed context structure
2574cdedef59SAnirudh Venkataramanan  * @src_ctx:  the context structure to read from
2575cdedef59SAnirudh Venkataramanan  * @dest_ctx: the context to be written to
2576cdedef59SAnirudh Venkataramanan  * @ce_info:  a description of the struct to be filled
2577cdedef59SAnirudh Venkataramanan  */
2578c8b7abddSBruce Allan static void
2579c8b7abddSBruce Allan ice_write_byte(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
2580cdedef59SAnirudh Venkataramanan {
2581cdedef59SAnirudh Venkataramanan 	u8 src_byte, dest_byte, mask;
2582cdedef59SAnirudh Venkataramanan 	u8 *from, *dest;
2583cdedef59SAnirudh Venkataramanan 	u16 shift_width;
2584cdedef59SAnirudh Venkataramanan 
2585cdedef59SAnirudh Venkataramanan 	/* copy from the next struct field */
2586cdedef59SAnirudh Venkataramanan 	from = src_ctx + ce_info->offset;
2587cdedef59SAnirudh Venkataramanan 
2588cdedef59SAnirudh Venkataramanan 	/* prepare the bits and mask */
2589cdedef59SAnirudh Venkataramanan 	shift_width = ce_info->lsb % 8;
2590cdedef59SAnirudh Venkataramanan 	mask = (u8)(BIT(ce_info->width) - 1);
2591cdedef59SAnirudh Venkataramanan 
2592cdedef59SAnirudh Venkataramanan 	src_byte = *from;
2593cdedef59SAnirudh Venkataramanan 	src_byte &= mask;
2594cdedef59SAnirudh Venkataramanan 
2595cdedef59SAnirudh Venkataramanan 	/* shift to correct alignment */
2596cdedef59SAnirudh Venkataramanan 	mask <<= shift_width;
2597cdedef59SAnirudh Venkataramanan 	src_byte <<= shift_width;
2598cdedef59SAnirudh Venkataramanan 
2599cdedef59SAnirudh Venkataramanan 	/* get the current bits from the target bit string */
2600cdedef59SAnirudh Venkataramanan 	dest = dest_ctx + (ce_info->lsb / 8);
2601cdedef59SAnirudh Venkataramanan 
2602cdedef59SAnirudh Venkataramanan 	memcpy(&dest_byte, dest, sizeof(dest_byte));
2603cdedef59SAnirudh Venkataramanan 
2604cdedef59SAnirudh Venkataramanan 	dest_byte &= ~mask;	/* get the bits not changing */
2605cdedef59SAnirudh Venkataramanan 	dest_byte |= src_byte;	/* add in the new bits */
2606cdedef59SAnirudh Venkataramanan 
2607cdedef59SAnirudh Venkataramanan 	/* put it all back */
2608cdedef59SAnirudh Venkataramanan 	memcpy(dest, &dest_byte, sizeof(dest_byte));
2609cdedef59SAnirudh Venkataramanan }
2610cdedef59SAnirudh Venkataramanan 
2611cdedef59SAnirudh Venkataramanan /**
2612cdedef59SAnirudh Venkataramanan  * ice_write_word - write a word to a packed context structure
2613cdedef59SAnirudh Venkataramanan  * @src_ctx:  the context structure to read from
2614cdedef59SAnirudh Venkataramanan  * @dest_ctx: the context to be written to
2615cdedef59SAnirudh Venkataramanan  * @ce_info:  a description of the struct to be filled
2616cdedef59SAnirudh Venkataramanan  */
2617c8b7abddSBruce Allan static void
2618c8b7abddSBruce Allan ice_write_word(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
2619cdedef59SAnirudh Venkataramanan {
2620cdedef59SAnirudh Venkataramanan 	u16 src_word, mask;
2621cdedef59SAnirudh Venkataramanan 	__le16 dest_word;
2622cdedef59SAnirudh Venkataramanan 	u8 *from, *dest;
2623cdedef59SAnirudh Venkataramanan 	u16 shift_width;
2624cdedef59SAnirudh Venkataramanan 
2625cdedef59SAnirudh Venkataramanan 	/* copy from the next struct field */
2626cdedef59SAnirudh Venkataramanan 	from = src_ctx + ce_info->offset;
2627cdedef59SAnirudh Venkataramanan 
2628cdedef59SAnirudh Venkataramanan 	/* prepare the bits and mask */
2629cdedef59SAnirudh Venkataramanan 	shift_width = ce_info->lsb % 8;
2630cdedef59SAnirudh Venkataramanan 	mask = BIT(ce_info->width) - 1;
2631cdedef59SAnirudh Venkataramanan 
2632cdedef59SAnirudh Venkataramanan 	/* don't swizzle the bits until after the mask because the mask bits
2633cdedef59SAnirudh Venkataramanan 	 * will be in a different bit position on big endian machines
2634cdedef59SAnirudh Venkataramanan 	 */
2635cdedef59SAnirudh Venkataramanan 	src_word = *(u16 *)from;
2636cdedef59SAnirudh Venkataramanan 	src_word &= mask;
2637cdedef59SAnirudh Venkataramanan 
2638cdedef59SAnirudh Venkataramanan 	/* shift to correct alignment */
2639cdedef59SAnirudh Venkataramanan 	mask <<= shift_width;
2640cdedef59SAnirudh Venkataramanan 	src_word <<= shift_width;
2641cdedef59SAnirudh Venkataramanan 
2642cdedef59SAnirudh Venkataramanan 	/* get the current bits from the target bit string */
2643cdedef59SAnirudh Venkataramanan 	dest = dest_ctx + (ce_info->lsb / 8);
2644cdedef59SAnirudh Venkataramanan 
2645cdedef59SAnirudh Venkataramanan 	memcpy(&dest_word, dest, sizeof(dest_word));
2646cdedef59SAnirudh Venkataramanan 
2647cdedef59SAnirudh Venkataramanan 	dest_word &= ~(cpu_to_le16(mask));	/* get the bits not changing */
2648cdedef59SAnirudh Venkataramanan 	dest_word |= cpu_to_le16(src_word);	/* add in the new bits */
2649cdedef59SAnirudh Venkataramanan 
2650cdedef59SAnirudh Venkataramanan 	/* put it all back */
2651cdedef59SAnirudh Venkataramanan 	memcpy(dest, &dest_word, sizeof(dest_word));
2652cdedef59SAnirudh Venkataramanan }
2653cdedef59SAnirudh Venkataramanan 
2654cdedef59SAnirudh Venkataramanan /**
2655cdedef59SAnirudh Venkataramanan  * ice_write_dword - write a dword to a packed context structure
2656cdedef59SAnirudh Venkataramanan  * @src_ctx:  the context structure to read from
2657cdedef59SAnirudh Venkataramanan  * @dest_ctx: the context to be written to
2658cdedef59SAnirudh Venkataramanan  * @ce_info:  a description of the struct to be filled
2659cdedef59SAnirudh Venkataramanan  */
2660c8b7abddSBruce Allan static void
2661c8b7abddSBruce Allan ice_write_dword(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
2662cdedef59SAnirudh Venkataramanan {
2663cdedef59SAnirudh Venkataramanan 	u32 src_dword, mask;
2664cdedef59SAnirudh Venkataramanan 	__le32 dest_dword;
2665cdedef59SAnirudh Venkataramanan 	u8 *from, *dest;
2666cdedef59SAnirudh Venkataramanan 	u16 shift_width;
2667cdedef59SAnirudh Venkataramanan 
2668cdedef59SAnirudh Venkataramanan 	/* copy from the next struct field */
2669cdedef59SAnirudh Venkataramanan 	from = src_ctx + ce_info->offset;
2670cdedef59SAnirudh Venkataramanan 
2671cdedef59SAnirudh Venkataramanan 	/* prepare the bits and mask */
2672cdedef59SAnirudh Venkataramanan 	shift_width = ce_info->lsb % 8;
2673cdedef59SAnirudh Venkataramanan 
2674cdedef59SAnirudh Venkataramanan 	/* if the field width is exactly 32 on an x86 machine, then the shift
2675cdedef59SAnirudh Venkataramanan 	 * operation will not work because the SHL instructions count is masked
2676cdedef59SAnirudh Venkataramanan 	 * to 5 bits so the shift will do nothing
2677cdedef59SAnirudh Venkataramanan 	 */
2678cdedef59SAnirudh Venkataramanan 	if (ce_info->width < 32)
2679cdedef59SAnirudh Venkataramanan 		mask = BIT(ce_info->width) - 1;
2680cdedef59SAnirudh Venkataramanan 	else
2681cdedef59SAnirudh Venkataramanan 		mask = (u32)~0;
2682cdedef59SAnirudh Venkataramanan 
2683cdedef59SAnirudh Venkataramanan 	/* don't swizzle the bits until after the mask because the mask bits
2684cdedef59SAnirudh Venkataramanan 	 * will be in a different bit position on big endian machines
2685cdedef59SAnirudh Venkataramanan 	 */
2686cdedef59SAnirudh Venkataramanan 	src_dword = *(u32 *)from;
2687cdedef59SAnirudh Venkataramanan 	src_dword &= mask;
2688cdedef59SAnirudh Venkataramanan 
2689cdedef59SAnirudh Venkataramanan 	/* shift to correct alignment */
2690cdedef59SAnirudh Venkataramanan 	mask <<= shift_width;
2691cdedef59SAnirudh Venkataramanan 	src_dword <<= shift_width;
2692cdedef59SAnirudh Venkataramanan 
2693cdedef59SAnirudh Venkataramanan 	/* get the current bits from the target bit string */
2694cdedef59SAnirudh Venkataramanan 	dest = dest_ctx + (ce_info->lsb / 8);
2695cdedef59SAnirudh Venkataramanan 
2696cdedef59SAnirudh Venkataramanan 	memcpy(&dest_dword, dest, sizeof(dest_dword));
2697cdedef59SAnirudh Venkataramanan 
2698cdedef59SAnirudh Venkataramanan 	dest_dword &= ~(cpu_to_le32(mask));	/* get the bits not changing */
2699cdedef59SAnirudh Venkataramanan 	dest_dword |= cpu_to_le32(src_dword);	/* add in the new bits */
2700cdedef59SAnirudh Venkataramanan 
2701cdedef59SAnirudh Venkataramanan 	/* put it all back */
2702cdedef59SAnirudh Venkataramanan 	memcpy(dest, &dest_dword, sizeof(dest_dword));
2703cdedef59SAnirudh Venkataramanan }
2704cdedef59SAnirudh Venkataramanan 
2705cdedef59SAnirudh Venkataramanan /**
2706cdedef59SAnirudh Venkataramanan  * ice_write_qword - write a qword to a packed context structure
2707cdedef59SAnirudh Venkataramanan  * @src_ctx:  the context structure to read from
2708cdedef59SAnirudh Venkataramanan  * @dest_ctx: the context to be written to
2709cdedef59SAnirudh Venkataramanan  * @ce_info:  a description of the struct to be filled
2710cdedef59SAnirudh Venkataramanan  */
2711c8b7abddSBruce Allan static void
2712c8b7abddSBruce Allan ice_write_qword(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
2713cdedef59SAnirudh Venkataramanan {
2714cdedef59SAnirudh Venkataramanan 	u64 src_qword, mask;
2715cdedef59SAnirudh Venkataramanan 	__le64 dest_qword;
2716cdedef59SAnirudh Venkataramanan 	u8 *from, *dest;
2717cdedef59SAnirudh Venkataramanan 	u16 shift_width;
2718cdedef59SAnirudh Venkataramanan 
2719cdedef59SAnirudh Venkataramanan 	/* copy from the next struct field */
2720cdedef59SAnirudh Venkataramanan 	from = src_ctx + ce_info->offset;
2721cdedef59SAnirudh Venkataramanan 
2722cdedef59SAnirudh Venkataramanan 	/* prepare the bits and mask */
2723cdedef59SAnirudh Venkataramanan 	shift_width = ce_info->lsb % 8;
2724cdedef59SAnirudh Venkataramanan 
2725cdedef59SAnirudh Venkataramanan 	/* if the field width is exactly 64 on an x86 machine, then the shift
2726cdedef59SAnirudh Venkataramanan 	 * operation will not work because the SHL instructions count is masked
2727cdedef59SAnirudh Venkataramanan 	 * to 6 bits so the shift will do nothing
2728cdedef59SAnirudh Venkataramanan 	 */
2729cdedef59SAnirudh Venkataramanan 	if (ce_info->width < 64)
2730cdedef59SAnirudh Venkataramanan 		mask = BIT_ULL(ce_info->width) - 1;
2731cdedef59SAnirudh Venkataramanan 	else
2732cdedef59SAnirudh Venkataramanan 		mask = (u64)~0;
2733cdedef59SAnirudh Venkataramanan 
2734cdedef59SAnirudh Venkataramanan 	/* don't swizzle the bits until after the mask because the mask bits
2735cdedef59SAnirudh Venkataramanan 	 * will be in a different bit position on big endian machines
2736cdedef59SAnirudh Venkataramanan 	 */
2737cdedef59SAnirudh Venkataramanan 	src_qword = *(u64 *)from;
2738cdedef59SAnirudh Venkataramanan 	src_qword &= mask;
2739cdedef59SAnirudh Venkataramanan 
2740cdedef59SAnirudh Venkataramanan 	/* shift to correct alignment */
2741cdedef59SAnirudh Venkataramanan 	mask <<= shift_width;
2742cdedef59SAnirudh Venkataramanan 	src_qword <<= shift_width;
2743cdedef59SAnirudh Venkataramanan 
2744cdedef59SAnirudh Venkataramanan 	/* get the current bits from the target bit string */
2745cdedef59SAnirudh Venkataramanan 	dest = dest_ctx + (ce_info->lsb / 8);
2746cdedef59SAnirudh Venkataramanan 
2747cdedef59SAnirudh Venkataramanan 	memcpy(&dest_qword, dest, sizeof(dest_qword));
2748cdedef59SAnirudh Venkataramanan 
2749cdedef59SAnirudh Venkataramanan 	dest_qword &= ~(cpu_to_le64(mask));	/* get the bits not changing */
2750cdedef59SAnirudh Venkataramanan 	dest_qword |= cpu_to_le64(src_qword);	/* add in the new bits */
2751cdedef59SAnirudh Venkataramanan 
2752cdedef59SAnirudh Venkataramanan 	/* put it all back */
2753cdedef59SAnirudh Venkataramanan 	memcpy(dest, &dest_qword, sizeof(dest_qword));
2754cdedef59SAnirudh Venkataramanan }
2755cdedef59SAnirudh Venkataramanan 
2756cdedef59SAnirudh Venkataramanan /**
2757cdedef59SAnirudh Venkataramanan  * ice_set_ctx - set context bits in packed structure
2758cdedef59SAnirudh Venkataramanan  * @src_ctx:  pointer to a generic non-packed context structure
2759cdedef59SAnirudh Venkataramanan  * @dest_ctx: pointer to memory for the packed structure
2760cdedef59SAnirudh Venkataramanan  * @ce_info:  a description of the structure to be transformed
2761cdedef59SAnirudh Venkataramanan  */
2762cdedef59SAnirudh Venkataramanan enum ice_status
2763cdedef59SAnirudh Venkataramanan ice_set_ctx(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
2764cdedef59SAnirudh Venkataramanan {
2765cdedef59SAnirudh Venkataramanan 	int f;
2766cdedef59SAnirudh Venkataramanan 
2767cdedef59SAnirudh Venkataramanan 	for (f = 0; ce_info[f].width; f++) {
2768cdedef59SAnirudh Venkataramanan 		/* We have to deal with each element of the FW response
2769cdedef59SAnirudh Venkataramanan 		 * using the correct size so that we are correct regardless
2770cdedef59SAnirudh Venkataramanan 		 * of the endianness of the machine.
2771cdedef59SAnirudh Venkataramanan 		 */
2772cdedef59SAnirudh Venkataramanan 		switch (ce_info[f].size_of) {
2773cdedef59SAnirudh Venkataramanan 		case sizeof(u8):
2774cdedef59SAnirudh Venkataramanan 			ice_write_byte(src_ctx, dest_ctx, &ce_info[f]);
2775cdedef59SAnirudh Venkataramanan 			break;
2776cdedef59SAnirudh Venkataramanan 		case sizeof(u16):
2777cdedef59SAnirudh Venkataramanan 			ice_write_word(src_ctx, dest_ctx, &ce_info[f]);
2778cdedef59SAnirudh Venkataramanan 			break;
2779cdedef59SAnirudh Venkataramanan 		case sizeof(u32):
2780cdedef59SAnirudh Venkataramanan 			ice_write_dword(src_ctx, dest_ctx, &ce_info[f]);
2781cdedef59SAnirudh Venkataramanan 			break;
2782cdedef59SAnirudh Venkataramanan 		case sizeof(u64):
2783cdedef59SAnirudh Venkataramanan 			ice_write_qword(src_ctx, dest_ctx, &ce_info[f]);
2784cdedef59SAnirudh Venkataramanan 			break;
2785cdedef59SAnirudh Venkataramanan 		default:
2786cdedef59SAnirudh Venkataramanan 			return ICE_ERR_INVAL_SIZE;
2787cdedef59SAnirudh Venkataramanan 		}
2788cdedef59SAnirudh Venkataramanan 	}
2789cdedef59SAnirudh Venkataramanan 
2790cdedef59SAnirudh Venkataramanan 	return 0;
2791cdedef59SAnirudh Venkataramanan }
2792cdedef59SAnirudh Venkataramanan 
2793cdedef59SAnirudh Venkataramanan /**
2794bb87ee0eSAnirudh Venkataramanan  * ice_get_lan_q_ctx - get the LAN queue context for the given VSI and TC
2795bb87ee0eSAnirudh Venkataramanan  * @hw: pointer to the HW struct
2796bb87ee0eSAnirudh Venkataramanan  * @vsi_handle: software VSI handle
2797bb87ee0eSAnirudh Venkataramanan  * @tc: TC number
2798bb87ee0eSAnirudh Venkataramanan  * @q_handle: software queue handle
2799bb87ee0eSAnirudh Venkataramanan  */
2800bb87ee0eSAnirudh Venkataramanan static struct ice_q_ctx *
2801bb87ee0eSAnirudh Venkataramanan ice_get_lan_q_ctx(struct ice_hw *hw, u16 vsi_handle, u8 tc, u16 q_handle)
2802bb87ee0eSAnirudh Venkataramanan {
2803bb87ee0eSAnirudh Venkataramanan 	struct ice_vsi_ctx *vsi;
2804bb87ee0eSAnirudh Venkataramanan 	struct ice_q_ctx *q_ctx;
2805bb87ee0eSAnirudh Venkataramanan 
2806bb87ee0eSAnirudh Venkataramanan 	vsi = ice_get_vsi_ctx(hw, vsi_handle);
2807bb87ee0eSAnirudh Venkataramanan 	if (!vsi)
2808bb87ee0eSAnirudh Venkataramanan 		return NULL;
2809bb87ee0eSAnirudh Venkataramanan 	if (q_handle >= vsi->num_lan_q_entries[tc])
2810bb87ee0eSAnirudh Venkataramanan 		return NULL;
2811bb87ee0eSAnirudh Venkataramanan 	if (!vsi->lan_q_ctx[tc])
2812bb87ee0eSAnirudh Venkataramanan 		return NULL;
2813bb87ee0eSAnirudh Venkataramanan 	q_ctx = vsi->lan_q_ctx[tc];
2814bb87ee0eSAnirudh Venkataramanan 	return &q_ctx[q_handle];
2815bb87ee0eSAnirudh Venkataramanan }
2816bb87ee0eSAnirudh Venkataramanan 
2817bb87ee0eSAnirudh Venkataramanan /**
2818cdedef59SAnirudh Venkataramanan  * ice_ena_vsi_txq
2819cdedef59SAnirudh Venkataramanan  * @pi: port information structure
28204fb33f31SAnirudh Venkataramanan  * @vsi_handle: software VSI handle
2821f9867df6SAnirudh Venkataramanan  * @tc: TC number
2822bb87ee0eSAnirudh Venkataramanan  * @q_handle: software queue handle
2823cdedef59SAnirudh Venkataramanan  * @num_qgrps: Number of added queue groups
2824cdedef59SAnirudh Venkataramanan  * @buf: list of queue groups to be added
2825cdedef59SAnirudh Venkataramanan  * @buf_size: size of buffer for indirect command
2826cdedef59SAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
2827cdedef59SAnirudh Venkataramanan  *
2828f9867df6SAnirudh Venkataramanan  * This function adds one LAN queue
2829cdedef59SAnirudh Venkataramanan  */
2830cdedef59SAnirudh Venkataramanan enum ice_status
2831bb87ee0eSAnirudh Venkataramanan ice_ena_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u16 q_handle,
2832bb87ee0eSAnirudh Venkataramanan 		u8 num_qgrps, struct ice_aqc_add_tx_qgrp *buf, u16 buf_size,
2833cdedef59SAnirudh Venkataramanan 		struct ice_sq_cd *cd)
2834cdedef59SAnirudh Venkataramanan {
2835cdedef59SAnirudh Venkataramanan 	struct ice_aqc_txsched_elem_data node = { 0 };
2836cdedef59SAnirudh Venkataramanan 	struct ice_sched_node *parent;
2837bb87ee0eSAnirudh Venkataramanan 	struct ice_q_ctx *q_ctx;
2838cdedef59SAnirudh Venkataramanan 	enum ice_status status;
2839cdedef59SAnirudh Venkataramanan 	struct ice_hw *hw;
2840cdedef59SAnirudh Venkataramanan 
2841cdedef59SAnirudh Venkataramanan 	if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY)
2842cdedef59SAnirudh Venkataramanan 		return ICE_ERR_CFG;
2843cdedef59SAnirudh Venkataramanan 
2844cdedef59SAnirudh Venkataramanan 	if (num_qgrps > 1 || buf->num_txqs > 1)
2845cdedef59SAnirudh Venkataramanan 		return ICE_ERR_MAX_LIMIT;
2846cdedef59SAnirudh Venkataramanan 
2847cdedef59SAnirudh Venkataramanan 	hw = pi->hw;
2848cdedef59SAnirudh Venkataramanan 
28494fb33f31SAnirudh Venkataramanan 	if (!ice_is_vsi_valid(hw, vsi_handle))
28504fb33f31SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
28514fb33f31SAnirudh Venkataramanan 
2852cdedef59SAnirudh Venkataramanan 	mutex_lock(&pi->sched_lock);
2853cdedef59SAnirudh Venkataramanan 
2854bb87ee0eSAnirudh Venkataramanan 	q_ctx = ice_get_lan_q_ctx(hw, vsi_handle, tc, q_handle);
2855bb87ee0eSAnirudh Venkataramanan 	if (!q_ctx) {
2856bb87ee0eSAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_SCHED, "Enaq: invalid queue handle %d\n",
2857bb87ee0eSAnirudh Venkataramanan 			  q_handle);
2858bb87ee0eSAnirudh Venkataramanan 		status = ICE_ERR_PARAM;
2859bb87ee0eSAnirudh Venkataramanan 		goto ena_txq_exit;
2860bb87ee0eSAnirudh Venkataramanan 	}
2861bb87ee0eSAnirudh Venkataramanan 
2862cdedef59SAnirudh Venkataramanan 	/* find a parent node */
28634fb33f31SAnirudh Venkataramanan 	parent = ice_sched_get_free_qparent(pi, vsi_handle, tc,
2864cdedef59SAnirudh Venkataramanan 					    ICE_SCHED_NODE_OWNER_LAN);
2865cdedef59SAnirudh Venkataramanan 	if (!parent) {
2866cdedef59SAnirudh Venkataramanan 		status = ICE_ERR_PARAM;
2867cdedef59SAnirudh Venkataramanan 		goto ena_txq_exit;
2868cdedef59SAnirudh Venkataramanan 	}
28694fb33f31SAnirudh Venkataramanan 
2870cdedef59SAnirudh Venkataramanan 	buf->parent_teid = parent->info.node_teid;
2871cdedef59SAnirudh Venkataramanan 	node.parent_teid = parent->info.node_teid;
2872cdedef59SAnirudh Venkataramanan 	/* Mark that the values in the "generic" section as valid. The default
2873cdedef59SAnirudh Venkataramanan 	 * value in the "generic" section is zero. This means that :
2874cdedef59SAnirudh Venkataramanan 	 * - Scheduling mode is Bytes Per Second (BPS), indicated by Bit 0.
2875cdedef59SAnirudh Venkataramanan 	 * - 0 priority among siblings, indicated by Bit 1-3.
2876cdedef59SAnirudh Venkataramanan 	 * - WFQ, indicated by Bit 4.
2877cdedef59SAnirudh Venkataramanan 	 * - 0 Adjustment value is used in PSM credit update flow, indicated by
2878cdedef59SAnirudh Venkataramanan 	 * Bit 5-6.
2879cdedef59SAnirudh Venkataramanan 	 * - Bit 7 is reserved.
2880cdedef59SAnirudh Venkataramanan 	 * Without setting the generic section as valid in valid_sections, the
2881f9867df6SAnirudh Venkataramanan 	 * Admin queue command will fail with error code ICE_AQ_RC_EINVAL.
2882cdedef59SAnirudh Venkataramanan 	 */
2883cdedef59SAnirudh Venkataramanan 	buf->txqs[0].info.valid_sections = ICE_AQC_ELEM_VALID_GENERIC;
2884cdedef59SAnirudh Venkataramanan 
2885f9867df6SAnirudh Venkataramanan 	/* add the LAN queue */
2886cdedef59SAnirudh Venkataramanan 	status = ice_aq_add_lan_txq(hw, num_qgrps, buf, buf_size, cd);
28876e9650d5SVictor Raj 	if (status) {
2888bb87ee0eSAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_SCHED, "enable queue %d failed %d\n",
28896e9650d5SVictor Raj 			  le16_to_cpu(buf->txqs[0].txq_id),
28906e9650d5SVictor Raj 			  hw->adminq.sq_last_status);
2891cdedef59SAnirudh Venkataramanan 		goto ena_txq_exit;
28926e9650d5SVictor Raj 	}
2893cdedef59SAnirudh Venkataramanan 
2894cdedef59SAnirudh Venkataramanan 	node.node_teid = buf->txqs[0].q_teid;
2895cdedef59SAnirudh Venkataramanan 	node.data.elem_type = ICE_AQC_ELEM_TYPE_LEAF;
2896bb87ee0eSAnirudh Venkataramanan 	q_ctx->q_handle = q_handle;
2897cdedef59SAnirudh Venkataramanan 
2898f9867df6SAnirudh Venkataramanan 	/* add a leaf node into schduler tree queue layer */
2899cdedef59SAnirudh Venkataramanan 	status = ice_sched_add_node(pi, hw->num_tx_sched_layers - 1, &node);
2900cdedef59SAnirudh Venkataramanan 
2901cdedef59SAnirudh Venkataramanan ena_txq_exit:
2902cdedef59SAnirudh Venkataramanan 	mutex_unlock(&pi->sched_lock);
2903cdedef59SAnirudh Venkataramanan 	return status;
2904cdedef59SAnirudh Venkataramanan }
2905cdedef59SAnirudh Venkataramanan 
2906cdedef59SAnirudh Venkataramanan /**
2907cdedef59SAnirudh Venkataramanan  * ice_dis_vsi_txq
2908cdedef59SAnirudh Venkataramanan  * @pi: port information structure
2909bb87ee0eSAnirudh Venkataramanan  * @vsi_handle: software VSI handle
2910bb87ee0eSAnirudh Venkataramanan  * @tc: TC number
2911cdedef59SAnirudh Venkataramanan  * @num_queues: number of queues
2912bb87ee0eSAnirudh Venkataramanan  * @q_handles: pointer to software queue handle array
2913cdedef59SAnirudh Venkataramanan  * @q_ids: pointer to the q_id array
2914cdedef59SAnirudh Venkataramanan  * @q_teids: pointer to queue node teids
291594c4441bSAnirudh Venkataramanan  * @rst_src: if called due to reset, specifies the reset source
2916ddf30f7fSAnirudh Venkataramanan  * @vmvf_num: the relative VM or VF number that is undergoing the reset
2917cdedef59SAnirudh Venkataramanan  * @cd: pointer to command details structure or NULL
2918cdedef59SAnirudh Venkataramanan  *
2919cdedef59SAnirudh Venkataramanan  * This function removes queues and their corresponding nodes in SW DB
2920cdedef59SAnirudh Venkataramanan  */
2921cdedef59SAnirudh Venkataramanan enum ice_status
2922bb87ee0eSAnirudh Venkataramanan ice_dis_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u8 num_queues,
2923bb87ee0eSAnirudh Venkataramanan 		u16 *q_handles, u16 *q_ids, u32 *q_teids,
2924bb87ee0eSAnirudh Venkataramanan 		enum ice_disq_rst_src rst_src, u16 vmvf_num,
2925ddf30f7fSAnirudh Venkataramanan 		struct ice_sq_cd *cd)
2926cdedef59SAnirudh Venkataramanan {
2927cdedef59SAnirudh Venkataramanan 	enum ice_status status = ICE_ERR_DOES_NOT_EXIST;
2928cdedef59SAnirudh Venkataramanan 	struct ice_aqc_dis_txq_item qg_list;
2929bb87ee0eSAnirudh Venkataramanan 	struct ice_q_ctx *q_ctx;
2930cdedef59SAnirudh Venkataramanan 	u16 i;
2931cdedef59SAnirudh Venkataramanan 
2932cdedef59SAnirudh Venkataramanan 	if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY)
2933cdedef59SAnirudh Venkataramanan 		return ICE_ERR_CFG;
2934cdedef59SAnirudh Venkataramanan 
2935ddf30f7fSAnirudh Venkataramanan 
293685796d6eSAkeem G Abodunrin 	if (!num_queues) {
293785796d6eSAkeem G Abodunrin 		/* if queue is disabled already yet the disable queue command
293885796d6eSAkeem G Abodunrin 		 * has to be sent to complete the VF reset, then call
293985796d6eSAkeem G Abodunrin 		 * ice_aq_dis_lan_txq without any queue information
294085796d6eSAkeem G Abodunrin 		 */
294185796d6eSAkeem G Abodunrin 		if (rst_src)
294285796d6eSAkeem G Abodunrin 			return ice_aq_dis_lan_txq(pi->hw, 0, NULL, 0, rst_src,
294385796d6eSAkeem G Abodunrin 						  vmvf_num, NULL);
294485796d6eSAkeem G Abodunrin 		return ICE_ERR_CFG;
294585796d6eSAkeem G Abodunrin 	}
2946ddf30f7fSAnirudh Venkataramanan 
2947cdedef59SAnirudh Venkataramanan 	mutex_lock(&pi->sched_lock);
2948cdedef59SAnirudh Venkataramanan 
2949cdedef59SAnirudh Venkataramanan 	for (i = 0; i < num_queues; i++) {
2950cdedef59SAnirudh Venkataramanan 		struct ice_sched_node *node;
2951cdedef59SAnirudh Venkataramanan 
2952cdedef59SAnirudh Venkataramanan 		node = ice_sched_find_node_by_teid(pi->root, q_teids[i]);
2953cdedef59SAnirudh Venkataramanan 		if (!node)
2954cdedef59SAnirudh Venkataramanan 			continue;
2955bb87ee0eSAnirudh Venkataramanan 		q_ctx = ice_get_lan_q_ctx(pi->hw, vsi_handle, tc, q_handles[i]);
2956bb87ee0eSAnirudh Venkataramanan 		if (!q_ctx) {
2957bb87ee0eSAnirudh Venkataramanan 			ice_debug(pi->hw, ICE_DBG_SCHED, "invalid queue handle%d\n",
2958bb87ee0eSAnirudh Venkataramanan 				  q_handles[i]);
2959bb87ee0eSAnirudh Venkataramanan 			continue;
2960bb87ee0eSAnirudh Venkataramanan 		}
2961bb87ee0eSAnirudh Venkataramanan 		if (q_ctx->q_handle != q_handles[i]) {
2962bb87ee0eSAnirudh Venkataramanan 			ice_debug(pi->hw, ICE_DBG_SCHED, "Err:handles %d %d\n",
2963bb87ee0eSAnirudh Venkataramanan 				  q_ctx->q_handle, q_handles[i]);
2964bb87ee0eSAnirudh Venkataramanan 			continue;
2965bb87ee0eSAnirudh Venkataramanan 		}
2966cdedef59SAnirudh Venkataramanan 		qg_list.parent_teid = node->info.parent_teid;
2967cdedef59SAnirudh Venkataramanan 		qg_list.num_qs = 1;
2968cdedef59SAnirudh Venkataramanan 		qg_list.q_id[0] = cpu_to_le16(q_ids[i]);
2969cdedef59SAnirudh Venkataramanan 		status = ice_aq_dis_lan_txq(pi->hw, 1, &qg_list,
2970ddf30f7fSAnirudh Venkataramanan 					    sizeof(qg_list), rst_src, vmvf_num,
2971ddf30f7fSAnirudh Venkataramanan 					    cd);
2972cdedef59SAnirudh Venkataramanan 
2973cdedef59SAnirudh Venkataramanan 		if (status)
2974cdedef59SAnirudh Venkataramanan 			break;
2975cdedef59SAnirudh Venkataramanan 		ice_free_sched_node(pi, node);
2976bb87ee0eSAnirudh Venkataramanan 		q_ctx->q_handle = ICE_INVAL_Q_HANDLE;
2977cdedef59SAnirudh Venkataramanan 	}
2978cdedef59SAnirudh Venkataramanan 	mutex_unlock(&pi->sched_lock);
2979cdedef59SAnirudh Venkataramanan 	return status;
2980cdedef59SAnirudh Venkataramanan }
29815513b920SAnirudh Venkataramanan 
29825513b920SAnirudh Venkataramanan /**
298394c4441bSAnirudh Venkataramanan  * ice_cfg_vsi_qs - configure the new/existing VSI queues
29845513b920SAnirudh Venkataramanan  * @pi: port information structure
29854fb33f31SAnirudh Venkataramanan  * @vsi_handle: software VSI handle
29865513b920SAnirudh Venkataramanan  * @tc_bitmap: TC bitmap
29875513b920SAnirudh Venkataramanan  * @maxqs: max queues array per TC
2988f9867df6SAnirudh Venkataramanan  * @owner: LAN or RDMA
29895513b920SAnirudh Venkataramanan  *
29905513b920SAnirudh Venkataramanan  * This function adds/updates the VSI queues per TC.
29915513b920SAnirudh Venkataramanan  */
29925513b920SAnirudh Venkataramanan static enum ice_status
29934fb33f31SAnirudh Venkataramanan ice_cfg_vsi_qs(struct ice_port_info *pi, u16 vsi_handle, u8 tc_bitmap,
29945513b920SAnirudh Venkataramanan 	       u16 *maxqs, u8 owner)
29955513b920SAnirudh Venkataramanan {
29965513b920SAnirudh Venkataramanan 	enum ice_status status = 0;
29975513b920SAnirudh Venkataramanan 	u8 i;
29985513b920SAnirudh Venkataramanan 
29995513b920SAnirudh Venkataramanan 	if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY)
30005513b920SAnirudh Venkataramanan 		return ICE_ERR_CFG;
30015513b920SAnirudh Venkataramanan 
30024fb33f31SAnirudh Venkataramanan 	if (!ice_is_vsi_valid(pi->hw, vsi_handle))
30034fb33f31SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
30044fb33f31SAnirudh Venkataramanan 
30055513b920SAnirudh Venkataramanan 	mutex_lock(&pi->sched_lock);
30065513b920SAnirudh Venkataramanan 
30072bdc97beSBruce Allan 	ice_for_each_traffic_class(i) {
30085513b920SAnirudh Venkataramanan 		/* configuration is possible only if TC node is present */
30095513b920SAnirudh Venkataramanan 		if (!ice_sched_get_tc_node(pi, i))
30105513b920SAnirudh Venkataramanan 			continue;
30115513b920SAnirudh Venkataramanan 
30124fb33f31SAnirudh Venkataramanan 		status = ice_sched_cfg_vsi(pi, vsi_handle, i, maxqs[i], owner,
30135513b920SAnirudh Venkataramanan 					   ice_is_tc_ena(tc_bitmap, i));
30145513b920SAnirudh Venkataramanan 		if (status)
30155513b920SAnirudh Venkataramanan 			break;
30165513b920SAnirudh Venkataramanan 	}
30175513b920SAnirudh Venkataramanan 
30185513b920SAnirudh Venkataramanan 	mutex_unlock(&pi->sched_lock);
30195513b920SAnirudh Venkataramanan 	return status;
30205513b920SAnirudh Venkataramanan }
30215513b920SAnirudh Venkataramanan 
30225513b920SAnirudh Venkataramanan /**
3023f9867df6SAnirudh Venkataramanan  * ice_cfg_vsi_lan - configure VSI LAN queues
30245513b920SAnirudh Venkataramanan  * @pi: port information structure
30254fb33f31SAnirudh Venkataramanan  * @vsi_handle: software VSI handle
30265513b920SAnirudh Venkataramanan  * @tc_bitmap: TC bitmap
3027f9867df6SAnirudh Venkataramanan  * @max_lanqs: max LAN queues array per TC
30285513b920SAnirudh Venkataramanan  *
3029f9867df6SAnirudh Venkataramanan  * This function adds/updates the VSI LAN queues per TC.
30305513b920SAnirudh Venkataramanan  */
30315513b920SAnirudh Venkataramanan enum ice_status
30324fb33f31SAnirudh Venkataramanan ice_cfg_vsi_lan(struct ice_port_info *pi, u16 vsi_handle, u8 tc_bitmap,
30335513b920SAnirudh Venkataramanan 		u16 *max_lanqs)
30345513b920SAnirudh Venkataramanan {
30354fb33f31SAnirudh Venkataramanan 	return ice_cfg_vsi_qs(pi, vsi_handle, tc_bitmap, max_lanqs,
30365513b920SAnirudh Venkataramanan 			      ICE_SCHED_NODE_OWNER_LAN);
30375513b920SAnirudh Venkataramanan }
303845d3d428SAnirudh Venkataramanan 
303945d3d428SAnirudh Venkataramanan /**
3040334cb062SAnirudh Venkataramanan  * ice_replay_pre_init - replay pre initialization
3041f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
3042334cb062SAnirudh Venkataramanan  *
3043334cb062SAnirudh Venkataramanan  * Initializes required config data for VSI, FD, ACL, and RSS before replay.
3044334cb062SAnirudh Venkataramanan  */
3045334cb062SAnirudh Venkataramanan static enum ice_status ice_replay_pre_init(struct ice_hw *hw)
3046334cb062SAnirudh Venkataramanan {
3047334cb062SAnirudh Venkataramanan 	struct ice_switch_info *sw = hw->switch_info;
3048334cb062SAnirudh Venkataramanan 	u8 i;
3049334cb062SAnirudh Venkataramanan 
3050334cb062SAnirudh Venkataramanan 	/* Delete old entries from replay filter list head if there is any */
3051334cb062SAnirudh Venkataramanan 	ice_rm_all_sw_replay_rule_info(hw);
3052334cb062SAnirudh Venkataramanan 	/* In start of replay, move entries into replay_rules list, it
3053334cb062SAnirudh Venkataramanan 	 * will allow adding rules entries back to filt_rules list,
3054334cb062SAnirudh Venkataramanan 	 * which is operational list.
3055334cb062SAnirudh Venkataramanan 	 */
3056334cb062SAnirudh Venkataramanan 	for (i = 0; i < ICE_SW_LKUP_LAST; i++)
3057334cb062SAnirudh Venkataramanan 		list_replace_init(&sw->recp_list[i].filt_rules,
3058334cb062SAnirudh Venkataramanan 				  &sw->recp_list[i].filt_replay_rules);
3059334cb062SAnirudh Venkataramanan 
3060334cb062SAnirudh Venkataramanan 	return 0;
3061334cb062SAnirudh Venkataramanan }
3062334cb062SAnirudh Venkataramanan 
3063334cb062SAnirudh Venkataramanan /**
3064334cb062SAnirudh Venkataramanan  * ice_replay_vsi - replay VSI configuration
3065f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
3066334cb062SAnirudh Venkataramanan  * @vsi_handle: driver VSI handle
3067334cb062SAnirudh Venkataramanan  *
3068334cb062SAnirudh Venkataramanan  * Restore all VSI configuration after reset. It is required to call this
3069334cb062SAnirudh Venkataramanan  * function with main VSI first.
3070334cb062SAnirudh Venkataramanan  */
3071334cb062SAnirudh Venkataramanan enum ice_status ice_replay_vsi(struct ice_hw *hw, u16 vsi_handle)
3072334cb062SAnirudh Venkataramanan {
3073334cb062SAnirudh Venkataramanan 	enum ice_status status;
3074334cb062SAnirudh Venkataramanan 
3075334cb062SAnirudh Venkataramanan 	if (!ice_is_vsi_valid(hw, vsi_handle))
3076334cb062SAnirudh Venkataramanan 		return ICE_ERR_PARAM;
3077334cb062SAnirudh Venkataramanan 
3078334cb062SAnirudh Venkataramanan 	/* Replay pre-initialization if there is any */
3079334cb062SAnirudh Venkataramanan 	if (vsi_handle == ICE_MAIN_VSI_HANDLE) {
3080334cb062SAnirudh Venkataramanan 		status = ice_replay_pre_init(hw);
3081334cb062SAnirudh Venkataramanan 		if (status)
3082334cb062SAnirudh Venkataramanan 			return status;
3083334cb062SAnirudh Venkataramanan 	}
3084334cb062SAnirudh Venkataramanan 
3085334cb062SAnirudh Venkataramanan 	/* Replay per VSI all filters */
3086334cb062SAnirudh Venkataramanan 	status = ice_replay_vsi_all_fltr(hw, vsi_handle);
3087334cb062SAnirudh Venkataramanan 	return status;
3088334cb062SAnirudh Venkataramanan }
3089334cb062SAnirudh Venkataramanan 
3090334cb062SAnirudh Venkataramanan /**
3091334cb062SAnirudh Venkataramanan  * ice_replay_post - post replay configuration cleanup
3092f9867df6SAnirudh Venkataramanan  * @hw: pointer to the HW struct
3093334cb062SAnirudh Venkataramanan  *
3094334cb062SAnirudh Venkataramanan  * Post replay cleanup.
3095334cb062SAnirudh Venkataramanan  */
3096334cb062SAnirudh Venkataramanan void ice_replay_post(struct ice_hw *hw)
3097334cb062SAnirudh Venkataramanan {
3098334cb062SAnirudh Venkataramanan 	/* Delete old entries from replay filter list head */
3099334cb062SAnirudh Venkataramanan 	ice_rm_all_sw_replay_rule_info(hw);
3100334cb062SAnirudh Venkataramanan }
3101334cb062SAnirudh Venkataramanan 
3102334cb062SAnirudh Venkataramanan /**
310345d3d428SAnirudh Venkataramanan  * ice_stat_update40 - read 40 bit stat from the chip and update stat values
310445d3d428SAnirudh Venkataramanan  * @hw: ptr to the hardware info
310545d3d428SAnirudh Venkataramanan  * @hireg: high 32 bit HW register to read from
310645d3d428SAnirudh Venkataramanan  * @loreg: low 32 bit HW register to read from
310745d3d428SAnirudh Venkataramanan  * @prev_stat_loaded: bool to specify if previous stats are loaded
310845d3d428SAnirudh Venkataramanan  * @prev_stat: ptr to previous loaded stat value
310945d3d428SAnirudh Venkataramanan  * @cur_stat: ptr to current stat value
311045d3d428SAnirudh Venkataramanan  */
3111c8b7abddSBruce Allan void
3112c8b7abddSBruce Allan ice_stat_update40(struct ice_hw *hw, u32 hireg, u32 loreg,
311345d3d428SAnirudh Venkataramanan 		  bool prev_stat_loaded, u64 *prev_stat, u64 *cur_stat)
311445d3d428SAnirudh Venkataramanan {
311545d3d428SAnirudh Venkataramanan 	u64 new_data;
311645d3d428SAnirudh Venkataramanan 
311745d3d428SAnirudh Venkataramanan 	new_data = rd32(hw, loreg);
311845d3d428SAnirudh Venkataramanan 	new_data |= ((u64)(rd32(hw, hireg) & 0xFFFF)) << 32;
311945d3d428SAnirudh Venkataramanan 
312045d3d428SAnirudh Venkataramanan 	/* device stats are not reset at PFR, they likely will not be zeroed
312145d3d428SAnirudh Venkataramanan 	 * when the driver starts. So save the first values read and use them as
312245d3d428SAnirudh Venkataramanan 	 * offsets to be subtracted from the raw values in order to report stats
312345d3d428SAnirudh Venkataramanan 	 * that count from zero.
312445d3d428SAnirudh Venkataramanan 	 */
312545d3d428SAnirudh Venkataramanan 	if (!prev_stat_loaded)
312645d3d428SAnirudh Venkataramanan 		*prev_stat = new_data;
312745d3d428SAnirudh Venkataramanan 	if (new_data >= *prev_stat)
312845d3d428SAnirudh Venkataramanan 		*cur_stat = new_data - *prev_stat;
312945d3d428SAnirudh Venkataramanan 	else
313045d3d428SAnirudh Venkataramanan 		/* to manage the potential roll-over */
313145d3d428SAnirudh Venkataramanan 		*cur_stat = (new_data + BIT_ULL(40)) - *prev_stat;
313245d3d428SAnirudh Venkataramanan 	*cur_stat &= 0xFFFFFFFFFFULL;
313345d3d428SAnirudh Venkataramanan }
313445d3d428SAnirudh Venkataramanan 
313545d3d428SAnirudh Venkataramanan /**
313645d3d428SAnirudh Venkataramanan  * ice_stat_update32 - read 32 bit stat from the chip and update stat values
313745d3d428SAnirudh Venkataramanan  * @hw: ptr to the hardware info
313845d3d428SAnirudh Venkataramanan  * @reg: HW register to read from
313945d3d428SAnirudh Venkataramanan  * @prev_stat_loaded: bool to specify if previous stats are loaded
314045d3d428SAnirudh Venkataramanan  * @prev_stat: ptr to previous loaded stat value
314145d3d428SAnirudh Venkataramanan  * @cur_stat: ptr to current stat value
314245d3d428SAnirudh Venkataramanan  */
3143c8b7abddSBruce Allan void
3144c8b7abddSBruce Allan ice_stat_update32(struct ice_hw *hw, u32 reg, bool prev_stat_loaded,
314545d3d428SAnirudh Venkataramanan 		  u64 *prev_stat, u64 *cur_stat)
314645d3d428SAnirudh Venkataramanan {
314745d3d428SAnirudh Venkataramanan 	u32 new_data;
314845d3d428SAnirudh Venkataramanan 
314945d3d428SAnirudh Venkataramanan 	new_data = rd32(hw, reg);
315045d3d428SAnirudh Venkataramanan 
315145d3d428SAnirudh Venkataramanan 	/* device stats are not reset at PFR, they likely will not be zeroed
315245d3d428SAnirudh Venkataramanan 	 * when the driver starts. So save the first values read and use them as
315345d3d428SAnirudh Venkataramanan 	 * offsets to be subtracted from the raw values in order to report stats
315445d3d428SAnirudh Venkataramanan 	 * that count from zero.
315545d3d428SAnirudh Venkataramanan 	 */
315645d3d428SAnirudh Venkataramanan 	if (!prev_stat_loaded)
315745d3d428SAnirudh Venkataramanan 		*prev_stat = new_data;
315845d3d428SAnirudh Venkataramanan 	if (new_data >= *prev_stat)
315945d3d428SAnirudh Venkataramanan 		*cur_stat = new_data - *prev_stat;
316045d3d428SAnirudh Venkataramanan 	else
316145d3d428SAnirudh Venkataramanan 		/* to manage the potential roll-over */
316245d3d428SAnirudh Venkataramanan 		*cur_stat = (new_data + BIT_ULL(32)) - *prev_stat;
316345d3d428SAnirudh Venkataramanan }
31647b9ffc76SAnirudh Venkataramanan 
31657b9ffc76SAnirudh Venkataramanan /**
31667b9ffc76SAnirudh Venkataramanan  * ice_sched_query_elem - query element information from HW
31677b9ffc76SAnirudh Venkataramanan  * @hw: pointer to the HW struct
31687b9ffc76SAnirudh Venkataramanan  * @node_teid: node TEID to be queried
31697b9ffc76SAnirudh Venkataramanan  * @buf: buffer to element information
31707b9ffc76SAnirudh Venkataramanan  *
31717b9ffc76SAnirudh Venkataramanan  * This function queries HW element information
31727b9ffc76SAnirudh Venkataramanan  */
31737b9ffc76SAnirudh Venkataramanan enum ice_status
31747b9ffc76SAnirudh Venkataramanan ice_sched_query_elem(struct ice_hw *hw, u32 node_teid,
31757b9ffc76SAnirudh Venkataramanan 		     struct ice_aqc_get_elem *buf)
31767b9ffc76SAnirudh Venkataramanan {
31777b9ffc76SAnirudh Venkataramanan 	u16 buf_size, num_elem_ret = 0;
31787b9ffc76SAnirudh Venkataramanan 	enum ice_status status;
31797b9ffc76SAnirudh Venkataramanan 
31807b9ffc76SAnirudh Venkataramanan 	buf_size = sizeof(*buf);
31817b9ffc76SAnirudh Venkataramanan 	memset(buf, 0, buf_size);
31827b9ffc76SAnirudh Venkataramanan 	buf->generic[0].node_teid = cpu_to_le32(node_teid);
31837b9ffc76SAnirudh Venkataramanan 	status = ice_aq_query_sched_elems(hw, 1, buf, buf_size, &num_elem_ret,
31847b9ffc76SAnirudh Venkataramanan 					  NULL);
31857b9ffc76SAnirudh Venkataramanan 	if (status || num_elem_ret != 1)
31867b9ffc76SAnirudh Venkataramanan 		ice_debug(hw, ICE_DBG_SCHED, "query element failed\n");
31877b9ffc76SAnirudh Venkataramanan 	return status;
31887b9ffc76SAnirudh Venkataramanan }
3189