Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2001-2023 Intel Corporation
3 : : */
4 : :
5 : : #include "ice_common.h"
6 : : #include "ice_sched.h"
7 : : #include "ice_adminq_cmd.h"
8 : : #include "ice_flow.h"
9 : : #include "ice_ptp_hw.h"
10 : : #include "ice_switch.h"
11 : :
12 : : #define ICE_PF_RESET_WAIT_COUNT 500
13 : :
14 : : static const char * const ice_link_mode_str_low[] = {
15 : : ice_arr_elem_idx(0, "100BASE_TX"),
16 : : ice_arr_elem_idx(1, "100M_SGMII"),
17 : : ice_arr_elem_idx(2, "1000BASE_T"),
18 : : ice_arr_elem_idx(3, "1000BASE_SX"),
19 : : ice_arr_elem_idx(4, "1000BASE_LX"),
20 : : ice_arr_elem_idx(5, "1000BASE_KX"),
21 : : ice_arr_elem_idx(6, "1G_SGMII"),
22 : : ice_arr_elem_idx(7, "2500BASE_T"),
23 : : ice_arr_elem_idx(8, "2500BASE_X"),
24 : : ice_arr_elem_idx(9, "2500BASE_KX"),
25 : : ice_arr_elem_idx(10, "5GBASE_T"),
26 : : ice_arr_elem_idx(11, "5GBASE_KR"),
27 : : ice_arr_elem_idx(12, "10GBASE_T"),
28 : : ice_arr_elem_idx(13, "10G_SFI_DA"),
29 : : ice_arr_elem_idx(14, "10GBASE_SR"),
30 : : ice_arr_elem_idx(15, "10GBASE_LR"),
31 : : ice_arr_elem_idx(16, "10GBASE_KR_CR1"),
32 : : ice_arr_elem_idx(17, "10G_SFI_AOC_ACC"),
33 : : ice_arr_elem_idx(18, "10G_SFI_C2C"),
34 : : ice_arr_elem_idx(19, "25GBASE_T"),
35 : : ice_arr_elem_idx(20, "25GBASE_CR"),
36 : : ice_arr_elem_idx(21, "25GBASE_CR_S"),
37 : : ice_arr_elem_idx(22, "25GBASE_CR1"),
38 : : ice_arr_elem_idx(23, "25GBASE_SR"),
39 : : ice_arr_elem_idx(24, "25GBASE_LR"),
40 : : ice_arr_elem_idx(25, "25GBASE_KR"),
41 : : ice_arr_elem_idx(26, "25GBASE_KR_S"),
42 : : ice_arr_elem_idx(27, "25GBASE_KR1"),
43 : : ice_arr_elem_idx(28, "25G_AUI_AOC_ACC"),
44 : : ice_arr_elem_idx(29, "25G_AUI_C2C"),
45 : : ice_arr_elem_idx(30, "40GBASE_CR4"),
46 : : ice_arr_elem_idx(31, "40GBASE_SR4"),
47 : : ice_arr_elem_idx(32, "40GBASE_LR4"),
48 : : ice_arr_elem_idx(33, "40GBASE_KR4"),
49 : : ice_arr_elem_idx(34, "40G_XLAUI_AOC_ACC"),
50 : : ice_arr_elem_idx(35, "40G_XLAUI"),
51 : : ice_arr_elem_idx(36, "50GBASE_CR2"),
52 : : ice_arr_elem_idx(37, "50GBASE_SR2"),
53 : : ice_arr_elem_idx(38, "50GBASE_LR2"),
54 : : ice_arr_elem_idx(39, "50GBASE_KR2"),
55 : : ice_arr_elem_idx(40, "50G_LAUI2_AOC_ACC"),
56 : : ice_arr_elem_idx(41, "50G_LAUI2"),
57 : : ice_arr_elem_idx(42, "50G_AUI2_AOC_ACC"),
58 : : ice_arr_elem_idx(43, "50G_AUI2"),
59 : : ice_arr_elem_idx(44, "50GBASE_CP"),
60 : : ice_arr_elem_idx(45, "50GBASE_SR"),
61 : : ice_arr_elem_idx(46, "50GBASE_FR"),
62 : : ice_arr_elem_idx(47, "50GBASE_LR"),
63 : : ice_arr_elem_idx(48, "50GBASE_KR_PAM4"),
64 : : ice_arr_elem_idx(49, "50G_AUI1_AOC_ACC"),
65 : : ice_arr_elem_idx(50, "50G_AUI1"),
66 : : ice_arr_elem_idx(51, "100GBASE_CR4"),
67 : : ice_arr_elem_idx(52, "100GBASE_SR4"),
68 : : ice_arr_elem_idx(53, "100GBASE_LR4"),
69 : : ice_arr_elem_idx(54, "100GBASE_KR4"),
70 : : ice_arr_elem_idx(55, "100G_CAUI4_AOC_ACC"),
71 : : ice_arr_elem_idx(56, "100G_CAUI4"),
72 : : ice_arr_elem_idx(57, "100G_AUI4_AOC_ACC"),
73 : : ice_arr_elem_idx(58, "100G_AUI4"),
74 : : ice_arr_elem_idx(59, "100GBASE_CR_PAM4"),
75 : : ice_arr_elem_idx(60, "100GBASE_KR_PAM4"),
76 : : ice_arr_elem_idx(61, "100GBASE_CP2"),
77 : : ice_arr_elem_idx(62, "100GBASE_SR2"),
78 : : ice_arr_elem_idx(63, "100GBASE_DR"),
79 : : };
80 : :
81 : : static const char * const ice_link_mode_str_high[] = {
82 : : ice_arr_elem_idx(0, "100GBASE_KR2_PAM4"),
83 : : ice_arr_elem_idx(1, "100G_CAUI2_AOC_ACC"),
84 : : ice_arr_elem_idx(2, "100G_CAUI2"),
85 : : ice_arr_elem_idx(3, "100G_AUI2_AOC_ACC"),
86 : : ice_arr_elem_idx(4, "100G_AUI2"),
87 : : ice_arr_elem_idx(5, "200G_CR4_PAM4"),
88 : : ice_arr_elem_idx(6, "200G_SR4"),
89 : : ice_arr_elem_idx(7, "200G_FR4"),
90 : : ice_arr_elem_idx(8, "200G_LR4"),
91 : : ice_arr_elem_idx(9, "200G_DR4"),
92 : : ice_arr_elem_idx(10, "200G_KR4_PAM4"),
93 : : ice_arr_elem_idx(11, "200G_AUI4_AOC_ACC"),
94 : : ice_arr_elem_idx(12, "200G_AUI4"),
95 : : ice_arr_elem_idx(13, "200G_AUI8_AOC_ACC"),
96 : : ice_arr_elem_idx(14, "200G_AUI8"),
97 : : ice_arr_elem_idx(15, "400GBASE_FR8"),
98 : : };
99 : :
100 : : /**
101 : : * ice_dump_phy_type - helper function to dump phy_type
102 : : * @hw: pointer to the HW structure
103 : : * @low: 64 bit value for phy_type_low
104 : : * @high: 64 bit value for phy_type_high
105 : : * @prefix: prefix string to differentiate multiple dumps
106 : : */
107 : : static void
108 : 0 : ice_dump_phy_type(struct ice_hw *hw, u64 low, u64 high, const char *prefix)
109 : : {
110 : : u32 i;
111 : :
112 [ # # ]: 0 : ice_debug(hw, ICE_DBG_PHY, "%s: phy_type_low: 0x%016llx\n", prefix,
113 : : (unsigned long long)low);
114 : :
115 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(ice_link_mode_str_low); i++) {
116 [ # # ]: 0 : if (low & BIT_ULL(i))
117 [ # # ]: 0 : ice_debug(hw, ICE_DBG_PHY, "%s: bit(%d): %s\n",
118 : : prefix, i, ice_link_mode_str_low[i]);
119 : : }
120 : :
121 [ # # ]: 0 : ice_debug(hw, ICE_DBG_PHY, "%s: phy_type_high: 0x%016llx\n", prefix,
122 : : (unsigned long long)high);
123 : :
124 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(ice_link_mode_str_high); i++) {
125 [ # # ]: 0 : if (high & BIT_ULL(i))
126 [ # # ]: 0 : ice_debug(hw, ICE_DBG_PHY, "%s: bit(%d): %s\n",
127 : : prefix, i, ice_link_mode_str_high[i]);
128 : : }
129 : 0 : }
130 : :
131 : : /**
132 : : * ice_set_mac_type - Sets MAC type
133 : : * @hw: pointer to the HW structure
134 : : *
135 : : * This function sets the MAC type of the adapter based on the
136 : : * vendor ID and device ID stored in the HW structure.
137 : : */
138 : 0 : static int ice_set_mac_type(struct ice_hw *hw)
139 : : {
140 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
141 : :
142 [ # # ]: 0 : if (hw->vendor_id != ICE_INTEL_VENDOR_ID)
143 : : return ICE_ERR_DEVICE_NOT_SUPPORTED;
144 : :
145 [ # # # # : 0 : switch (hw->device_id) {
# ]
146 : 0 : case ICE_DEV_ID_E810C_BACKPLANE:
147 : : case ICE_DEV_ID_E810C_QSFP:
148 : : case ICE_DEV_ID_E810C_SFP:
149 : : case ICE_DEV_ID_E810_XXV_BACKPLANE:
150 : : case ICE_DEV_ID_E810_XXV_QSFP:
151 : : case ICE_DEV_ID_E810_XXV_SFP:
152 : 0 : hw->mac_type = ICE_MAC_E810;
153 : 0 : break;
154 : 0 : case ICE_DEV_ID_E822C_10G_BASE_T:
155 : : case ICE_DEV_ID_E822C_BACKPLANE:
156 : : case ICE_DEV_ID_E822C_QSFP:
157 : : case ICE_DEV_ID_E822C_SFP:
158 : : case ICE_DEV_ID_E822C_SGMII:
159 : : case ICE_DEV_ID_E822L_10G_BASE_T:
160 : : case ICE_DEV_ID_E822L_BACKPLANE:
161 : : case ICE_DEV_ID_E822L_SFP:
162 : : case ICE_DEV_ID_E822L_SGMII:
163 : : case ICE_DEV_ID_E823L_10G_BASE_T:
164 : : case ICE_DEV_ID_E823L_1GBE:
165 : : case ICE_DEV_ID_E823L_BACKPLANE:
166 : : case ICE_DEV_ID_E823L_QSFP:
167 : : case ICE_DEV_ID_E823L_SFP:
168 : : case ICE_DEV_ID_E823C_10G_BASE_T:
169 : : case ICE_DEV_ID_E823C_BACKPLANE:
170 : : case ICE_DEV_ID_E823C_QSFP:
171 : : case ICE_DEV_ID_E823C_SFP:
172 : : case ICE_DEV_ID_E823C_SGMII:
173 : 0 : hw->mac_type = ICE_MAC_GENERIC;
174 : 0 : break;
175 : 0 : case ICE_DEV_ID_E824S:
176 : : case ICE_DEV_ID_E825C_BACKPLANE:
177 : : case ICE_DEV_ID_E825C_QSFP:
178 : : case ICE_DEV_ID_E825C_SFP:
179 : : case ICE_DEV_ID_C825X:
180 : : case ICE_DEV_ID_E825C_SGMII:
181 : 0 : hw->mac_type = ICE_MAC_GENERIC_3K_E825;
182 : 0 : break;
183 : 0 : case ICE_DEV_ID_E830_BACKPLANE:
184 : : case ICE_DEV_ID_E830_QSFP56:
185 : : case ICE_DEV_ID_E830_SFP:
186 : : case ICE_DEV_ID_E830C_BACKPLANE:
187 : : case ICE_DEV_ID_E830_L_BACKPLANE:
188 : : case ICE_DEV_ID_E830C_QSFP:
189 : : case ICE_DEV_ID_E830_L_QSFP:
190 : : case ICE_DEV_ID_E830C_SFP:
191 : : case ICE_DEV_ID_E830_L_SFP:
192 : 0 : hw->mac_type = ICE_MAC_E830;
193 : 0 : break;
194 : 0 : default:
195 : 0 : hw->mac_type = ICE_MAC_UNKNOWN;
196 : 0 : break;
197 : : }
198 : :
199 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "mac_type: %d\n", hw->mac_type);
200 : : return 0;
201 : : }
202 : :
203 : : /**
204 : : * ice_is_generic_mac
205 : : * @hw: pointer to the hardware structure
206 : : *
207 : : * returns true if mac_type is ICE_MAC_GENERIC, false if not
208 : : */
209 : 0 : bool ice_is_generic_mac(struct ice_hw *hw)
210 : : {
211 : 0 : return (hw->mac_type == ICE_MAC_GENERIC ||
212 : 0 : hw->mac_type == ICE_MAC_GENERIC_3K ||
213 : : hw->mac_type == ICE_MAC_GENERIC_3K_E825);
214 : : }
215 : :
216 : : /**
217 : : * ice_is_e810
218 : : * @hw: pointer to the hardware structure
219 : : *
220 : : * returns true if the device is E810 based, false if not.
221 : : */
222 : 0 : bool ice_is_e810(struct ice_hw *hw)
223 : : {
224 : 0 : return hw->mac_type == ICE_MAC_E810;
225 : : }
226 : :
227 : : /**
228 : : * ice_is_e810t
229 : : * @hw: pointer to the hardware structure
230 : : *
231 : : * returns true if the device is E810T based, false if not.
232 : : */
233 : 0 : bool ice_is_e810t(struct ice_hw *hw)
234 : : {
235 [ # # # ]: 0 : switch (hw->device_id) {
236 : 0 : case ICE_DEV_ID_E810C_SFP:
237 [ # # ]: 0 : switch (hw->subsystem_device_id) {
238 : : case ICE_SUBDEV_ID_E810T:
239 : : case ICE_SUBDEV_ID_E810T2:
240 : : case ICE_SUBDEV_ID_E810T3:
241 : : case ICE_SUBDEV_ID_E810T4:
242 : : case ICE_SUBDEV_ID_E810T6:
243 : : case ICE_SUBDEV_ID_E810T7:
244 : : return true;
245 : : }
246 : : break;
247 : 0 : case ICE_DEV_ID_E810C_QSFP:
248 [ # # ]: 0 : switch (hw->subsystem_device_id) {
249 : : case ICE_SUBDEV_ID_E810T2:
250 : : case ICE_SUBDEV_ID_E810T3:
251 : : case ICE_SUBDEV_ID_E810T5:
252 : : return true;
253 : : }
254 : : break;
255 : : default:
256 : : break;
257 : : }
258 : :
259 : 0 : return false;
260 : : }
261 : :
262 : : /**
263 : : * ice_is_e830
264 : : * @hw: pointer to the hardware structure
265 : : *
266 : : * returns true if the device is E830 based, false if not.
267 : : */
268 : 0 : bool ice_is_e830(struct ice_hw *hw)
269 : : {
270 : 0 : return hw->mac_type == ICE_MAC_E830;
271 : : }
272 : :
273 : : /**
274 : : * ice_is_e823
275 : : * @hw: pointer to the hardware structure
276 : : *
277 : : * returns true if the device is E823-L or E823-C based, false if not.
278 : : */
279 : 0 : bool ice_is_e823(struct ice_hw *hw)
280 : : {
281 [ # # ]: 0 : switch (hw->device_id) {
282 : : case ICE_DEV_ID_E823L_BACKPLANE:
283 : : case ICE_DEV_ID_E823L_SFP:
284 : : case ICE_DEV_ID_E823L_10G_BASE_T:
285 : : case ICE_DEV_ID_E823L_1GBE:
286 : : case ICE_DEV_ID_E823L_QSFP:
287 : : case ICE_DEV_ID_E823C_BACKPLANE:
288 : : case ICE_DEV_ID_E823C_QSFP:
289 : : case ICE_DEV_ID_E823C_SFP:
290 : : case ICE_DEV_ID_E823C_10G_BASE_T:
291 : : case ICE_DEV_ID_E823C_SGMII:
292 : : return true;
293 : 0 : default:
294 : 0 : return false;
295 : : }
296 : : }
297 : :
298 : : /**
299 : : * ice_is_e825c
300 : : * @hw: pointer to the hardware structure
301 : : *
302 : : * returns true if the device is E825-C based, false if not.
303 : : */
304 : 0 : bool ice_is_e825c(struct ice_hw *hw)
305 : : {
306 [ # # ]: 0 : switch (hw->device_id) {
307 : : case ICE_DEV_ID_E825C_BACKPLANE:
308 : : case ICE_DEV_ID_E825C_QSFP:
309 : : case ICE_DEV_ID_E825C_SFP:
310 : : case ICE_DEV_ID_E825C_SGMII:
311 : : return true;
312 : 0 : default:
313 : 0 : return false;
314 : : }
315 : : }
316 : :
317 : : /**
318 : : * ice_clear_pf_cfg - Clear PF configuration
319 : : * @hw: pointer to the hardware structure
320 : : *
321 : : * Clears any existing PF configuration (VSIs, VSI lists, switch rules, port
322 : : * configuration, flow director filters, etc.).
323 : : */
324 : 0 : int ice_clear_pf_cfg(struct ice_hw *hw)
325 : : {
326 : : struct ice_aq_desc desc;
327 : :
328 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_clear_pf_cfg);
329 : :
330 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
331 : : }
332 : :
333 : : /**
334 : : * ice_aq_manage_mac_read - manage MAC address read command
335 : : * @hw: pointer to the HW struct
336 : : * @buf: a virtual buffer to hold the manage MAC read response
337 : : * @buf_size: Size of the virtual buffer
338 : : * @cd: pointer to command details structure or NULL
339 : : *
340 : : * This function is used to return per PF station MAC address (0x0107).
341 : : * NOTE: Upon successful completion of this command, MAC address information
342 : : * is returned in user specified buffer. Please interpret user specified
343 : : * buffer as "manage_mac_read" response.
344 : : * Response such as various MAC addresses are stored in HW struct (port.mac)
345 : : * ice_discover_dev_caps is expected to be called before this function is
346 : : * called.
347 : : */
348 : : static int
349 : 0 : ice_aq_manage_mac_read(struct ice_hw *hw, void *buf, u16 buf_size,
350 : : struct ice_sq_cd *cd)
351 : : {
352 : : struct ice_aqc_manage_mac_read_resp *resp;
353 : : struct ice_aqc_manage_mac_read *cmd;
354 : : struct ice_aq_desc desc;
355 : : int status;
356 : : u16 flags;
357 : : u8 i;
358 : :
359 : : cmd = &desc.params.mac_read;
360 : :
361 [ # # ]: 0 : if (buf_size < sizeof(*resp))
362 : : return ICE_ERR_BUF_TOO_SHORT;
363 : :
364 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_manage_mac_read);
365 : :
366 : 0 : status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
367 [ # # ]: 0 : if (status)
368 : : return status;
369 : :
370 : : resp = (struct ice_aqc_manage_mac_read_resp *)buf;
371 : 0 : flags = LE16_TO_CPU(cmd->flags) & ICE_AQC_MAN_MAC_READ_M;
372 : :
373 [ # # ]: 0 : if (!(flags & ICE_AQC_MAN_MAC_LAN_ADDR_VALID)) {
374 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LAN, "got invalid MAC address\n");
375 : 0 : return ICE_ERR_CFG;
376 : : }
377 : :
378 : : /* A single port can report up to two (LAN and WoL) addresses */
379 [ # # ]: 0 : for (i = 0; i < cmd->num_addr; i++)
380 [ # # ]: 0 : if (resp[i].addr_type == ICE_AQC_MAN_MAC_ADDR_TYPE_LAN) {
381 [ # # ]: 0 : ice_memcpy(hw->port_info->mac.lan_addr,
382 : : resp[i].mac_addr, ETH_ALEN,
383 : : ICE_NONDMA_TO_NONDMA);
384 [ # # ]: 0 : ice_memcpy(hw->port_info->mac.perm_addr,
385 : : resp[i].mac_addr,
386 : : ETH_ALEN, ICE_NONDMA_TO_NONDMA);
387 : : break;
388 : : }
389 : : return 0;
390 : : }
391 : :
392 : : /**
393 : : * ice_phy_maps_to_media
394 : : * @phy_type_low: PHY type low bits
395 : : * @phy_type_high: PHY type high bits
396 : : * @media_mask_low: media type PHY type low bitmask
397 : : * @media_mask_high: media type PHY type high bitmask
398 : : *
399 : : * Return true if PHY type [low|high] bits are only of media type PHY types
400 : : * [low|high] bitmask.
401 : : */
402 : : static bool
403 : : ice_phy_maps_to_media(u64 phy_type_low, u64 phy_type_high,
404 : : u64 media_mask_low, u64 media_mask_high)
405 : : {
406 : : /* check if a PHY type exist for media type */
407 [ # # # # : 0 : if (!(phy_type_low & media_mask_low ||
# # # # #
# ]
408 [ # # # # : 0 : phy_type_high & media_mask_high))
# # # # ]
409 : : return false;
410 : :
411 : : /* check that PHY types are only of media type */
412 [ # # # # : 0 : if (!(phy_type_low & ~media_mask_low) &&
# # # # #
# # # ]
413 [ # # # # : 0 : !(phy_type_high & ~media_mask_high))
# # # # ]
414 : : return true;
415 : :
416 : : return false;
417 : : }
418 : :
419 : : /**
420 : : * ice_set_media_type - Sets media type
421 : : * @pi: port information structure
422 : : *
423 : : * Set ice_port_info PHY media type based on PHY type. This should be called
424 : : * from Get PHY caps with media.
425 : : */
426 : 0 : static void ice_set_media_type(struct ice_port_info *pi)
427 : : {
428 : : enum ice_media_type *media_type;
429 : : u64 phy_type_high, phy_type_low;
430 : :
431 : 0 : phy_type_high = pi->phy.phy_type_high;
432 : 0 : phy_type_low = pi->phy.phy_type_low;
433 : : media_type = &pi->phy.media_type;
434 : :
435 : : /* if no media, then media type is NONE */
436 [ # # ]: 0 : if (!(pi->phy.link_info.link_info & ICE_AQ_MEDIA_AVAILABLE))
437 : 0 : *media_type = ICE_MEDIA_NONE;
438 : : /* else if PHY types are only BASE-T, then media type is BASET */
439 : : else if (ice_phy_maps_to_media(phy_type_low, phy_type_high,
440 : : ICE_MEDIA_BASET_PHY_TYPE_LOW_M, 0))
441 : 0 : *media_type = ICE_MEDIA_BASET;
442 : : /* else if any PHY type is BACKPLANE, then media type is BACKPLANE */
443 [ # # ]: 0 : else if (phy_type_low & ICE_MEDIA_BP_PHY_TYPE_LOW_M ||
444 [ # # ]: 0 : phy_type_high & ICE_MEDIA_BP_PHY_TYPE_HIGH_M)
445 : 0 : *media_type = ICE_MEDIA_BACKPLANE;
446 : : /* else if PHY types are only optical, or optical and C2M, then media
447 : : * type is FIBER
448 : : */
449 : : else if (ice_phy_maps_to_media(phy_type_low, phy_type_high,
450 : : ICE_MEDIA_OPT_PHY_TYPE_LOW_M,
451 [ # # ]: 0 : ICE_MEDIA_OPT_PHY_TYPE_HIGH_M) ||
452 : 0 : ((phy_type_low & ICE_MEDIA_OPT_PHY_TYPE_LOW_M ||
453 [ # # ]: 0 : phy_type_high & ICE_MEDIA_OPT_PHY_TYPE_HIGH_M) &&
454 [ # # ]: 0 : (phy_type_low & ICE_MEDIA_C2M_PHY_TYPE_LOW_M ||
455 [ # # ]: 0 : phy_type_high & ICE_MEDIA_C2C_PHY_TYPE_HIGH_M)))
456 : 0 : *media_type = ICE_MEDIA_FIBER;
457 : : /* else if PHY types are only DA, or DA and C2C, then media type DA */
458 : : else if (ice_phy_maps_to_media(phy_type_low, phy_type_high,
459 : : ICE_MEDIA_DAC_PHY_TYPE_LOW_M,
460 [ # # ]: 0 : ICE_MEDIA_DAC_PHY_TYPE_HIGH_M) ||
461 : 0 : ((phy_type_low & ICE_MEDIA_DAC_PHY_TYPE_LOW_M ||
462 [ # # ]: 0 : phy_type_high & ICE_MEDIA_DAC_PHY_TYPE_HIGH_M) &&
463 [ # # ]: 0 : (phy_type_low & ICE_MEDIA_C2C_PHY_TYPE_LOW_M ||
464 [ # # ]: 0 : phy_type_high & ICE_MEDIA_C2C_PHY_TYPE_HIGH_M)))
465 : 0 : *media_type = ICE_MEDIA_DA;
466 : : /* else if PHY types are only C2M or only C2C, then media is AUI */
467 : : else if (ice_phy_maps_to_media(phy_type_low, phy_type_high,
468 : : ICE_MEDIA_C2M_PHY_TYPE_LOW_M,
469 : : ICE_MEDIA_C2M_PHY_TYPE_HIGH_M) ||
470 : : ice_phy_maps_to_media(phy_type_low, phy_type_high,
471 : : ICE_MEDIA_C2C_PHY_TYPE_LOW_M,
472 : : ICE_MEDIA_C2C_PHY_TYPE_HIGH_M))
473 : 0 : *media_type = ICE_MEDIA_AUI;
474 : :
475 : : else
476 : 0 : *media_type = ICE_MEDIA_UNKNOWN;
477 : 0 : }
478 : :
479 : : /**
480 : : * ice_aq_get_phy_caps - returns PHY capabilities
481 : : * @pi: port information structure
482 : : * @qual_mods: report qualified modules
483 : : * @report_mode: report mode capabilities
484 : : * @pcaps: structure for PHY capabilities to be filled
485 : : * @cd: pointer to command details structure or NULL
486 : : *
487 : : * Returns the various PHY capabilities supported on the Port (0x0600)
488 : : */
489 : : int
490 : 0 : ice_aq_get_phy_caps(struct ice_port_info *pi, bool qual_mods, u8 report_mode,
491 : : struct ice_aqc_get_phy_caps_data *pcaps,
492 : : struct ice_sq_cd *cd)
493 : : {
494 : : struct ice_aqc_get_phy_caps *cmd;
495 : : u16 pcaps_size = sizeof(*pcaps);
496 : : struct ice_aq_desc desc;
497 : : const char *prefix;
498 : : struct ice_hw *hw;
499 : : int status;
500 : :
501 : : cmd = &desc.params.get_phy;
502 : :
503 [ # # # # : 0 : if (!pcaps || (report_mode & ~ICE_AQC_REPORT_MODE_M) || !pi)
# # ]
504 : : return ICE_ERR_PARAM;
505 : 0 : hw = pi->hw;
506 : :
507 [ # # # # ]: 0 : if (report_mode == ICE_AQC_REPORT_DFLT_CFG &&
508 : 0 : !ice_fw_supports_report_dflt_cfg(hw))
509 : : return ICE_ERR_PARAM;
510 : :
511 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_phy_caps);
512 : :
513 [ # # ]: 0 : if (qual_mods)
514 : 0 : cmd->param0 |= CPU_TO_LE16(ICE_AQC_GET_PHY_RQM);
515 : :
516 : 0 : cmd->param0 |= CPU_TO_LE16(report_mode);
517 : :
518 : 0 : status = ice_aq_send_cmd(hw, &desc, pcaps, pcaps_size, cd);
519 : :
520 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, "get phy caps dump\n");
521 : :
522 [ # # # # : 0 : switch (report_mode) {
# ]
523 : : case ICE_AQC_REPORT_TOPO_CAP_MEDIA:
524 : : prefix = "phy_caps_media";
525 : : break;
526 : 0 : case ICE_AQC_REPORT_TOPO_CAP_NO_MEDIA:
527 : : prefix = "phy_caps_no_media";
528 : 0 : break;
529 : 0 : case ICE_AQC_REPORT_ACTIVE_CFG:
530 : : prefix = "phy_caps_active";
531 : 0 : break;
532 : 0 : case ICE_AQC_REPORT_DFLT_CFG:
533 : : prefix = "phy_caps_default";
534 : 0 : break;
535 : 0 : default:
536 : : prefix = "phy_caps_invalid";
537 : : }
538 : :
539 : 0 : ice_dump_phy_type(hw, LE64_TO_CPU(pcaps->phy_type_low),
540 : : LE64_TO_CPU(pcaps->phy_type_high), prefix);
541 : :
542 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, "%s: report_mode = 0x%x\n",
543 : : prefix, report_mode);
544 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, "%s: caps = 0x%x\n", prefix, pcaps->caps);
545 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, "%s: low_power_ctrl_an = 0x%x\n", prefix,
546 : : pcaps->low_power_ctrl_an);
547 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, "%s: eee_cap = 0x%x\n", prefix,
548 : : pcaps->eee_cap);
549 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, "%s: eeer_value = 0x%x\n", prefix,
550 : : pcaps->eeer_value);
551 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, "%s: link_fec_options = 0x%x\n", prefix,
552 : : pcaps->link_fec_options);
553 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, "%s: module_compliance_enforcement = 0x%x\n",
554 : : prefix, pcaps->module_compliance_enforcement);
555 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, "%s: extended_compliance_code = 0x%x\n",
556 : : prefix, pcaps->extended_compliance_code);
557 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, "%s: module_type[0] = 0x%x\n", prefix,
558 : : pcaps->module_type[0]);
559 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, "%s: module_type[1] = 0x%x\n", prefix,
560 : : pcaps->module_type[1]);
561 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, "%s: module_type[2] = 0x%x\n", prefix,
562 : : pcaps->module_type[2]);
563 : :
564 [ # # ]: 0 : if (!status && report_mode == ICE_AQC_REPORT_TOPO_CAP_MEDIA) {
565 : 0 : pi->phy.phy_type_low = LE64_TO_CPU(pcaps->phy_type_low);
566 : 0 : pi->phy.phy_type_high = LE64_TO_CPU(pcaps->phy_type_high);
567 [ # # ]: 0 : ice_memcpy(pi->phy.link_info.module_type, &pcaps->module_type,
568 : : sizeof(pi->phy.link_info.module_type),
569 : : ICE_NONDMA_TO_NONDMA);
570 : 0 : ice_set_media_type(pi);
571 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, "%s: media_type = 0x%x\n", prefix,
572 : : pi->phy.media_type);
573 : : }
574 : :
575 : : return status;
576 : : }
577 : :
578 : : #define ice_get_link_status_data_ver(hw) ((hw)->mac_type == ICE_MAC_E830 ? \
579 : : ICE_GET_LINK_STATUS_DATA_V2 : ICE_GET_LINK_STATUS_DATA_V1)
580 : :
581 : : /**
582 : : * ice_get_link_status_datalen
583 : : * @hw: pointer to the HW struct
584 : : *
585 : : * return Get Link Status datalen
586 : : */
587 : : static u16 ice_get_link_status_datalen(struct ice_hw *hw)
588 : : {
589 : 0 : return (ice_get_link_status_data_ver(hw) ==
590 : 0 : ICE_GET_LINK_STATUS_DATA_V1) ? ICE_GET_LINK_STATUS_DATALEN_V1 :
591 : : ICE_GET_LINK_STATUS_DATALEN_V2;
592 : : }
593 : :
594 : : /**
595 : : * ice_aq_get_link_info
596 : : * @pi: port information structure
597 : : * @ena_lse: enable/disable LinkStatusEvent reporting
598 : : * @link: pointer to link status structure - optional
599 : : * @cd: pointer to command details structure or NULL
600 : : *
601 : : * Get Link Status (0x607). Returns the link status of the adapter.
602 : : */
603 : : int
604 : 0 : ice_aq_get_link_info(struct ice_port_info *pi, bool ena_lse,
605 : : struct ice_link_status *link, struct ice_sq_cd *cd)
606 : : {
607 : 0 : struct ice_aqc_get_link_status_data link_data = { 0 };
608 : : struct ice_aqc_get_link_status *resp;
609 : : struct ice_link_status *li_old, *li;
610 : : struct ice_fc_info *hw_fc_info;
611 : : bool tx_pause, rx_pause;
612 : : struct ice_aq_desc desc;
613 : : struct ice_hw *hw;
614 : : u16 cmd_flags;
615 : : int status;
616 : :
617 [ # # ]: 0 : if (!pi)
618 : : return ICE_ERR_PARAM;
619 : 0 : hw = pi->hw;
620 : :
621 : : li_old = &pi->phy.link_info_old;
622 : : li = &pi->phy.link_info;
623 : : hw_fc_info = &pi->fc;
624 : :
625 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_status);
626 [ # # ]: 0 : cmd_flags = (ena_lse) ? ICE_AQ_LSE_ENA : ICE_AQ_LSE_DIS;
627 : : resp = &desc.params.get_link_status;
628 : 0 : resp->cmd_flags = CPU_TO_LE16(cmd_flags);
629 [ # # ]: 0 : resp->lport_num = pi->lport;
630 : :
631 : 0 : status = ice_aq_send_cmd(hw, &desc, &link_data,
632 : : ice_get_link_status_datalen(hw), cd);
633 [ # # ]: 0 : if (status)
634 : : return status;
635 : :
636 : : /* save off old link status information */
637 : 0 : *li_old = *li;
638 : :
639 : : /* update current link status information */
640 : 0 : li->link_speed = LE16_TO_CPU(link_data.link_speed);
641 : 0 : li->phy_type_low = LE64_TO_CPU(link_data.phy_type_low);
642 : 0 : li->phy_type_high = LE64_TO_CPU(link_data.phy_type_high);
643 : 0 : li->link_info = link_data.link_info;
644 : 0 : li->link_cfg_err = link_data.link_cfg_err;
645 : 0 : li->an_info = link_data.an_info;
646 : 0 : li->ext_info = link_data.ext_info;
647 : 0 : li->max_frame_size = LE16_TO_CPU(link_data.max_frame_size);
648 : 0 : li->fec_info = link_data.cfg & ICE_AQ_FEC_MASK;
649 : 0 : li->topo_media_conflict = link_data.topo_media_conflict;
650 : 0 : li->pacing = link_data.cfg & (ICE_AQ_CFG_PACING_M |
651 : : ICE_AQ_CFG_PACING_TYPE_M);
652 : :
653 : : /* update fc info */
654 : 0 : tx_pause = !!(link_data.an_info & ICE_AQ_LINK_PAUSE_TX);
655 : 0 : rx_pause = !!(link_data.an_info & ICE_AQ_LINK_PAUSE_RX);
656 [ # # ]: 0 : if (tx_pause && rx_pause)
657 : 0 : hw_fc_info->current_mode = ICE_FC_FULL;
658 [ # # ]: 0 : else if (tx_pause)
659 : 0 : hw_fc_info->current_mode = ICE_FC_TX_PAUSE;
660 [ # # ]: 0 : else if (rx_pause)
661 : 0 : hw_fc_info->current_mode = ICE_FC_RX_PAUSE;
662 : : else
663 : 0 : hw_fc_info->current_mode = ICE_FC_NONE;
664 : :
665 : 0 : li->lse_ena = !!(resp->cmd_flags & CPU_TO_LE16(ICE_AQ_LSE_IS_ENABLED));
666 : :
667 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, "get link info\n");
668 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, " link_speed = 0x%x\n", li->link_speed);
669 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, " phy_type_low = 0x%llx\n",
670 : : (unsigned long long)li->phy_type_low);
671 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, " phy_type_high = 0x%llx\n",
672 : : (unsigned long long)li->phy_type_high);
673 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, " link_info = 0x%x\n", li->link_info);
674 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, " link_cfg_err = 0x%x\n", li->link_cfg_err);
675 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, " an_info = 0x%x\n", li->an_info);
676 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, " ext_info = 0x%x\n", li->ext_info);
677 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, " fec_info = 0x%x\n", li->fec_info);
678 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, " lse_ena = 0x%x\n", li->lse_ena);
679 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, " max_frame = 0x%x\n",
680 : : li->max_frame_size);
681 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, " pacing = 0x%x\n", li->pacing);
682 : :
683 : : /* save link status information */
684 [ # # ]: 0 : if (link)
685 : 0 : *link = *li;
686 : :
687 : : /* flag cleared so calling functions don't call AQ again */
688 : 0 : pi->phy.get_link_info = false;
689 : :
690 : 0 : return 0;
691 : : }
692 : :
693 : : /**
694 : : * ice_fill_tx_timer_and_fc_thresh
695 : : * @hw: pointer to the HW struct
696 : : * @cmd: pointer to MAC cfg structure
697 : : *
698 : : * Add Tx timer and FC refresh threshold info to Set MAC Config AQ command
699 : : * descriptor
700 : : */
701 : : static void
702 : : ice_fill_tx_timer_and_fc_thresh(struct ice_hw *hw,
703 : : struct ice_aqc_set_mac_cfg *cmd)
704 : : {
705 : : u16 fc_thres_val, tx_timer_val;
706 : : u32 val;
707 : :
708 : : /* We read back the transmit timer and fc threshold value of
709 : : * LFC. Thus, we will use index =
710 : : * PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_MAX_INDEX.
711 : : *
712 : : * Also, because we are operating on transmit timer and fc
713 : : * threshold of LFC, we don't turn on any bit in tx_tmr_priority
714 : : */
715 : : #define E800_IDX_OF_LFC E800_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_MAX_INDEX
716 : :
717 [ # # ]: 0 : if ((hw)->mac_type == ICE_MAC_E830) {
718 : : /* Retrieve the transmit timer */
719 : 0 : val = rd32(hw, E830_PRTMAC_CL01_PAUSE_QUANTA);
720 : 0 : tx_timer_val = val & E830_PRTMAC_CL01_PAUSE_QUANTA_CL0_PAUSE_QUANTA_M;
721 : 0 : cmd->tx_tmr_value = CPU_TO_LE16(tx_timer_val);
722 : :
723 : : /* Retrieve the fc threshold */
724 : 0 : val = rd32(hw, E830_PRTMAC_CL01_QUANTA_THRESH);
725 : 0 : fc_thres_val = val & E830_PRTMAC_CL01_QUANTA_THRESH_CL0_QUANTA_THRESH_M;
726 : : } else {
727 : : /* Retrieve the transmit timer */
728 : 0 : val = rd32(hw, E800_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA(E800_IDX_OF_LFC));
729 : 0 : tx_timer_val = val &
730 : : E800_PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_HSEC_CTL_TX_PAUSE_QUANTA_M;
731 : 0 : cmd->tx_tmr_value = CPU_TO_LE16(tx_timer_val);
732 : :
733 : : /* Retrieve the fc threshold */
734 : 0 : val = rd32(hw, E800_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER(E800_IDX_OF_LFC));
735 : 0 : fc_thres_val = val & E800_PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_M;
736 : : }
737 : :
738 : 0 : cmd->fc_refresh_threshold = CPU_TO_LE16(fc_thres_val);
739 : : }
740 : :
741 : : /**
742 : : * ice_aq_set_mac_cfg
743 : : * @hw: pointer to the HW struct
744 : : * @max_frame_size: Maximum Frame Size to be supported
745 : : * @auto_drop: Tell HW to drop packets if TC queue is blocked
746 : : * @cd: pointer to command details structure or NULL
747 : : *
748 : : * Set MAC configuration (0x0603)
749 : : */
750 : : int
751 : 0 : ice_aq_set_mac_cfg(struct ice_hw *hw, u16 max_frame_size, bool auto_drop,
752 : : struct ice_sq_cd *cd)
753 : : {
754 : : struct ice_aqc_set_mac_cfg *cmd;
755 : : struct ice_aq_desc desc;
756 : :
757 : : cmd = &desc.params.set_mac_cfg;
758 : :
759 [ # # ]: 0 : if (max_frame_size == 0)
760 : : return ICE_ERR_PARAM;
761 : :
762 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_mac_cfg);
763 : :
764 : 0 : cmd->max_frame_size = CPU_TO_LE16(max_frame_size);
765 : :
766 [ # # # # ]: 0 : if (ice_is_fw_auto_drop_supported(hw) && auto_drop)
767 : 0 : cmd->drop_opts |= ICE_AQ_SET_MAC_AUTO_DROP_BLOCKING_PKTS;
768 : : ice_fill_tx_timer_and_fc_thresh(hw, cmd);
769 : :
770 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
771 : : }
772 : :
773 : : /**
774 : : * ice_init_fltr_mgmt_struct - initializes filter management list and locks
775 : : * @hw: pointer to the HW struct
776 : : */
777 : 0 : int ice_init_fltr_mgmt_struct(struct ice_hw *hw)
778 : : {
779 : : struct ice_switch_info *sw;
780 : : int status;
781 : :
782 : 0 : hw->switch_info = (struct ice_switch_info *)
783 : 0 : ice_malloc(hw, sizeof(*hw->switch_info));
784 : :
785 : : sw = hw->switch_info;
786 : :
787 [ # # ]: 0 : if (!sw)
788 : : return ICE_ERR_NO_MEMORY;
789 : :
790 : 0 : INIT_LIST_HEAD(&sw->vsi_list_map_head);
791 : 0 : sw->prof_res_bm_init = 0;
792 : :
793 : 0 : status = ice_init_def_sw_recp(hw, &hw->switch_info->recp_list);
794 [ # # ]: 0 : if (status) {
795 : 0 : ice_free(hw, hw->switch_info);
796 : 0 : return status;
797 : : }
798 : : return 0;
799 : : }
800 : :
801 : : /**
802 : : * ice_cleanup_fltr_mgmt_single - clears single filter mngt struct
803 : : * @hw: pointer to the HW struct
804 : : * @sw: pointer to switch info struct for which function clears filters
805 : : */
806 : : static void
807 : 0 : ice_cleanup_fltr_mgmt_single(struct ice_hw *hw, struct ice_switch_info *sw)
808 : : {
809 : : struct ice_vsi_list_map_info *v_pos_map;
810 : : struct ice_vsi_list_map_info *v_tmp_map;
811 : : struct ice_sw_recipe *recps;
812 : : u8 i;
813 : :
814 [ # # ]: 0 : if (!sw)
815 : : return;
816 : :
817 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(v_pos_map, v_tmp_map, &sw->vsi_list_map_head,
# # # # #
# ]
818 : : ice_vsi_list_map_info, list_entry) {
819 [ # # ]: 0 : LIST_DEL(&v_pos_map->list_entry);
820 : 0 : ice_free(hw, v_pos_map);
821 : : }
822 : 0 : recps = sw->recp_list;
823 [ # # ]: 0 : for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
824 : : struct ice_recp_grp_entry *rg_entry, *tmprg_entry;
825 : :
826 : 0 : recps[i].root_rid = i;
827 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(rg_entry, tmprg_entry,
# # # # #
# ]
828 : : &recps[i].rg_list, ice_recp_grp_entry,
829 : : l_entry) {
830 [ # # ]: 0 : LIST_DEL(&rg_entry->l_entry);
831 : 0 : ice_free(hw, rg_entry);
832 : : }
833 : :
834 [ # # ]: 0 : if (recps[i].adv_rule) {
835 : : struct ice_adv_fltr_mgmt_list_entry *tmp_entry;
836 : : struct ice_adv_fltr_mgmt_list_entry *lst_itr;
837 : :
838 : : ice_destroy_lock(&recps[i].filt_rule_lock);
839 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(lst_itr, tmp_entry,
# # # # #
# ]
840 : : &recps[i].filt_rules,
841 : : ice_adv_fltr_mgmt_list_entry,
842 : : list_entry) {
843 [ # # ]: 0 : LIST_DEL(&lst_itr->list_entry);
844 : 0 : ice_free(hw, lst_itr->lkups);
845 : 0 : ice_free(hw, lst_itr);
846 : : }
847 : : } else {
848 : : struct ice_fltr_mgmt_list_entry *lst_itr, *tmp_entry;
849 : :
850 : : ice_destroy_lock(&recps[i].filt_rule_lock);
851 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(lst_itr, tmp_entry,
# # # # #
# # # ]
852 : : &recps[i].filt_rules,
853 : : ice_fltr_mgmt_list_entry,
854 : : list_entry) {
855 [ # # ]: 0 : LIST_DEL(&lst_itr->list_entry);
856 : 0 : ice_free(hw, lst_itr);
857 : : }
858 : : }
859 [ # # ]: 0 : if (recps[i].root_buf)
860 : 0 : ice_free(hw, recps[i].root_buf);
861 : : }
862 : 0 : ice_rm_sw_replay_rule_info(hw, sw);
863 : 0 : ice_free(hw, sw->recp_list);
864 : 0 : ice_free(hw, sw);
865 : : }
866 : :
867 : : /**
868 : : * ice_cleanup_fltr_mgmt_struct - cleanup filter management list and locks
869 : : * @hw: pointer to the HW struct
870 : : */
871 : 0 : void ice_cleanup_fltr_mgmt_struct(struct ice_hw *hw)
872 : : {
873 : 0 : ice_cleanup_fltr_mgmt_single(hw, hw->switch_info);
874 : 0 : }
875 : :
876 : : /**
877 : : * ice_get_itr_intrl_gran
878 : : * @hw: pointer to the HW struct
879 : : *
880 : : * Determines the ITR/INTRL granularities based on the maximum aggregate
881 : : * bandwidth according to the device's configuration during power-on.
882 : : */
883 : : static void ice_get_itr_intrl_gran(struct ice_hw *hw)
884 : : {
885 : 0 : u8 max_agg_bw = (rd32(hw, GL_PWR_MODE_CTL) &
886 : 0 : GL_PWR_MODE_CTL_CAR_MAX_BW_M) >>
887 : : GL_PWR_MODE_CTL_CAR_MAX_BW_S;
888 : :
889 [ # # ]: 0 : switch (max_agg_bw) {
890 : 0 : case ICE_MAX_AGG_BW_200G:
891 : : case ICE_MAX_AGG_BW_100G:
892 : : case ICE_MAX_AGG_BW_50G:
893 : 0 : hw->itr_gran = ICE_ITR_GRAN_ABOVE_25;
894 : 0 : hw->intrl_gran = ICE_INTRL_GRAN_ABOVE_25;
895 : 0 : break;
896 : 0 : case ICE_MAX_AGG_BW_25G:
897 : 0 : hw->itr_gran = ICE_ITR_GRAN_MAX_25;
898 : 0 : hw->intrl_gran = ICE_INTRL_GRAN_MAX_25;
899 : 0 : break;
900 : : }
901 : : }
902 : :
903 : : /**
904 : : * ice_print_rollback_msg - print FW rollback message
905 : : * @hw: pointer to the hardware structure
906 : : */
907 : 0 : void ice_print_rollback_msg(struct ice_hw *hw)
908 : : {
909 : 0 : char nvm_str[ICE_NVM_VER_LEN] = { 0 };
910 : : struct ice_orom_info *orom;
911 : : struct ice_nvm_info *nvm;
912 : :
913 : : orom = &hw->flash.orom;
914 : : nvm = &hw->flash.nvm;
915 : :
916 : 0 : (void)SNPRINTF(nvm_str, sizeof(nvm_str), "%x.%02x 0x%x %d.%d.%d",
917 : 0 : nvm->major, nvm->minor, nvm->eetrack, orom->major,
918 [ # # ]: 0 : orom->build, orom->patch);
919 [ # # ]: 0 : ice_warn(hw,
920 : : "Firmware rollback mode detected. Current version is NVM: %s, FW: %d.%d. Device may exhibit limited functionality. Refer to the Intel(R) Ethernet Adapters and Devices User Guide for details on firmware rollback mode\n",
921 : : nvm_str, hw->fw_maj_ver, hw->fw_min_ver);
922 : 0 : }
923 : :
924 : : /**
925 : : * ice_set_umac_shared
926 : : * @hw: pointer to the hw struct
927 : : *
928 : : * Set boolean flag to allow unicast MAC sharing
929 : : */
930 : 0 : void ice_set_umac_shared(struct ice_hw *hw)
931 : : {
932 : 0 : hw->umac_shared = true;
933 : 0 : }
934 : :
935 : : /**
936 : : * ice_init_hw - main hardware initialization routine
937 : : * @hw: pointer to the hardware structure
938 : : */
939 : 0 : int ice_init_hw(struct ice_hw *hw)
940 : : {
941 : : struct ice_aqc_get_phy_caps_data *pcaps;
942 : : u16 mac_buf_len;
943 : : void *mac_buf;
944 : : int status;
945 : :
946 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
947 : :
948 : : /* Set MAC type based on DeviceID */
949 : 0 : status = ice_set_mac_type(hw);
950 [ # # ]: 0 : if (status)
951 : : return status;
952 : :
953 : 0 : hw->pf_id = (u8)(rd32(hw, PF_FUNC_RID) &
954 : 0 : PF_FUNC_RID_FUNCTION_NUMBER_M) >>
955 : : PF_FUNC_RID_FUNCTION_NUMBER_S;
956 : :
957 : 0 : status = ice_reset(hw, ICE_RESET_PFR);
958 [ # # ]: 0 : if (status)
959 : : return status;
960 : :
961 : : ice_get_itr_intrl_gran(hw);
962 : :
963 : 0 : hw->fw_vsi_num = ICE_DFLT_VSI_INVAL;
964 : :
965 : 0 : status = ice_create_all_ctrlq(hw);
966 [ # # ]: 0 : if (status)
967 : 0 : goto err_unroll_cqinit;
968 : :
969 : 0 : status = ice_init_nvm(hw);
970 [ # # ]: 0 : if (status)
971 : 0 : goto err_unroll_cqinit;
972 : :
973 [ # # ]: 0 : if (ice_get_fw_mode(hw) == ICE_FW_MODE_ROLLBACK)
974 : 0 : ice_print_rollback_msg(hw);
975 : :
976 [ # # ]: 0 : if (!hw->skip_clear_pf) {
977 : 0 : status = ice_clear_pf_cfg(hw);
978 [ # # ]: 0 : if (status)
979 : 0 : goto err_unroll_cqinit;
980 : : }
981 : :
982 : : /* Set bit to enable Flow Director filters */
983 : 0 : wr32(hw, PFQF_FD_ENA, PFQF_FD_ENA_FD_ENA_M);
984 : 0 : INIT_LIST_HEAD(&hw->fdir_list_head);
985 : :
986 : 0 : ice_clear_pxe_mode(hw);
987 : :
988 : 0 : status = ice_get_caps(hw);
989 [ # # ]: 0 : if (status)
990 : 0 : goto err_unroll_cqinit;
991 : :
992 [ # # ]: 0 : if (!hw->port_info)
993 : 0 : hw->port_info = (struct ice_port_info *)
994 : 0 : ice_malloc(hw, sizeof(*hw->port_info));
995 [ # # ]: 0 : if (!hw->port_info) {
996 : : status = ICE_ERR_NO_MEMORY;
997 : 0 : goto err_unroll_cqinit;
998 : : }
999 : :
1000 : 0 : hw->port_info->loopback_mode = ICE_AQC_SET_P_PARAMS_LOOPBACK_MODE_NORMAL;
1001 : :
1002 : : /* set the back pointer to HW */
1003 : 0 : hw->port_info->hw = hw;
1004 : :
1005 : : /* Initialize port_info struct with switch configuration data */
1006 : 0 : status = ice_get_initial_sw_cfg(hw);
1007 [ # # ]: 0 : if (status)
1008 : 0 : goto err_unroll_alloc;
1009 : :
1010 : 0 : hw->evb_veb = true;
1011 : : /* Query the allocated resources for Tx scheduler */
1012 : 0 : status = ice_sched_query_res_alloc(hw);
1013 [ # # ]: 0 : if (status) {
1014 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SCHED, "Failed to get scheduler allocated resources\n");
1015 : 0 : goto err_unroll_alloc;
1016 : : }
1017 : 0 : ice_sched_get_psm_clk_freq(hw);
1018 : :
1019 : : /* Initialize port_info struct with scheduler data */
1020 : 0 : status = ice_sched_init_port(hw->port_info);
1021 [ # # ]: 0 : if (status)
1022 : 0 : goto err_unroll_sched;
1023 : : pcaps = (struct ice_aqc_get_phy_caps_data *)
1024 : 0 : ice_malloc(hw, sizeof(*pcaps));
1025 [ # # ]: 0 : if (!pcaps) {
1026 : : status = ICE_ERR_NO_MEMORY;
1027 : 0 : goto err_unroll_sched;
1028 : : }
1029 : :
1030 : : /* Initialize port_info struct with PHY capabilities */
1031 : 0 : status = ice_aq_get_phy_caps(hw->port_info, false,
1032 : : ICE_AQC_REPORT_TOPO_CAP_MEDIA, pcaps, NULL);
1033 : 0 : ice_free(hw, pcaps);
1034 [ # # ]: 0 : if (status)
1035 [ # # ]: 0 : ice_warn(hw, "Get PHY capabilities failed status = %d, continuing anyway\n",
1036 : : status);
1037 : :
1038 : : /* Initialize port_info struct with link information */
1039 : 0 : status = ice_aq_get_link_info(hw->port_info, false, NULL, NULL);
1040 [ # # ]: 0 : if (status)
1041 : 0 : goto err_unroll_sched;
1042 : : /* need a valid SW entry point to build a Tx tree */
1043 [ # # ]: 0 : if (!hw->sw_entry_point_layer) {
1044 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SCHED, "invalid sw entry point\n");
1045 : : status = ICE_ERR_CFG;
1046 : 0 : goto err_unroll_sched;
1047 : : }
1048 : 0 : INIT_LIST_HEAD(&hw->agg_list);
1049 : : /* Initialize max burst size */
1050 [ # # ]: 0 : if (!hw->max_burst_size)
1051 : 0 : ice_cfg_rl_burst_size(hw, ICE_SCHED_DFLT_BURST_SIZE);
1052 : 0 : status = ice_init_fltr_mgmt_struct(hw);
1053 [ # # ]: 0 : if (status)
1054 : 0 : goto err_unroll_sched;
1055 : :
1056 : : /* Get MAC information */
1057 : :
1058 : : /* A single port can report up to two (LAN and WoL) addresses */
1059 : 0 : mac_buf = ice_calloc(hw, 2,
1060 : : sizeof(struct ice_aqc_manage_mac_read_resp));
1061 : : mac_buf_len = 2 * sizeof(struct ice_aqc_manage_mac_read_resp);
1062 : :
1063 [ # # ]: 0 : if (!mac_buf) {
1064 : : status = ICE_ERR_NO_MEMORY;
1065 : 0 : goto err_unroll_fltr_mgmt_struct;
1066 : : }
1067 : :
1068 : 0 : status = ice_aq_manage_mac_read(hw, mac_buf, mac_buf_len, NULL);
1069 : 0 : ice_free(hw, mac_buf);
1070 : :
1071 [ # # ]: 0 : if (status)
1072 : 0 : goto err_unroll_fltr_mgmt_struct;
1073 : :
1074 : : /* enable jumbo frame support at MAC level */
1075 : 0 : status = ice_aq_set_mac_cfg(hw, ICE_AQ_SET_MAC_FRAME_SIZE_MAX, false,
1076 : : NULL);
1077 [ # # ]: 0 : if (status)
1078 : 0 : goto err_unroll_fltr_mgmt_struct;
1079 : :
1080 : : /* Obtain counter base index which would be used by flow director */
1081 : 0 : status = ice_alloc_fd_res_cntr(hw, &hw->fd_ctr_base);
1082 [ # # ]: 0 : if (status)
1083 : 0 : goto err_unroll_fltr_mgmt_struct;
1084 : :
1085 : 0 : status = ice_init_hw_tbls(hw);
1086 [ # # ]: 0 : if (status)
1087 : 0 : goto err_unroll_fltr_mgmt_struct;
1088 : : ice_init_lock(&hw->tnl_lock);
1089 : :
1090 : 0 : return 0;
1091 : :
1092 : 0 : err_unroll_fltr_mgmt_struct:
1093 : 0 : ice_cleanup_fltr_mgmt_struct(hw);
1094 : 0 : err_unroll_sched:
1095 : 0 : ice_sched_cleanup_all(hw);
1096 : 0 : err_unroll_alloc:
1097 : 0 : ice_free(hw, hw->port_info);
1098 : 0 : hw->port_info = NULL;
1099 : 0 : err_unroll_cqinit:
1100 : 0 : ice_destroy_all_ctrlq(hw);
1101 : 0 : return status;
1102 : : }
1103 : :
1104 : : /**
1105 : : * ice_deinit_hw - unroll initialization operations done by ice_init_hw
1106 : : * @hw: pointer to the hardware structure
1107 : : *
1108 : : * This should be called only during nominal operation, not as a result of
1109 : : * ice_init_hw() failing since ice_init_hw() will take care of unrolling
1110 : : * applicable initializations if it fails for any reason.
1111 : : */
1112 : 0 : void ice_deinit_hw(struct ice_hw *hw)
1113 : : {
1114 : 0 : ice_free_fd_res_cntr(hw, hw->fd_ctr_base);
1115 : 0 : ice_cleanup_fltr_mgmt_struct(hw);
1116 : :
1117 : 0 : ice_sched_cleanup_all(hw);
1118 : 0 : ice_sched_clear_agg(hw);
1119 : 0 : ice_free_seg(hw);
1120 : 0 : ice_free_hw_tbls(hw);
1121 : : ice_destroy_lock(&hw->tnl_lock);
1122 : :
1123 [ # # ]: 0 : if (hw->port_info) {
1124 : 0 : ice_free(hw, hw->port_info);
1125 : 0 : hw->port_info = NULL;
1126 : : }
1127 : :
1128 : 0 : ice_destroy_all_ctrlq(hw);
1129 : :
1130 : : /* Clear VSI contexts if not already cleared */
1131 : 0 : ice_clear_all_vsi_ctx(hw);
1132 : 0 : }
1133 : :
1134 : : /**
1135 : : * ice_check_reset - Check to see if a global reset is complete
1136 : : * @hw: pointer to the hardware structure
1137 : : */
1138 : 0 : int ice_check_reset(struct ice_hw *hw)
1139 : : {
1140 : : u32 cnt, reg = 0, grst_timeout, uld_mask, reset_wait_cnt;
1141 : :
1142 : : /* Poll for Device Active state in case a recent CORER, GLOBR,
1143 : : * or EMPR has occurred. The grst delay value is in 100ms units.
1144 : : * Add 1sec for outstanding AQ commands that can take a long time.
1145 : : */
1146 : 0 : grst_timeout = ((rd32(hw, GLGEN_RSTCTL) & GLGEN_RSTCTL_GRSTDEL_M) >>
1147 : : GLGEN_RSTCTL_GRSTDEL_S) + 10;
1148 : :
1149 [ # # ]: 0 : for (cnt = 0; cnt < grst_timeout; cnt++) {
1150 : 0 : ice_msec_delay(100, true);
1151 : 0 : reg = rd32(hw, GLGEN_RSTAT);
1152 [ # # ]: 0 : if (!(reg & GLGEN_RSTAT_DEVSTATE_M))
1153 : : break;
1154 : : }
1155 : :
1156 [ # # ]: 0 : if (cnt == grst_timeout) {
1157 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "Global reset polling failed to complete.\n");
1158 : 0 : return ICE_ERR_RESET_FAILED;
1159 : : }
1160 : :
1161 : : #define ICE_RESET_DONE_MASK (GLNVM_ULD_PCIER_DONE_M |\
1162 : : GLNVM_ULD_PCIER_DONE_1_M |\
1163 : : GLNVM_ULD_CORER_DONE_M |\
1164 : : GLNVM_ULD_GLOBR_DONE_M |\
1165 : : GLNVM_ULD_POR_DONE_M |\
1166 : : GLNVM_ULD_POR_DONE_1_M |\
1167 : : GLNVM_ULD_PCIER_DONE_2_M)
1168 : :
1169 : : uld_mask = ICE_RESET_DONE_MASK;
1170 : :
1171 : : reset_wait_cnt = ICE_PF_RESET_WAIT_COUNT;
1172 : :
1173 : : /* Device is Active; check Global Reset processes are done */
1174 [ # # ]: 0 : for (cnt = 0; cnt < reset_wait_cnt; cnt++) {
1175 : 0 : reg = rd32(hw, GLNVM_ULD) & uld_mask;
1176 [ # # ]: 0 : if (reg == uld_mask) {
1177 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "Global reset processes done. %d\n", cnt);
1178 : : break;
1179 : : }
1180 : 0 : ice_msec_delay(10, true);
1181 : : }
1182 : :
1183 [ # # ]: 0 : if (cnt == reset_wait_cnt) {
1184 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "Wait for Reset Done timed out. GLNVM_ULD = 0x%x\n",
1185 : : reg);
1186 : 0 : return ICE_ERR_RESET_FAILED;
1187 : : }
1188 : :
1189 : : return 0;
1190 : : }
1191 : :
1192 : : /**
1193 : : * ice_pf_reset - Reset the PF
1194 : : * @hw: pointer to the hardware structure
1195 : : *
1196 : : * If a global reset has been triggered, this function checks
1197 : : * for its completion and then issues the PF reset
1198 : : */
1199 : 0 : static int ice_pf_reset(struct ice_hw *hw)
1200 : : {
1201 : : u32 cnt, reg, reset_wait_cnt, cfg_lock_timeout;
1202 : :
1203 : : /* If at function entry a global reset was already in progress, i.e.
1204 : : * state is not 'device active' or any of the reset done bits are not
1205 : : * set in GLNVM_ULD, there is no need for a PF Reset; poll until the
1206 : : * global reset is done.
1207 : : */
1208 [ # # ]: 0 : if ((rd32(hw, GLGEN_RSTAT) & GLGEN_RSTAT_DEVSTATE_M) ||
1209 [ # # ]: 0 : (rd32(hw, GLNVM_ULD) & ICE_RESET_DONE_MASK) ^ ICE_RESET_DONE_MASK) {
1210 : : /* poll on global reset currently in progress until done */
1211 [ # # ]: 0 : if (ice_check_reset(hw))
1212 : : return ICE_ERR_RESET_FAILED;
1213 : :
1214 : 0 : return 0;
1215 : : }
1216 : :
1217 : : /* Reset the PF */
1218 : 0 : reg = rd32(hw, PFGEN_CTRL);
1219 : :
1220 : 0 : wr32(hw, PFGEN_CTRL, (reg | PFGEN_CTRL_PFSWR_M));
1221 : :
1222 : : /* Wait for the PFR to complete. The wait time is the global config lock
1223 : : * timeout plus the PFR timeout which will account for a possible reset
1224 : : * that is occurring during a download package operation.
1225 : : */
1226 : : reset_wait_cnt = ICE_PF_RESET_WAIT_COUNT;
1227 : : cfg_lock_timeout = ICE_GLOBAL_CFG_LOCK_TIMEOUT;
1228 : :
1229 [ # # ]: 0 : for (cnt = 0; cnt < cfg_lock_timeout + reset_wait_cnt; cnt++) {
1230 : 0 : reg = rd32(hw, PFGEN_CTRL);
1231 [ # # ]: 0 : if (!(reg & PFGEN_CTRL_PFSWR_M))
1232 : : break;
1233 : :
1234 : 0 : ice_msec_delay(1, true);
1235 : : }
1236 : :
1237 [ # # ]: 0 : if (cnt == cfg_lock_timeout + reset_wait_cnt) {
1238 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "PF reset polling failed to complete.\n");
1239 : 0 : return ICE_ERR_RESET_FAILED;
1240 : : }
1241 : :
1242 : : return 0;
1243 : : }
1244 : :
1245 : : /**
1246 : : * ice_reset - Perform different types of reset
1247 : : * @hw: pointer to the hardware structure
1248 : : * @req: reset request
1249 : : *
1250 : : * This function triggers a reset as specified by the req parameter.
1251 : : *
1252 : : * Note:
1253 : : * If anything other than a PF reset is triggered, PXE mode is restored.
1254 : : * This has to be cleared using ice_clear_pxe_mode again, once the AQ
1255 : : * interface has been restored in the rebuild flow.
1256 : : */
1257 : 0 : int ice_reset(struct ice_hw *hw, enum ice_reset_req req)
1258 : : {
1259 : : u32 val = 0;
1260 : :
1261 [ # # # # ]: 0 : switch (req) {
1262 : 0 : case ICE_RESET_PFR:
1263 : 0 : return ice_pf_reset(hw);
1264 : 0 : case ICE_RESET_CORER:
1265 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "CoreR requested\n");
1266 : : val = GLGEN_RTRIG_CORER_M;
1267 : : break;
1268 : 0 : case ICE_RESET_GLOBR:
1269 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "GlobalR requested\n");
1270 : : val = GLGEN_RTRIG_GLOBR_M;
1271 : : break;
1272 : : default:
1273 : : return ICE_ERR_PARAM;
1274 : : }
1275 : :
1276 : 0 : val |= rd32(hw, GLGEN_RTRIG);
1277 : 0 : wr32(hw, GLGEN_RTRIG, val);
1278 : 0 : ice_flush(hw);
1279 : :
1280 : : /* wait for the FW to be ready */
1281 : 0 : return ice_check_reset(hw);
1282 : : }
1283 : :
1284 : : /**
1285 : : * ice_copy_rxq_ctx_to_hw
1286 : : * @hw: pointer to the hardware structure
1287 : : * @ice_rxq_ctx: pointer to the rxq context
1288 : : * @rxq_index: the index of the Rx queue
1289 : : *
1290 : : * Copies rxq context from dense structure to HW register space
1291 : : */
1292 : : static int
1293 : 0 : ice_copy_rxq_ctx_to_hw(struct ice_hw *hw, u8 *ice_rxq_ctx, u32 rxq_index)
1294 : : {
1295 : : u8 i;
1296 : :
1297 [ # # ]: 0 : if (!ice_rxq_ctx)
1298 : : return ICE_ERR_BAD_PTR;
1299 : :
1300 [ # # ]: 0 : if (rxq_index > QRX_CTRL_MAX_INDEX)
1301 : : return ICE_ERR_PARAM;
1302 : :
1303 : : /* Copy each dword separately to HW */
1304 [ # # ]: 0 : for (i = 0; i < ICE_RXQ_CTX_SIZE_DWORDS; i++) {
1305 : 0 : wr32(hw, QRX_CONTEXT(i, rxq_index),
1306 : : *((u32 *)(ice_rxq_ctx + (i * sizeof(u32)))));
1307 : :
1308 [ # # ]: 0 : ice_debug(hw, ICE_DBG_QCTX, "qrxdata[%d]: %08X\n", i,
1309 : : *((u32 *)(ice_rxq_ctx + (i * sizeof(u32)))));
1310 : : }
1311 : :
1312 : : return 0;
1313 : : }
1314 : :
1315 : : /**
1316 : : * ice_copy_rxq_ctx_from_hw - Copy rxq context register from HW
1317 : : * @hw: pointer to the hardware structure
1318 : : * @ice_rxq_ctx: pointer to the rxq context
1319 : : * @rxq_index: the index of the Rx queue
1320 : : *
1321 : : * Copies rxq context from HW register space to dense structure
1322 : : */
1323 : : static int
1324 : 0 : ice_copy_rxq_ctx_from_hw(struct ice_hw *hw, u8 *ice_rxq_ctx, u32 rxq_index)
1325 : : {
1326 : : u8 i;
1327 : :
1328 [ # # ]: 0 : if (!ice_rxq_ctx)
1329 : : return ICE_ERR_BAD_PTR;
1330 : :
1331 [ # # ]: 0 : if (rxq_index > QRX_CTRL_MAX_INDEX)
1332 : : return ICE_ERR_PARAM;
1333 : :
1334 : : /* Copy each dword separately from HW */
1335 [ # # ]: 0 : for (i = 0; i < ICE_RXQ_CTX_SIZE_DWORDS; i++) {
1336 : 0 : u32 *ctx = (u32 *)(ice_rxq_ctx + (i * sizeof(u32)));
1337 : :
1338 : 0 : *ctx = rd32(hw, QRX_CONTEXT(i, rxq_index));
1339 : :
1340 [ # # ]: 0 : ice_debug(hw, ICE_DBG_QCTX, "qrxdata[%d]: %08X\n", i, *ctx);
1341 : : }
1342 : :
1343 : : return 0;
1344 : : }
1345 : :
1346 : : /* LAN Rx Queue Context */
1347 : : static const struct ice_ctx_ele ice_rlan_ctx_info[] = {
1348 : : /* Field Width LSB */
1349 : : ICE_CTX_STORE(ice_rlan_ctx, head, 13, 0),
1350 : : ICE_CTX_STORE(ice_rlan_ctx, cpuid, 8, 13),
1351 : : ICE_CTX_STORE(ice_rlan_ctx, base, 57, 32),
1352 : : ICE_CTX_STORE(ice_rlan_ctx, qlen, 13, 89),
1353 : : ICE_CTX_STORE(ice_rlan_ctx, dbuf, 7, 102),
1354 : : ICE_CTX_STORE(ice_rlan_ctx, hbuf, 5, 109),
1355 : : ICE_CTX_STORE(ice_rlan_ctx, dtype, 2, 114),
1356 : : ICE_CTX_STORE(ice_rlan_ctx, dsize, 1, 116),
1357 : : ICE_CTX_STORE(ice_rlan_ctx, crcstrip, 1, 117),
1358 : : ICE_CTX_STORE(ice_rlan_ctx, l2tsel, 1, 119),
1359 : : ICE_CTX_STORE(ice_rlan_ctx, hsplit_0, 4, 120),
1360 : : ICE_CTX_STORE(ice_rlan_ctx, hsplit_1, 2, 124),
1361 : : ICE_CTX_STORE(ice_rlan_ctx, showiv, 1, 127),
1362 : : ICE_CTX_STORE(ice_rlan_ctx, rxmax, 14, 174),
1363 : : ICE_CTX_STORE(ice_rlan_ctx, tphrdesc_ena, 1, 193),
1364 : : ICE_CTX_STORE(ice_rlan_ctx, tphwdesc_ena, 1, 194),
1365 : : ICE_CTX_STORE(ice_rlan_ctx, tphdata_ena, 1, 195),
1366 : : ICE_CTX_STORE(ice_rlan_ctx, tphhead_ena, 1, 196),
1367 : : ICE_CTX_STORE(ice_rlan_ctx, lrxqthresh, 3, 198),
1368 : : ICE_CTX_STORE(ice_rlan_ctx, prefena, 1, 201),
1369 : : { 0 }
1370 : : };
1371 : :
1372 : : /**
1373 : : * ice_write_rxq_ctx
1374 : : * @hw: pointer to the hardware structure
1375 : : * @rlan_ctx: pointer to the rxq context
1376 : : * @rxq_index: the index of the Rx queue
1377 : : *
1378 : : * Converts rxq context from sparse to dense structure and then writes
1379 : : * it to HW register space and enables the hardware to prefetch descriptors
1380 : : * instead of only fetching them on demand
1381 : : */
1382 : : int
1383 : 0 : ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx,
1384 : : u32 rxq_index)
1385 : : {
1386 : 0 : u8 ctx_buf[ICE_RXQ_CTX_SZ] = { 0 };
1387 : :
1388 [ # # ]: 0 : if (!rlan_ctx)
1389 : : return ICE_ERR_BAD_PTR;
1390 : :
1391 : 0 : rlan_ctx->prefena = 1;
1392 : :
1393 : 0 : ice_set_ctx(hw, (u8 *)rlan_ctx, ctx_buf, ice_rlan_ctx_info);
1394 : 0 : return ice_copy_rxq_ctx_to_hw(hw, ctx_buf, rxq_index);
1395 : : }
1396 : :
1397 : : /**
1398 : : * ice_read_rxq_ctx - Read rxq context from HW
1399 : : * @hw: pointer to the hardware structure
1400 : : * @rlan_ctx: pointer to the rxq context
1401 : : * @rxq_index: the index of the Rx queue
1402 : : *
1403 : : * Read rxq context from HW register space and then converts it from dense
1404 : : * structure to sparse
1405 : : */
1406 : : int
1407 : 0 : ice_read_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx,
1408 : : u32 rxq_index)
1409 : : {
1410 : 0 : u8 ctx_buf[ICE_RXQ_CTX_SZ] = { 0 };
1411 : : int status;
1412 : :
1413 [ # # ]: 0 : if (!rlan_ctx)
1414 : : return ICE_ERR_BAD_PTR;
1415 : :
1416 : 0 : status = ice_copy_rxq_ctx_from_hw(hw, ctx_buf, rxq_index);
1417 [ # # ]: 0 : if (status)
1418 : : return status;
1419 : :
1420 : 0 : return ice_get_ctx(ctx_buf, (u8 *)rlan_ctx, ice_rlan_ctx_info);
1421 : : }
1422 : :
1423 : : /**
1424 : : * ice_clear_rxq_ctx
1425 : : * @hw: pointer to the hardware structure
1426 : : * @rxq_index: the index of the Rx queue to clear
1427 : : *
1428 : : * Clears rxq context in HW register space
1429 : : */
1430 : 0 : int ice_clear_rxq_ctx(struct ice_hw *hw, u32 rxq_index)
1431 : : {
1432 : : u8 i;
1433 : :
1434 [ # # ]: 0 : if (rxq_index > QRX_CTRL_MAX_INDEX)
1435 : : return ICE_ERR_PARAM;
1436 : :
1437 : : /* Clear each dword register separately */
1438 [ # # ]: 0 : for (i = 0; i < ICE_RXQ_CTX_SIZE_DWORDS; i++)
1439 : 0 : wr32(hw, QRX_CONTEXT(i, rxq_index), 0);
1440 : :
1441 : : return 0;
1442 : : }
1443 : :
1444 : : /* LAN Tx Queue Context used for set Tx config by ice_aqc_opc_add_txqs,
1445 : : * Bit[0-175] is valid
1446 : : */
1447 : : const struct ice_ctx_ele ice_tlan_ctx_info[] = {
1448 : : /* Field Width LSB */
1449 : : ICE_CTX_STORE(ice_tlan_ctx, base, 57, 0),
1450 : : ICE_CTX_STORE(ice_tlan_ctx, port_num, 3, 57),
1451 : : ICE_CTX_STORE(ice_tlan_ctx, cgd_num, 5, 60),
1452 : : ICE_CTX_STORE(ice_tlan_ctx, pf_num, 3, 65),
1453 : : ICE_CTX_STORE(ice_tlan_ctx, vmvf_num, 10, 68),
1454 : : ICE_CTX_STORE(ice_tlan_ctx, vmvf_type, 2, 78),
1455 : : ICE_CTX_STORE(ice_tlan_ctx, src_vsi, 10, 80),
1456 : : ICE_CTX_STORE(ice_tlan_ctx, tsyn_ena, 1, 90),
1457 : : ICE_CTX_STORE(ice_tlan_ctx, internal_usage_flag, 1, 91),
1458 : : ICE_CTX_STORE(ice_tlan_ctx, alt_vlan, 1, 92),
1459 : : ICE_CTX_STORE(ice_tlan_ctx, cpuid, 8, 93),
1460 : : ICE_CTX_STORE(ice_tlan_ctx, wb_mode, 1, 101),
1461 : : ICE_CTX_STORE(ice_tlan_ctx, tphrd_desc, 1, 102),
1462 : : ICE_CTX_STORE(ice_tlan_ctx, tphrd, 1, 103),
1463 : : ICE_CTX_STORE(ice_tlan_ctx, tphwr_desc, 1, 104),
1464 : : ICE_CTX_STORE(ice_tlan_ctx, cmpq_id, 9, 105),
1465 : : ICE_CTX_STORE(ice_tlan_ctx, qnum_in_func, 14, 114),
1466 : : ICE_CTX_STORE(ice_tlan_ctx, itr_notification_mode, 1, 128),
1467 : : ICE_CTX_STORE(ice_tlan_ctx, adjust_prof_id, 6, 129),
1468 : : ICE_CTX_STORE(ice_tlan_ctx, qlen, 13, 135),
1469 : : ICE_CTX_STORE(ice_tlan_ctx, quanta_prof_idx, 4, 148),
1470 : : ICE_CTX_STORE(ice_tlan_ctx, tso_ena, 1, 152),
1471 : : ICE_CTX_STORE(ice_tlan_ctx, tso_qnum, 11, 153),
1472 : : ICE_CTX_STORE(ice_tlan_ctx, legacy_int, 1, 164),
1473 : : ICE_CTX_STORE(ice_tlan_ctx, drop_ena, 1, 165),
1474 : : ICE_CTX_STORE(ice_tlan_ctx, cache_prof_idx, 2, 166),
1475 : : ICE_CTX_STORE(ice_tlan_ctx, pkt_shaper_prof_idx, 3, 168),
1476 : : ICE_CTX_STORE(ice_tlan_ctx, int_q_state, 122, 171),
1477 : : ICE_CTX_STORE(ice_tlan_ctx, gsc_ena, 1, 172),
1478 : : { 0 }
1479 : : };
1480 : :
1481 : : /**
1482 : : * ice_copy_tx_cmpltnq_ctx_to_hw
1483 : : * @hw: pointer to the hardware structure
1484 : : * @ice_tx_cmpltnq_ctx: pointer to the Tx completion queue context
1485 : : * @tx_cmpltnq_index: the index of the completion queue
1486 : : *
1487 : : * Copies Tx completion queue context from dense structure to HW register space
1488 : : */
1489 : : static int
1490 : 0 : ice_copy_tx_cmpltnq_ctx_to_hw(struct ice_hw *hw, u8 *ice_tx_cmpltnq_ctx,
1491 : : u32 tx_cmpltnq_index)
1492 : : {
1493 : : u8 i;
1494 : :
1495 [ # # ]: 0 : if (!ice_tx_cmpltnq_ctx)
1496 : : return ICE_ERR_BAD_PTR;
1497 : :
1498 [ # # ]: 0 : if (tx_cmpltnq_index > GLTCLAN_CQ_CNTX0_MAX_INDEX)
1499 : : return ICE_ERR_PARAM;
1500 : :
1501 : : /* Copy each dword separately to HW */
1502 [ # # ]: 0 : for (i = 0; i < ICE_TX_CMPLTNQ_CTX_SIZE_DWORDS; i++) {
1503 : 0 : wr32(hw, GLTCLAN_CQ_CNTX(i, tx_cmpltnq_index),
1504 : : *((u32 *)(ice_tx_cmpltnq_ctx + (i * sizeof(u32)))));
1505 : :
1506 [ # # ]: 0 : ice_debug(hw, ICE_DBG_QCTX, "cmpltnqdata[%d]: %08X\n", i,
1507 : : *((u32 *)(ice_tx_cmpltnq_ctx + (i * sizeof(u32)))));
1508 : : }
1509 : :
1510 : : return 0;
1511 : : }
1512 : :
1513 : : /* LAN Tx Completion Queue Context */
1514 : : static const struct ice_ctx_ele ice_tx_cmpltnq_ctx_info[] = {
1515 : : /* Field Width LSB */
1516 : : ICE_CTX_STORE(ice_tx_cmpltnq_ctx, base, 57, 0),
1517 : : ICE_CTX_STORE(ice_tx_cmpltnq_ctx, q_len, 18, 64),
1518 : : ICE_CTX_STORE(ice_tx_cmpltnq_ctx, generation, 1, 96),
1519 : : ICE_CTX_STORE(ice_tx_cmpltnq_ctx, wrt_ptr, 22, 97),
1520 : : ICE_CTX_STORE(ice_tx_cmpltnq_ctx, pf_num, 3, 128),
1521 : : ICE_CTX_STORE(ice_tx_cmpltnq_ctx, vmvf_num, 10, 131),
1522 : : ICE_CTX_STORE(ice_tx_cmpltnq_ctx, vmvf_type, 2, 141),
1523 : : ICE_CTX_STORE(ice_tx_cmpltnq_ctx, tph_desc_wr, 1, 160),
1524 : : ICE_CTX_STORE(ice_tx_cmpltnq_ctx, cpuid, 8, 161),
1525 : : ICE_CTX_STORE(ice_tx_cmpltnq_ctx, cmpltn_cache, 512, 192),
1526 : : { 0 }
1527 : : };
1528 : :
1529 : : /**
1530 : : * ice_write_tx_cmpltnq_ctx
1531 : : * @hw: pointer to the hardware structure
1532 : : * @tx_cmpltnq_ctx: pointer to the completion queue context
1533 : : * @tx_cmpltnq_index: the index of the completion queue
1534 : : *
1535 : : * Converts completion queue context from sparse to dense structure and then
1536 : : * writes it to HW register space
1537 : : */
1538 : : int
1539 : 0 : ice_write_tx_cmpltnq_ctx(struct ice_hw *hw,
1540 : : struct ice_tx_cmpltnq_ctx *tx_cmpltnq_ctx,
1541 : : u32 tx_cmpltnq_index)
1542 : : {
1543 : 0 : u8 ctx_buf[ICE_TX_CMPLTNQ_CTX_SIZE_DWORDS * sizeof(u32)] = { 0 };
1544 : :
1545 : 0 : ice_set_ctx(hw, (u8 *)tx_cmpltnq_ctx, ctx_buf, ice_tx_cmpltnq_ctx_info);
1546 : 0 : return ice_copy_tx_cmpltnq_ctx_to_hw(hw, ctx_buf, tx_cmpltnq_index);
1547 : : }
1548 : :
1549 : : /**
1550 : : * ice_clear_tx_cmpltnq_ctx
1551 : : * @hw: pointer to the hardware structure
1552 : : * @tx_cmpltnq_index: the index of the completion queue to clear
1553 : : *
1554 : : * Clears Tx completion queue context in HW register space
1555 : : */
1556 : : int
1557 : 0 : ice_clear_tx_cmpltnq_ctx(struct ice_hw *hw, u32 tx_cmpltnq_index)
1558 : : {
1559 : : u8 i;
1560 : :
1561 [ # # ]: 0 : if (tx_cmpltnq_index > GLTCLAN_CQ_CNTX0_MAX_INDEX)
1562 : : return ICE_ERR_PARAM;
1563 : :
1564 : : /* Clear each dword register separately */
1565 [ # # ]: 0 : for (i = 0; i < ICE_TX_CMPLTNQ_CTX_SIZE_DWORDS; i++)
1566 : 0 : wr32(hw, GLTCLAN_CQ_CNTX(i, tx_cmpltnq_index), 0);
1567 : :
1568 : : return 0;
1569 : : }
1570 : :
1571 : : /**
1572 : : * ice_copy_tx_drbell_q_ctx_to_hw
1573 : : * @hw: pointer to the hardware structure
1574 : : * @ice_tx_drbell_q_ctx: pointer to the doorbell queue context
1575 : : * @tx_drbell_q_index: the index of the doorbell queue
1576 : : *
1577 : : * Copies doorbell queue context from dense structure to HW register space
1578 : : */
1579 : : static int
1580 : 0 : ice_copy_tx_drbell_q_ctx_to_hw(struct ice_hw *hw, u8 *ice_tx_drbell_q_ctx,
1581 : : u32 tx_drbell_q_index)
1582 : : {
1583 : : u8 i;
1584 : :
1585 [ # # ]: 0 : if (!ice_tx_drbell_q_ctx)
1586 : : return ICE_ERR_BAD_PTR;
1587 : :
1588 [ # # ]: 0 : if (tx_drbell_q_index > QTX_COMM_DBLQ_DBELL_MAX_INDEX)
1589 : : return ICE_ERR_PARAM;
1590 : :
1591 : : /* Copy each dword separately to HW */
1592 [ # # ]: 0 : for (i = 0; i < ICE_TX_DRBELL_Q_CTX_SIZE_DWORDS; i++) {
1593 : 0 : wr32(hw, QTX_COMM_DBLQ_CNTX(i, tx_drbell_q_index),
1594 : : *((u32 *)(ice_tx_drbell_q_ctx + (i * sizeof(u32)))));
1595 : :
1596 [ # # ]: 0 : ice_debug(hw, ICE_DBG_QCTX, "tx_drbell_qdata[%d]: %08X\n", i,
1597 : : *((u32 *)(ice_tx_drbell_q_ctx + (i * sizeof(u32)))));
1598 : : }
1599 : :
1600 : : return 0;
1601 : : }
1602 : :
1603 : : /* LAN Tx Doorbell Queue Context info */
1604 : : static const struct ice_ctx_ele ice_tx_drbell_q_ctx_info[] = {
1605 : : /* Field Width LSB */
1606 : : ICE_CTX_STORE(ice_tx_drbell_q_ctx, base, 57, 0),
1607 : : ICE_CTX_STORE(ice_tx_drbell_q_ctx, ring_len, 13, 64),
1608 : : ICE_CTX_STORE(ice_tx_drbell_q_ctx, pf_num, 3, 80),
1609 : : ICE_CTX_STORE(ice_tx_drbell_q_ctx, vf_num, 8, 84),
1610 : : ICE_CTX_STORE(ice_tx_drbell_q_ctx, vmvf_type, 2, 94),
1611 : : ICE_CTX_STORE(ice_tx_drbell_q_ctx, cpuid, 8, 96),
1612 : : ICE_CTX_STORE(ice_tx_drbell_q_ctx, tph_desc_rd, 1, 104),
1613 : : ICE_CTX_STORE(ice_tx_drbell_q_ctx, tph_desc_wr, 1, 108),
1614 : : ICE_CTX_STORE(ice_tx_drbell_q_ctx, db_q_en, 1, 112),
1615 : : ICE_CTX_STORE(ice_tx_drbell_q_ctx, rd_head, 13, 128),
1616 : : ICE_CTX_STORE(ice_tx_drbell_q_ctx, rd_tail, 13, 144),
1617 : : { 0 }
1618 : : };
1619 : :
1620 : : /**
1621 : : * ice_write_tx_drbell_q_ctx
1622 : : * @hw: pointer to the hardware structure
1623 : : * @tx_drbell_q_ctx: pointer to the doorbell queue context
1624 : : * @tx_drbell_q_index: the index of the doorbell queue
1625 : : *
1626 : : * Converts doorbell queue context from sparse to dense structure and then
1627 : : * writes it to HW register space
1628 : : */
1629 : : int
1630 : 0 : ice_write_tx_drbell_q_ctx(struct ice_hw *hw,
1631 : : struct ice_tx_drbell_q_ctx *tx_drbell_q_ctx,
1632 : : u32 tx_drbell_q_index)
1633 : : {
1634 : 0 : u8 ctx_buf[ICE_TX_DRBELL_Q_CTX_SIZE_DWORDS * sizeof(u32)] = { 0 };
1635 : :
1636 : 0 : ice_set_ctx(hw, (u8 *)tx_drbell_q_ctx, ctx_buf,
1637 : : ice_tx_drbell_q_ctx_info);
1638 : 0 : return ice_copy_tx_drbell_q_ctx_to_hw(hw, ctx_buf, tx_drbell_q_index);
1639 : : }
1640 : :
1641 : : /**
1642 : : * ice_clear_tx_drbell_q_ctx
1643 : : * @hw: pointer to the hardware structure
1644 : : * @tx_drbell_q_index: the index of the doorbell queue to clear
1645 : : *
1646 : : * Clears doorbell queue context in HW register space
1647 : : */
1648 : : int
1649 : 0 : ice_clear_tx_drbell_q_ctx(struct ice_hw *hw, u32 tx_drbell_q_index)
1650 : : {
1651 : : u8 i;
1652 : :
1653 [ # # ]: 0 : if (tx_drbell_q_index > QTX_COMM_DBLQ_DBELL_MAX_INDEX)
1654 : : return ICE_ERR_PARAM;
1655 : :
1656 : : /* Clear each dword register separately */
1657 [ # # ]: 0 : for (i = 0; i < ICE_TX_DRBELL_Q_CTX_SIZE_DWORDS; i++)
1658 : 0 : wr32(hw, QTX_COMM_DBLQ_CNTX(i, tx_drbell_q_index), 0);
1659 : :
1660 : : return 0;
1661 : : }
1662 : :
1663 : : /* Sideband Queue command wrappers */
1664 : :
1665 : : /**
1666 : : * ice_get_sbq - returns the right control queue to use for sideband
1667 : : * @hw: pointer to the hardware structure
1668 : : */
1669 : : static struct ice_ctl_q_info *ice_get_sbq(struct ice_hw *hw)
1670 : : {
1671 [ # # # # : 0 : if (!ice_is_generic_mac(hw))
# # # # ]
1672 : 0 : return &hw->adminq;
1673 : 0 : return &hw->sbq;
1674 : : }
1675 : :
1676 : : /**
1677 : : * ice_sbq_send_cmd - send Sideband Queue command to Sideband Queue
1678 : : * @hw: pointer to the HW struct
1679 : : * @desc: descriptor describing the command
1680 : : * @buf: buffer to use for indirect commands (NULL for direct commands)
1681 : : * @buf_size: size of buffer for indirect commands (0 for direct commands)
1682 : : * @cd: pointer to command details structure
1683 : : */
1684 : : static int
1685 : 0 : ice_sbq_send_cmd(struct ice_hw *hw, struct ice_sbq_cmd_desc *desc,
1686 : : void *buf, u16 buf_size, struct ice_sq_cd *cd)
1687 : : {
1688 : 0 : return ice_sq_send_cmd(hw, ice_get_sbq(hw), (struct ice_aq_desc *)desc,
1689 : : buf, buf_size, cd);
1690 : : }
1691 : :
1692 : : /**
1693 : : * ice_sbq_send_cmd_nolock - send Sideband Queue command to Sideband Queue
1694 : : * but do not lock sq_lock
1695 : : * @hw: pointer to the HW struct
1696 : : * @desc: descriptor describing the command
1697 : : * @buf: buffer to use for indirect commands (NULL for direct commands)
1698 : : * @buf_size: size of buffer for indirect commands (0 for direct commands)
1699 : : * @cd: pointer to command details structure
1700 : : */
1701 : : static int
1702 : 0 : ice_sbq_send_cmd_nolock(struct ice_hw *hw, struct ice_sbq_cmd_desc *desc,
1703 : : void *buf, u16 buf_size, struct ice_sq_cd *cd)
1704 : : {
1705 : 0 : return ice_sq_send_cmd_nolock(hw, ice_get_sbq(hw),
1706 : : (struct ice_aq_desc *)desc, buf,
1707 : : buf_size, cd);
1708 : : }
1709 : :
1710 : : /**
1711 : : * ice_sbq_rw_reg_lp - Fill Sideband Queue command, with lock parameter
1712 : : * @hw: pointer to the HW struct
1713 : : * @in: message info to be filled in descriptor
1714 : : * @flag: flag to fill desc structure
1715 : : * @lock: true to lock the sq_lock (the usual case); false if the sq_lock has
1716 : : * already been locked at a higher level
1717 : : */
1718 : 0 : int ice_sbq_rw_reg_lp(struct ice_hw *hw, struct ice_sbq_msg_input *in,
1719 : : u16 flag, bool lock)
1720 : : {
1721 : 0 : struct ice_sbq_cmd_desc desc = {0};
1722 : 0 : struct ice_sbq_msg_req msg = {0};
1723 : : u16 msg_len;
1724 : : int status;
1725 : :
1726 : : msg_len = sizeof(msg);
1727 : :
1728 : 0 : msg.dest_dev = in->dest_dev;
1729 : 0 : msg.opcode = in->opcode;
1730 : 0 : msg.flags = ICE_SBQ_MSG_FLAGS;
1731 : 0 : msg.sbe_fbe = ICE_SBQ_MSG_SBE_FBE;
1732 : 0 : msg.msg_addr_low = CPU_TO_LE16(in->msg_addr_low);
1733 : 0 : msg.msg_addr_high = CPU_TO_LE32(in->msg_addr_high);
1734 : :
1735 [ # # ]: 0 : if (in->opcode)
1736 : 0 : msg.data = CPU_TO_LE32(in->data);
1737 : : else
1738 : : /* data read comes back in completion, so shorten the struct by
1739 : : * sizeof(msg.data)
1740 : : */
1741 : : msg_len -= sizeof(msg.data);
1742 : :
1743 : 0 : desc.flags = CPU_TO_LE16(flag);
1744 : 0 : desc.opcode = CPU_TO_LE16(ice_sbq_opc_neigh_dev_req);
1745 : 0 : desc.param0.cmd_len = CPU_TO_LE16(msg_len);
1746 [ # # ]: 0 : if (lock)
1747 : 0 : status = ice_sbq_send_cmd(hw, &desc, &msg, msg_len, NULL);
1748 : : else
1749 : 0 : status = ice_sbq_send_cmd_nolock(hw, &desc, &msg, msg_len,
1750 : : NULL);
1751 [ # # # # ]: 0 : if (!status && !in->opcode)
1752 : 0 : in->data = LE32_TO_CPU
1753 : : (((struct ice_sbq_msg_cmpl *)&msg)->data);
1754 : 0 : return status;
1755 : : }
1756 : :
1757 : : /**
1758 : : * ice_sbq_rw_reg - Fill Sideband Queue command
1759 : : * @hw: pointer to the HW struct
1760 : : * @in: message info to be filled in descriptor
1761 : : * @flag: flag to fill desc structure
1762 : : */
1763 : 0 : int ice_sbq_rw_reg(struct ice_hw *hw, struct ice_sbq_msg_input *in, u16 flag)
1764 : : {
1765 : 0 : return ice_sbq_rw_reg_lp(hw, in, flag, true);
1766 : : }
1767 : :
1768 : : /**
1769 : : * ice_sbq_lock - Lock the sideband queue's sq_lock
1770 : : * @hw: pointer to the HW struct
1771 : : */
1772 : 0 : void ice_sbq_lock(struct ice_hw *hw)
1773 : : {
1774 : 0 : ice_acquire_lock(&ice_get_sbq(hw)->sq_lock);
1775 : 0 : }
1776 : :
1777 : : /**
1778 : : * ice_sbq_unlock - Unlock the sideband queue's sq_lock
1779 : : * @hw: pointer to the HW struct
1780 : : */
1781 : 0 : void ice_sbq_unlock(struct ice_hw *hw)
1782 : : {
1783 : 0 : ice_release_lock(&ice_get_sbq(hw)->sq_lock);
1784 : 0 : }
1785 : :
1786 : : /* FW Admin Queue command wrappers */
1787 : :
1788 : : /**
1789 : : * ice_should_retry_sq_send_cmd
1790 : : * @opcode: AQ opcode
1791 : : *
1792 : : * Decide if we should retry the send command routine for the ATQ, depending
1793 : : * on the opcode.
1794 : : */
1795 : : static bool ice_should_retry_sq_send_cmd(u16 opcode)
1796 : : {
1797 : 0 : switch (opcode) {
1798 : : case ice_aqc_opc_get_link_topo:
1799 : : case ice_aqc_opc_lldp_stop:
1800 : : case ice_aqc_opc_lldp_start:
1801 : : case ice_aqc_opc_lldp_filter_ctrl:
1802 : : return true;
1803 : : }
1804 : :
1805 : 0 : return false;
1806 : : }
1807 : :
1808 : : /**
1809 : : * ice_sq_send_cmd_retry - send command to Control Queue (ATQ)
1810 : : * @hw: pointer to the HW struct
1811 : : * @cq: pointer to the specific Control queue
1812 : : * @desc: prefilled descriptor describing the command
1813 : : * @buf: buffer to use for indirect commands (or NULL for direct commands)
1814 : : * @buf_size: size of buffer for indirect commands (or 0 for direct commands)
1815 : : * @cd: pointer to command details structure
1816 : : *
1817 : : * Retry sending the FW Admin Queue command, multiple times, to the FW Admin
1818 : : * Queue if the EBUSY AQ error is returned.
1819 : : */
1820 : : static int
1821 : 0 : ice_sq_send_cmd_retry(struct ice_hw *hw, struct ice_ctl_q_info *cq,
1822 : : struct ice_aq_desc *desc, void *buf, u16 buf_size,
1823 : : struct ice_sq_cd *cd)
1824 : : {
1825 : : struct ice_aq_desc desc_cpy;
1826 : : bool is_cmd_for_retry;
1827 : : u8 *buf_cpy = NULL;
1828 : : u8 idx = 0;
1829 : : u16 opcode;
1830 : : int status;
1831 : :
1832 [ # # ]: 0 : opcode = LE16_TO_CPU(desc->opcode);
1833 : : is_cmd_for_retry = ice_should_retry_sq_send_cmd(opcode);
1834 : : ice_memset(&desc_cpy, 0, sizeof(desc_cpy), ICE_NONDMA_MEM);
1835 : :
1836 [ # # ]: 0 : if (is_cmd_for_retry) {
1837 [ # # ]: 0 : if (buf) {
1838 : 0 : buf_cpy = (u8 *)ice_malloc(hw, buf_size);
1839 [ # # ]: 0 : if (!buf_cpy)
1840 : : return ICE_ERR_NO_MEMORY;
1841 : : }
1842 : :
1843 : : ice_memcpy(&desc_cpy, desc, sizeof(desc_cpy),
1844 : : ICE_NONDMA_TO_NONDMA);
1845 : : }
1846 : :
1847 : : do {
1848 : 0 : status = ice_sq_send_cmd(hw, cq, desc, buf, buf_size, cd);
1849 : :
1850 [ # # ]: 0 : if (!is_cmd_for_retry || !status ||
1851 [ # # ]: 0 : hw->adminq.sq_last_status != ICE_AQ_RC_EBUSY)
1852 : : break;
1853 : :
1854 [ # # ]: 0 : if (buf_cpy)
1855 [ # # ]: 0 : ice_memcpy(buf, buf_cpy, buf_size,
1856 : : ICE_NONDMA_TO_NONDMA);
1857 : :
1858 : : ice_memcpy(desc, &desc_cpy, sizeof(desc_cpy),
1859 : : ICE_NONDMA_TO_NONDMA);
1860 : :
1861 : 0 : ice_msec_delay(ICE_SQ_SEND_DELAY_TIME_MS, false);
1862 : :
1863 [ # # ]: 0 : } while (++idx < ICE_SQ_SEND_MAX_EXECUTE);
1864 : :
1865 [ # # ]: 0 : if (buf_cpy)
1866 : 0 : ice_free(hw, buf_cpy);
1867 : :
1868 : : return status;
1869 : : }
1870 : :
1871 : : /**
1872 : : * ice_aq_send_cmd - send FW Admin Queue command to FW Admin Queue
1873 : : * @hw: pointer to the HW struct
1874 : : * @desc: descriptor describing the command
1875 : : * @buf: buffer to use for indirect commands (NULL for direct commands)
1876 : : * @buf_size: size of buffer for indirect commands (0 for direct commands)
1877 : : * @cd: pointer to command details structure
1878 : : *
1879 : : * Helper function to send FW Admin Queue commands to the FW Admin Queue.
1880 : : */
1881 : : int
1882 : 0 : ice_aq_send_cmd(struct ice_hw *hw, struct ice_aq_desc *desc, void *buf,
1883 : : u16 buf_size, struct ice_sq_cd *cd)
1884 : : {
1885 [ # # ]: 0 : if (hw->aq_send_cmd_fn) {
1886 : : u16 retval = ICE_AQ_RC_OK;
1887 : : int status = ICE_ERR_NOT_READY;
1888 : :
1889 : 0 : ice_acquire_lock(&hw->adminq.sq_lock);
1890 [ # # ]: 0 : if (!hw->aq_send_cmd_fn(hw->aq_send_cmd_param, desc,
1891 : : buf, buf_size)) {
1892 : 0 : retval = LE16_TO_CPU(desc->retval);
1893 : : /* strip off FW internal code */
1894 [ # # ]: 0 : if (retval)
1895 : 0 : retval &= 0xff;
1896 [ # # ]: 0 : if (retval == ICE_AQ_RC_OK)
1897 : : status = 0;
1898 : : else
1899 : : status = ICE_ERR_AQ_ERROR;
1900 : : }
1901 : :
1902 : 0 : hw->adminq.sq_last_status = (enum ice_aq_err)retval;
1903 : : ice_release_lock(&hw->adminq.sq_lock);
1904 : :
1905 : 0 : return status;
1906 : : }
1907 : 0 : return ice_sq_send_cmd_retry(hw, &hw->adminq, desc, buf, buf_size, cd);
1908 : : }
1909 : :
1910 : : /**
1911 : : * ice_aq_get_fw_ver
1912 : : * @hw: pointer to the HW struct
1913 : : * @cd: pointer to command details structure or NULL
1914 : : *
1915 : : * Get the firmware version (0x0001) from the admin queue commands
1916 : : */
1917 : 0 : int ice_aq_get_fw_ver(struct ice_hw *hw, struct ice_sq_cd *cd)
1918 : : {
1919 : : struct ice_aqc_get_ver *resp;
1920 : : struct ice_aq_desc desc;
1921 : : int status;
1922 : :
1923 : : resp = &desc.params.get_ver;
1924 : :
1925 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_ver);
1926 : :
1927 : 0 : status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
1928 : :
1929 [ # # ]: 0 : if (!status) {
1930 : 0 : hw->fw_branch = resp->fw_branch;
1931 : 0 : hw->fw_maj_ver = resp->fw_major;
1932 : 0 : hw->fw_min_ver = resp->fw_minor;
1933 : 0 : hw->fw_patch = resp->fw_patch;
1934 : 0 : hw->fw_build = LE32_TO_CPU(resp->fw_build);
1935 : 0 : hw->api_branch = resp->api_branch;
1936 : 0 : hw->api_maj_ver = resp->api_major;
1937 : 0 : hw->api_min_ver = resp->api_minor;
1938 : 0 : hw->api_patch = resp->api_patch;
1939 : : }
1940 : :
1941 : 0 : return status;
1942 : : }
1943 : :
1944 : : /**
1945 : : * ice_aq_send_driver_ver
1946 : : * @hw: pointer to the HW struct
1947 : : * @dv: driver's major, minor version
1948 : : * @cd: pointer to command details structure or NULL
1949 : : *
1950 : : * Send the driver version (0x0002) to the firmware
1951 : : */
1952 : : int
1953 : 0 : ice_aq_send_driver_ver(struct ice_hw *hw, struct ice_driver_ver *dv,
1954 : : struct ice_sq_cd *cd)
1955 : : {
1956 : : struct ice_aqc_driver_ver *cmd;
1957 : : struct ice_aq_desc desc;
1958 : : u16 len;
1959 : :
1960 : : cmd = &desc.params.driver_ver;
1961 : :
1962 [ # # ]: 0 : if (!dv)
1963 : : return ICE_ERR_PARAM;
1964 : :
1965 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_driver_ver);
1966 : :
1967 : 0 : desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
1968 : 0 : cmd->major_ver = dv->major_ver;
1969 : 0 : cmd->minor_ver = dv->minor_ver;
1970 : 0 : cmd->build_ver = dv->build_ver;
1971 : 0 : cmd->subbuild_ver = dv->subbuild_ver;
1972 : :
1973 : : len = 0;
1974 : 0 : while (len < sizeof(dv->driver_string) &&
1975 [ # # # # : 0 : IS_ASCII(dv->driver_string[len]) && dv->driver_string[len])
# # ]
1976 : 0 : len++;
1977 : :
1978 : 0 : return ice_aq_send_cmd(hw, &desc, dv->driver_string, len, cd);
1979 : : }
1980 : :
1981 : : /**
1982 : : * ice_aq_q_shutdown
1983 : : * @hw: pointer to the HW struct
1984 : : * @unloading: is the driver unloading itself
1985 : : *
1986 : : * Tell the Firmware that we're shutting down the AdminQ and whether
1987 : : * or not the driver is unloading as well (0x0003).
1988 : : */
1989 : 0 : int ice_aq_q_shutdown(struct ice_hw *hw, bool unloading)
1990 : : {
1991 : : struct ice_aqc_q_shutdown *cmd;
1992 : : struct ice_aq_desc desc;
1993 : :
1994 : : cmd = &desc.params.q_shutdown;
1995 : :
1996 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_q_shutdown);
1997 : :
1998 [ # # ]: 0 : if (unloading)
1999 : 0 : cmd->driver_unloading = ICE_AQC_DRIVER_UNLOADING;
2000 : :
2001 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
2002 : : }
2003 : :
2004 : : /**
2005 : : * ice_aq_req_res
2006 : : * @hw: pointer to the HW struct
2007 : : * @res: resource ID
2008 : : * @access: access type
2009 : : * @sdp_number: resource number
2010 : : * @timeout: the maximum time in ms that the driver may hold the resource
2011 : : * @cd: pointer to command details structure or NULL
2012 : : *
2013 : : * Requests common resource using the admin queue commands (0x0008).
2014 : : * When attempting to acquire the Global Config Lock, the driver can
2015 : : * learn of three states:
2016 : : * 1) 0 - acquired lock, and can perform download package
2017 : : * 2) ICE_ERR_AQ_ERROR - did not get lock, driver should fail to load
2018 : : * 3) ICE_ERR_AQ_NO_WORK - did not get lock, but another driver has
2019 : : * successfully downloaded the package; the driver does
2020 : : * not have to download the package and can continue
2021 : : * loading
2022 : : *
2023 : : * Note that if the caller is in an acquire lock, perform action, release lock
2024 : : * phase of operation, it is possible that the FW may detect a timeout and issue
2025 : : * a CORER. In this case, the driver will receive a CORER interrupt and will
2026 : : * have to determine its cause. The calling thread that is handling this flow
2027 : : * will likely get an error propagated back to it indicating the Download
2028 : : * Package, Update Package or the Release Resource AQ commands timed out.
2029 : : */
2030 : : static int
2031 : 0 : ice_aq_req_res(struct ice_hw *hw, enum ice_aq_res_ids res,
2032 : : enum ice_aq_res_access_type access, u8 sdp_number, u32 *timeout,
2033 : : struct ice_sq_cd *cd)
2034 : : {
2035 : : struct ice_aqc_req_res *cmd_resp;
2036 : : struct ice_aq_desc desc;
2037 : : int status;
2038 : :
2039 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
2040 : :
2041 : : cmd_resp = &desc.params.res_owner;
2042 : :
2043 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_req_res);
2044 : :
2045 : 0 : cmd_resp->res_id = CPU_TO_LE16(res);
2046 : 0 : cmd_resp->access_type = CPU_TO_LE16(access);
2047 : 0 : cmd_resp->res_number = CPU_TO_LE32(sdp_number);
2048 : 0 : cmd_resp->timeout = CPU_TO_LE32(*timeout);
2049 : 0 : *timeout = 0;
2050 : :
2051 : 0 : status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
2052 : :
2053 : : /* The completion specifies the maximum time in ms that the driver
2054 : : * may hold the resource in the Timeout field.
2055 : : */
2056 : :
2057 : : /* Global config lock response utilizes an additional status field.
2058 : : *
2059 : : * If the Global config lock resource is held by some other driver, the
2060 : : * command completes with ICE_AQ_RES_GLBL_IN_PROG in the status field
2061 : : * and the timeout field indicates the maximum time the current owner
2062 : : * of the resource has to free it.
2063 : : */
2064 [ # # ]: 0 : if (res == ICE_GLOBAL_CFG_LOCK_RES_ID) {
2065 [ # # ]: 0 : if (LE16_TO_CPU(cmd_resp->status) == ICE_AQ_RES_GLBL_SUCCESS) {
2066 : 0 : *timeout = LE32_TO_CPU(cmd_resp->timeout);
2067 : 0 : return 0;
2068 [ # # ]: 0 : } else if (LE16_TO_CPU(cmd_resp->status) ==
2069 : : ICE_AQ_RES_GLBL_IN_PROG) {
2070 : 0 : *timeout = LE32_TO_CPU(cmd_resp->timeout);
2071 : 0 : return ICE_ERR_AQ_ERROR;
2072 [ # # ]: 0 : } else if (LE16_TO_CPU(cmd_resp->status) ==
2073 : : ICE_AQ_RES_GLBL_DONE) {
2074 : : return ICE_ERR_AQ_NO_WORK;
2075 : : }
2076 : :
2077 : : /* invalid FW response, force a timeout immediately */
2078 : 0 : *timeout = 0;
2079 : 0 : return ICE_ERR_AQ_ERROR;
2080 : : }
2081 : :
2082 : : /* If the resource is held by some other driver, the command completes
2083 : : * with a busy return value and the timeout field indicates the maximum
2084 : : * time the current owner of the resource has to free it.
2085 : : */
2086 [ # # # # ]: 0 : if (!status || hw->adminq.sq_last_status == ICE_AQ_RC_EBUSY)
2087 : 0 : *timeout = LE32_TO_CPU(cmd_resp->timeout);
2088 : :
2089 : : return status;
2090 : : }
2091 : :
2092 : : /**
2093 : : * ice_aq_release_res
2094 : : * @hw: pointer to the HW struct
2095 : : * @res: resource ID
2096 : : * @sdp_number: resource number
2097 : : * @cd: pointer to command details structure or NULL
2098 : : *
2099 : : * release common resource using the admin queue commands (0x0009)
2100 : : */
2101 : : static int
2102 : 0 : ice_aq_release_res(struct ice_hw *hw, enum ice_aq_res_ids res, u8 sdp_number,
2103 : : struct ice_sq_cd *cd)
2104 : : {
2105 : : struct ice_aqc_req_res *cmd;
2106 : : struct ice_aq_desc desc;
2107 : :
2108 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
2109 : :
2110 : : cmd = &desc.params.res_owner;
2111 : :
2112 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_release_res);
2113 : :
2114 : 0 : cmd->res_id = CPU_TO_LE16(res);
2115 : 0 : cmd->res_number = CPU_TO_LE32(sdp_number);
2116 : :
2117 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
2118 : : }
2119 : :
2120 : : /**
2121 : : * ice_acquire_res
2122 : : * @hw: pointer to the HW structure
2123 : : * @res: resource ID
2124 : : * @access: access type (read or write)
2125 : : * @timeout: timeout in milliseconds
2126 : : *
2127 : : * This function will attempt to acquire the ownership of a resource.
2128 : : */
2129 : : int
2130 : 0 : ice_acquire_res(struct ice_hw *hw, enum ice_aq_res_ids res,
2131 : : enum ice_aq_res_access_type access, u32 timeout)
2132 : : {
2133 : : #define ICE_RES_POLLING_DELAY_MS 10
2134 : : u32 delay = ICE_RES_POLLING_DELAY_MS;
2135 : 0 : u32 time_left = timeout;
2136 : : int status;
2137 : :
2138 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
2139 : :
2140 : 0 : status = ice_aq_req_res(hw, res, access, 0, &time_left, NULL);
2141 : :
2142 : : /* A return code of ICE_ERR_AQ_NO_WORK means that another driver has
2143 : : * previously acquired the resource and performed any necessary updates;
2144 : : * in this case the caller does not obtain the resource and has no
2145 : : * further work to do.
2146 : : */
2147 [ # # ]: 0 : if (status == ICE_ERR_AQ_NO_WORK)
2148 : 0 : goto ice_acquire_res_exit;
2149 : :
2150 [ # # ]: 0 : if (status)
2151 [ # # ]: 0 : ice_debug(hw, ICE_DBG_RES, "resource %d acquire type %d failed.\n", res, access);
2152 : :
2153 : : /* If necessary, poll until the current lock owner timeouts */
2154 : 0 : timeout = time_left;
2155 [ # # # # ]: 0 : while (status && timeout && time_left) {
2156 : 0 : ice_msec_delay(delay, true);
2157 [ # # ]: 0 : timeout = (timeout > delay) ? timeout - delay : 0;
2158 : 0 : status = ice_aq_req_res(hw, res, access, 0, &time_left, NULL);
2159 : :
2160 [ # # ]: 0 : if (status == ICE_ERR_AQ_NO_WORK)
2161 : : /* lock free, but no work to do */
2162 : : break;
2163 : :
2164 [ # # ]: 0 : if (!status)
2165 : : /* lock acquired */
2166 : : break;
2167 : : }
2168 [ # # ]: 0 : if (status && status != ICE_ERR_AQ_NO_WORK)
2169 [ # # ]: 0 : ice_debug(hw, ICE_DBG_RES, "resource acquire timed out.\n");
2170 : :
2171 : 0 : ice_acquire_res_exit:
2172 [ # # ]: 0 : if (status == ICE_ERR_AQ_NO_WORK) {
2173 [ # # ]: 0 : if (access == ICE_RES_WRITE)
2174 [ # # ]: 0 : ice_debug(hw, ICE_DBG_RES, "resource indicates no work to do.\n");
2175 : : else
2176 [ # # ]: 0 : ice_debug(hw, ICE_DBG_RES, "Warning: ICE_ERR_AQ_NO_WORK not expected\n");
2177 : : }
2178 : 0 : return status;
2179 : : }
2180 : :
2181 : : /**
2182 : : * ice_release_res
2183 : : * @hw: pointer to the HW structure
2184 : : * @res: resource ID
2185 : : *
2186 : : * This function will release a resource using the proper Admin Command.
2187 : : */
2188 : 0 : void ice_release_res(struct ice_hw *hw, enum ice_aq_res_ids res)
2189 : : {
2190 : : u32 total_delay = 0;
2191 : : int status;
2192 : :
2193 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
2194 : :
2195 : 0 : status = ice_aq_release_res(hw, res, 0, NULL);
2196 : :
2197 : : /* there are some rare cases when trying to release the resource
2198 : : * results in an admin queue timeout, so handle them correctly
2199 : : */
2200 [ # # ]: 0 : while ((status == ICE_ERR_AQ_TIMEOUT) &&
2201 [ # # ]: 0 : (total_delay < hw->adminq.sq_cmd_timeout)) {
2202 : 0 : ice_msec_delay(1, true);
2203 : 0 : status = ice_aq_release_res(hw, res, 0, NULL);
2204 : 0 : total_delay++;
2205 : : }
2206 : 0 : }
2207 : :
2208 : : /**
2209 : : * ice_aq_alloc_free_res - command to allocate/free resources
2210 : : * @hw: pointer to the HW struct
2211 : : * @num_entries: number of resource entries in buffer
2212 : : * @buf: Indirect buffer to hold data parameters and response
2213 : : * @buf_size: size of buffer for indirect commands
2214 : : * @opc: pass in the command opcode
2215 : : * @cd: pointer to command details structure or NULL
2216 : : *
2217 : : * Helper function to allocate/free resources using the admin queue commands
2218 : : */
2219 : : int
2220 : 0 : ice_aq_alloc_free_res(struct ice_hw *hw, u16 num_entries,
2221 : : struct ice_aqc_alloc_free_res_elem *buf, u16 buf_size,
2222 : : enum ice_adminq_opc opc, struct ice_sq_cd *cd)
2223 : : {
2224 : : struct ice_aqc_alloc_free_res_cmd *cmd;
2225 : : struct ice_aq_desc desc;
2226 : :
2227 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
2228 : :
2229 : : cmd = &desc.params.sw_res_ctrl;
2230 : :
2231 [ # # ]: 0 : if (!buf)
2232 : : return ICE_ERR_PARAM;
2233 : :
2234 [ # # ]: 0 : if (buf_size < FLEX_ARRAY_SIZE(buf, elem, num_entries))
2235 : : return ICE_ERR_PARAM;
2236 : :
2237 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, opc);
2238 : :
2239 : 0 : desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
2240 : :
2241 : 0 : cmd->num_entries = CPU_TO_LE16(num_entries);
2242 : :
2243 : 0 : return ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
2244 : : }
2245 : :
2246 : : /**
2247 : : * ice_alloc_hw_res - allocate resource
2248 : : * @hw: pointer to the HW struct
2249 : : * @type: type of resource
2250 : : * @num: number of resources to allocate
2251 : : * @btm: allocate from bottom
2252 : : * @res: pointer to array that will receive the resources
2253 : : */
2254 : : int
2255 : 0 : ice_alloc_hw_res(struct ice_hw *hw, u16 type, u16 num, bool btm, u16 *res)
2256 : : {
2257 : : struct ice_aqc_alloc_free_res_elem *buf;
2258 : : u16 buf_len;
2259 : : int status;
2260 : :
2261 : 0 : buf_len = ice_struct_size(buf, elem, num);
2262 : 0 : buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
2263 [ # # ]: 0 : if (!buf)
2264 : : return ICE_ERR_NO_MEMORY;
2265 : :
2266 : : /* Prepare buffer to allocate resource. */
2267 : 0 : buf->num_elems = CPU_TO_LE16(num);
2268 : 0 : buf->res_type = CPU_TO_LE16(type | ICE_AQC_RES_TYPE_FLAG_DEDICATED |
2269 : : ICE_AQC_RES_TYPE_FLAG_IGNORE_INDEX);
2270 [ # # ]: 0 : if (btm)
2271 : 0 : buf->res_type |= CPU_TO_LE16(ICE_AQC_RES_TYPE_FLAG_SCAN_BOTTOM);
2272 : :
2273 : 0 : status = ice_aq_alloc_free_res(hw, 1, buf, buf_len,
2274 : : ice_aqc_opc_alloc_res, NULL);
2275 [ # # ]: 0 : if (status)
2276 : 0 : goto ice_alloc_res_exit;
2277 : :
2278 [ # # ]: 0 : ice_memcpy(res, buf->elem, sizeof(*buf->elem) * num,
2279 : : ICE_NONDMA_TO_NONDMA);
2280 : :
2281 : 0 : ice_alloc_res_exit:
2282 : 0 : ice_free(hw, buf);
2283 : 0 : return status;
2284 : : }
2285 : :
2286 : : /**
2287 : : * ice_free_hw_res - free allocated HW resource
2288 : : * @hw: pointer to the HW struct
2289 : : * @type: type of resource to free
2290 : : * @num: number of resources
2291 : : * @res: pointer to array that contains the resources to free
2292 : : */
2293 : 0 : int ice_free_hw_res(struct ice_hw *hw, u16 type, u16 num, u16 *res)
2294 : : {
2295 : : struct ice_aqc_alloc_free_res_elem *buf;
2296 : : u16 buf_len;
2297 : : int status;
2298 : :
2299 : 0 : buf_len = ice_struct_size(buf, elem, num);
2300 : 0 : buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
2301 [ # # ]: 0 : if (!buf)
2302 : : return ICE_ERR_NO_MEMORY;
2303 : :
2304 : : /* Prepare buffer to free resource. */
2305 : 0 : buf->num_elems = CPU_TO_LE16(num);
2306 : 0 : buf->res_type = CPU_TO_LE16(type);
2307 [ # # ]: 0 : ice_memcpy(buf->elem, res, sizeof(*buf->elem) * num,
2308 : : ICE_NONDMA_TO_NONDMA);
2309 : :
2310 : 0 : status = ice_aq_alloc_free_res(hw, num, buf, buf_len,
2311 : : ice_aqc_opc_free_res, NULL);
2312 [ # # ]: 0 : if (status)
2313 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "CQ CMD Buffer:\n");
2314 : :
2315 : 0 : ice_free(hw, buf);
2316 : 0 : return status;
2317 : : }
2318 : :
2319 : : /**
2320 : : * ice_get_num_per_func - determine number of resources per PF
2321 : : * @hw: pointer to the HW structure
2322 : : * @max: value to be evenly split between each PF
2323 : : *
2324 : : * Determine the number of valid functions by going through the bitmap returned
2325 : : * from parsing capabilities and use this to calculate the number of resources
2326 : : * per PF based on the max value passed in.
2327 : : */
2328 : : static u32 ice_get_num_per_func(struct ice_hw *hw, u32 max)
2329 : : {
2330 : : u8 funcs;
2331 : :
2332 : : #define ICE_CAPS_VALID_FUNCS_M 0xFF
2333 : 0 : funcs = ice_hweight8(hw->dev_caps.common_cap.valid_functions &
2334 : : ICE_CAPS_VALID_FUNCS_M);
2335 : :
2336 [ # # # # ]: 0 : if (!funcs)
2337 : : return 0;
2338 : :
2339 : 0 : return max / funcs;
2340 : : }
2341 : :
2342 : : /**
2343 : : * ice_parse_common_caps - parse common device/function capabilities
2344 : : * @hw: pointer to the HW struct
2345 : : * @caps: pointer to common capabilities structure
2346 : : * @elem: the capability element to parse
2347 : : * @prefix: message prefix for tracing capabilities
2348 : : *
2349 : : * Given a capability element, extract relevant details into the common
2350 : : * capability structure.
2351 : : *
2352 : : * Returns: true if the capability matches one of the common capability ids,
2353 : : * false otherwise.
2354 : : */
2355 : : static bool
2356 : 0 : ice_parse_common_caps(struct ice_hw *hw, struct ice_hw_common_caps *caps,
2357 : : struct ice_aqc_list_caps_elem *elem, const char *prefix)
2358 : : {
2359 : 0 : u32 logical_id = LE32_TO_CPU(elem->logical_id);
2360 : 0 : u32 phys_id = LE32_TO_CPU(elem->phys_id);
2361 : 0 : u32 number = LE32_TO_CPU(elem->number);
2362 : 0 : u16 cap = LE16_TO_CPU(elem->cap);
2363 : : bool found = true;
2364 : :
2365 [ # # # # : 0 : switch (cap) {
# # # # #
# # # # #
# ]
2366 : 0 : case ICE_AQC_CAPS_VALID_FUNCTIONS:
2367 : 0 : caps->valid_functions = number;
2368 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "%s: valid_functions (bitmap) = 0x%x\n", prefix,
2369 : : caps->valid_functions);
2370 : : break;
2371 : 0 : case ICE_AQC_CAPS_DCB:
2372 : 0 : caps->dcb = (number == 1);
2373 : 0 : caps->active_tc_bitmap = logical_id;
2374 : 0 : caps->maxtc = phys_id;
2375 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "%s: dcb = %u\n", prefix, caps->dcb);
2376 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "%s: active_tc_bitmap = 0x%x\n", prefix,
2377 : : caps->active_tc_bitmap);
2378 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "%s: maxtc = %u\n", prefix, caps->maxtc);
2379 : : break;
2380 : 0 : case ICE_AQC_CAPS_RSS:
2381 : 0 : caps->rss_table_size = number;
2382 : 0 : caps->rss_table_entry_width = logical_id;
2383 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "%s: rss_table_size = %u\n", prefix,
2384 : : caps->rss_table_size);
2385 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "%s: rss_table_entry_width = %u\n", prefix,
2386 : : caps->rss_table_entry_width);
2387 : : break;
2388 : 0 : case ICE_AQC_CAPS_RXQS:
2389 : 0 : caps->num_rxq = number;
2390 : 0 : caps->rxq_first_id = phys_id;
2391 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "%s: num_rxq = %u\n", prefix,
2392 : : caps->num_rxq);
2393 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "%s: rxq_first_id = %u\n", prefix,
2394 : : caps->rxq_first_id);
2395 : : break;
2396 : 0 : case ICE_AQC_CAPS_TXQS:
2397 : 0 : caps->num_txq = number;
2398 : 0 : caps->txq_first_id = phys_id;
2399 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "%s: num_txq = %u\n", prefix,
2400 : : caps->num_txq);
2401 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "%s: txq_first_id = %u\n", prefix,
2402 : : caps->txq_first_id);
2403 : : break;
2404 : 0 : case ICE_AQC_CAPS_MSIX:
2405 : 0 : caps->num_msix_vectors = number;
2406 : 0 : caps->msix_vector_first_id = phys_id;
2407 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "%s: num_msix_vectors = %u\n", prefix,
2408 : : caps->num_msix_vectors);
2409 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "%s: msix_vector_first_id = %u\n", prefix,
2410 : : caps->msix_vector_first_id);
2411 : : break;
2412 : 0 : case ICE_AQC_CAPS_NVM_MGMT:
2413 : 0 : caps->sec_rev_disabled =
2414 : : (number & ICE_NVM_MGMT_SEC_REV_DISABLED) ?
2415 : 0 : true : false;
2416 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "%s: sec_rev_disabled = %d\n", prefix,
2417 : : caps->sec_rev_disabled);
2418 : 0 : caps->update_disabled =
2419 : : (number & ICE_NVM_MGMT_UPDATE_DISABLED) ?
2420 : 0 : true : false;
2421 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "%s: update_disabled = %d\n", prefix,
2422 : : caps->update_disabled);
2423 : 0 : caps->nvm_unified_update =
2424 : : (number & ICE_NVM_MGMT_UNIFIED_UPD_SUPPORT) ?
2425 : 0 : true : false;
2426 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "%s: nvm_unified_update = %d\n", prefix,
2427 : : caps->nvm_unified_update);
2428 : 0 : caps->netlist_auth =
2429 : : (number & ICE_NVM_MGMT_NETLIST_AUTH_SUPPORT) ?
2430 : 0 : true : false;
2431 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "%s: netlist_auth = %d\n", prefix,
2432 : : caps->netlist_auth);
2433 : : break;
2434 : 0 : case ICE_AQC_CAPS_MAX_MTU:
2435 : 0 : caps->max_mtu = number;
2436 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "%s: max_mtu = %u\n",
2437 : : prefix, caps->max_mtu);
2438 : : break;
2439 : 0 : case ICE_AQC_CAPS_PCIE_RESET_AVOIDANCE:
2440 : 0 : caps->pcie_reset_avoidance = (number > 0);
2441 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT,
2442 : : "%s: pcie_reset_avoidance = %d\n", prefix,
2443 : : caps->pcie_reset_avoidance);
2444 : : break;
2445 : 0 : case ICE_AQC_CAPS_POST_UPDATE_RESET_RESTRICT:
2446 : 0 : caps->reset_restrict_support = (number == 1);
2447 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT,
2448 : : "%s: reset_restrict_support = %d\n", prefix,
2449 : : caps->reset_restrict_support);
2450 : : break;
2451 : 0 : case ICE_AQC_CAPS_EXT_TOPO_DEV_IMG0:
2452 : : case ICE_AQC_CAPS_EXT_TOPO_DEV_IMG1:
2453 : : case ICE_AQC_CAPS_EXT_TOPO_DEV_IMG2:
2454 : : case ICE_AQC_CAPS_EXT_TOPO_DEV_IMG3:
2455 : : {
2456 : 0 : u8 index = (u8)(cap - ICE_AQC_CAPS_EXT_TOPO_DEV_IMG0);
2457 : :
2458 : 0 : caps->ext_topo_dev_img_ver_high[index] = number;
2459 : 0 : caps->ext_topo_dev_img_ver_low[index] = logical_id;
2460 : 0 : caps->ext_topo_dev_img_part_num[index] =
2461 : 0 : (phys_id & ICE_EXT_TOPO_DEV_IMG_PART_NUM_M) >>
2462 : : ICE_EXT_TOPO_DEV_IMG_PART_NUM_S;
2463 : 0 : caps->ext_topo_dev_img_load_en[index] =
2464 : 0 : (phys_id & ICE_EXT_TOPO_DEV_IMG_LOAD_EN) != 0;
2465 : 0 : caps->ext_topo_dev_img_prog_en[index] =
2466 : 0 : (phys_id & ICE_EXT_TOPO_DEV_IMG_PROG_EN) != 0;
2467 : 0 : caps->ext_topo_dev_img_ver_schema[index] =
2468 : 0 : (phys_id & ICE_EXT_TOPO_DEV_IMG_VER_SCHEMA) != 0;
2469 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT,
2470 : : "%s: ext_topo_dev_img_ver_high[%d] = %u\n",
2471 : : prefix, index,
2472 : : caps->ext_topo_dev_img_ver_high[index]);
2473 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT,
2474 : : "%s: ext_topo_dev_img_ver_low[%d] = %u\n",
2475 : : prefix, index,
2476 : : caps->ext_topo_dev_img_ver_low[index]);
2477 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT,
2478 : : "%s: ext_topo_dev_img_part_num[%d] = %u\n",
2479 : : prefix, index,
2480 : : caps->ext_topo_dev_img_part_num[index]);
2481 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT,
2482 : : "%s: ext_topo_dev_img_load_en[%d] = %d\n",
2483 : : prefix, index,
2484 : : caps->ext_topo_dev_img_load_en[index]);
2485 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT,
2486 : : "%s: ext_topo_dev_img_prog_en[%d] = %d\n",
2487 : : prefix, index,
2488 : : caps->ext_topo_dev_img_prog_en[index]);
2489 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT,
2490 : : "%s: ext_topo_dev_img_ver_schema[%d] = %d\n",
2491 : : prefix, index,
2492 : : caps->ext_topo_dev_img_ver_schema[index]);
2493 : : break;
2494 : : }
2495 : 0 : case ICE_AQC_CAPS_TX_SCHED_TOPO_COMP_MODE:
2496 : 0 : caps->tx_sched_topo_comp_mode_en = (number == 1);
2497 : 0 : break;
2498 : 0 : case ICE_AQC_CAPS_OROM_RECOVERY_UPDATE:
2499 : 0 : caps->orom_recovery_update = (number == 1);
2500 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "%s: orom_recovery_update = %d\n",
2501 : : prefix, caps->orom_recovery_update);
2502 : : break;
2503 : 0 : case ICE_AQC_CAPS_NEXT_CLUSTER_ID:
2504 : 0 : caps->next_cluster_id_support = (number == 1);
2505 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "%s: next_cluster_id_support = %d\n",
2506 : : prefix, caps->next_cluster_id_support);
2507 : : break;
2508 : : default:
2509 : : /* Not one of the recognized common capabilities */
2510 : : found = false;
2511 : : }
2512 : :
2513 : 0 : return found;
2514 : : }
2515 : :
2516 : : /**
2517 : : * ice_recalc_port_limited_caps - Recalculate port limited capabilities
2518 : : * @hw: pointer to the HW structure
2519 : : * @caps: pointer to capabilities structure to fix
2520 : : *
2521 : : * Re-calculate the capabilities that are dependent on the number of physical
2522 : : * ports; i.e. some features are not supported or function differently on
2523 : : * devices with more than 4 ports.
2524 : : */
2525 : : static void
2526 : 0 : ice_recalc_port_limited_caps(struct ice_hw *hw, struct ice_hw_common_caps *caps)
2527 : : {
2528 : : /* This assumes device capabilities are always scanned before function
2529 : : * capabilities during the initialization flow.
2530 : : */
2531 [ # # ]: 0 : if (hw->dev_caps.num_funcs > 4) {
2532 : : /* Max 4 TCs per port */
2533 : 0 : caps->maxtc = 4;
2534 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "reducing maxtc to %u (based on #ports)\n",
2535 : : caps->maxtc);
2536 : : }
2537 : 0 : }
2538 : :
2539 : : /**
2540 : : * ice_parse_vsi_func_caps - Parse ICE_AQC_CAPS_VSI function caps
2541 : : * @hw: pointer to the HW struct
2542 : : * @func_p: pointer to function capabilities structure
2543 : : * @cap: pointer to the capability element to parse
2544 : : *
2545 : : * Extract function capabilities for ICE_AQC_CAPS_VSI.
2546 : : */
2547 : : static void
2548 : 0 : ice_parse_vsi_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p,
2549 : : struct ice_aqc_list_caps_elem *cap)
2550 : : {
2551 : 0 : func_p->guar_num_vsi = ice_get_num_per_func(hw, ICE_MAX_VSI);
2552 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "func caps: guar_num_vsi (fw) = %u\n",
2553 : : LE32_TO_CPU(cap->number));
2554 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "func caps: guar_num_vsi = %u\n",
2555 : : func_p->guar_num_vsi);
2556 : 0 : }
2557 : :
2558 : : /**
2559 : : * ice_parse_1588_func_caps - Parse ICE_AQC_CAPS_1588 function caps
2560 : : * @hw: pointer to the HW struct
2561 : : * @func_p: pointer to function capabilities structure
2562 : : * @cap: pointer to the capability element to parse
2563 : : *
2564 : : * Extract function capabilities for ICE_AQC_CAPS_1588.
2565 : : */
2566 : : static void
2567 : 0 : ice_parse_1588_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p,
2568 : : struct ice_aqc_list_caps_elem *cap)
2569 : : {
2570 : : struct ice_ts_func_info *info = &func_p->ts_func_info;
2571 : 0 : u32 number = LE32_TO_CPU(cap->number);
2572 : : u8 clk_freq;
2573 : :
2574 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "1588 func caps: raw value %#x\n", number);
2575 : :
2576 : 0 : info->ena = ((number & ICE_TS_FUNC_ENA_M) != 0);
2577 : 0 : func_p->common_cap.ieee_1588 = info->ena;
2578 : :
2579 : 0 : info->src_tmr_owned = ((number & ICE_TS_SRC_TMR_OWND_M) != 0);
2580 : 0 : info->tmr_ena = ((number & ICE_TS_TMR_ENA_M) != 0);
2581 : 0 : info->tmr_index_owned = ((number & ICE_TS_TMR_IDX_OWND_M) != 0);
2582 : 0 : info->tmr_index_assoc = ((number & ICE_TS_TMR_IDX_ASSOC_M) != 0);
2583 : :
2584 : 0 : info->gpio_1pps = ((number & ICE_TS_GPIO_1PPS_ASSOC) != 0);
2585 : :
2586 : 0 : info->clk_src = ((number & ICE_TS_CLK_SRC_M) != 0);
2587 : 0 : clk_freq = (number & ICE_TS_CLK_FREQ_M) >> ICE_TS_CLK_FREQ_S;
2588 [ # # ]: 0 : if (ice_is_e825c(hw)) {
2589 : 0 : info->clk_src = ICE_CLK_SRC_TCX0;
2590 : : clk_freq = ICE_TIME_REF_FREQ_156_250;
2591 : : }
2592 [ # # ]: 0 : if (clk_freq < NUM_ICE_TIME_REF_FREQ) {
2593 : 0 : info->time_ref = (enum ice_time_ref_freq)clk_freq;
2594 : : } else {
2595 : : /* Unknown clock frequency, so assume a (probably incorrect)
2596 : : * default to avoid out-of-bounds look ups of frequency
2597 : : * related information.
2598 : : */
2599 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "1588 func caps: unknown clock frequency %u\n",
2600 : : clk_freq);
2601 : 0 : info->time_ref = ICE_TIME_REF_FREQ_25_000;
2602 : : }
2603 : :
2604 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "func caps: ieee_1588 = %u\n",
2605 : : func_p->common_cap.ieee_1588);
2606 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "func caps: src_tmr_owned = %u\n",
2607 : : info->src_tmr_owned);
2608 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "func caps: tmr_ena = %u\n",
2609 : : info->tmr_ena);
2610 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "func caps: tmr_index_owned = %u\n",
2611 : : info->tmr_index_owned);
2612 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "func caps: tmr_index_assoc = %u\n",
2613 : : info->tmr_index_assoc);
2614 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "func caps: clk_freq = %u\n",
2615 : : clk_freq);
2616 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "func caps: clk_src = %u\n",
2617 : : info->clk_src);
2618 : 0 : }
2619 : :
2620 : : /**
2621 : : * ice_parse_fdir_func_caps - Parse ICE_AQC_CAPS_FD function caps
2622 : : * @hw: pointer to the HW struct
2623 : : * @func_p: pointer to function capabilities structure
2624 : : *
2625 : : * Extract function capabilities for ICE_AQC_CAPS_FD.
2626 : : */
2627 : : static void
2628 : 0 : ice_parse_fdir_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p)
2629 : : {
2630 : : u32 reg_val, val;
2631 : :
2632 [ # # ]: 0 : if (hw->dcf_enabled)
2633 : : return;
2634 : 0 : reg_val = rd32(hw, GLQF_FD_SIZE);
2635 [ # # ]: 0 : val = (reg_val & GLQF_FD_SIZE_FD_GSIZE_M_BY_MAC(hw)) >>
2636 : : GLQF_FD_SIZE_FD_GSIZE_S;
2637 : 0 : func_p->fd_fltr_guar =
2638 : : ice_get_num_per_func(hw, val);
2639 [ # # ]: 0 : val = (reg_val & GLQF_FD_SIZE_FD_BSIZE_M_BY_MAC(hw)) >>
2640 : : GLQF_FD_SIZE_FD_BSIZE_S;
2641 : 0 : func_p->fd_fltr_best_effort = val;
2642 : :
2643 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "func caps: fd_fltr_guar = %u\n",
2644 : : func_p->fd_fltr_guar);
2645 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "func caps: fd_fltr_best_effort = %u\n",
2646 : : func_p->fd_fltr_best_effort);
2647 : : }
2648 : :
2649 : : /**
2650 : : * ice_parse_func_caps - Parse function capabilities
2651 : : * @hw: pointer to the HW struct
2652 : : * @func_p: pointer to function capabilities structure
2653 : : * @buf: buffer containing the function capability records
2654 : : * @cap_count: the number of capabilities
2655 : : *
2656 : : * Helper function to parse function (0x000A) capabilities list. For
2657 : : * capabilities shared between device and function, this relies on
2658 : : * ice_parse_common_caps.
2659 : : *
2660 : : * Loop through the list of provided capabilities and extract the relevant
2661 : : * data into the function capabilities structured.
2662 : : */
2663 : : static void
2664 : 0 : ice_parse_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_p,
2665 : : void *buf, u32 cap_count)
2666 : : {
2667 : : struct ice_aqc_list_caps_elem *cap_resp;
2668 : : u32 i;
2669 : :
2670 : : cap_resp = (struct ice_aqc_list_caps_elem *)buf;
2671 : :
2672 : : ice_memset(func_p, 0, sizeof(*func_p), ICE_NONDMA_MEM);
2673 : :
2674 [ # # ]: 0 : for (i = 0; i < cap_count; i++) {
2675 : 0 : u16 cap = LE16_TO_CPU(cap_resp[i].cap);
2676 : : bool found;
2677 : :
2678 : 0 : found = ice_parse_common_caps(hw, &func_p->common_cap,
2679 : : &cap_resp[i], "func caps");
2680 : :
2681 [ # # # # ]: 0 : switch (cap) {
2682 : 0 : case ICE_AQC_CAPS_VSI:
2683 : 0 : ice_parse_vsi_func_caps(hw, func_p, &cap_resp[i]);
2684 : 0 : break;
2685 : 0 : case ICE_AQC_CAPS_1588:
2686 : 0 : ice_parse_1588_func_caps(hw, func_p, &cap_resp[i]);
2687 : 0 : break;
2688 : 0 : case ICE_AQC_CAPS_FD:
2689 : 0 : ice_parse_fdir_func_caps(hw, func_p);
2690 : 0 : break;
2691 : 0 : default:
2692 : : /* Don't list common capabilities as unknown */
2693 [ # # ]: 0 : if (!found)
2694 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "func caps: unknown capability[%d]: 0x%x\n",
2695 : : i, cap);
2696 : : break;
2697 : : }
2698 : : }
2699 : :
2700 : 0 : ice_recalc_port_limited_caps(hw, &func_p->common_cap);
2701 : 0 : }
2702 : :
2703 : : /**
2704 : : * ice_func_id_to_logical_id - map from function id to logical pf id
2705 : : * @active_function_bitmap: active function bitmap
2706 : : * @pf_id: function number of device
2707 : : */
2708 : : static int ice_func_id_to_logical_id(u32 active_function_bitmap, u8 pf_id)
2709 : : {
2710 : : u8 logical_id = 0;
2711 : : u8 i;
2712 : :
2713 [ # # ]: 0 : for (i = 0; i < pf_id; i++)
2714 [ # # ]: 0 : if (active_function_bitmap & BIT(i))
2715 : 0 : logical_id++;
2716 : :
2717 : : return logical_id;
2718 : : }
2719 : :
2720 : : /**
2721 : : * ice_parse_valid_functions_cap - Parse ICE_AQC_CAPS_VALID_FUNCTIONS caps
2722 : : * @hw: pointer to the HW struct
2723 : : * @dev_p: pointer to device capabilities structure
2724 : : * @cap: capability element to parse
2725 : : *
2726 : : * Parse ICE_AQC_CAPS_VALID_FUNCTIONS for device capabilities.
2727 : : */
2728 : : static void
2729 : 0 : ice_parse_valid_functions_cap(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
2730 : : struct ice_aqc_list_caps_elem *cap)
2731 : : {
2732 : 0 : u32 number = LE32_TO_CPU(cap->number);
2733 : :
2734 : 0 : dev_p->num_funcs = ice_hweight32(number);
2735 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "dev caps: num_funcs = %u\n",
2736 : : dev_p->num_funcs);
2737 : :
2738 : 0 : hw->logical_pf_id = ice_func_id_to_logical_id(number, hw->pf_id);
2739 : 0 : }
2740 : :
2741 : : /**
2742 : : * ice_parse_vsi_dev_caps - Parse ICE_AQC_CAPS_VSI device caps
2743 : : * @hw: pointer to the HW struct
2744 : : * @dev_p: pointer to device capabilities structure
2745 : : * @cap: capability element to parse
2746 : : *
2747 : : * Parse ICE_AQC_CAPS_VSI for device capabilities.
2748 : : */
2749 : : static void
2750 : 0 : ice_parse_vsi_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
2751 : : struct ice_aqc_list_caps_elem *cap)
2752 : : {
2753 : 0 : u32 number = LE32_TO_CPU(cap->number);
2754 : :
2755 : 0 : dev_p->num_vsi_allocd_to_host = number;
2756 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "dev caps: num_vsi_allocd_to_host = %u\n",
2757 : : dev_p->num_vsi_allocd_to_host);
2758 : 0 : }
2759 : :
2760 : : /**
2761 : : * ice_parse_1588_dev_caps - Parse ICE_AQC_CAPS_1588 device caps
2762 : : * @hw: pointer to the HW struct
2763 : : * @dev_p: pointer to device capabilities structure
2764 : : * @cap: capability element to parse
2765 : : *
2766 : : * Parse ICE_AQC_CAPS_1588 for device capabilities.
2767 : : */
2768 : : static void
2769 : 0 : ice_parse_1588_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
2770 : : struct ice_aqc_list_caps_elem *cap)
2771 : : {
2772 : : struct ice_ts_dev_info *info = &dev_p->ts_dev_info;
2773 : 0 : u32 phys_id = LE32_TO_CPU(cap->phys_id);
2774 : 0 : u32 number = LE32_TO_CPU(cap->number);
2775 : :
2776 : 0 : info->ena = ((number & ICE_TS_DEV_ENA_M) != 0);
2777 : 0 : dev_p->common_cap.ieee_1588 = info->ena;
2778 : :
2779 : 0 : info->tmr0_owner = number & ICE_TS_TMR0_OWNR_M;
2780 : 0 : info->tmr0_owned = ((number & ICE_TS_TMR0_OWND_M) != 0);
2781 : 0 : info->tmr0_ena = ((number & ICE_TS_TMR0_ENA_M) != 0);
2782 : :
2783 : 0 : info->tmr1_owner = (number & ICE_TS_TMR1_OWNR_M) >> ICE_TS_TMR1_OWNR_S;
2784 : 0 : info->tmr1_owned = ((number & ICE_TS_TMR1_OWND_M) != 0);
2785 : 0 : info->tmr1_ena = ((number & ICE_TS_TMR1_ENA_M) != 0);
2786 : :
2787 : 0 : info->ts_ll_read = ((number & ICE_TS_LL_TX_TS_READ_M) != 0);
2788 : 0 : info->ts_ll_int_read = ((number & ICE_TS_LL_TX_TS_INT_READ_M) != 0);
2789 : :
2790 : 0 : info->tmr_own_map = phys_id;
2791 : :
2792 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "dev caps: ieee_1588 = %u\n",
2793 : : dev_p->common_cap.ieee_1588);
2794 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr0_owner = %u\n",
2795 : : info->tmr0_owner);
2796 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr0_owned = %u\n",
2797 : : info->tmr0_owned);
2798 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr0_ena = %u\n",
2799 : : info->tmr0_ena);
2800 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr1_owner = %u\n",
2801 : : info->tmr1_owner);
2802 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr1_owned = %u\n",
2803 : : info->tmr1_owned);
2804 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr1_ena = %u\n",
2805 : : info->tmr1_ena);
2806 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "dev caps: ts_ll_read = %u\n",
2807 : : info->ts_ll_read);
2808 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "dev caps: ts_ll_int_read = %u\n",
2809 : : info->ts_ll_int_read);
2810 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "dev caps: tmr_own_map = %u\n",
2811 : : info->tmr_own_map);
2812 : 0 : }
2813 : :
2814 : : /**
2815 : : * ice_parse_fdir_dev_caps - Parse ICE_AQC_CAPS_FD device caps
2816 : : * @hw: pointer to the HW struct
2817 : : * @dev_p: pointer to device capabilities structure
2818 : : * @cap: capability element to parse
2819 : : *
2820 : : * Parse ICE_AQC_CAPS_FD for device capabilities.
2821 : : */
2822 : : static void
2823 : 0 : ice_parse_fdir_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
2824 : : struct ice_aqc_list_caps_elem *cap)
2825 : : {
2826 : 0 : u32 number = LE32_TO_CPU(cap->number);
2827 : :
2828 : 0 : dev_p->num_flow_director_fltr = number;
2829 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "dev caps: num_flow_director_fltr = %u\n",
2830 : : dev_p->num_flow_director_fltr);
2831 : 0 : }
2832 : :
2833 : : /**
2834 : : * ice_parse_nac_topo_dev_caps - Parse ICE_AQC_CAPS_NAC_TOPOLOGY cap
2835 : : * @hw: pointer to the HW struct
2836 : : * @dev_p: pointer to device capabilities structure
2837 : : * @cap: capability element to parse
2838 : : *
2839 : : * Parse ICE_AQC_CAPS_NAC_TOPOLOGY for device capabilities.
2840 : : */
2841 : : static void
2842 : 0 : ice_parse_nac_topo_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
2843 : : struct ice_aqc_list_caps_elem *cap)
2844 : : {
2845 : 0 : dev_p->nac_topo.mode = LE32_TO_CPU(cap->number);
2846 : 0 : dev_p->nac_topo.id = LE32_TO_CPU(cap->phys_id) & ICE_NAC_TOPO_ID_M;
2847 : :
2848 [ # # # # ]: 0 : ice_info(hw, "PF is configured in %s mode with IP instance ID %u\n",
2849 : : (dev_p->nac_topo.mode & ICE_NAC_TOPO_PRIMARY_M) ?
2850 : : "primary" : "secondary", dev_p->nac_topo.id);
2851 : :
2852 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "dev caps: nac topology is_primary = %d\n",
2853 : : !!(dev_p->nac_topo.mode & ICE_NAC_TOPO_PRIMARY_M));
2854 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "dev caps: nac topology is_dual = %d\n",
2855 : : !!(dev_p->nac_topo.mode & ICE_NAC_TOPO_DUAL_M));
2856 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "dev caps: nac topology id = %u\n",
2857 : : dev_p->nac_topo.id);
2858 : 0 : }
2859 : :
2860 : : /**
2861 : : * ice_parse_sensor_reading_cap - Parse ICE_AQC_CAPS_SENSOR_READING cap
2862 : : * @hw: pointer to the HW struct
2863 : : * @dev_p: pointer to device capabilities structure
2864 : : * @cap: capability element to parse
2865 : : *
2866 : : * Parse ICE_AQC_CAPS_SENSOR_READING for device capability for reading
2867 : : * enabled sensors.
2868 : : */
2869 : : static void
2870 : 0 : ice_parse_sensor_reading_cap(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
2871 : : struct ice_aqc_list_caps_elem *cap)
2872 : : {
2873 : 0 : dev_p->supported_sensors = LE32_TO_CPU(cap->number);
2874 : :
2875 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT,
2876 : : "dev caps: supported sensors (bitmap) = 0x%x\n",
2877 : : dev_p->supported_sensors);
2878 : 0 : }
2879 : :
2880 : : /**
2881 : : * ice_parse_dev_caps - Parse device capabilities
2882 : : * @hw: pointer to the HW struct
2883 : : * @dev_p: pointer to device capabilities structure
2884 : : * @buf: buffer containing the device capability records
2885 : : * @cap_count: the number of capabilities
2886 : : *
2887 : : * Helper device to parse device (0x000B) capabilities list. For
2888 : : * capabilities shared between device and function, this relies on
2889 : : * ice_parse_common_caps.
2890 : : *
2891 : : * Loop through the list of provided capabilities and extract the relevant
2892 : : * data into the device capabilities structured.
2893 : : */
2894 : : static void
2895 : 0 : ice_parse_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_p,
2896 : : void *buf, u32 cap_count)
2897 : : {
2898 : : struct ice_aqc_list_caps_elem *cap_resp;
2899 : : u32 i;
2900 : :
2901 : : cap_resp = (struct ice_aqc_list_caps_elem *)buf;
2902 : :
2903 : : ice_memset(dev_p, 0, sizeof(*dev_p), ICE_NONDMA_MEM);
2904 : :
2905 [ # # ]: 0 : for (i = 0; i < cap_count; i++) {
2906 : 0 : u16 cap = LE16_TO_CPU(cap_resp[i].cap);
2907 : : bool found;
2908 : :
2909 : 0 : found = ice_parse_common_caps(hw, &dev_p->common_cap,
2910 : : &cap_resp[i], "dev caps");
2911 : :
2912 [ # # # # : 0 : switch (cap) {
# # # ]
2913 : 0 : case ICE_AQC_CAPS_VALID_FUNCTIONS:
2914 : 0 : ice_parse_valid_functions_cap(hw, dev_p, &cap_resp[i]);
2915 : 0 : break;
2916 : 0 : case ICE_AQC_CAPS_VSI:
2917 : 0 : ice_parse_vsi_dev_caps(hw, dev_p, &cap_resp[i]);
2918 : 0 : break;
2919 : 0 : case ICE_AQC_CAPS_1588:
2920 : 0 : ice_parse_1588_dev_caps(hw, dev_p, &cap_resp[i]);
2921 : 0 : break;
2922 : 0 : case ICE_AQC_CAPS_FD:
2923 : 0 : ice_parse_fdir_dev_caps(hw, dev_p, &cap_resp[i]);
2924 : 0 : break;
2925 : 0 : case ICE_AQC_CAPS_NAC_TOPOLOGY:
2926 : 0 : ice_parse_nac_topo_dev_caps(hw, dev_p, &cap_resp[i]);
2927 : 0 : break;
2928 : 0 : case ICE_AQC_CAPS_SENSOR_READING:
2929 : 0 : ice_parse_sensor_reading_cap(hw, dev_p, &cap_resp[i]);
2930 : 0 : break;
2931 : 0 : default:
2932 : : /* Don't list common capabilities as unknown */
2933 [ # # ]: 0 : if (!found)
2934 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "dev caps: unknown capability[%u]: 0x%x\n",
2935 : : i, cap);
2936 : : break;
2937 : : }
2938 : : }
2939 : :
2940 : 0 : ice_recalc_port_limited_caps(hw, &dev_p->common_cap);
2941 : 0 : }
2942 : :
2943 : : /**
2944 : : * ice_aq_get_netlist_node_pin
2945 : : * @hw: pointer to the hw struct
2946 : : * @cmd: get_link_topo_pin AQ structure
2947 : : * @node_handle: output node handle parameter if node found
2948 : : */
2949 : : int
2950 : 0 : ice_aq_get_netlist_node_pin(struct ice_hw *hw,
2951 : : struct ice_aqc_get_link_topo_pin *cmd,
2952 : : u16 *node_handle)
2953 : : {
2954 : : struct ice_aq_desc desc;
2955 : :
2956 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_topo_pin);
2957 : 0 : desc.params.get_link_topo_pin = *cmd;
2958 : :
2959 [ # # ]: 0 : if (ice_aq_send_cmd(hw, &desc, NULL, 0, NULL))
2960 : : return ICE_ERR_NOT_SUPPORTED;
2961 : :
2962 [ # # ]: 0 : if (node_handle)
2963 : 0 : *node_handle =
2964 : 0 : LE16_TO_CPU(desc.params.get_link_topo_pin.addr.handle);
2965 : :
2966 : 0 : cmd->output_io_params = desc.params.get_link_topo_pin.output_io_params;
2967 : 0 : cmd->output_io_flags = desc.params.get_link_topo_pin.output_io_flags;
2968 : :
2969 : 0 : return 0;
2970 : : }
2971 : :
2972 : : /**
2973 : : * ice_aq_get_netlist_node
2974 : : * @hw: pointer to the hw struct
2975 : : * @cmd: get_link_topo AQ structure
2976 : : * @node_part_number: output node part number if node found
2977 : : * @node_handle: output node handle parameter if node found
2978 : : */
2979 : : int
2980 : 0 : ice_aq_get_netlist_node(struct ice_hw *hw, struct ice_aqc_get_link_topo *cmd,
2981 : : u8 *node_part_number, u16 *node_handle)
2982 : : {
2983 : : struct ice_aq_desc desc;
2984 : :
2985 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_topo);
2986 : 0 : desc.params.get_link_topo = *cmd;
2987 : :
2988 [ # # ]: 0 : if (ice_aq_send_cmd(hw, &desc, NULL, 0, NULL))
2989 : : return ICE_ERR_NOT_SUPPORTED;
2990 : :
2991 [ # # ]: 0 : if (node_handle)
2992 : 0 : *node_handle =
2993 : 0 : LE16_TO_CPU(desc.params.get_link_topo.addr.handle);
2994 [ # # ]: 0 : if (node_part_number)
2995 : 0 : *node_part_number = desc.params.get_link_topo.node_part_num;
2996 : :
2997 : : return 0;
2998 : : }
2999 : :
3000 : : #define MAX_NETLIST_SIZE 10
3001 : : /**
3002 : : * ice_find_netlist_node
3003 : : * @hw: pointer to the hw struct
3004 : : * @node_type_ctx: type of netlist node to look for
3005 : : * @node_part_number: node part number to look for
3006 : : * @node_handle: output parameter if node found - optional
3007 : : *
3008 : : * Scan the netlist for a node handle of the given node type and part number.
3009 : : *
3010 : : * If node_handle is non-NULL it will be modified on function exit. It is only
3011 : : * valid if the function returns zero, and should be ignored on any non-zero
3012 : : * return value.
3013 : : *
3014 : : * Returns: 0 if the node is found, ICE_ERR_DOES_NOT_EXIST if no handle was
3015 : : * found, and an error code on failure to access the AQ.
3016 : : */
3017 : : int
3018 : 0 : ice_find_netlist_node(struct ice_hw *hw, u8 node_type_ctx, u8 node_part_number,
3019 : : u16 *node_handle)
3020 : : {
3021 : : u8 idx;
3022 : :
3023 [ # # ]: 0 : for (idx = 0; idx < MAX_NETLIST_SIZE; idx++) {
3024 : : struct ice_aqc_get_link_topo cmd;
3025 : : u8 rec_node_part_number;
3026 : : int status;
3027 : :
3028 : : memset(&cmd, 0, sizeof(cmd));
3029 : :
3030 : 0 : cmd.addr.topo_params.node_type_ctx =
3031 : : (node_type_ctx << ICE_AQC_LINK_TOPO_NODE_TYPE_S);
3032 : 0 : cmd.addr.topo_params.index = idx;
3033 : :
3034 : 0 : status = ice_aq_get_netlist_node(hw, &cmd,
3035 : : &rec_node_part_number,
3036 : : node_handle);
3037 [ # # ]: 0 : if (status)
3038 : 0 : return status;
3039 : :
3040 [ # # ]: 0 : if (rec_node_part_number == node_part_number)
3041 : : return 0;
3042 : : }
3043 : :
3044 : : return ICE_ERR_DOES_NOT_EXIST;
3045 : : }
3046 : :
3047 : : /**
3048 : : * ice_is_gps_in_netlist
3049 : : * @hw: pointer to the hw struct
3050 : : *
3051 : : * Check if the GPS generic device is present in the netlist
3052 : : */
3053 : 0 : bool ice_is_gps_in_netlist(struct ice_hw *hw)
3054 : : {
3055 [ # # ]: 0 : if (ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_GPS,
3056 : : ICE_AQC_GET_LINK_TOPO_NODE_NR_GEN_GPS, NULL))
3057 : 0 : return false;
3058 : :
3059 : : return true;
3060 : : }
3061 : :
3062 : : /**
3063 : : * ice_aq_list_caps - query function/device capabilities
3064 : : * @hw: pointer to the HW struct
3065 : : * @buf: a buffer to hold the capabilities
3066 : : * @buf_size: size of the buffer
3067 : : * @cap_count: if not NULL, set to the number of capabilities reported
3068 : : * @opc: capabilities type to discover, device or function
3069 : : * @cd: pointer to command details structure or NULL
3070 : : *
3071 : : * Get the function (0x000A) or device (0x000B) capabilities description from
3072 : : * firmware and store it in the buffer.
3073 : : *
3074 : : * If the cap_count pointer is not NULL, then it is set to the number of
3075 : : * capabilities firmware will report. Note that if the buffer size is too
3076 : : * small, it is possible the command will return ICE_AQ_ERR_ENOMEM. The
3077 : : * cap_count will still be updated in this case. It is recommended that the
3078 : : * buffer size be set to ICE_AQ_MAX_BUF_LEN (the largest possible buffer that
3079 : : * firmware could return) to avoid this.
3080 : : */
3081 : : static int
3082 : : ice_aq_list_caps(struct ice_hw *hw, void *buf, u16 buf_size, u32 *cap_count,
3083 : : enum ice_adminq_opc opc, struct ice_sq_cd *cd)
3084 : : {
3085 : : struct ice_aqc_list_caps *cmd;
3086 : : struct ice_aq_desc desc;
3087 : : int status;
3088 : :
3089 : : cmd = &desc.params.get_cap;
3090 : :
3091 : : if (opc != ice_aqc_opc_list_func_caps &&
3092 : : opc != ice_aqc_opc_list_dev_caps)
3093 : : return ICE_ERR_PARAM;
3094 : :
3095 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, opc);
3096 : 0 : status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
3097 : :
3098 : : if (cap_count)
3099 : 0 : *cap_count = LE32_TO_CPU(cmd->count);
3100 : :
3101 : : return status;
3102 : : }
3103 : :
3104 : : /**
3105 : : * ice_discover_dev_caps - Read and extract device capabilities
3106 : : * @hw: pointer to the hardware structure
3107 : : * @dev_caps: pointer to device capabilities structure
3108 : : *
3109 : : * Read the device capabilities and extract them into the dev_caps structure
3110 : : * for later use.
3111 : : */
3112 : : static int
3113 : 0 : ice_discover_dev_caps(struct ice_hw *hw, struct ice_hw_dev_caps *dev_caps)
3114 : : {
3115 : : u32 cap_count = 0;
3116 : : void *cbuf;
3117 : : int status;
3118 : :
3119 : 0 : cbuf = ice_malloc(hw, ICE_AQ_MAX_BUF_LEN);
3120 [ # # ]: 0 : if (!cbuf)
3121 : : return ICE_ERR_NO_MEMORY;
3122 : :
3123 : : /* Although the driver doesn't know the number of capabilities the
3124 : : * device will return, we can simply send a 4KB buffer, the maximum
3125 : : * possible size that firmware can return.
3126 : : */
3127 : : cap_count = ICE_AQ_MAX_BUF_LEN / sizeof(struct ice_aqc_list_caps_elem);
3128 : :
3129 : : status = ice_aq_list_caps(hw, cbuf, ICE_AQ_MAX_BUF_LEN, &cap_count,
3130 : : ice_aqc_opc_list_dev_caps, NULL);
3131 [ # # ]: 0 : if (!status)
3132 : 0 : ice_parse_dev_caps(hw, dev_caps, cbuf, cap_count);
3133 : 0 : ice_free(hw, cbuf);
3134 : :
3135 : 0 : return status;
3136 : : }
3137 : :
3138 : : /**
3139 : : * ice_discover_func_caps - Read and extract function capabilities
3140 : : * @hw: pointer to the hardware structure
3141 : : * @func_caps: pointer to function capabilities structure
3142 : : *
3143 : : * Read the function capabilities and extract them into the func_caps structure
3144 : : * for later use.
3145 : : */
3146 : : static int
3147 : 0 : ice_discover_func_caps(struct ice_hw *hw, struct ice_hw_func_caps *func_caps)
3148 : : {
3149 : : u32 cap_count = 0;
3150 : : void *cbuf;
3151 : : int status;
3152 : :
3153 : 0 : cbuf = ice_malloc(hw, ICE_AQ_MAX_BUF_LEN);
3154 [ # # ]: 0 : if (!cbuf)
3155 : : return ICE_ERR_NO_MEMORY;
3156 : :
3157 : : /* Although the driver doesn't know the number of capabilities the
3158 : : * device will return, we can simply send a 4KB buffer, the maximum
3159 : : * possible size that firmware can return.
3160 : : */
3161 : : cap_count = ICE_AQ_MAX_BUF_LEN / sizeof(struct ice_aqc_list_caps_elem);
3162 : :
3163 : : status = ice_aq_list_caps(hw, cbuf, ICE_AQ_MAX_BUF_LEN, &cap_count,
3164 : : ice_aqc_opc_list_func_caps, NULL);
3165 [ # # ]: 0 : if (!status)
3166 : 0 : ice_parse_func_caps(hw, func_caps, cbuf, cap_count);
3167 : 0 : ice_free(hw, cbuf);
3168 : :
3169 : 0 : return status;
3170 : : }
3171 : :
3172 : : /**
3173 : : * ice_set_safe_mode_caps - Override dev/func capabilities when in safe mode
3174 : : * @hw: pointer to the hardware structure
3175 : : */
3176 : 0 : void ice_set_safe_mode_caps(struct ice_hw *hw)
3177 : : {
3178 : 0 : struct ice_hw_func_caps *func_caps = &hw->func_caps;
3179 : 0 : struct ice_hw_dev_caps *dev_caps = &hw->dev_caps;
3180 : : struct ice_hw_common_caps cached_caps;
3181 : : u32 num_funcs;
3182 : :
3183 : : /* cache some func_caps values that should be restored after memset */
3184 : 0 : cached_caps = func_caps->common_cap;
3185 : :
3186 : : /* unset func capabilities */
3187 : : memset(func_caps, 0, sizeof(*func_caps));
3188 : :
3189 : : #define ICE_RESTORE_FUNC_CAP(name) \
3190 : : func_caps->common_cap.name = cached_caps.name
3191 : :
3192 : : /* restore cached values */
3193 : 0 : ICE_RESTORE_FUNC_CAP(valid_functions);
3194 : 0 : ICE_RESTORE_FUNC_CAP(txq_first_id);
3195 : 0 : ICE_RESTORE_FUNC_CAP(rxq_first_id);
3196 : 0 : ICE_RESTORE_FUNC_CAP(msix_vector_first_id);
3197 : 0 : ICE_RESTORE_FUNC_CAP(max_mtu);
3198 : 0 : ICE_RESTORE_FUNC_CAP(nvm_unified_update);
3199 : :
3200 : : /* one Tx and one Rx queue in safe mode */
3201 : 0 : func_caps->common_cap.num_rxq = 1;
3202 : 0 : func_caps->common_cap.num_txq = 1;
3203 : :
3204 : : /* two MSIX vectors, one for traffic and one for misc causes */
3205 : 0 : func_caps->common_cap.num_msix_vectors = 2;
3206 : 0 : func_caps->guar_num_vsi = 1;
3207 : :
3208 : : /* cache some dev_caps values that should be restored after memset */
3209 : 0 : cached_caps = dev_caps->common_cap;
3210 : 0 : num_funcs = dev_caps->num_funcs;
3211 : :
3212 : : /* unset dev capabilities */
3213 : : memset(dev_caps, 0, sizeof(*dev_caps));
3214 : :
3215 : : #define ICE_RESTORE_DEV_CAP(name) \
3216 : : dev_caps->common_cap.name = cached_caps.name
3217 : :
3218 : : /* restore cached values */
3219 : 0 : ICE_RESTORE_DEV_CAP(valid_functions);
3220 : 0 : ICE_RESTORE_DEV_CAP(txq_first_id);
3221 : 0 : ICE_RESTORE_DEV_CAP(rxq_first_id);
3222 : 0 : ICE_RESTORE_DEV_CAP(msix_vector_first_id);
3223 : 0 : ICE_RESTORE_DEV_CAP(max_mtu);
3224 : 0 : ICE_RESTORE_DEV_CAP(nvm_unified_update);
3225 : 0 : dev_caps->num_funcs = num_funcs;
3226 : :
3227 : : /* one Tx and one Rx queue per function in safe mode */
3228 : 0 : dev_caps->common_cap.num_rxq = num_funcs;
3229 : 0 : dev_caps->common_cap.num_txq = num_funcs;
3230 : :
3231 : : /* two MSIX vectors per function */
3232 : 0 : dev_caps->common_cap.num_msix_vectors = 2 * num_funcs;
3233 : 0 : }
3234 : :
3235 : : /**
3236 : : * ice_get_caps - get info about the HW
3237 : : * @hw: pointer to the hardware structure
3238 : : */
3239 : 0 : int ice_get_caps(struct ice_hw *hw)
3240 : : {
3241 : : int status;
3242 : :
3243 : 0 : status = ice_discover_dev_caps(hw, &hw->dev_caps);
3244 [ # # ]: 0 : if (status)
3245 : : return status;
3246 : :
3247 : 0 : return ice_discover_func_caps(hw, &hw->func_caps);
3248 : : }
3249 : :
3250 : : /**
3251 : : * ice_aq_manage_mac_write - manage MAC address write command
3252 : : * @hw: pointer to the HW struct
3253 : : * @mac_addr: MAC address to be written as LAA/LAA+WoL/Port address
3254 : : * @flags: flags to control write behavior
3255 : : * @cd: pointer to command details structure or NULL
3256 : : *
3257 : : * This function is used to write MAC address to the NVM (0x0108).
3258 : : */
3259 : : int
3260 : 0 : ice_aq_manage_mac_write(struct ice_hw *hw, const u8 *mac_addr, u8 flags,
3261 : : struct ice_sq_cd *cd)
3262 : : {
3263 : : struct ice_aqc_manage_mac_write *cmd;
3264 : : struct ice_aq_desc desc;
3265 : :
3266 : : cmd = &desc.params.mac_write;
3267 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_manage_mac_write);
3268 : :
3269 [ # # ]: 0 : cmd->flags = flags;
3270 : : ice_memcpy(cmd->mac_addr, mac_addr, ETH_ALEN, ICE_NONDMA_TO_NONDMA);
3271 : :
3272 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
3273 : : }
3274 : :
3275 : : /**
3276 : : * ice_aq_clear_pxe_mode
3277 : : * @hw: pointer to the HW struct
3278 : : *
3279 : : * Tell the firmware that the driver is taking over from PXE (0x0110).
3280 : : */
3281 : 0 : static int ice_aq_clear_pxe_mode(struct ice_hw *hw)
3282 : : {
3283 : : struct ice_aq_desc desc;
3284 : :
3285 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_clear_pxe_mode);
3286 : 0 : desc.params.clear_pxe.rx_cnt = ICE_AQC_CLEAR_PXE_RX_CNT;
3287 : :
3288 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
3289 : : }
3290 : :
3291 : : /**
3292 : : * ice_clear_pxe_mode - clear pxe operations mode
3293 : : * @hw: pointer to the HW struct
3294 : : *
3295 : : * Make sure all PXE mode settings are cleared, including things
3296 : : * like descriptor fetch/write-back mode.
3297 : : */
3298 : 0 : void ice_clear_pxe_mode(struct ice_hw *hw)
3299 : : {
3300 [ # # ]: 0 : if (ice_check_sq_alive(hw, &hw->adminq))
3301 : 0 : ice_aq_clear_pxe_mode(hw);
3302 : 0 : }
3303 : :
3304 : : /**
3305 : : * ice_aq_set_port_params - set physical port parameters
3306 : : * @pi: pointer to the port info struct
3307 : : * @bad_frame_vsi: defines the VSI to which bad frames are forwarded
3308 : : * @save_bad_pac: if set packets with errors are forwarded to the bad frames VSI
3309 : : * @pad_short_pac: if set transmit packets smaller than 60 bytes are padded
3310 : : * @double_vlan: if set double VLAN is enabled
3311 : : * @cd: pointer to command details structure or NULL
3312 : : *
3313 : : * Set Physical port parameters (0x0203)
3314 : : */
3315 : : int
3316 : 0 : ice_aq_set_port_params(struct ice_port_info *pi, u16 bad_frame_vsi,
3317 : : bool save_bad_pac, bool pad_short_pac, bool double_vlan,
3318 : : struct ice_sq_cd *cd)
3319 : : {
3320 : : struct ice_aqc_set_port_params *cmd;
3321 : 0 : struct ice_hw *hw = pi->hw;
3322 : : struct ice_aq_desc desc;
3323 : : u16 cmd_flags = 0;
3324 : :
3325 : : cmd = &desc.params.set_port_params;
3326 : :
3327 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_port_params);
3328 : 0 : cmd->lb_mode = pi->loopback_mode |
3329 : : ICE_AQC_SET_P_PARAMS_LOOPBACK_MODE_VALID;
3330 : 0 : cmd->bad_frame_vsi = CPU_TO_LE16(bad_frame_vsi);
3331 [ # # ]: 0 : if (save_bad_pac)
3332 : : cmd_flags |= ICE_AQC_SET_P_PARAMS_SAVE_BAD_PACKETS;
3333 [ # # ]: 0 : if (pad_short_pac)
3334 : 0 : cmd_flags |= ICE_AQC_SET_P_PARAMS_PAD_SHORT_PACKETS;
3335 [ # # ]: 0 : if (double_vlan)
3336 : 0 : cmd_flags |= ICE_AQC_SET_P_PARAMS_DOUBLE_VLAN_ENA;
3337 : 0 : cmd->cmd_flags = CPU_TO_LE16(cmd_flags);
3338 : :
3339 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
3340 : : }
3341 : :
3342 : : /**
3343 : : * ice_is_100m_speed_supported
3344 : : * @hw: pointer to the HW struct
3345 : : *
3346 : : * returns true if 100M speeds are supported by the device,
3347 : : * false otherwise.
3348 : : */
3349 : 0 : bool ice_is_100m_speed_supported(struct ice_hw *hw)
3350 : : {
3351 [ # # ]: 0 : switch (hw->device_id) {
3352 : : case ICE_DEV_ID_E822C_SGMII:
3353 : : case ICE_DEV_ID_E822L_SGMII:
3354 : : case ICE_DEV_ID_E823L_1GBE:
3355 : : case ICE_DEV_ID_E823C_SGMII:
3356 : : return true;
3357 : 0 : default:
3358 : 0 : return false;
3359 : : }
3360 : : }
3361 : :
3362 : : /**
3363 : : * ice_get_link_speed_based_on_phy_type - returns link speed
3364 : : * @phy_type_low: lower part of phy_type
3365 : : * @phy_type_high: higher part of phy_type
3366 : : *
3367 : : * This helper function will convert an entry in PHY type structure
3368 : : * [phy_type_low, phy_type_high] to its corresponding link speed.
3369 : : * Note: In the structure of [phy_type_low, phy_type_high], there should
3370 : : * be one bit set, as this function will convert one PHY type to its
3371 : : * speed.
3372 : : * If no bit gets set, ICE_AQ_LINK_SPEED_UNKNOWN will be returned
3373 : : * If more than one bit gets set, ICE_AQ_LINK_SPEED_UNKNOWN will be returned
3374 : : */
3375 : : static u16
3376 : 0 : ice_get_link_speed_based_on_phy_type(u64 phy_type_low, u64 phy_type_high)
3377 : : {
3378 : : u16 speed_phy_type_high = ICE_AQ_LINK_SPEED_UNKNOWN;
3379 : : u16 speed_phy_type_low = ICE_AQ_LINK_SPEED_UNKNOWN;
3380 : :
3381 [ # # # # : 0 : switch (phy_type_low) {
# # # # #
# ]
3382 : : case ICE_PHY_TYPE_LOW_100BASE_TX:
3383 : : case ICE_PHY_TYPE_LOW_100M_SGMII:
3384 : : speed_phy_type_low = ICE_AQ_LINK_SPEED_100MB;
3385 : : break;
3386 : 0 : case ICE_PHY_TYPE_LOW_1000BASE_T:
3387 : : case ICE_PHY_TYPE_LOW_1000BASE_SX:
3388 : : case ICE_PHY_TYPE_LOW_1000BASE_LX:
3389 : : case ICE_PHY_TYPE_LOW_1000BASE_KX:
3390 : : case ICE_PHY_TYPE_LOW_1G_SGMII:
3391 : : speed_phy_type_low = ICE_AQ_LINK_SPEED_1000MB;
3392 : 0 : break;
3393 : 0 : case ICE_PHY_TYPE_LOW_2500BASE_T:
3394 : : case ICE_PHY_TYPE_LOW_2500BASE_X:
3395 : : case ICE_PHY_TYPE_LOW_2500BASE_KX:
3396 : : speed_phy_type_low = ICE_AQ_LINK_SPEED_2500MB;
3397 : 0 : break;
3398 : 0 : case ICE_PHY_TYPE_LOW_5GBASE_T:
3399 : : case ICE_PHY_TYPE_LOW_5GBASE_KR:
3400 : : speed_phy_type_low = ICE_AQ_LINK_SPEED_5GB;
3401 : 0 : break;
3402 : 0 : case ICE_PHY_TYPE_LOW_10GBASE_T:
3403 : : case ICE_PHY_TYPE_LOW_10G_SFI_DA:
3404 : : case ICE_PHY_TYPE_LOW_10GBASE_SR:
3405 : : case ICE_PHY_TYPE_LOW_10GBASE_LR:
3406 : : case ICE_PHY_TYPE_LOW_10GBASE_KR_CR1:
3407 : : case ICE_PHY_TYPE_LOW_10G_SFI_AOC_ACC:
3408 : : case ICE_PHY_TYPE_LOW_10G_SFI_C2C:
3409 : : speed_phy_type_low = ICE_AQ_LINK_SPEED_10GB;
3410 : 0 : break;
3411 : 0 : case ICE_PHY_TYPE_LOW_25GBASE_T:
3412 : : case ICE_PHY_TYPE_LOW_25GBASE_CR:
3413 : : case ICE_PHY_TYPE_LOW_25GBASE_CR_S:
3414 : : case ICE_PHY_TYPE_LOW_25GBASE_CR1:
3415 : : case ICE_PHY_TYPE_LOW_25GBASE_SR:
3416 : : case ICE_PHY_TYPE_LOW_25GBASE_LR:
3417 : : case ICE_PHY_TYPE_LOW_25GBASE_KR:
3418 : : case ICE_PHY_TYPE_LOW_25GBASE_KR_S:
3419 : : case ICE_PHY_TYPE_LOW_25GBASE_KR1:
3420 : : case ICE_PHY_TYPE_LOW_25G_AUI_AOC_ACC:
3421 : : case ICE_PHY_TYPE_LOW_25G_AUI_C2C:
3422 : : speed_phy_type_low = ICE_AQ_LINK_SPEED_25GB;
3423 : 0 : break;
3424 : 0 : case ICE_PHY_TYPE_LOW_40GBASE_CR4:
3425 : : case ICE_PHY_TYPE_LOW_40GBASE_SR4:
3426 : : case ICE_PHY_TYPE_LOW_40GBASE_LR4:
3427 : : case ICE_PHY_TYPE_LOW_40GBASE_KR4:
3428 : : case ICE_PHY_TYPE_LOW_40G_XLAUI_AOC_ACC:
3429 : : case ICE_PHY_TYPE_LOW_40G_XLAUI:
3430 : : speed_phy_type_low = ICE_AQ_LINK_SPEED_40GB;
3431 : 0 : break;
3432 : 0 : case ICE_PHY_TYPE_LOW_50GBASE_CR2:
3433 : : case ICE_PHY_TYPE_LOW_50GBASE_SR2:
3434 : : case ICE_PHY_TYPE_LOW_50GBASE_LR2:
3435 : : case ICE_PHY_TYPE_LOW_50GBASE_KR2:
3436 : : case ICE_PHY_TYPE_LOW_50G_LAUI2_AOC_ACC:
3437 : : case ICE_PHY_TYPE_LOW_50G_LAUI2:
3438 : : case ICE_PHY_TYPE_LOW_50G_AUI2_AOC_ACC:
3439 : : case ICE_PHY_TYPE_LOW_50G_AUI2:
3440 : : case ICE_PHY_TYPE_LOW_50GBASE_CP:
3441 : : case ICE_PHY_TYPE_LOW_50GBASE_SR:
3442 : : case ICE_PHY_TYPE_LOW_50GBASE_FR:
3443 : : case ICE_PHY_TYPE_LOW_50GBASE_LR:
3444 : : case ICE_PHY_TYPE_LOW_50GBASE_KR_PAM4:
3445 : : case ICE_PHY_TYPE_LOW_50G_AUI1_AOC_ACC:
3446 : : case ICE_PHY_TYPE_LOW_50G_AUI1:
3447 : : speed_phy_type_low = ICE_AQ_LINK_SPEED_50GB;
3448 : 0 : break;
3449 : 0 : case ICE_PHY_TYPE_LOW_100GBASE_CR4:
3450 : : case ICE_PHY_TYPE_LOW_100GBASE_SR4:
3451 : : case ICE_PHY_TYPE_LOW_100GBASE_LR4:
3452 : : case ICE_PHY_TYPE_LOW_100GBASE_KR4:
3453 : : case ICE_PHY_TYPE_LOW_100G_CAUI4_AOC_ACC:
3454 : : case ICE_PHY_TYPE_LOW_100G_CAUI4:
3455 : : case ICE_PHY_TYPE_LOW_100G_AUI4_AOC_ACC:
3456 : : case ICE_PHY_TYPE_LOW_100G_AUI4:
3457 : : case ICE_PHY_TYPE_LOW_100GBASE_CR_PAM4:
3458 : : case ICE_PHY_TYPE_LOW_100GBASE_KR_PAM4:
3459 : : case ICE_PHY_TYPE_LOW_100GBASE_CP2:
3460 : : case ICE_PHY_TYPE_LOW_100GBASE_SR2:
3461 : : case ICE_PHY_TYPE_LOW_100GBASE_DR:
3462 : : speed_phy_type_low = ICE_AQ_LINK_SPEED_100GB;
3463 : 0 : break;
3464 : 0 : default:
3465 : : speed_phy_type_low = ICE_AQ_LINK_SPEED_UNKNOWN;
3466 : 0 : break;
3467 : : }
3468 : :
3469 [ # # # ]: 0 : switch (phy_type_high) {
3470 : : case ICE_PHY_TYPE_HIGH_100GBASE_KR2_PAM4:
3471 : : case ICE_PHY_TYPE_HIGH_100G_CAUI2_AOC_ACC:
3472 : : case ICE_PHY_TYPE_HIGH_100G_CAUI2:
3473 : : case ICE_PHY_TYPE_HIGH_100G_AUI2_AOC_ACC:
3474 : : case ICE_PHY_TYPE_HIGH_100G_AUI2:
3475 : : speed_phy_type_high = ICE_AQ_LINK_SPEED_100GB;
3476 : : break;
3477 : 0 : case ICE_PHY_TYPE_HIGH_200G_CR4_PAM4:
3478 : : case ICE_PHY_TYPE_HIGH_200G_SR4:
3479 : : case ICE_PHY_TYPE_HIGH_200G_FR4:
3480 : : case ICE_PHY_TYPE_HIGH_200G_LR4:
3481 : : case ICE_PHY_TYPE_HIGH_200G_DR4:
3482 : : case ICE_PHY_TYPE_HIGH_200G_KR4_PAM4:
3483 : : case ICE_PHY_TYPE_HIGH_200G_AUI4_AOC_ACC:
3484 : : case ICE_PHY_TYPE_HIGH_200G_AUI4:
3485 : : case ICE_PHY_TYPE_HIGH_200G_AUI8_AOC_ACC:
3486 : : case ICE_PHY_TYPE_HIGH_200G_AUI8:
3487 : : speed_phy_type_high = ICE_AQ_LINK_SPEED_200GB;
3488 : 0 : break;
3489 : 0 : default:
3490 : : speed_phy_type_high = ICE_AQ_LINK_SPEED_UNKNOWN;
3491 : 0 : break;
3492 : : }
3493 : :
3494 : 0 : if (speed_phy_type_low == ICE_AQ_LINK_SPEED_UNKNOWN &&
3495 [ # # ]: 0 : speed_phy_type_high == ICE_AQ_LINK_SPEED_UNKNOWN)
3496 : : return ICE_AQ_LINK_SPEED_UNKNOWN;
3497 : 0 : else if (speed_phy_type_low != ICE_AQ_LINK_SPEED_UNKNOWN &&
3498 [ # # ]: 0 : speed_phy_type_high != ICE_AQ_LINK_SPEED_UNKNOWN)
3499 : : return ICE_AQ_LINK_SPEED_UNKNOWN;
3500 [ # # ]: 0 : else if (speed_phy_type_low != ICE_AQ_LINK_SPEED_UNKNOWN &&
3501 : : speed_phy_type_high == ICE_AQ_LINK_SPEED_UNKNOWN)
3502 : : return speed_phy_type_low;
3503 : : else
3504 : 0 : return speed_phy_type_high;
3505 : : }
3506 : :
3507 : : /**
3508 : : * ice_update_phy_type
3509 : : * @phy_type_low: pointer to the lower part of phy_type
3510 : : * @phy_type_high: pointer to the higher part of phy_type
3511 : : * @link_speeds_bitmap: targeted link speeds bitmap
3512 : : *
3513 : : * Note: For the link_speeds_bitmap structure, you can check it at
3514 : : * [ice_aqc_get_link_status->link_speed]. Caller can pass in
3515 : : * link_speeds_bitmap include multiple speeds.
3516 : : *
3517 : : * Each entry in this [phy_type_low, phy_type_high] structure will
3518 : : * present a certain link speed. This helper function will turn on bits
3519 : : * in [phy_type_low, phy_type_high] structure based on the value of
3520 : : * link_speeds_bitmap input parameter.
3521 : : */
3522 : : void
3523 : 0 : ice_update_phy_type(u64 *phy_type_low, u64 *phy_type_high,
3524 : : u16 link_speeds_bitmap)
3525 : : {
3526 : : u64 pt_high;
3527 : : u64 pt_low;
3528 : : int index;
3529 : : u16 speed;
3530 : :
3531 : : /* We first check with low part of phy_type */
3532 [ # # ]: 0 : for (index = 0; index <= ICE_PHY_TYPE_LOW_MAX_INDEX; index++) {
3533 : 0 : pt_low = BIT_ULL(index);
3534 : 0 : speed = ice_get_link_speed_based_on_phy_type(pt_low, 0);
3535 : :
3536 [ # # ]: 0 : if (link_speeds_bitmap & speed)
3537 : 0 : *phy_type_low |= BIT_ULL(index);
3538 : : }
3539 : :
3540 : : /* We then check with high part of phy_type */
3541 [ # # ]: 0 : for (index = 0; index <= ICE_PHY_TYPE_HIGH_MAX_INDEX; index++) {
3542 : 0 : pt_high = BIT_ULL(index);
3543 : 0 : speed = ice_get_link_speed_based_on_phy_type(0, pt_high);
3544 : :
3545 [ # # ]: 0 : if (link_speeds_bitmap & speed)
3546 : 0 : *phy_type_high |= BIT_ULL(index);
3547 : : }
3548 : 0 : }
3549 : :
3550 : : /**
3551 : : * ice_aq_set_phy_cfg
3552 : : * @hw: pointer to the HW struct
3553 : : * @pi: port info structure of the interested logical port
3554 : : * @cfg: structure with PHY configuration data to be set
3555 : : * @cd: pointer to command details structure or NULL
3556 : : *
3557 : : * Set the various PHY configuration parameters supported on the Port.
3558 : : * One or more of the Set PHY config parameters may be ignored in an MFP
3559 : : * mode as the PF may not have the privilege to set some of the PHY Config
3560 : : * parameters. This status will be indicated by the command response (0x0601).
3561 : : */
3562 : : int
3563 : 0 : ice_aq_set_phy_cfg(struct ice_hw *hw, struct ice_port_info *pi,
3564 : : struct ice_aqc_set_phy_cfg_data *cfg, struct ice_sq_cd *cd)
3565 : : {
3566 : : struct ice_aq_desc desc;
3567 : : int status;
3568 : :
3569 [ # # ]: 0 : if (!cfg)
3570 : : return ICE_ERR_PARAM;
3571 : :
3572 : : /* Ensure that only valid bits of cfg->caps can be turned on. */
3573 [ # # ]: 0 : if (cfg->caps & ~ICE_AQ_PHY_ENA_VALID_MASK) {
3574 [ # # ]: 0 : ice_debug(hw, ICE_DBG_PHY, "Invalid bit is set in ice_aqc_set_phy_cfg_data->caps : 0x%x\n",
3575 : : cfg->caps);
3576 : :
3577 : 0 : cfg->caps &= ICE_AQ_PHY_ENA_VALID_MASK;
3578 : : }
3579 : :
3580 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_phy_cfg);
3581 : 0 : desc.params.set_phy.lport_num = pi->lport;
3582 : 0 : desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
3583 : :
3584 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, "set phy cfg\n");
3585 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, " phy_type_low = 0x%llx\n",
3586 : : (unsigned long long)LE64_TO_CPU(cfg->phy_type_low));
3587 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, " phy_type_high = 0x%llx\n",
3588 : : (unsigned long long)LE64_TO_CPU(cfg->phy_type_high));
3589 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, " caps = 0x%x\n", cfg->caps);
3590 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, " low_power_ctrl_an = 0x%x\n",
3591 : : cfg->low_power_ctrl_an);
3592 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, " eee_cap = 0x%x\n", cfg->eee_cap);
3593 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, " eeer_value = 0x%x\n", cfg->eeer_value);
3594 [ # # ]: 0 : ice_debug(hw, ICE_DBG_LINK, " link_fec_opt = 0x%x\n",
3595 : : cfg->link_fec_opt);
3596 : :
3597 : 0 : status = ice_aq_send_cmd(hw, &desc, cfg, sizeof(*cfg), cd);
3598 : :
3599 [ # # ]: 0 : if (hw->adminq.sq_last_status == ICE_AQ_RC_EMODE)
3600 : : status = 0;
3601 : :
3602 [ # # ]: 0 : if (!status)
3603 : 0 : pi->phy.curr_user_phy_cfg = *cfg;
3604 : :
3605 : : return status;
3606 : : }
3607 : :
3608 : : /**
3609 : : * ice_update_link_info - update status of the HW network link
3610 : : * @pi: port info structure of the interested logical port
3611 : : */
3612 : 0 : int ice_update_link_info(struct ice_port_info *pi)
3613 : : {
3614 : : struct ice_link_status *li;
3615 : : int status;
3616 : :
3617 [ # # ]: 0 : if (!pi)
3618 : : return ICE_ERR_PARAM;
3619 : :
3620 : : li = &pi->phy.link_info;
3621 : :
3622 : 0 : status = ice_aq_get_link_info(pi, true, NULL, NULL);
3623 [ # # ]: 0 : if (status)
3624 : : return status;
3625 : :
3626 [ # # ]: 0 : if (li->link_info & ICE_AQ_MEDIA_AVAILABLE) {
3627 : : struct ice_aqc_get_phy_caps_data *pcaps;
3628 : : struct ice_hw *hw;
3629 : :
3630 : : hw = pi->hw;
3631 : : pcaps = (struct ice_aqc_get_phy_caps_data *)
3632 : 0 : ice_malloc(hw, sizeof(*pcaps));
3633 [ # # ]: 0 : if (!pcaps)
3634 : : return ICE_ERR_NO_MEMORY;
3635 : :
3636 : 0 : status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_TOPO_CAP_MEDIA,
3637 : : pcaps, NULL);
3638 : :
3639 [ # # ]: 0 : if (!status)
3640 [ # # ]: 0 : ice_memcpy(li->module_type, &pcaps->module_type,
3641 : : sizeof(li->module_type),
3642 : : ICE_NONDMA_TO_NONDMA);
3643 : :
3644 : 0 : ice_free(hw, pcaps);
3645 : : }
3646 : :
3647 : : return status;
3648 : : }
3649 : :
3650 : : /**
3651 : : * ice_cache_phy_user_req
3652 : : * @pi: port information structure
3653 : : * @cache_data: PHY logging data
3654 : : * @cache_mode: PHY logging mode
3655 : : *
3656 : : * Log the user request on (FC, FEC, SPEED) for later user.
3657 : : */
3658 : : static void
3659 : : ice_cache_phy_user_req(struct ice_port_info *pi,
3660 : : struct ice_phy_cache_mode_data cache_data,
3661 : : enum ice_phy_cache_mode cache_mode)
3662 : : {
3663 : : if (!pi)
3664 : : return;
3665 : :
3666 : : switch (cache_mode) {
3667 : : case ICE_FC_MODE:
3668 : 0 : pi->phy.curr_user_fc_req = cache_data.data.curr_user_fc_req;
3669 : : break;
3670 : : case ICE_SPEED_MODE:
3671 : : pi->phy.curr_user_speed_req =
3672 : : cache_data.data.curr_user_speed_req;
3673 : : break;
3674 : : case ICE_FEC_MODE:
3675 : : pi->phy.curr_user_fec_req = cache_data.data.curr_user_fec_req;
3676 : : break;
3677 : : default:
3678 : : break;
3679 : : }
3680 : : }
3681 : :
3682 : : /**
3683 : : * ice_caps_to_fc_mode
3684 : : * @caps: PHY capabilities
3685 : : *
3686 : : * Convert PHY FC capabilities to ice FC mode
3687 : : */
3688 : 0 : enum ice_fc_mode ice_caps_to_fc_mode(u8 caps)
3689 : : {
3690 [ # # ]: 0 : if (caps & ICE_AQC_PHY_EN_TX_LINK_PAUSE &&
3691 : : caps & ICE_AQC_PHY_EN_RX_LINK_PAUSE)
3692 : : return ICE_FC_FULL;
3693 : :
3694 [ # # ]: 0 : if (caps & ICE_AQC_PHY_EN_TX_LINK_PAUSE)
3695 : : return ICE_FC_TX_PAUSE;
3696 : :
3697 [ # # ]: 0 : if (caps & ICE_AQC_PHY_EN_RX_LINK_PAUSE)
3698 : 0 : return ICE_FC_RX_PAUSE;
3699 : :
3700 : : return ICE_FC_NONE;
3701 : : }
3702 : :
3703 : : /**
3704 : : * ice_caps_to_fec_mode
3705 : : * @caps: PHY capabilities
3706 : : * @fec_options: Link FEC options
3707 : : *
3708 : : * Convert PHY FEC capabilities to ice FEC mode
3709 : : */
3710 : 0 : enum ice_fec_mode ice_caps_to_fec_mode(u8 caps, u8 fec_options)
3711 : : {
3712 [ # # ]: 0 : if (caps & ICE_AQC_PHY_EN_AUTO_FEC) {
3713 [ # # ]: 0 : if (fec_options & ICE_AQC_PHY_FEC_DIS)
3714 : : return ICE_FEC_DIS_AUTO;
3715 : : else
3716 : 0 : return ICE_FEC_AUTO;
3717 : : }
3718 : :
3719 [ # # ]: 0 : if (fec_options & (ICE_AQC_PHY_FEC_10G_KR_40G_KR4_EN |
3720 : : ICE_AQC_PHY_FEC_10G_KR_40G_KR4_REQ |
3721 : : ICE_AQC_PHY_FEC_25G_KR_CLAUSE74_EN |
3722 : : ICE_AQC_PHY_FEC_25G_KR_REQ))
3723 : : return ICE_FEC_BASER;
3724 : :
3725 [ # # ]: 0 : if (fec_options & (ICE_AQC_PHY_FEC_25G_RS_528_REQ |
3726 : : ICE_AQC_PHY_FEC_25G_RS_544_REQ |
3727 : : ICE_AQC_PHY_FEC_25G_RS_CLAUSE91_EN))
3728 : 0 : return ICE_FEC_RS;
3729 : :
3730 : : return ICE_FEC_NONE;
3731 : : }
3732 : :
3733 : : /**
3734 : : * ice_cfg_phy_fc - Configure PHY FC data based on FC mode
3735 : : * @pi: port information structure
3736 : : * @cfg: PHY configuration data to set FC mode
3737 : : * @req_mode: FC mode to configure
3738 : : */
3739 : : static int
3740 : 0 : ice_cfg_phy_fc(struct ice_port_info *pi, struct ice_aqc_set_phy_cfg_data *cfg,
3741 : : enum ice_fc_mode req_mode)
3742 : : {
3743 : : struct ice_phy_cache_mode_data cache_data;
3744 : : u8 pause_mask = 0x0;
3745 : :
3746 [ # # ]: 0 : if (!pi || !cfg)
3747 : : return ICE_ERR_BAD_PTR;
3748 : :
3749 [ # # # # : 0 : switch (req_mode) {
# ]
3750 : 0 : case ICE_FC_AUTO:
3751 : : {
3752 : : struct ice_aqc_get_phy_caps_data *pcaps;
3753 : : int status;
3754 : :
3755 : : pcaps = (struct ice_aqc_get_phy_caps_data *)
3756 : 0 : ice_malloc(pi->hw, sizeof(*pcaps));
3757 [ # # ]: 0 : if (!pcaps)
3758 : : return ICE_ERR_NO_MEMORY;
3759 : :
3760 : : /* Query the value of FC that both the NIC and attached media
3761 : : * can do.
3762 : : */
3763 : 0 : status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_TOPO_CAP_MEDIA,
3764 : : pcaps, NULL);
3765 [ # # ]: 0 : if (status) {
3766 : 0 : ice_free(pi->hw, pcaps);
3767 : 0 : return status;
3768 : : }
3769 : :
3770 : 0 : pause_mask |= pcaps->caps & ICE_AQC_PHY_EN_TX_LINK_PAUSE;
3771 : 0 : pause_mask |= pcaps->caps & ICE_AQC_PHY_EN_RX_LINK_PAUSE;
3772 : :
3773 : 0 : ice_free(pi->hw, pcaps);
3774 : 0 : break;
3775 : : }
3776 : 0 : case ICE_FC_FULL:
3777 : : pause_mask |= ICE_AQC_PHY_EN_TX_LINK_PAUSE;
3778 : : pause_mask |= ICE_AQC_PHY_EN_RX_LINK_PAUSE;
3779 : 0 : break;
3780 : 0 : case ICE_FC_RX_PAUSE:
3781 : : pause_mask |= ICE_AQC_PHY_EN_RX_LINK_PAUSE;
3782 : 0 : break;
3783 : 0 : case ICE_FC_TX_PAUSE:
3784 : : pause_mask |= ICE_AQC_PHY_EN_TX_LINK_PAUSE;
3785 : 0 : break;
3786 : : default:
3787 : : break;
3788 : : }
3789 : :
3790 : : /* clear the old pause settings */
3791 : 0 : cfg->caps &= ~(ICE_AQC_PHY_EN_TX_LINK_PAUSE |
3792 : : ICE_AQC_PHY_EN_RX_LINK_PAUSE);
3793 : :
3794 : : /* set the new capabilities */
3795 : 0 : cfg->caps |= pause_mask;
3796 : :
3797 : : /* Cache user FC request */
3798 : : cache_data.data.curr_user_fc_req = req_mode;
3799 : : ice_cache_phy_user_req(pi, cache_data, ICE_FC_MODE);
3800 : :
3801 : 0 : return 0;
3802 : : }
3803 : :
3804 : : /**
3805 : : * ice_set_fc
3806 : : * @pi: port information structure
3807 : : * @aq_failures: pointer to status code, specific to ice_set_fc routine
3808 : : * @ena_auto_link_update: enable automatic link update
3809 : : *
3810 : : * Set the requested flow control mode.
3811 : : */
3812 : : int
3813 : 0 : ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update)
3814 : : {
3815 : 0 : struct ice_aqc_set_phy_cfg_data cfg = { 0 };
3816 : : struct ice_aqc_get_phy_caps_data *pcaps;
3817 : : struct ice_hw *hw;
3818 : : int status;
3819 : :
3820 [ # # ]: 0 : if (!pi || !aq_failures)
3821 : : return ICE_ERR_BAD_PTR;
3822 : :
3823 : 0 : *aq_failures = 0;
3824 : 0 : hw = pi->hw;
3825 : :
3826 : : pcaps = (struct ice_aqc_get_phy_caps_data *)
3827 : 0 : ice_malloc(hw, sizeof(*pcaps));
3828 [ # # ]: 0 : if (!pcaps)
3829 : : return ICE_ERR_NO_MEMORY;
3830 : :
3831 : : /* Get the current PHY config */
3832 : 0 : status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_ACTIVE_CFG,
3833 : : pcaps, NULL);
3834 : :
3835 [ # # ]: 0 : if (status) {
3836 : 0 : *aq_failures = ICE_SET_FC_AQ_FAIL_GET;
3837 : 0 : goto out;
3838 : : }
3839 : :
3840 : 0 : ice_copy_phy_caps_to_cfg(pi, pcaps, &cfg);
3841 : :
3842 : : /* Configure the set PHY data */
3843 : 0 : status = ice_cfg_phy_fc(pi, &cfg, pi->fc.req_mode);
3844 [ # # ]: 0 : if (status) {
3845 [ # # ]: 0 : if (status != ICE_ERR_BAD_PTR)
3846 : 0 : *aq_failures = ICE_SET_FC_AQ_FAIL_GET;
3847 : :
3848 : 0 : goto out;
3849 : : }
3850 : :
3851 : : /* If the capabilities have changed, then set the new config */
3852 [ # # ]: 0 : if (cfg.caps != pcaps->caps) {
3853 : : int retry_count, retry_max = 10;
3854 : :
3855 : : /* Auto restart link so settings take effect */
3856 [ # # ]: 0 : if (ena_auto_link_update)
3857 : 0 : cfg.caps |= ICE_AQ_PHY_ENA_AUTO_LINK_UPDT;
3858 : :
3859 : 0 : status = ice_aq_set_phy_cfg(hw, pi, &cfg, NULL);
3860 [ # # ]: 0 : if (status) {
3861 : 0 : *aq_failures = ICE_SET_FC_AQ_FAIL_SET;
3862 : 0 : goto out;
3863 : : }
3864 : :
3865 : : /* Update the link info
3866 : : * It sometimes takes a really long time for link to
3867 : : * come back from the atomic reset. Thus, we wait a
3868 : : * little bit.
3869 : : */
3870 [ # # ]: 0 : for (retry_count = 0; retry_count < retry_max; retry_count++) {
3871 : 0 : status = ice_update_link_info(pi);
3872 : :
3873 [ # # ]: 0 : if (!status)
3874 : : break;
3875 : :
3876 : 0 : ice_msec_delay(100, true);
3877 : : }
3878 : :
3879 [ # # ]: 0 : if (status)
3880 : 0 : *aq_failures = ICE_SET_FC_AQ_FAIL_UPDATE;
3881 : : }
3882 : :
3883 : 0 : out:
3884 : 0 : ice_free(hw, pcaps);
3885 : 0 : return status;
3886 : : }
3887 : :
3888 : : /**
3889 : : * ice_phy_caps_equals_cfg
3890 : : * @phy_caps: PHY capabilities
3891 : : * @phy_cfg: PHY configuration
3892 : : *
3893 : : * Helper function to determine if PHY capabilities matches PHY
3894 : : * configuration
3895 : : */
3896 : : bool
3897 : 0 : ice_phy_caps_equals_cfg(struct ice_aqc_get_phy_caps_data *phy_caps,
3898 : : struct ice_aqc_set_phy_cfg_data *phy_cfg)
3899 : : {
3900 : : u8 caps_mask, cfg_mask;
3901 : :
3902 [ # # ]: 0 : if (!phy_caps || !phy_cfg)
3903 : : return false;
3904 : :
3905 : : /* These bits are not common between capabilities and configuration.
3906 : : * Do not use them to determine equality.
3907 : : */
3908 : : caps_mask = ICE_AQC_PHY_CAPS_MASK & ~(ICE_AQC_PHY_AN_MODE |
3909 : : ICE_AQC_PHY_EN_MOD_QUAL);
3910 : : cfg_mask = ICE_AQ_PHY_ENA_VALID_MASK & ~ICE_AQ_PHY_ENA_AUTO_LINK_UPDT;
3911 : :
3912 [ # # ]: 0 : if (phy_caps->phy_type_low != phy_cfg->phy_type_low ||
3913 [ # # ]: 0 : phy_caps->phy_type_high != phy_cfg->phy_type_high ||
3914 [ # # ]: 0 : ((phy_caps->caps & caps_mask) != (phy_cfg->caps & cfg_mask)) ||
3915 [ # # ]: 0 : phy_caps->low_power_ctrl_an != phy_cfg->low_power_ctrl_an ||
3916 : 0 : phy_caps->eee_cap != phy_cfg->eee_cap ||
3917 [ # # ]: 0 : phy_caps->eeer_value != phy_cfg->eeer_value ||
3918 [ # # ]: 0 : phy_caps->link_fec_options != phy_cfg->link_fec_opt)
3919 : 0 : return false;
3920 : :
3921 : : return true;
3922 : : }
3923 : :
3924 : : /**
3925 : : * ice_copy_phy_caps_to_cfg - Copy PHY ability data to configuration data
3926 : : * @pi: port information structure
3927 : : * @caps: PHY ability structure to copy data from
3928 : : * @cfg: PHY configuration structure to copy data to
3929 : : *
3930 : : * Helper function to copy AQC PHY get ability data to PHY set configuration
3931 : : * data structure
3932 : : */
3933 : : void
3934 : 0 : ice_copy_phy_caps_to_cfg(struct ice_port_info *pi,
3935 : : struct ice_aqc_get_phy_caps_data *caps,
3936 : : struct ice_aqc_set_phy_cfg_data *cfg)
3937 : : {
3938 [ # # # # ]: 0 : if (!pi || !caps || !cfg)
3939 : : return;
3940 : :
3941 : : ice_memset(cfg, 0, sizeof(*cfg), ICE_NONDMA_MEM);
3942 : 0 : cfg->phy_type_low = caps->phy_type_low;
3943 : 0 : cfg->phy_type_high = caps->phy_type_high;
3944 : 0 : cfg->caps = caps->caps;
3945 : 0 : cfg->low_power_ctrl_an = caps->low_power_ctrl_an;
3946 : 0 : cfg->eee_cap = caps->eee_cap;
3947 : 0 : cfg->eeer_value = caps->eeer_value;
3948 : 0 : cfg->link_fec_opt = caps->link_fec_options;
3949 : 0 : cfg->module_compliance_enforcement =
3950 : 0 : caps->module_compliance_enforcement;
3951 : : }
3952 : :
3953 : : /**
3954 : : * ice_cfg_phy_fec - Configure PHY FEC data based on FEC mode
3955 : : * @pi: port information structure
3956 : : * @cfg: PHY configuration data to set FEC mode
3957 : : * @fec: FEC mode to configure
3958 : : */
3959 : : int
3960 : 0 : ice_cfg_phy_fec(struct ice_port_info *pi, struct ice_aqc_set_phy_cfg_data *cfg,
3961 : : enum ice_fec_mode fec)
3962 : : {
3963 : : struct ice_aqc_get_phy_caps_data *pcaps;
3964 : : struct ice_hw *hw;
3965 : : int status = 0;
3966 : :
3967 [ # # ]: 0 : if (!pi || !cfg)
3968 : : return ICE_ERR_BAD_PTR;
3969 : :
3970 : 0 : hw = pi->hw;
3971 : :
3972 : : pcaps = (struct ice_aqc_get_phy_caps_data *)
3973 : 0 : ice_malloc(hw, sizeof(*pcaps));
3974 [ # # ]: 0 : if (!pcaps)
3975 : : return ICE_ERR_NO_MEMORY;
3976 : :
3977 [ # # ]: 0 : status = ice_aq_get_phy_caps(pi, false,
3978 : 0 : (ice_fw_supports_report_dflt_cfg(hw) ?
3979 : : ICE_AQC_REPORT_DFLT_CFG :
3980 : : ICE_AQC_REPORT_TOPO_CAP_MEDIA), pcaps, NULL);
3981 : :
3982 [ # # ]: 0 : if (status)
3983 : 0 : goto out;
3984 : :
3985 : 0 : cfg->caps |= (pcaps->caps & ICE_AQC_PHY_EN_AUTO_FEC);
3986 : 0 : cfg->link_fec_opt = pcaps->link_fec_options;
3987 : :
3988 [ # # # # : 0 : switch (fec) {
# # ]
3989 : 0 : case ICE_FEC_BASER:
3990 : : /* Clear RS bits, and AND BASE-R ability
3991 : : * bits and OR request bits.
3992 : : */
3993 : 0 : cfg->link_fec_opt &= ICE_AQC_PHY_FEC_10G_KR_40G_KR4_EN |
3994 : : ICE_AQC_PHY_FEC_25G_KR_CLAUSE74_EN;
3995 : 0 : cfg->link_fec_opt |= ICE_AQC_PHY_FEC_10G_KR_40G_KR4_REQ |
3996 : : ICE_AQC_PHY_FEC_25G_KR_REQ;
3997 : 0 : break;
3998 : 0 : case ICE_FEC_RS:
3999 : : /* Clear BASE-R bits, and AND RS ability
4000 : : * bits and OR request bits.
4001 : : */
4002 : 0 : cfg->link_fec_opt &= ICE_AQC_PHY_FEC_25G_RS_CLAUSE91_EN;
4003 : 0 : cfg->link_fec_opt |= ICE_AQC_PHY_FEC_25G_RS_528_REQ |
4004 : : ICE_AQC_PHY_FEC_25G_RS_544_REQ;
4005 : 0 : break;
4006 : 0 : case ICE_FEC_NONE:
4007 : : /* Clear all FEC option bits. */
4008 : 0 : cfg->link_fec_opt &= ~ICE_AQC_PHY_FEC_MASK;
4009 : 0 : break;
4010 : 0 : case ICE_FEC_DIS_AUTO:
4011 : : /* Set No FEC and auto FEC */
4012 [ # # ]: 0 : if (!ice_fw_supports_fec_dis_auto(hw)) {
4013 : : status = ICE_ERR_NOT_SUPPORTED;
4014 : 0 : goto out;
4015 : : }
4016 : 0 : cfg->link_fec_opt |= ICE_AQC_PHY_FEC_DIS;
4017 : : /* fall-through */
4018 : 0 : case ICE_FEC_AUTO:
4019 : : /* AND auto FEC bit, and all caps bits. */
4020 : : cfg->caps &= ICE_AQC_PHY_CAPS_MASK;
4021 : 0 : cfg->link_fec_opt |= pcaps->link_fec_options;
4022 : 0 : break;
4023 : : default:
4024 : : status = ICE_ERR_PARAM;
4025 : : break;
4026 : : }
4027 : :
4028 [ # # # # : 0 : if (fec == ICE_FEC_AUTO && ice_fw_supports_link_override(pi->hw) &&
# # ]
4029 : 0 : !ice_fw_supports_report_dflt_cfg(pi->hw)) {
4030 : : struct ice_link_default_override_tlv tlv;
4031 : :
4032 [ # # ]: 0 : if (ice_get_link_default_override(&tlv, pi))
4033 : 0 : goto out;
4034 : :
4035 [ # # ]: 0 : if (!(tlv.options & ICE_LINK_OVERRIDE_STRICT_MODE) &&
4036 : : (tlv.options & ICE_LINK_OVERRIDE_EN))
4037 : 0 : cfg->link_fec_opt = tlv.fec_options;
4038 : : }
4039 : :
4040 : 0 : out:
4041 : 0 : ice_free(hw, pcaps);
4042 : :
4043 : 0 : return status;
4044 : : }
4045 : :
4046 : : /**
4047 : : * ice_get_link_status - get status of the HW network link
4048 : : * @pi: port information structure
4049 : : * @link_up: pointer to bool (true/false = linkup/linkdown)
4050 : : *
4051 : : * Variable link_up is true if link is up, false if link is down.
4052 : : * The variable link_up is invalid if status is non zero. As a
4053 : : * result of this call, link status reporting becomes enabled
4054 : : */
4055 : 0 : int ice_get_link_status(struct ice_port_info *pi, bool *link_up)
4056 : : {
4057 : : struct ice_phy_info *phy_info;
4058 : : int status = 0;
4059 : :
4060 [ # # ]: 0 : if (!pi || !link_up)
4061 : : return ICE_ERR_PARAM;
4062 : :
4063 : : phy_info = &pi->phy;
4064 : :
4065 [ # # ]: 0 : if (phy_info->get_link_info) {
4066 : 0 : status = ice_update_link_info(pi);
4067 : :
4068 [ # # ]: 0 : if (status)
4069 [ # # ]: 0 : ice_debug(pi->hw, ICE_DBG_LINK, "get link status error, status = %d\n",
4070 : : status);
4071 : : }
4072 : :
4073 : 0 : *link_up = phy_info->link_info.link_info & ICE_AQ_LINK_UP;
4074 : :
4075 : 0 : return status;
4076 : : }
4077 : :
4078 : : /**
4079 : : * ice_aq_set_link_restart_an
4080 : : * @pi: pointer to the port information structure
4081 : : * @ena_link: if true: enable link, if false: disable link
4082 : : * @cd: pointer to command details structure or NULL
4083 : : *
4084 : : * Sets up the link and restarts the Auto-Negotiation over the link.
4085 : : */
4086 : : int
4087 : 0 : ice_aq_set_link_restart_an(struct ice_port_info *pi, bool ena_link,
4088 : : struct ice_sq_cd *cd)
4089 : : {
4090 : : int status = ICE_ERR_AQ_ERROR;
4091 : : struct ice_aqc_restart_an *cmd;
4092 : : struct ice_aq_desc desc;
4093 : :
4094 : : cmd = &desc.params.restart_an;
4095 : :
4096 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_restart_an);
4097 : :
4098 : 0 : cmd->cmd_flags = ICE_AQC_RESTART_AN_LINK_RESTART;
4099 : 0 : cmd->lport_num = pi->lport;
4100 [ # # ]: 0 : if (ena_link)
4101 : 0 : cmd->cmd_flags |= ICE_AQC_RESTART_AN_LINK_ENABLE;
4102 : : else
4103 : : cmd->cmd_flags &= ~ICE_AQC_RESTART_AN_LINK_ENABLE;
4104 : :
4105 : 0 : status = ice_aq_send_cmd(pi->hw, &desc, NULL, 0, cd);
4106 [ # # ]: 0 : if (status)
4107 : : return status;
4108 : :
4109 [ # # ]: 0 : if (ena_link)
4110 : 0 : pi->phy.curr_user_phy_cfg.caps |= ICE_AQC_PHY_EN_LINK;
4111 : : else
4112 : 0 : pi->phy.curr_user_phy_cfg.caps &= ~ICE_AQC_PHY_EN_LINK;
4113 : :
4114 : : return 0;
4115 : : }
4116 : :
4117 : : /**
4118 : : * ice_aq_set_event_mask
4119 : : * @hw: pointer to the HW struct
4120 : : * @port_num: port number of the physical function
4121 : : * @mask: event mask to be set
4122 : : * @cd: pointer to command details structure or NULL
4123 : : *
4124 : : * Set event mask (0x0613)
4125 : : */
4126 : : int
4127 : 0 : ice_aq_set_event_mask(struct ice_hw *hw, u8 port_num, u16 mask,
4128 : : struct ice_sq_cd *cd)
4129 : : {
4130 : : struct ice_aqc_set_event_mask *cmd;
4131 : : struct ice_aq_desc desc;
4132 : :
4133 : : cmd = &desc.params.set_event_mask;
4134 : :
4135 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_event_mask);
4136 : :
4137 : 0 : cmd->lport_num = port_num;
4138 : :
4139 : 0 : cmd->event_mask = CPU_TO_LE16(mask);
4140 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
4141 : : }
4142 : :
4143 : : /**
4144 : : * ice_aq_set_mac_loopback
4145 : : * @hw: pointer to the HW struct
4146 : : * @ena_lpbk: Enable or Disable loopback
4147 : : * @cd: pointer to command details structure or NULL
4148 : : *
4149 : : * Enable/disable loopback on a given port
4150 : : */
4151 : : int
4152 : 0 : ice_aq_set_mac_loopback(struct ice_hw *hw, bool ena_lpbk, struct ice_sq_cd *cd)
4153 : : {
4154 : : struct ice_aqc_set_mac_lb *cmd;
4155 : : struct ice_aq_desc desc;
4156 : :
4157 : : cmd = &desc.params.set_mac_lb;
4158 : :
4159 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_mac_lb);
4160 [ # # ]: 0 : if (ena_lpbk)
4161 : 0 : cmd->lb_mode = ICE_AQ_MAC_LB_EN;
4162 : :
4163 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
4164 : : }
4165 : :
4166 : : /**
4167 : : * ice_aq_set_port_id_led
4168 : : * @pi: pointer to the port information
4169 : : * @is_orig_mode: is this LED set to original mode (by the net-list)
4170 : : * @cd: pointer to command details structure or NULL
4171 : : *
4172 : : * Set LED value for the given port (0x06e9)
4173 : : */
4174 : : int
4175 : 0 : ice_aq_set_port_id_led(struct ice_port_info *pi, bool is_orig_mode,
4176 : : struct ice_sq_cd *cd)
4177 : : {
4178 : : struct ice_aqc_set_port_id_led *cmd;
4179 : 0 : struct ice_hw *hw = pi->hw;
4180 : : struct ice_aq_desc desc;
4181 : :
4182 : : cmd = &desc.params.set_port_id_led;
4183 : :
4184 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_port_id_led);
4185 : :
4186 [ # # ]: 0 : if (is_orig_mode)
4187 : 0 : cmd->ident_mode = ICE_AQC_PORT_IDENT_LED_ORIG;
4188 : : else
4189 : 0 : cmd->ident_mode = ICE_AQC_PORT_IDENT_LED_BLINK;
4190 : :
4191 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
4192 : : }
4193 : :
4194 : : /**
4195 : : * ice_aq_sff_eeprom
4196 : : * @hw: pointer to the HW struct
4197 : : * @lport: bits [7:0] = logical port, bit [8] = logical port valid
4198 : : * @bus_addr: I2C bus address of the eeprom (typically 0xA0, 0=topo default)
4199 : : * @mem_addr: I2C offset. lower 8 bits for address, 8 upper bits zero padding.
4200 : : * @page: QSFP page
4201 : : * @set_page: set or ignore the page
4202 : : * @data: pointer to data buffer to be read/written to the I2C device.
4203 : : * @length: 1-16 for read, 1 for write.
4204 : : * @write: 0 read, 1 for write.
4205 : : * @cd: pointer to command details structure or NULL
4206 : : *
4207 : : * Read/Write SFF EEPROM (0x06EE)
4208 : : */
4209 : : int
4210 : 0 : ice_aq_sff_eeprom(struct ice_hw *hw, u16 lport, u8 bus_addr,
4211 : : u16 mem_addr, u8 page, u8 set_page, u8 *data, u8 length,
4212 : : bool write, struct ice_sq_cd *cd)
4213 : : {
4214 : : struct ice_aqc_sff_eeprom *cmd;
4215 : : struct ice_aq_desc desc;
4216 : : int status;
4217 : :
4218 [ # # # # ]: 0 : if (!data || (mem_addr & 0xff00))
4219 : : return ICE_ERR_PARAM;
4220 : :
4221 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_sff_eeprom);
4222 : : cmd = &desc.params.read_write_sff_param;
4223 : 0 : desc.flags = CPU_TO_LE16(ICE_AQ_FLAG_RD);
4224 : 0 : cmd->lport_num = (u8)(lport & 0xff);
4225 : 0 : cmd->lport_num_valid = (u8)((lport >> 8) & 0x01);
4226 : 0 : cmd->i2c_bus_addr = CPU_TO_LE16(((bus_addr >> 1) &
4227 : : ICE_AQC_SFF_I2CBUS_7BIT_M) |
4228 : : ((set_page <<
4229 : : ICE_AQC_SFF_SET_EEPROM_PAGE_S) &
4230 : : ICE_AQC_SFF_SET_EEPROM_PAGE_M));
4231 : 0 : cmd->i2c_mem_addr = CPU_TO_LE16(mem_addr & 0xff);
4232 : 0 : cmd->eeprom_page = CPU_TO_LE16((u16)page << ICE_AQC_SFF_EEPROM_PAGE_S);
4233 [ # # ]: 0 : if (write)
4234 : 0 : cmd->i2c_bus_addr |= CPU_TO_LE16(ICE_AQC_SFF_IS_WRITE);
4235 : :
4236 : 0 : status = ice_aq_send_cmd(hw, &desc, data, length, cd);
4237 : 0 : return status;
4238 : : }
4239 : :
4240 : : /**
4241 : : * ice_aq_prog_topo_dev_nvm
4242 : : * @hw: pointer to the hardware structure
4243 : : * @topo_params: pointer to structure storing topology parameters for a device
4244 : : * @cd: pointer to command details structure or NULL
4245 : : *
4246 : : * Program Topology Device NVM (0x06F2)
4247 : : *
4248 : : */
4249 : : int
4250 : 0 : ice_aq_prog_topo_dev_nvm(struct ice_hw *hw,
4251 : : struct ice_aqc_link_topo_params *topo_params,
4252 : : struct ice_sq_cd *cd)
4253 : : {
4254 : : struct ice_aqc_prog_topo_dev_nvm *cmd;
4255 : : struct ice_aq_desc desc;
4256 : :
4257 : : cmd = &desc.params.prog_topo_dev_nvm;
4258 : :
4259 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_prog_topo_dev_nvm);
4260 : :
4261 : : ice_memcpy(&cmd->topo_params, topo_params, sizeof(*topo_params),
4262 : : ICE_NONDMA_TO_NONDMA);
4263 : :
4264 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
4265 : : }
4266 : :
4267 : : /**
4268 : : * ice_aq_read_topo_dev_nvm
4269 : : * @hw: pointer to the hardware structure
4270 : : * @topo_params: pointer to structure storing topology parameters for a device
4271 : : * @start_address: byte offset in the topology device NVM
4272 : : * @data: pointer to data buffer
4273 : : * @data_size: number of bytes to be read from the topology device NVM
4274 : : * @cd: pointer to command details structure or NULL
4275 : : * Read Topology Device NVM (0x06F3)
4276 : : *
4277 : : */
4278 : : int
4279 : 0 : ice_aq_read_topo_dev_nvm(struct ice_hw *hw,
4280 : : struct ice_aqc_link_topo_params *topo_params,
4281 : : u32 start_address, u8 *data, u8 data_size,
4282 : : struct ice_sq_cd *cd)
4283 : : {
4284 : : struct ice_aqc_read_topo_dev_nvm *cmd;
4285 : : struct ice_aq_desc desc;
4286 : : int status;
4287 : :
4288 [ # # # # ]: 0 : if (!data || data_size == 0 ||
4289 : : data_size > ICE_AQC_READ_TOPO_DEV_NVM_DATA_READ_SIZE)
4290 : : return ICE_ERR_PARAM;
4291 : :
4292 : : cmd = &desc.params.read_topo_dev_nvm;
4293 : :
4294 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_read_topo_dev_nvm);
4295 : :
4296 [ # # ]: 0 : desc.datalen = CPU_TO_LE16(data_size);
4297 : : ice_memcpy(&cmd->topo_params, topo_params, sizeof(*topo_params),
4298 : : ICE_NONDMA_TO_NONDMA);
4299 : 0 : cmd->start_address = CPU_TO_LE32(start_address);
4300 : :
4301 : 0 : status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
4302 [ # # ]: 0 : if (status)
4303 : : return status;
4304 : :
4305 : : ice_memcpy(data, cmd->data_read, data_size, ICE_NONDMA_TO_NONDMA);
4306 : :
4307 : : return 0;
4308 : : }
4309 : :
4310 : : /**
4311 : : * __ice_aq_get_set_rss_lut
4312 : : * @hw: pointer to the hardware structure
4313 : : * @params: RSS LUT parameters
4314 : : * @set: set true to set the table, false to get the table
4315 : : *
4316 : : * Internal function to get (0x0B05) or set (0x0B03) RSS look up table
4317 : : */
4318 : : static int
4319 : 0 : __ice_aq_get_set_rss_lut(struct ice_hw *hw, struct ice_aq_get_set_rss_lut_params *params, bool set)
4320 : : {
4321 : : u16 flags = 0, vsi_id, lut_type, lut_size, glob_lut_idx, vsi_handle;
4322 : : struct ice_aqc_get_set_rss_lut *cmd_resp;
4323 : : struct ice_aq_desc desc;
4324 : : int status;
4325 : : u8 *lut;
4326 : :
4327 [ # # ]: 0 : if (!params)
4328 : : return ICE_ERR_PARAM;
4329 : :
4330 : 0 : vsi_handle = params->vsi_handle;
4331 : 0 : lut = params->lut;
4332 : :
4333 [ # # # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle) || !lut)
4334 : : return ICE_ERR_PARAM;
4335 : :
4336 : 0 : lut_size = params->lut_size;
4337 : 0 : lut_type = params->lut_type;
4338 : 0 : glob_lut_idx = params->global_lut_id;
4339 : 0 : vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
4340 : :
4341 : : cmd_resp = &desc.params.get_set_rss_lut;
4342 : :
4343 [ # # ]: 0 : if (set) {
4344 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_rss_lut);
4345 : 0 : desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
4346 : : } else {
4347 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_rss_lut);
4348 : : }
4349 : :
4350 : 0 : cmd_resp->vsi_id = CPU_TO_LE16(((vsi_id <<
4351 : : ICE_AQC_GSET_RSS_LUT_VSI_ID_S) &
4352 : : ICE_AQC_GSET_RSS_LUT_VSI_ID_M) |
4353 : : ICE_AQC_GSET_RSS_LUT_VSI_VALID);
4354 : :
4355 [ # # ]: 0 : switch (lut_type) {
4356 : 0 : case ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_VSI:
4357 : : case ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF:
4358 : : case ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_GLOBAL:
4359 : 0 : flags |= ((lut_type << ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_S) &
4360 : : ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_M);
4361 : : break;
4362 : 0 : default:
4363 : : status = ICE_ERR_PARAM;
4364 : 0 : goto ice_aq_get_set_rss_lut_exit;
4365 : : }
4366 : :
4367 [ # # ]: 0 : if (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_GLOBAL) {
4368 : 0 : flags |= ((glob_lut_idx << ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_S) &
4369 : : ICE_AQC_GSET_RSS_LUT_GLOBAL_IDX_M);
4370 : :
4371 [ # # ]: 0 : if (!set)
4372 : 0 : goto ice_aq_get_set_rss_lut_send;
4373 [ # # ]: 0 : } else if (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF) {
4374 [ # # ]: 0 : if (!set)
4375 : 0 : goto ice_aq_get_set_rss_lut_send;
4376 : : } else {
4377 : 0 : goto ice_aq_get_set_rss_lut_send;
4378 : : }
4379 : :
4380 : : /* LUT size is only valid for Global and PF table types */
4381 [ # # # # ]: 0 : switch (lut_size) {
4382 : : case ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_128:
4383 : : flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_128_FLAG <<
4384 : : ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) &
4385 : : ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
4386 : : break;
4387 : 0 : case ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512:
4388 : 0 : flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_512_FLAG <<
4389 : : ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) &
4390 : : ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
4391 : 0 : break;
4392 : 0 : case ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K:
4393 [ # # ]: 0 : if (lut_type == ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF) {
4394 : 0 : flags |= (ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_2K_FLAG <<
4395 : : ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_S) &
4396 : : ICE_AQC_GSET_RSS_LUT_TABLE_SIZE_M;
4397 : 0 : break;
4398 : : }
4399 : : /* fall-through */
4400 : : default:
4401 : : status = ICE_ERR_PARAM;
4402 : 0 : goto ice_aq_get_set_rss_lut_exit;
4403 : : }
4404 : :
4405 : 0 : ice_aq_get_set_rss_lut_send:
4406 : 0 : cmd_resp->flags = CPU_TO_LE16(flags);
4407 : 0 : status = ice_aq_send_cmd(hw, &desc, lut, lut_size, NULL);
4408 : :
4409 : : ice_aq_get_set_rss_lut_exit:
4410 : : return status;
4411 : : }
4412 : :
4413 : : /**
4414 : : * ice_aq_get_rss_lut
4415 : : * @hw: pointer to the hardware structure
4416 : : * @get_params: RSS LUT parameters used to specify which RSS LUT to get
4417 : : *
4418 : : * get the RSS lookup table, PF or VSI type
4419 : : */
4420 : : int
4421 : 0 : ice_aq_get_rss_lut(struct ice_hw *hw, struct ice_aq_get_set_rss_lut_params *get_params)
4422 : : {
4423 : 0 : return __ice_aq_get_set_rss_lut(hw, get_params, false);
4424 : : }
4425 : :
4426 : : /**
4427 : : * ice_aq_set_rss_lut
4428 : : * @hw: pointer to the hardware structure
4429 : : * @set_params: RSS LUT parameters used to specify how to set the RSS LUT
4430 : : *
4431 : : * set the RSS lookup table, PF or VSI type
4432 : : */
4433 : : int
4434 : 0 : ice_aq_set_rss_lut(struct ice_hw *hw, struct ice_aq_get_set_rss_lut_params *set_params)
4435 : : {
4436 : 0 : return __ice_aq_get_set_rss_lut(hw, set_params, true);
4437 : : }
4438 : :
4439 : : /**
4440 : : * __ice_aq_get_set_rss_key
4441 : : * @hw: pointer to the HW struct
4442 : : * @vsi_id: VSI FW index
4443 : : * @key: pointer to key info struct
4444 : : * @set: set true to set the key, false to get the key
4445 : : *
4446 : : * get (0x0B04) or set (0x0B02) the RSS key per VSI
4447 : : */
4448 : 0 : static int __ice_aq_get_set_rss_key(struct ice_hw *hw, u16 vsi_id,
4449 : : struct ice_aqc_get_set_rss_keys *key,
4450 : : bool set)
4451 : : {
4452 : : struct ice_aqc_get_set_rss_key *cmd_resp;
4453 : : u16 key_size = sizeof(*key);
4454 : : struct ice_aq_desc desc;
4455 : :
4456 : : cmd_resp = &desc.params.get_set_rss_key;
4457 : :
4458 [ # # ]: 0 : if (set) {
4459 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_rss_key);
4460 : 0 : desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
4461 : : } else {
4462 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_rss_key);
4463 : : }
4464 : :
4465 : 0 : cmd_resp->vsi_id = CPU_TO_LE16(((vsi_id <<
4466 : : ICE_AQC_GSET_RSS_KEY_VSI_ID_S) &
4467 : : ICE_AQC_GSET_RSS_KEY_VSI_ID_M) |
4468 : : ICE_AQC_GSET_RSS_KEY_VSI_VALID);
4469 : :
4470 : 0 : return ice_aq_send_cmd(hw, &desc, key, key_size, NULL);
4471 : : }
4472 : :
4473 : : /**
4474 : : * ice_aq_get_rss_key
4475 : : * @hw: pointer to the HW struct
4476 : : * @vsi_handle: software VSI handle
4477 : : * @key: pointer to key info struct
4478 : : *
4479 : : * get the RSS key per VSI
4480 : : */
4481 : : int
4482 : 0 : ice_aq_get_rss_key(struct ice_hw *hw, u16 vsi_handle,
4483 : : struct ice_aqc_get_set_rss_keys *key)
4484 : : {
4485 [ # # # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle) || !key)
4486 : : return ICE_ERR_PARAM;
4487 : :
4488 : 0 : return __ice_aq_get_set_rss_key(hw, ice_get_hw_vsi_num(hw, vsi_handle),
4489 : : key, false);
4490 : : }
4491 : :
4492 : : /**
4493 : : * ice_aq_set_rss_key
4494 : : * @hw: pointer to the HW struct
4495 : : * @vsi_handle: software VSI handle
4496 : : * @keys: pointer to key info struct
4497 : : *
4498 : : * set the RSS key per VSI
4499 : : */
4500 : : int
4501 : 0 : ice_aq_set_rss_key(struct ice_hw *hw, u16 vsi_handle,
4502 : : struct ice_aqc_get_set_rss_keys *keys)
4503 : : {
4504 [ # # # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle) || !keys)
4505 : : return ICE_ERR_PARAM;
4506 : :
4507 : 0 : return __ice_aq_get_set_rss_key(hw, ice_get_hw_vsi_num(hw, vsi_handle),
4508 : : keys, true);
4509 : : }
4510 : :
4511 : : /**
4512 : : * ice_aq_add_lan_txq
4513 : : * @hw: pointer to the hardware structure
4514 : : * @num_qgrps: Number of added queue groups
4515 : : * @qg_list: list of queue groups to be added
4516 : : * @buf_size: size of buffer for indirect command
4517 : : * @cd: pointer to command details structure or NULL
4518 : : *
4519 : : * Add Tx LAN queue (0x0C30)
4520 : : *
4521 : : * NOTE:
4522 : : * Prior to calling add Tx LAN queue:
4523 : : * Initialize the following as part of the Tx queue context:
4524 : : * Completion queue ID if the queue uses Completion queue, Quanta profile,
4525 : : * Cache profile and Packet shaper profile.
4526 : : *
4527 : : * After add Tx LAN queue AQ command is completed:
4528 : : * Interrupts should be associated with specific queues,
4529 : : * Association of Tx queue to Doorbell queue is not part of Add LAN Tx queue
4530 : : * flow.
4531 : : */
4532 : : int
4533 : 0 : ice_aq_add_lan_txq(struct ice_hw *hw, u8 num_qgrps,
4534 : : struct ice_aqc_add_tx_qgrp *qg_list, u16 buf_size,
4535 : : struct ice_sq_cd *cd)
4536 : : {
4537 : : struct ice_aqc_add_tx_qgrp *list;
4538 : : struct ice_aqc_add_txqs *cmd;
4539 : : struct ice_aq_desc desc;
4540 : : u16 i, sum_size = 0;
4541 : :
4542 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
4543 : :
4544 : : cmd = &desc.params.add_txqs;
4545 : :
4546 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_txqs);
4547 : :
4548 [ # # ]: 0 : if (!qg_list)
4549 : : return ICE_ERR_PARAM;
4550 : :
4551 [ # # ]: 0 : if (num_qgrps > ICE_LAN_TXQ_MAX_QGRPS)
4552 : : return ICE_ERR_PARAM;
4553 : :
4554 [ # # ]: 0 : for (i = 0, list = qg_list; i < num_qgrps; i++) {
4555 : 0 : sum_size += ice_struct_size(list, txqs, list->num_txqs);
4556 : 0 : list = (struct ice_aqc_add_tx_qgrp *)(list->txqs +
4557 : 0 : list->num_txqs);
4558 : : }
4559 : :
4560 [ # # ]: 0 : if (buf_size != sum_size)
4561 : : return ICE_ERR_PARAM;
4562 : :
4563 : 0 : desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
4564 : :
4565 : 0 : cmd->num_qgrps = num_qgrps;
4566 : :
4567 : 0 : return ice_aq_send_cmd(hw, &desc, qg_list, buf_size, cd);
4568 : : }
4569 : :
4570 : : /**
4571 : : * ice_aq_dis_lan_txq
4572 : : * @hw: pointer to the hardware structure
4573 : : * @num_qgrps: number of groups in the list
4574 : : * @qg_list: the list of groups to disable
4575 : : * @buf_size: the total size of the qg_list buffer in bytes
4576 : : * @rst_src: if called due to reset, specifies the reset source
4577 : : * @vmvf_num: the relative VM or VF number that is undergoing the reset
4578 : : * @cd: pointer to command details structure or NULL
4579 : : *
4580 : : * Disable LAN Tx queue (0x0C31)
4581 : : */
4582 : : static int
4583 : 0 : ice_aq_dis_lan_txq(struct ice_hw *hw, u8 num_qgrps,
4584 : : struct ice_aqc_dis_txq_item *qg_list, u16 buf_size,
4585 : : enum ice_disq_rst_src rst_src, u16 vmvf_num,
4586 : : struct ice_sq_cd *cd)
4587 : : {
4588 : : struct ice_aqc_dis_txq_item *item;
4589 : : struct ice_aqc_dis_txqs *cmd;
4590 : : struct ice_aq_desc desc;
4591 : : int status;
4592 : : u16 i, sz = 0;
4593 : :
4594 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
4595 : : cmd = &desc.params.dis_txqs;
4596 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_dis_txqs);
4597 : :
4598 : : /* qg_list can be NULL only in VM/VF reset flow */
4599 [ # # ]: 0 : if (!qg_list && !rst_src)
4600 : : return ICE_ERR_PARAM;
4601 : :
4602 [ # # ]: 0 : if (num_qgrps > ICE_LAN_TXQ_MAX_QGRPS)
4603 : : return ICE_ERR_PARAM;
4604 : :
4605 : 0 : cmd->num_entries = num_qgrps;
4606 : :
4607 : 0 : cmd->vmvf_and_timeout = CPU_TO_LE16((5 << ICE_AQC_Q_DIS_TIMEOUT_S) &
4608 : : ICE_AQC_Q_DIS_TIMEOUT_M);
4609 : :
4610 [ # # ]: 0 : switch (rst_src) {
4611 : 0 : case ICE_VM_RESET:
4612 : 0 : cmd->cmd_type = ICE_AQC_Q_DIS_CMD_VM_RESET;
4613 : 0 : cmd->vmvf_and_timeout |=
4614 : 0 : CPU_TO_LE16(vmvf_num & ICE_AQC_Q_DIS_VMVF_NUM_M);
4615 : 0 : break;
4616 : : case ICE_NO_RESET:
4617 : : default:
4618 : : break;
4619 : : }
4620 : :
4621 : : /* flush pipe on time out */
4622 : 0 : cmd->cmd_type |= ICE_AQC_Q_DIS_CMD_FLUSH_PIPE;
4623 : : /* If no queue group info, we are in a reset flow. Issue the AQ */
4624 [ # # ]: 0 : if (!qg_list)
4625 : 0 : goto do_aq;
4626 : :
4627 : : /* set RD bit to indicate that command buffer is provided by the driver
4628 : : * and it needs to be read by the firmware
4629 : : */
4630 : 0 : desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
4631 : :
4632 [ # # ]: 0 : for (i = 0, item = qg_list; i < num_qgrps; i++) {
4633 : 0 : u16 item_size = ice_struct_size(item, q_id, item->num_qs);
4634 : :
4635 : : /* If the num of queues is even, add 2 bytes of padding */
4636 [ # # ]: 0 : if ((item->num_qs % 2) == 0)
4637 : 0 : item_size += 2;
4638 : :
4639 : 0 : sz += item_size;
4640 : :
4641 : 0 : item = (struct ice_aqc_dis_txq_item *)((u8 *)item + item_size);
4642 : : }
4643 : :
4644 [ # # ]: 0 : if (buf_size != sz)
4645 : : return ICE_ERR_PARAM;
4646 : :
4647 : 0 : do_aq:
4648 : 0 : status = ice_aq_send_cmd(hw, &desc, qg_list, buf_size, cd);
4649 [ # # ]: 0 : if (status) {
4650 [ # # ]: 0 : if (!qg_list)
4651 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SCHED, "VM%d disable failed %d\n",
4652 : : vmvf_num, hw->adminq.sq_last_status);
4653 : : else
4654 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SCHED, "disable queue %d failed %d\n",
4655 : : LE16_TO_CPU(qg_list[0].q_id[0]),
4656 : : hw->adminq.sq_last_status);
4657 : : }
4658 : : return status;
4659 : : }
4660 : :
4661 : : /**
4662 : : * ice_aq_move_recfg_lan_txq
4663 : : * @hw: pointer to the hardware structure
4664 : : * @num_qs: number of queues to move/reconfigure
4665 : : * @is_move: true if this operation involves node movement
4666 : : * @is_tc_change: true if this operation involves a TC change
4667 : : * @subseq_call: true if this operation is a subsequent call
4668 : : * @flush_pipe: on timeout, true to flush pipe, false to return EAGAIN
4669 : : * @timeout: timeout in units of 100 usec (valid values 0-50)
4670 : : * @blocked_cgds: out param, bitmap of CGDs that timed out if returning EAGAIN
4671 : : * @buf: struct containing src/dest TEID and per-queue info
4672 : : * @buf_size: size of buffer for indirect command
4673 : : * @txqs_moved: out param, number of queues successfully moved
4674 : : * @cd: pointer to command details structure or NULL
4675 : : *
4676 : : * Move / Reconfigure Tx LAN queues (0x0C32)
4677 : : */
4678 : : int
4679 : 0 : ice_aq_move_recfg_lan_txq(struct ice_hw *hw, u8 num_qs, bool is_move,
4680 : : bool is_tc_change, bool subseq_call, bool flush_pipe,
4681 : : u8 timeout, u32 *blocked_cgds,
4682 : : struct ice_aqc_move_txqs_data *buf, u16 buf_size,
4683 : : u8 *txqs_moved, struct ice_sq_cd *cd)
4684 : : {
4685 : : struct ice_aqc_move_txqs *cmd;
4686 : : struct ice_aq_desc desc;
4687 : : int status;
4688 : :
4689 : : cmd = &desc.params.move_txqs;
4690 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_move_recfg_txqs);
4691 : :
4692 : : #define ICE_LAN_TXQ_MOVE_TIMEOUT_MAX 50
4693 [ # # ]: 0 : if (timeout > ICE_LAN_TXQ_MOVE_TIMEOUT_MAX)
4694 : : return ICE_ERR_PARAM;
4695 : :
4696 [ # # # # ]: 0 : if (is_tc_change && !flush_pipe && !blocked_cgds)
4697 : : return ICE_ERR_PARAM;
4698 : :
4699 [ # # ]: 0 : if (!is_move && !is_tc_change)
4700 : : return ICE_ERR_PARAM;
4701 : :
4702 : 0 : desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
4703 : :
4704 [ # # ]: 0 : if (is_move)
4705 : 0 : cmd->cmd_type |= ICE_AQC_Q_CMD_TYPE_MOVE;
4706 : :
4707 [ # # ]: 0 : if (is_tc_change)
4708 : 0 : cmd->cmd_type |= ICE_AQC_Q_CMD_TYPE_TC_CHANGE;
4709 : :
4710 [ # # ]: 0 : if (subseq_call)
4711 : 0 : cmd->cmd_type |= ICE_AQC_Q_CMD_SUBSEQ_CALL;
4712 : :
4713 [ # # ]: 0 : if (flush_pipe)
4714 : 0 : cmd->cmd_type |= ICE_AQC_Q_CMD_FLUSH_PIPE;
4715 : :
4716 : 0 : cmd->num_qs = num_qs;
4717 : 0 : cmd->timeout = ((timeout << ICE_AQC_Q_CMD_TIMEOUT_S) &
4718 : : ICE_AQC_Q_CMD_TIMEOUT_M);
4719 : :
4720 : 0 : status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
4721 : :
4722 [ # # ]: 0 : if (!status && txqs_moved)
4723 : 0 : *txqs_moved = cmd->num_qs;
4724 : :
4725 [ # # ]: 0 : if (hw->adminq.sq_last_status == ICE_AQ_RC_EAGAIN &&
4726 [ # # ]: 0 : is_tc_change && !flush_pipe)
4727 : 0 : *blocked_cgds = LE32_TO_CPU(cmd->blocked_cgds);
4728 : :
4729 : : return status;
4730 : : }
4731 : :
4732 : : /* End of FW Admin Queue command wrappers */
4733 : :
4734 : : /**
4735 : : * ice_write_byte - write a byte to a packed context structure
4736 : : * @src_ctx: the context structure to read from
4737 : : * @dest_ctx: the context to be written to
4738 : : * @ce_info: a description of the struct to be filled
4739 : : */
4740 : : static void
4741 : 0 : ice_write_byte(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
4742 : : {
4743 : : u8 src_byte, dest_byte, mask;
4744 : : u8 *from, *dest;
4745 : : u16 shift_width;
4746 : :
4747 : : /* copy from the next struct field */
4748 : 0 : from = src_ctx + ce_info->offset;
4749 : :
4750 : : /* prepare the bits and mask */
4751 : 0 : shift_width = ce_info->lsb % 8;
4752 : 0 : mask = (u8)(BIT(ce_info->width) - 1);
4753 : :
4754 : 0 : src_byte = *from;
4755 : 0 : src_byte &= mask;
4756 : :
4757 : : /* shift to correct alignment */
4758 : 0 : mask <<= shift_width;
4759 : 0 : src_byte <<= shift_width;
4760 : :
4761 : : /* get the current bits from the target bit string */
4762 [ # # ]: 0 : dest = dest_ctx + (ce_info->lsb / 8);
4763 : :
4764 : : ice_memcpy(&dest_byte, dest, sizeof(dest_byte), ICE_NONDMA_TO_NONDMA);
4765 : :
4766 : 0 : dest_byte &= ~mask; /* get the bits not changing */
4767 [ # # ]: 0 : dest_byte |= src_byte; /* add in the new bits */
4768 : :
4769 : : /* put it all back */
4770 : : ice_memcpy(dest, &dest_byte, sizeof(dest_byte), ICE_NONDMA_TO_NONDMA);
4771 : 0 : }
4772 : :
4773 : : /**
4774 : : * ice_write_word - write a word to a packed context structure
4775 : : * @src_ctx: the context structure to read from
4776 : : * @dest_ctx: the context to be written to
4777 : : * @ce_info: a description of the struct to be filled
4778 : : */
4779 : : static void
4780 : 0 : ice_write_word(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
4781 : : {
4782 : : u16 src_word, mask;
4783 : : __le16 dest_word;
4784 : : u8 *from, *dest;
4785 : : u16 shift_width;
4786 : :
4787 : : /* copy from the next struct field */
4788 : 0 : from = src_ctx + ce_info->offset;
4789 : :
4790 : : /* prepare the bits and mask */
4791 : 0 : shift_width = ce_info->lsb % 8;
4792 : 0 : mask = BIT(ce_info->width) - 1;
4793 : :
4794 : : /* don't swizzle the bits until after the mask because the mask bits
4795 : : * will be in a different bit position on big endian machines
4796 : : */
4797 : 0 : src_word = *(u16 *)from;
4798 : 0 : src_word &= mask;
4799 : :
4800 : : /* shift to correct alignment */
4801 : 0 : mask <<= shift_width;
4802 : 0 : src_word <<= shift_width;
4803 : :
4804 : : /* get the current bits from the target bit string */
4805 [ # # ]: 0 : dest = dest_ctx + (ce_info->lsb / 8);
4806 : :
4807 : : ice_memcpy(&dest_word, dest, sizeof(dest_word), ICE_NONDMA_TO_NONDMA);
4808 : :
4809 : 0 : dest_word &= ~(CPU_TO_LE16(mask)); /* get the bits not changing */
4810 [ # # ]: 0 : dest_word |= CPU_TO_LE16(src_word); /* add in the new bits */
4811 : :
4812 : : /* put it all back */
4813 : : ice_memcpy(dest, &dest_word, sizeof(dest_word), ICE_NONDMA_TO_NONDMA);
4814 : 0 : }
4815 : :
4816 : : /**
4817 : : * ice_write_dword - write a dword to a packed context structure
4818 : : * @src_ctx: the context structure to read from
4819 : : * @dest_ctx: the context to be written to
4820 : : * @ce_info: a description of the struct to be filled
4821 : : */
4822 : : static void
4823 : 0 : ice_write_dword(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
4824 : : {
4825 : : u32 src_dword, mask;
4826 : : __le32 dest_dword;
4827 : : u8 *from, *dest;
4828 : : u16 shift_width;
4829 : :
4830 : : /* copy from the next struct field */
4831 : 0 : from = src_ctx + ce_info->offset;
4832 : :
4833 : : /* prepare the bits and mask */
4834 : 0 : shift_width = ce_info->lsb % 8;
4835 : :
4836 : : /* if the field width is exactly 32 on an x86 machine, then the shift
4837 : : * operation will not work because the SHL instructions count is masked
4838 : : * to 5 bits so the shift will do nothing
4839 : : */
4840 [ # # ]: 0 : if (ce_info->width < 32)
4841 : 0 : mask = BIT(ce_info->width) - 1;
4842 : : else
4843 : : mask = (u32)~0;
4844 : :
4845 : : /* don't swizzle the bits until after the mask because the mask bits
4846 : : * will be in a different bit position on big endian machines
4847 : : */
4848 : 0 : src_dword = *(u32 *)from;
4849 : 0 : src_dword &= mask;
4850 : :
4851 : : /* shift to correct alignment */
4852 : 0 : mask <<= shift_width;
4853 : 0 : src_dword <<= shift_width;
4854 : :
4855 : : /* get the current bits from the target bit string */
4856 [ # # ]: 0 : dest = dest_ctx + (ce_info->lsb / 8);
4857 : :
4858 : : ice_memcpy(&dest_dword, dest, sizeof(dest_dword), ICE_NONDMA_TO_NONDMA);
4859 : :
4860 : 0 : dest_dword &= ~(CPU_TO_LE32(mask)); /* get the bits not changing */
4861 [ # # ]: 0 : dest_dword |= CPU_TO_LE32(src_dword); /* add in the new bits */
4862 : :
4863 : : /* put it all back */
4864 : : ice_memcpy(dest, &dest_dword, sizeof(dest_dword), ICE_NONDMA_TO_NONDMA);
4865 : 0 : }
4866 : :
4867 : : /**
4868 : : * ice_write_qword - write a qword to a packed context structure
4869 : : * @src_ctx: the context structure to read from
4870 : : * @dest_ctx: the context to be written to
4871 : : * @ce_info: a description of the struct to be filled
4872 : : */
4873 : : static void
4874 : 0 : ice_write_qword(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
4875 : : {
4876 : : u64 src_qword, mask;
4877 : : __le64 dest_qword;
4878 : : u8 *from, *dest;
4879 : : u16 shift_width;
4880 : :
4881 : : /* copy from the next struct field */
4882 : 0 : from = src_ctx + ce_info->offset;
4883 : :
4884 : : /* prepare the bits and mask */
4885 : 0 : shift_width = ce_info->lsb % 8;
4886 : :
4887 : : /* if the field width is exactly 64 on an x86 machine, then the shift
4888 : : * operation will not work because the SHL instructions count is masked
4889 : : * to 6 bits so the shift will do nothing
4890 : : */
4891 [ # # ]: 0 : if (ce_info->width < 64)
4892 : 0 : mask = BIT_ULL(ce_info->width) - 1;
4893 : : else
4894 : : mask = (u64)~0;
4895 : :
4896 : : /* don't swizzle the bits until after the mask because the mask bits
4897 : : * will be in a different bit position on big endian machines
4898 : : */
4899 : 0 : src_qword = *(u64 *)from;
4900 : 0 : src_qword &= mask;
4901 : :
4902 : : /* shift to correct alignment */
4903 : 0 : mask <<= shift_width;
4904 : 0 : src_qword <<= shift_width;
4905 : :
4906 : : /* get the current bits from the target bit string */
4907 [ # # ]: 0 : dest = dest_ctx + (ce_info->lsb / 8);
4908 : :
4909 : : ice_memcpy(&dest_qword, dest, sizeof(dest_qword), ICE_NONDMA_TO_NONDMA);
4910 : :
4911 : 0 : dest_qword &= ~(CPU_TO_LE64(mask)); /* get the bits not changing */
4912 [ # # ]: 0 : dest_qword |= CPU_TO_LE64(src_qword); /* add in the new bits */
4913 : :
4914 : : /* put it all back */
4915 : : ice_memcpy(dest, &dest_qword, sizeof(dest_qword), ICE_NONDMA_TO_NONDMA);
4916 : 0 : }
4917 : :
4918 : : /**
4919 : : * ice_set_ctx - set context bits in packed structure
4920 : : * @hw: pointer to the hardware structure
4921 : : * @src_ctx: pointer to a generic non-packed context structure
4922 : : * @dest_ctx: pointer to memory for the packed structure
4923 : : * @ce_info: a description of the structure to be transformed
4924 : : */
4925 : : int
4926 : 0 : ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx,
4927 : : const struct ice_ctx_ele *ce_info)
4928 : : {
4929 : : int f;
4930 : :
4931 [ # # ]: 0 : for (f = 0; ce_info[f].width; f++) {
4932 : : /* We have to deal with each element of the FW response
4933 : : * using the correct size so that we are correct regardless
4934 : : * of the endianness of the machine.
4935 : : */
4936 [ # # ]: 0 : if (ce_info[f].width > (ce_info[f].size_of * BITS_PER_BYTE)) {
4937 [ # # ]: 0 : ice_debug(hw, ICE_DBG_QCTX, "Field %d width of %d bits larger than size of %d byte(s) ... skipping write\n",
4938 : : f, ce_info[f].width, ce_info[f].size_of);
4939 : 0 : continue;
4940 : : }
4941 [ # # # # : 0 : switch (ce_info[f].size_of) {
# ]
4942 : 0 : case sizeof(u8):
4943 : 0 : ice_write_byte(src_ctx, dest_ctx, &ce_info[f]);
4944 : 0 : break;
4945 : 0 : case sizeof(u16):
4946 : 0 : ice_write_word(src_ctx, dest_ctx, &ce_info[f]);
4947 : 0 : break;
4948 : 0 : case sizeof(u32):
4949 : 0 : ice_write_dword(src_ctx, dest_ctx, &ce_info[f]);
4950 : 0 : break;
4951 : 0 : case sizeof(u64):
4952 : 0 : ice_write_qword(src_ctx, dest_ctx, &ce_info[f]);
4953 : 0 : break;
4954 : : default:
4955 : : return ICE_ERR_INVAL_SIZE;
4956 : : }
4957 : : }
4958 : :
4959 : : return 0;
4960 : : }
4961 : :
4962 : : /**
4963 : : * ice_aq_get_internal_data
4964 : : * @hw: pointer to the hardware structure
4965 : : * @cluster_id: specific cluster to dump
4966 : : * @table_id: table ID within cluster
4967 : : * @start: index of line in the block to read
4968 : : * @buf: dump buffer
4969 : : * @buf_size: dump buffer size
4970 : : * @ret_buf_size: return buffer size (returned by FW)
4971 : : * @ret_next_cluster: next cluster to read (returned by FW)
4972 : : * @ret_next_table: next block to read (returned by FW)
4973 : : * @ret_next_index: next index to read (returned by FW)
4974 : : * @cd: pointer to command details structure
4975 : : *
4976 : : * Get internal FW/HW data (0xFF08) for debug purposes.
4977 : : */
4978 : : int
4979 : 0 : ice_aq_get_internal_data(struct ice_hw *hw, u16 cluster_id, u16 table_id,
4980 : : u32 start, void *buf, u16 buf_size, u16 *ret_buf_size,
4981 : : u16 *ret_next_cluster, u16 *ret_next_table,
4982 : : u32 *ret_next_index, struct ice_sq_cd *cd)
4983 : : {
4984 : : struct ice_aqc_debug_dump_internals *cmd;
4985 : : struct ice_aq_desc desc;
4986 : : int status;
4987 : :
4988 : : cmd = &desc.params.debug_dump;
4989 : :
4990 [ # # ]: 0 : if (buf_size == 0 || !buf)
4991 : : return ICE_ERR_PARAM;
4992 : :
4993 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_debug_dump_internals);
4994 : :
4995 : 0 : cmd->cluster_id = CPU_TO_LE16(cluster_id);
4996 : 0 : cmd->table_id = CPU_TO_LE16(table_id);
4997 : 0 : cmd->idx = CPU_TO_LE32(start);
4998 : :
4999 : 0 : status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
5000 : :
5001 [ # # ]: 0 : if (!status) {
5002 [ # # ]: 0 : if (ret_buf_size)
5003 : 0 : *ret_buf_size = LE16_TO_CPU(desc.datalen);
5004 [ # # ]: 0 : if (ret_next_cluster)
5005 : 0 : *ret_next_cluster = LE16_TO_CPU(cmd->cluster_id);
5006 [ # # ]: 0 : if (ret_next_table)
5007 : 0 : *ret_next_table = LE16_TO_CPU(cmd->table_id);
5008 [ # # ]: 0 : if (ret_next_index)
5009 : 0 : *ret_next_index = LE32_TO_CPU(cmd->idx);
5010 : : }
5011 : :
5012 : : return status;
5013 : : }
5014 : :
5015 : : /**
5016 : : * ice_read_byte - read context byte into struct
5017 : : * @src_ctx: the context structure to read from
5018 : : * @dest_ctx: the context to be written to
5019 : : * @ce_info: a description of the struct to be filled
5020 : : */
5021 : : static void
5022 : 0 : ice_read_byte(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
5023 : : {
5024 : : u8 dest_byte, mask;
5025 : : u8 *src, *target;
5026 : : u16 shift_width;
5027 : :
5028 : : /* prepare the bits and mask */
5029 : 0 : shift_width = ce_info->lsb % 8;
5030 : 0 : mask = (u8)(BIT(ce_info->width) - 1);
5031 : :
5032 : : /* shift to correct alignment */
5033 : 0 : mask <<= shift_width;
5034 : :
5035 : : /* get the current bits from the src bit string */
5036 [ # # ]: 0 : src = src_ctx + (ce_info->lsb / 8);
5037 : :
5038 : : ice_memcpy(&dest_byte, src, sizeof(dest_byte), ICE_NONDMA_TO_NONDMA);
5039 : :
5040 : 0 : dest_byte &= mask;
5041 : :
5042 : 0 : dest_byte >>= shift_width;
5043 : :
5044 : : /* get the address from the struct field */
5045 [ # # ]: 0 : target = dest_ctx + ce_info->offset;
5046 : :
5047 : : /* put it back in the struct */
5048 : : ice_memcpy(target, &dest_byte, sizeof(dest_byte), ICE_NONDMA_TO_NONDMA);
5049 : 0 : }
5050 : :
5051 : : /**
5052 : : * ice_read_word - read context word into struct
5053 : : * @src_ctx: the context structure to read from
5054 : : * @dest_ctx: the context to be written to
5055 : : * @ce_info: a description of the struct to be filled
5056 : : */
5057 : : static void
5058 : 0 : ice_read_word(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
5059 : : {
5060 : : u16 dest_word, mask;
5061 : : u8 *src, *target;
5062 : : __le16 src_word;
5063 : : u16 shift_width;
5064 : :
5065 : : /* prepare the bits and mask */
5066 : 0 : shift_width = ce_info->lsb % 8;
5067 : 0 : mask = BIT(ce_info->width) - 1;
5068 : :
5069 : : /* shift to correct alignment */
5070 : 0 : mask <<= shift_width;
5071 : :
5072 : : /* get the current bits from the src bit string */
5073 [ # # ]: 0 : src = src_ctx + (ce_info->lsb / 8);
5074 : :
5075 : : ice_memcpy(&src_word, src, sizeof(src_word), ICE_NONDMA_TO_NONDMA);
5076 : :
5077 : : /* the data in the memory is stored as little endian so mask it
5078 : : * correctly
5079 : : */
5080 : 0 : src_word &= CPU_TO_LE16(mask);
5081 : :
5082 : : /* get the data back into host order before shifting */
5083 : : dest_word = LE16_TO_CPU(src_word);
5084 : :
5085 : 0 : dest_word >>= shift_width;
5086 : :
5087 : : /* get the address from the struct field */
5088 [ # # ]: 0 : target = dest_ctx + ce_info->offset;
5089 : :
5090 : : /* put it back in the struct */
5091 : : ice_memcpy(target, &dest_word, sizeof(dest_word), ICE_NONDMA_TO_NONDMA);
5092 : 0 : }
5093 : :
5094 : : /**
5095 : : * ice_read_dword - read context dword into struct
5096 : : * @src_ctx: the context structure to read from
5097 : : * @dest_ctx: the context to be written to
5098 : : * @ce_info: a description of the struct to be filled
5099 : : */
5100 : : static void
5101 : 0 : ice_read_dword(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
5102 : : {
5103 : : u32 dest_dword, mask;
5104 : : __le32 src_dword;
5105 : : u8 *src, *target;
5106 : : u16 shift_width;
5107 : :
5108 : : /* prepare the bits and mask */
5109 : 0 : shift_width = ce_info->lsb % 8;
5110 : :
5111 : : /* if the field width is exactly 32 on an x86 machine, then the shift
5112 : : * operation will not work because the SHL instructions count is masked
5113 : : * to 5 bits so the shift will do nothing
5114 : : */
5115 [ # # ]: 0 : if (ce_info->width < 32)
5116 : 0 : mask = BIT(ce_info->width) - 1;
5117 : : else
5118 : : mask = (u32)~0;
5119 : :
5120 : : /* shift to correct alignment */
5121 : 0 : mask <<= shift_width;
5122 : :
5123 : : /* get the current bits from the src bit string */
5124 [ # # ]: 0 : src = src_ctx + (ce_info->lsb / 8);
5125 : :
5126 : : ice_memcpy(&src_dword, src, sizeof(src_dword), ICE_NONDMA_TO_NONDMA);
5127 : :
5128 : : /* the data in the memory is stored as little endian so mask it
5129 : : * correctly
5130 : : */
5131 : 0 : src_dword &= CPU_TO_LE32(mask);
5132 : :
5133 : : /* get the data back into host order before shifting */
5134 : : dest_dword = LE32_TO_CPU(src_dword);
5135 : :
5136 : 0 : dest_dword >>= shift_width;
5137 : :
5138 : : /* get the address from the struct field */
5139 [ # # ]: 0 : target = dest_ctx + ce_info->offset;
5140 : :
5141 : : /* put it back in the struct */
5142 : : ice_memcpy(target, &dest_dword, sizeof(dest_dword), ICE_NONDMA_TO_NONDMA);
5143 : 0 : }
5144 : :
5145 : : /**
5146 : : * ice_read_qword - read context qword into struct
5147 : : * @src_ctx: the context structure to read from
5148 : : * @dest_ctx: the context to be written to
5149 : : * @ce_info: a description of the struct to be filled
5150 : : */
5151 : : static void
5152 : 0 : ice_read_qword(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
5153 : : {
5154 : : u64 dest_qword, mask;
5155 : : __le64 src_qword;
5156 : : u8 *src, *target;
5157 : : u16 shift_width;
5158 : :
5159 : : /* prepare the bits and mask */
5160 : 0 : shift_width = ce_info->lsb % 8;
5161 : :
5162 : : /* if the field width is exactly 64 on an x86 machine, then the shift
5163 : : * operation will not work because the SHL instructions count is masked
5164 : : * to 6 bits so the shift will do nothing
5165 : : */
5166 [ # # ]: 0 : if (ce_info->width < 64)
5167 : 0 : mask = BIT_ULL(ce_info->width) - 1;
5168 : : else
5169 : : mask = (u64)~0;
5170 : :
5171 : : /* shift to correct alignment */
5172 : 0 : mask <<= shift_width;
5173 : :
5174 : : /* get the current bits from the src bit string */
5175 [ # # ]: 0 : src = src_ctx + (ce_info->lsb / 8);
5176 : :
5177 : : ice_memcpy(&src_qword, src, sizeof(src_qword), ICE_NONDMA_TO_NONDMA);
5178 : :
5179 : : /* the data in the memory is stored as little endian so mask it
5180 : : * correctly
5181 : : */
5182 : 0 : src_qword &= CPU_TO_LE64(mask);
5183 : :
5184 : : /* get the data back into host order before shifting */
5185 : : dest_qword = LE64_TO_CPU(src_qword);
5186 : :
5187 : 0 : dest_qword >>= shift_width;
5188 : :
5189 : : /* get the address from the struct field */
5190 [ # # ]: 0 : target = dest_ctx + ce_info->offset;
5191 : :
5192 : : /* put it back in the struct */
5193 : : ice_memcpy(target, &dest_qword, sizeof(dest_qword), ICE_NONDMA_TO_NONDMA);
5194 : 0 : }
5195 : :
5196 : : /**
5197 : : * ice_get_ctx - extract context bits from a packed structure
5198 : : * @src_ctx: pointer to a generic packed context structure
5199 : : * @dest_ctx: pointer to a generic non-packed context structure
5200 : : * @ce_info: a description of the structure to be read from
5201 : : */
5202 : : int
5203 : 0 : ice_get_ctx(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info)
5204 : : {
5205 : : int f;
5206 : :
5207 [ # # ]: 0 : for (f = 0; ce_info[f].width; f++) {
5208 [ # # # # : 0 : switch (ce_info[f].size_of) {
# ]
5209 : 0 : case 1:
5210 : 0 : ice_read_byte(src_ctx, dest_ctx, &ce_info[f]);
5211 : 0 : break;
5212 : 0 : case 2:
5213 : 0 : ice_read_word(src_ctx, dest_ctx, &ce_info[f]);
5214 : 0 : break;
5215 : 0 : case 4:
5216 : 0 : ice_read_dword(src_ctx, dest_ctx, &ce_info[f]);
5217 : 0 : break;
5218 : 0 : case 8:
5219 : 0 : ice_read_qword(src_ctx, dest_ctx, &ce_info[f]);
5220 : 0 : break;
5221 : : default:
5222 : : /* nothing to do, just keep going */
5223 : : break;
5224 : : }
5225 : : }
5226 : :
5227 : 0 : return 0;
5228 : : }
5229 : :
5230 : : /**
5231 : : * ice_get_lan_q_ctx - get the LAN queue context for the given VSI and TC
5232 : : * @hw: pointer to the HW struct
5233 : : * @vsi_handle: software VSI handle
5234 : : * @tc: TC number
5235 : : * @q_handle: software queue handle
5236 : : */
5237 : : struct ice_q_ctx *
5238 : 0 : ice_get_lan_q_ctx(struct ice_hw *hw, u16 vsi_handle, u8 tc, u16 q_handle)
5239 : : {
5240 : : struct ice_vsi_ctx *vsi;
5241 : : struct ice_q_ctx *q_ctx;
5242 : :
5243 : 0 : vsi = ice_get_vsi_ctx(hw, vsi_handle);
5244 [ # # ]: 0 : if (!vsi)
5245 : : return NULL;
5246 [ # # ]: 0 : if (q_handle >= vsi->num_lan_q_entries[tc])
5247 : : return NULL;
5248 [ # # ]: 0 : if (!vsi->lan_q_ctx[tc])
5249 : : return NULL;
5250 : : q_ctx = vsi->lan_q_ctx[tc];
5251 : 0 : return &q_ctx[q_handle];
5252 : : }
5253 : :
5254 : : /**
5255 : : * ice_ena_vsi_txq
5256 : : * @pi: port information structure
5257 : : * @vsi_handle: software VSI handle
5258 : : * @tc: TC number
5259 : : * @q_handle: software queue handle
5260 : : * @num_qgrps: Number of added queue groups
5261 : : * @buf: list of queue groups to be added
5262 : : * @buf_size: size of buffer for indirect command
5263 : : * @cd: pointer to command details structure or NULL
5264 : : *
5265 : : * This function adds one LAN queue
5266 : : */
5267 : : int
5268 : 0 : ice_ena_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u16 q_handle,
5269 : : u8 num_qgrps, struct ice_aqc_add_tx_qgrp *buf, u16 buf_size,
5270 : : struct ice_sq_cd *cd)
5271 : : {
5272 : 0 : struct ice_aqc_txsched_elem_data node = { 0 };
5273 : : struct ice_sched_node *parent;
5274 : : struct ice_q_ctx *q_ctx;
5275 : : struct ice_hw *hw;
5276 : : int status;
5277 : :
5278 [ # # # # ]: 0 : if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY)
5279 : : return ICE_ERR_CFG;
5280 : :
5281 [ # # # # ]: 0 : if (num_qgrps > 1 || buf->num_txqs > 1)
5282 : : return ICE_ERR_MAX_LIMIT;
5283 : :
5284 : 0 : hw = pi->hw;
5285 : :
5286 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
5287 : : return ICE_ERR_PARAM;
5288 : :
5289 : 0 : ice_acquire_lock(&pi->sched_lock);
5290 : :
5291 : 0 : q_ctx = ice_get_lan_q_ctx(hw, vsi_handle, tc, q_handle);
5292 [ # # ]: 0 : if (!q_ctx) {
5293 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SCHED, "Enaq: invalid queue handle %d\n",
5294 : : q_handle);
5295 : : status = ICE_ERR_PARAM;
5296 : 0 : goto ena_txq_exit;
5297 : : }
5298 : :
5299 : : /* find a parent node */
5300 : 0 : parent = ice_sched_get_free_qparent(pi, vsi_handle, tc,
5301 : : ICE_SCHED_NODE_OWNER_LAN);
5302 [ # # ]: 0 : if (!parent) {
5303 : : status = ICE_ERR_PARAM;
5304 : 0 : goto ena_txq_exit;
5305 : : }
5306 : :
5307 : 0 : buf->parent_teid = parent->info.node_teid;
5308 : 0 : node.parent_teid = parent->info.node_teid;
5309 : : /* Mark that the values in the "generic" section as valid. The default
5310 : : * value in the "generic" section is zero. This means that :
5311 : : * - Scheduling mode is Bytes Per Second (BPS), indicated by Bit 0.
5312 : : * - 0 priority among siblings, indicated by Bit 1-3.
5313 : : * - WFQ, indicated by Bit 4.
5314 : : * - 0 Adjustment value is used in PSM credit update flow, indicated by
5315 : : * Bit 5-6.
5316 : : * - Bit 7 is reserved.
5317 : : * Without setting the generic section as valid in valid_sections, the
5318 : : * Admin queue command will fail with error code ICE_AQ_RC_EINVAL.
5319 : : */
5320 : 0 : buf->txqs[0].info.valid_sections =
5321 : : ICE_AQC_ELEM_VALID_GENERIC | ICE_AQC_ELEM_VALID_CIR |
5322 : : ICE_AQC_ELEM_VALID_EIR;
5323 : 0 : buf->txqs[0].info.generic = 0;
5324 : 0 : buf->txqs[0].info.cir_bw.bw_profile_idx =
5325 : : CPU_TO_LE16(ICE_SCHED_DFLT_RL_PROF_ID);
5326 : 0 : buf->txqs[0].info.cir_bw.bw_alloc =
5327 : : CPU_TO_LE16(ICE_SCHED_DFLT_BW_WT);
5328 : 0 : buf->txqs[0].info.eir_bw.bw_profile_idx =
5329 : : CPU_TO_LE16(ICE_SCHED_DFLT_RL_PROF_ID);
5330 : 0 : buf->txqs[0].info.eir_bw.bw_alloc =
5331 : : CPU_TO_LE16(ICE_SCHED_DFLT_BW_WT);
5332 : :
5333 : : /* add the LAN queue */
5334 : 0 : status = ice_aq_add_lan_txq(hw, num_qgrps, buf, buf_size, cd);
5335 [ # # ]: 0 : if (status != 0) {
5336 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SCHED, "enable queue %d failed %d\n",
5337 : : LE16_TO_CPU(buf->txqs[0].txq_id),
5338 : : hw->adminq.sq_last_status);
5339 : 0 : goto ena_txq_exit;
5340 : : }
5341 : :
5342 : 0 : node.node_teid = buf->txqs[0].q_teid;
5343 : 0 : node.data.elem_type = ICE_AQC_ELEM_TYPE_LEAF;
5344 : 0 : q_ctx->q_handle = q_handle;
5345 : 0 : q_ctx->q_teid = LE32_TO_CPU(node.node_teid);
5346 : :
5347 : : /* add a leaf node into scheduler tree queue layer */
5348 : 0 : status = ice_sched_add_node(pi, hw->num_tx_sched_layers - 1, &node, NULL);
5349 [ # # ]: 0 : if (!status)
5350 : 0 : status = ice_sched_replay_q_bw(pi, q_ctx);
5351 : :
5352 : 0 : ena_txq_exit:
5353 : : ice_release_lock(&pi->sched_lock);
5354 : 0 : return status;
5355 : : }
5356 : :
5357 : : /**
5358 : : * ice_dis_vsi_txq
5359 : : * @pi: port information structure
5360 : : * @vsi_handle: software VSI handle
5361 : : * @tc: TC number
5362 : : * @num_queues: number of queues
5363 : : * @q_handles: pointer to software queue handle array
5364 : : * @q_ids: pointer to the q_id array
5365 : : * @q_teids: pointer to queue node teids
5366 : : * @rst_src: if called due to reset, specifies the reset source
5367 : : * @vmvf_num: the relative VM or VF number that is undergoing the reset
5368 : : * @cd: pointer to command details structure or NULL
5369 : : *
5370 : : * This function removes queues and their corresponding nodes in SW DB
5371 : : */
5372 : : int
5373 : 0 : ice_dis_vsi_txq(struct ice_port_info *pi, u16 vsi_handle, u8 tc, u8 num_queues,
5374 : : u16 *q_handles, u16 *q_ids, u32 *q_teids,
5375 : : enum ice_disq_rst_src rst_src, u16 vmvf_num,
5376 : : struct ice_sq_cd *cd)
5377 : : {
5378 : : struct ice_aqc_dis_txq_item *qg_list;
5379 : : struct ice_q_ctx *q_ctx;
5380 : : int status = ICE_ERR_DOES_NOT_EXIST;
5381 : : struct ice_hw *hw;
5382 : : u16 i, buf_size;
5383 : :
5384 [ # # # # ]: 0 : if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY)
5385 : : return ICE_ERR_CFG;
5386 : :
5387 : 0 : hw = pi->hw;
5388 : :
5389 [ # # ]: 0 : if (!num_queues) {
5390 : : /* if queue is disabled already yet the disable queue command
5391 : : * has to be sent to complete the VF reset, then call
5392 : : * ice_aq_dis_lan_txq without any queue information
5393 : : */
5394 [ # # ]: 0 : if (rst_src)
5395 : 0 : return ice_aq_dis_lan_txq(hw, 0, NULL, 0, rst_src,
5396 : : vmvf_num, NULL);
5397 : : return ICE_ERR_CFG;
5398 : : }
5399 : :
5400 : : buf_size = ice_struct_size(qg_list, q_id, 1);
5401 : 0 : qg_list = (struct ice_aqc_dis_txq_item *)ice_malloc(hw, buf_size);
5402 [ # # ]: 0 : if (!qg_list)
5403 : : return ICE_ERR_NO_MEMORY;
5404 : :
5405 : 0 : ice_acquire_lock(&pi->sched_lock);
5406 : :
5407 [ # # ]: 0 : for (i = 0; i < num_queues; i++) {
5408 : : struct ice_sched_node *node;
5409 : :
5410 : 0 : node = ice_sched_find_node_by_teid(pi->root, q_teids[i]);
5411 [ # # ]: 0 : if (!node)
5412 : 0 : continue;
5413 : 0 : q_ctx = ice_get_lan_q_ctx(hw, vsi_handle, tc, q_handles[i]);
5414 [ # # ]: 0 : if (!q_ctx) {
5415 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SCHED, "invalid queue handle%d\n",
5416 : : q_handles[i]);
5417 : 0 : continue;
5418 : : }
5419 [ # # ]: 0 : if (q_ctx->q_handle != q_handles[i]) {
5420 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SCHED, "Err:handles %d %d\n",
5421 : : q_ctx->q_handle, q_handles[i]);
5422 : 0 : continue;
5423 : : }
5424 : 0 : qg_list->parent_teid = node->info.parent_teid;
5425 : 0 : qg_list->num_qs = 1;
5426 : 0 : qg_list->q_id[0] = CPU_TO_LE16(q_ids[i]);
5427 : 0 : status = ice_aq_dis_lan_txq(hw, 1, qg_list, buf_size, rst_src,
5428 : : vmvf_num, cd);
5429 : :
5430 [ # # ]: 0 : if (status)
5431 : : break;
5432 : 0 : ice_free_sched_node(pi, node);
5433 : 0 : q_ctx->q_handle = ICE_INVAL_Q_HANDLE;
5434 : : }
5435 : : ice_release_lock(&pi->sched_lock);
5436 : 0 : ice_free(hw, qg_list);
5437 : 0 : return status;
5438 : : }
5439 : :
5440 : : /**
5441 : : * ice_cfg_vsi_qs - configure the new/existing VSI queues
5442 : : * @pi: port information structure
5443 : : * @vsi_handle: software VSI handle
5444 : : * @tc_bitmap: TC bitmap
5445 : : * @maxqs: max queues array per TC
5446 : : * @owner: LAN or RDMA
5447 : : *
5448 : : * This function adds/updates the VSI queues per TC.
5449 : : */
5450 : : static int
5451 : 0 : ice_cfg_vsi_qs(struct ice_port_info *pi, u16 vsi_handle, u16 tc_bitmap,
5452 : : u16 *maxqs, u8 owner)
5453 : : {
5454 : : int status = 0;
5455 : : u8 i;
5456 : :
5457 [ # # # # ]: 0 : if (!pi || pi->port_state != ICE_SCHED_PORT_STATE_READY)
5458 : : return ICE_ERR_CFG;
5459 : :
5460 [ # # ]: 0 : if (!ice_is_vsi_valid(pi->hw, vsi_handle))
5461 : : return ICE_ERR_PARAM;
5462 : :
5463 : 0 : ice_acquire_lock(&pi->sched_lock);
5464 : :
5465 [ # # ]: 0 : ice_for_each_traffic_class(i) {
5466 : : /* configuration is possible only if TC node is present */
5467 [ # # ]: 0 : if (!ice_sched_get_tc_node(pi, i))
5468 : 0 : continue;
5469 : :
5470 : 0 : status = ice_sched_cfg_vsi(pi, vsi_handle, i, maxqs[i], owner,
5471 : 0 : ice_is_tc_ena(tc_bitmap, i));
5472 [ # # ]: 0 : if (status)
5473 : : break;
5474 : : }
5475 : :
5476 : : ice_release_lock(&pi->sched_lock);
5477 : 0 : return status;
5478 : : }
5479 : :
5480 : : /**
5481 : : * ice_cfg_vsi_lan - configure VSI LAN queues
5482 : : * @pi: port information structure
5483 : : * @vsi_handle: software VSI handle
5484 : : * @tc_bitmap: TC bitmap
5485 : : * @max_lanqs: max LAN queues array per TC
5486 : : *
5487 : : * This function adds/updates the VSI LAN queues per TC.
5488 : : */
5489 : : int
5490 : 0 : ice_cfg_vsi_lan(struct ice_port_info *pi, u16 vsi_handle, u16 tc_bitmap,
5491 : : u16 *max_lanqs)
5492 : : {
5493 : 0 : return ice_cfg_vsi_qs(pi, vsi_handle, tc_bitmap, max_lanqs,
5494 : : ICE_SCHED_NODE_OWNER_LAN);
5495 : : }
5496 : :
5497 : : /**
5498 : : * ice_aq_cfg_cgu_err
5499 : : * @hw: pointer to the HW struct
5500 : : * @ena_event_report: enable or disable event reporting
5501 : : * @ena_err_report: enable/re-enable or disable error reporting mechanism
5502 : : * @cd: pointer to command details structure or NULL
5503 : : *
5504 : : * Configure CGU error reporting mechanism (0x0C60)
5505 : : */
5506 : : int
5507 : 0 : ice_aq_cfg_cgu_err(struct ice_hw *hw, bool ena_event_report,
5508 : : bool ena_err_report, struct ice_sq_cd *cd)
5509 : : {
5510 : : struct ice_aqc_cfg_cgu_err *cmd;
5511 : : struct ice_aq_desc desc;
5512 : :
5513 : : cmd = &desc.params.config_cgu_err;
5514 : :
5515 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_cfg_cgu_err);
5516 : :
5517 [ # # ]: 0 : if (!ena_event_report)
5518 : 0 : cmd->cmd |= ICE_AQC_CFG_CGU_EVENT_DIS;
5519 : :
5520 [ # # ]: 0 : if (!ena_err_report)
5521 : 0 : cmd->cmd |= ICE_AQC_CFG_CGU_ERR_DIS;
5522 : :
5523 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
5524 : : }
5525 : :
5526 : : /**
5527 : : * ice_aq_get_sensor_reading
5528 : : * @hw: pointer to the HW struct
5529 : : * @sensor: sensor type
5530 : : * @format: requested response format
5531 : : * @data: pointer to data to be read from the sensor
5532 : : * @cd: pointer to command details structure or NULL
5533 : : *
5534 : : * Get sensor reading (0x0632)
5535 : : */
5536 : : int
5537 : 0 : ice_aq_get_sensor_reading(struct ice_hw *hw, u8 sensor, u8 format,
5538 : : struct ice_aqc_get_sensor_reading_resp *data,
5539 : : struct ice_sq_cd *cd)
5540 : : {
5541 : : struct ice_aqc_get_sensor_reading *cmd;
5542 : : struct ice_aq_desc desc;
5543 : : int status;
5544 : :
5545 [ # # ]: 0 : if (!data)
5546 : : return ICE_ERR_PARAM;
5547 : :
5548 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_sensor_reading);
5549 : : cmd = &desc.params.get_sensor_reading;
5550 : 0 : cmd->sensor = sensor;
5551 : 0 : cmd->format = format;
5552 : :
5553 : 0 : status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
5554 : :
5555 [ # # ]: 0 : if (!status)
5556 : : ice_memcpy(data, &desc.params.get_sensor_reading_resp,
5557 : : sizeof(*data), ICE_NONDMA_TO_NONDMA);
5558 : :
5559 : : return status;
5560 : : }
5561 : :
5562 : : /**
5563 : : * ice_is_main_vsi - checks whether the VSI is main VSI
5564 : : * @hw: pointer to the HW struct
5565 : : * @vsi_handle: VSI handle
5566 : : *
5567 : : * Checks whether the VSI is the main VSI (the first PF VSI created on
5568 : : * given PF).
5569 : : */
5570 : : static bool ice_is_main_vsi(struct ice_hw *hw, u16 vsi_handle)
5571 : : {
5572 [ # # # # ]: 0 : return vsi_handle == ICE_MAIN_VSI_HANDLE && hw->vsi_ctx[vsi_handle];
5573 : : }
5574 : :
5575 : : /**
5576 : : * ice_replay_pre_init - replay pre initialization
5577 : : * @hw: pointer to the HW struct
5578 : : * @sw: pointer to switch info struct for which function initializes filters
5579 : : *
5580 : : * Initializes required config data for VSI, FD, ACL, and RSS before replay.
5581 : : */
5582 : : int
5583 : 0 : ice_replay_pre_init(struct ice_hw *hw, struct ice_switch_info *sw)
5584 : : {
5585 : : int status;
5586 : : u8 i;
5587 : :
5588 : : /* Delete old entries from replay filter list head if there is any */
5589 : 0 : ice_rm_sw_replay_rule_info(hw, sw);
5590 : : /* In start of replay, move entries into replay_rules list, it
5591 : : * will allow adding rules entries back to filt_rules list,
5592 : : * which is operational list.
5593 : : */
5594 [ # # ]: 0 : for (i = 0; i < ICE_MAX_NUM_RECIPES; i++)
5595 : 0 : LIST_REPLACE_INIT(&sw->recp_list[i].filt_rules,
5596 : : &sw->recp_list[i].filt_replay_rules);
5597 : 0 : ice_sched_replay_agg_vsi_preinit(hw);
5598 : :
5599 : 0 : status = ice_sched_replay_root_node_bw(hw->port_info);
5600 [ # # ]: 0 : if (status)
5601 : : return status;
5602 : :
5603 : 0 : return ice_sched_replay_tc_node_bw(hw->port_info);
5604 : : }
5605 : :
5606 : : /**
5607 : : * ice_replay_vsi - replay VSI configuration
5608 : : * @hw: pointer to the HW struct
5609 : : * @vsi_handle: driver VSI handle
5610 : : *
5611 : : * Restore all VSI configuration after reset. It is required to call this
5612 : : * function with main VSI first.
5613 : : */
5614 : 0 : int ice_replay_vsi(struct ice_hw *hw, u16 vsi_handle)
5615 : : {
5616 : 0 : struct ice_switch_info *sw = hw->switch_info;
5617 : 0 : struct ice_port_info *pi = hw->port_info;
5618 : : int status;
5619 : :
5620 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
5621 : : return ICE_ERR_PARAM;
5622 : :
5623 : : /* Replay pre-initialization if there is any */
5624 [ # # ]: 0 : if (ice_is_main_vsi(hw, vsi_handle)) {
5625 : 0 : status = ice_replay_pre_init(hw, sw);
5626 [ # # ]: 0 : if (status)
5627 : : return status;
5628 : : }
5629 : : /* Replay per VSI all RSS configurations */
5630 : 0 : status = ice_replay_rss_cfg(hw, vsi_handle);
5631 [ # # ]: 0 : if (status)
5632 : : return status;
5633 : : /* Replay per VSI all filters */
5634 : 0 : status = ice_replay_vsi_all_fltr(hw, pi, vsi_handle);
5635 [ # # ]: 0 : if (!status)
5636 : 0 : status = ice_replay_vsi_agg(hw, vsi_handle);
5637 : : return status;
5638 : : }
5639 : :
5640 : : /**
5641 : : * ice_replay_post - post replay configuration cleanup
5642 : : * @hw: pointer to the HW struct
5643 : : *
5644 : : * Post replay cleanup.
5645 : : */
5646 : 0 : void ice_replay_post(struct ice_hw *hw)
5647 : : {
5648 : : /* Delete old entries from replay filter list head */
5649 : 0 : ice_rm_all_sw_replay_rule_info(hw);
5650 : 0 : ice_sched_replay_agg(hw);
5651 : 0 : }
5652 : :
5653 : : /**
5654 : : * ice_stat_update40 - read 40 bit stat from the chip and update stat values
5655 : : * @hw: ptr to the hardware info
5656 : : * @reg: offset of 64 bit HW register to read from
5657 : : * @prev_stat_loaded: bool to specify if previous stats are loaded
5658 : : * @prev_stat: ptr to previous loaded stat value
5659 : : * @cur_stat: ptr to current stat value
5660 : : */
5661 : : void
5662 : 0 : ice_stat_update40(struct ice_hw *hw, u32 reg, bool prev_stat_loaded,
5663 : : u64 *prev_stat, u64 *cur_stat)
5664 : : {
5665 : 0 : u64 new_data = rd64(hw, reg) & (BIT_ULL(40) - 1);
5666 : :
5667 : : /* device stats are not reset at PFR, they likely will not be zeroed
5668 : : * when the driver starts. Thus, save the value from the first read
5669 : : * without adding to the statistic value so that we report stats which
5670 : : * count up from zero.
5671 : : */
5672 [ # # ]: 0 : if (!prev_stat_loaded) {
5673 : 0 : *prev_stat = new_data;
5674 : 0 : return;
5675 : : }
5676 : :
5677 : : /* Calculate the difference between the new and old values, and then
5678 : : * add it to the software stat value.
5679 : : */
5680 [ # # ]: 0 : if (new_data >= *prev_stat)
5681 : 0 : *cur_stat += new_data - *prev_stat;
5682 : : else
5683 : : /* to manage the potential roll-over */
5684 : 0 : *cur_stat += (new_data + BIT_ULL(40)) - *prev_stat;
5685 : :
5686 : : /* Update the previously stored value to prepare for next read */
5687 : 0 : *prev_stat = new_data;
5688 : : }
5689 : :
5690 : : /**
5691 : : * ice_stat_update32 - read 32 bit stat from the chip and update stat values
5692 : : * @hw: ptr to the hardware info
5693 : : * @reg: offset of HW register to read from
5694 : : * @prev_stat_loaded: bool to specify if previous stats are loaded
5695 : : * @prev_stat: ptr to previous loaded stat value
5696 : : * @cur_stat: ptr to current stat value
5697 : : */
5698 : : void
5699 : 0 : ice_stat_update32(struct ice_hw *hw, u32 reg, bool prev_stat_loaded,
5700 : : u64 *prev_stat, u64 *cur_stat)
5701 : : {
5702 : : u32 new_data;
5703 : :
5704 : 0 : new_data = rd32(hw, reg);
5705 : :
5706 : : /* device stats are not reset at PFR, they likely will not be zeroed
5707 : : * when the driver starts. Thus, save the value from the first read
5708 : : * without adding to the statistic value so that we report stats which
5709 : : * count up from zero.
5710 : : */
5711 [ # # ]: 0 : if (!prev_stat_loaded) {
5712 : 0 : *prev_stat = new_data;
5713 : 0 : return;
5714 : : }
5715 : :
5716 : : /* Calculate the difference between the new and old values, and then
5717 : : * add it to the software stat value.
5718 : : */
5719 [ # # ]: 0 : if (new_data >= *prev_stat)
5720 : 0 : *cur_stat += new_data - *prev_stat;
5721 : : else
5722 : : /* to manage the potential roll-over */
5723 : 0 : *cur_stat += (new_data + BIT_ULL(32)) - *prev_stat;
5724 : :
5725 : : /* Update the previously stored value to prepare for next read */
5726 : 0 : *prev_stat = new_data;
5727 : : }
5728 : :
5729 : : /**
5730 : : * ice_stat_update_repc - read GLV_REPC stats from chip and update stat values
5731 : : * @hw: ptr to the hardware info
5732 : : * @vsi_handle: VSI handle
5733 : : * @prev_stat_loaded: bool to specify if the previous stat values are loaded
5734 : : * @cur_stats: ptr to current stats structure
5735 : : *
5736 : : * The GLV_REPC statistic register actually tracks two 16bit statistics, and
5737 : : * thus cannot be read using the normal ice_stat_update32 function.
5738 : : *
5739 : : * Read the GLV_REPC register associated with the given VSI, and update the
5740 : : * rx_no_desc and rx_error values in the ice_eth_stats structure.
5741 : : *
5742 : : * Because the statistics in GLV_REPC stick at 0xFFFF, the register must be
5743 : : * cleared each time it's read.
5744 : : *
5745 : : * Note that the GLV_RDPC register also counts the causes that would trigger
5746 : : * GLV_REPC. However, it does not give the finer grained detail about why the
5747 : : * packets are being dropped. The GLV_REPC values can be used to distinguish
5748 : : * whether Rx packets are dropped due to errors or due to no available
5749 : : * descriptors.
5750 : : */
5751 : : void
5752 : 0 : ice_stat_update_repc(struct ice_hw *hw, u16 vsi_handle, bool prev_stat_loaded,
5753 : : struct ice_eth_stats *cur_stats)
5754 : : {
5755 : : u16 vsi_num, no_desc, error_cnt;
5756 : : u32 repc;
5757 : :
5758 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
5759 : : return;
5760 : :
5761 : 0 : vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
5762 : :
5763 : : /* If we haven't loaded stats yet, just clear the current value */
5764 [ # # ]: 0 : if (!prev_stat_loaded) {
5765 : 0 : wr32(hw, GLV_REPC(vsi_num), 0);
5766 : 0 : return;
5767 : : }
5768 : :
5769 : 0 : repc = rd32(hw, GLV_REPC(vsi_num));
5770 : 0 : no_desc = (repc & GLV_REPC_NO_DESC_CNT_M) >> GLV_REPC_NO_DESC_CNT_S;
5771 : 0 : error_cnt = (repc & GLV_REPC_ERROR_CNT_M) >> GLV_REPC_ERROR_CNT_S;
5772 : :
5773 : : /* Clear the count by writing to the stats register */
5774 : 0 : wr32(hw, GLV_REPC(vsi_num), 0);
5775 : :
5776 : 0 : cur_stats->rx_no_desc += no_desc;
5777 : 0 : cur_stats->rx_errors += error_cnt;
5778 : : }
5779 : :
5780 : : /**
5781 : : * ice_sched_query_elem - query element information from HW
5782 : : * @hw: pointer to the HW struct
5783 : : * @node_teid: node TEID to be queried
5784 : : * @buf: buffer to element information
5785 : : *
5786 : : * This function queries HW element information
5787 : : */
5788 : : int
5789 : 0 : ice_sched_query_elem(struct ice_hw *hw, u32 node_teid,
5790 : : struct ice_aqc_txsched_elem_data *buf)
5791 : : {
5792 : 0 : u16 buf_size, num_elem_ret = 0;
5793 : : int status;
5794 : :
5795 : : buf_size = sizeof(*buf);
5796 : : ice_memset(buf, 0, buf_size, ICE_NONDMA_MEM);
5797 : 0 : buf->node_teid = CPU_TO_LE32(node_teid);
5798 : 0 : status = ice_aq_query_sched_elems(hw, 1, buf, buf_size, &num_elem_ret,
5799 : : NULL);
5800 [ # # # # ]: 0 : if (status || num_elem_ret != 1)
5801 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SCHED, "query element failed\n");
5802 : 0 : return status;
5803 : : }
5804 : :
5805 : : /**
5806 : : * ice_get_fw_mode - returns FW mode
5807 : : * @hw: pointer to the HW struct
5808 : : */
5809 : 0 : enum ice_fw_modes ice_get_fw_mode(struct ice_hw *hw)
5810 : : {
5811 : : #define ICE_FW_MODE_DBG_M BIT(0)
5812 : : #define ICE_FW_MODE_REC_M BIT(1)
5813 : : #define ICE_FW_MODE_ROLLBACK_M BIT(2)
5814 : : u32 fw_mode;
5815 : :
5816 : : /* check the current FW mode */
5817 : 0 : fw_mode = rd32(hw, GL_MNG_FWSM) & E800_GL_MNG_FWSM_FW_MODES_M;
5818 : :
5819 [ # # ]: 0 : if (fw_mode & ICE_FW_MODE_DBG_M)
5820 : : return ICE_FW_MODE_DBG;
5821 [ # # ]: 0 : else if (fw_mode & ICE_FW_MODE_REC_M)
5822 : : return ICE_FW_MODE_REC;
5823 [ # # ]: 0 : else if (fw_mode & ICE_FW_MODE_ROLLBACK_M)
5824 : : return ICE_FW_MODE_ROLLBACK;
5825 : : else
5826 : 0 : return ICE_FW_MODE_NORMAL;
5827 : : }
5828 : :
5829 : : /**
5830 : : * ice_aq_read_i2c
5831 : : * @hw: pointer to the hw struct
5832 : : * @topo_addr: topology address for a device to communicate with
5833 : : * @bus_addr: 7-bit I2C bus address
5834 : : * @addr: I2C memory address (I2C offset) with up to 16 bits
5835 : : * @params: I2C parameters: bit [7] - Repeated start, bits [6:5] data offset size,
5836 : : * bit [4] - I2C address type, bits [3:0] - data size to read (0-16 bytes)
5837 : : * @data: pointer to data (0 to 16 bytes) to be read from the I2C device
5838 : : * @cd: pointer to command details structure or NULL
5839 : : *
5840 : : * Read I2C (0x06E2)
5841 : : */
5842 : : int
5843 : 0 : ice_aq_read_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr,
5844 : : u16 bus_addr, __le16 addr, u8 params, u8 *data,
5845 : : struct ice_sq_cd *cd)
5846 : : {
5847 : 0 : struct ice_aq_desc desc = { 0 };
5848 : : struct ice_aqc_i2c *cmd;
5849 : : u8 data_size;
5850 : : int status;
5851 : :
5852 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_read_i2c);
5853 : : cmd = &desc.params.read_write_i2c;
5854 : :
5855 [ # # ]: 0 : if (!data)
5856 : : return ICE_ERR_PARAM;
5857 : :
5858 : 0 : data_size = (params & ICE_AQC_I2C_DATA_SIZE_M) >> ICE_AQC_I2C_DATA_SIZE_S;
5859 : :
5860 : 0 : cmd->i2c_bus_addr = CPU_TO_LE16(bus_addr);
5861 : 0 : cmd->topo_addr = topo_addr;
5862 : 0 : cmd->i2c_params = params;
5863 : 0 : cmd->i2c_addr = addr;
5864 : :
5865 : 0 : status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
5866 [ # # ]: 0 : if (!status) {
5867 : : struct ice_aqc_read_i2c_resp *resp;
5868 : : u8 i;
5869 : :
5870 : : resp = &desc.params.read_i2c_resp;
5871 [ # # ]: 0 : for (i = 0; i < data_size; i++) {
5872 : 0 : *data = resp->i2c_data[i];
5873 : 0 : data++;
5874 : : }
5875 : : }
5876 : :
5877 : : return status;
5878 : : }
5879 : :
5880 : : /**
5881 : : * ice_aq_write_i2c
5882 : : * @hw: pointer to the hw struct
5883 : : * @topo_addr: topology address for a device to communicate with
5884 : : * @bus_addr: 7-bit I2C bus address
5885 : : * @addr: I2C memory address (I2C offset) with up to 16 bits
5886 : : * @params: I2C parameters: bit [4] - I2C address type, bits [3:0] - data size to write (0-7 bytes)
5887 : : * @data: pointer to data (0 to 4 bytes) to be written to the I2C device
5888 : : * @cd: pointer to command details structure or NULL
5889 : : *
5890 : : * Write I2C (0x06E3)
5891 : : */
5892 : : int
5893 : 0 : ice_aq_write_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr,
5894 : : u16 bus_addr, __le16 addr, u8 params, const u8 *data,
5895 : : struct ice_sq_cd *cd)
5896 : : {
5897 : 0 : struct ice_aq_desc desc = { 0 };
5898 : : struct ice_aqc_i2c *cmd;
5899 : : u8 i, data_size;
5900 : :
5901 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_write_i2c);
5902 : : cmd = &desc.params.read_write_i2c;
5903 : :
5904 : 0 : data_size = (params & ICE_AQC_I2C_DATA_SIZE_M) >> ICE_AQC_I2C_DATA_SIZE_S;
5905 : :
5906 : : /* data_size limited to 4 */
5907 [ # # ]: 0 : if (data_size > 4)
5908 : : return ICE_ERR_PARAM;
5909 : :
5910 : 0 : cmd->i2c_bus_addr = CPU_TO_LE16(bus_addr);
5911 : 0 : cmd->topo_addr = topo_addr;
5912 : 0 : cmd->i2c_params = params;
5913 : 0 : cmd->i2c_addr = addr;
5914 : :
5915 [ # # ]: 0 : for (i = 0; i < data_size; i++) {
5916 : 0 : cmd->i2c_data[i] = *data;
5917 : 0 : data++;
5918 : : }
5919 : :
5920 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
5921 : : }
5922 : :
5923 : : /**
5924 : : * ice_aq_set_driver_param - Set driver parameter to share via firmware
5925 : : * @hw: pointer to the HW struct
5926 : : * @idx: parameter index to set
5927 : : * @value: the value to set the parameter to
5928 : : * @cd: pointer to command details structure or NULL
5929 : : *
5930 : : * Set the value of one of the software defined parameters. All PFs connected
5931 : : * to this device can read the value using ice_aq_get_driver_param.
5932 : : *
5933 : : * Note that firmware provides no synchronization or locking, and will not
5934 : : * save the parameter value during a device reset. It is expected that
5935 : : * a single PF will write the parameter value, while all other PFs will only
5936 : : * read it.
5937 : : */
5938 : : int
5939 : 0 : ice_aq_set_driver_param(struct ice_hw *hw, enum ice_aqc_driver_params idx,
5940 : : u32 value, struct ice_sq_cd *cd)
5941 : : {
5942 : : struct ice_aqc_driver_shared_params *cmd;
5943 : : struct ice_aq_desc desc;
5944 : :
5945 [ # # ]: 0 : if (idx >= ICE_AQC_DRIVER_PARAM_MAX)
5946 : : return ICE_ERR_OUT_OF_RANGE;
5947 : :
5948 : : cmd = &desc.params.drv_shared_params;
5949 : :
5950 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_driver_shared_params);
5951 : :
5952 : 0 : cmd->set_or_get_op = ICE_AQC_DRIVER_PARAM_SET;
5953 : 0 : cmd->param_indx = (u8)idx;
5954 : 0 : cmd->param_val = CPU_TO_LE32(value);
5955 : :
5956 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
5957 : : }
5958 : :
5959 : : /**
5960 : : * ice_aq_get_driver_param - Get driver parameter shared via firmware
5961 : : * @hw: pointer to the HW struct
5962 : : * @idx: parameter index to set
5963 : : * @value: storage to return the shared parameter
5964 : : * @cd: pointer to command details structure or NULL
5965 : : *
5966 : : * Get the value of one of the software defined parameters.
5967 : : *
5968 : : * Note that firmware provides no synchronization or locking. It is expected
5969 : : * that only a single PF will write a given parameter.
5970 : : */
5971 : : int
5972 : 0 : ice_aq_get_driver_param(struct ice_hw *hw, enum ice_aqc_driver_params idx,
5973 : : u32 *value, struct ice_sq_cd *cd)
5974 : : {
5975 : : struct ice_aqc_driver_shared_params *cmd;
5976 : : struct ice_aq_desc desc;
5977 : : int status;
5978 : :
5979 [ # # ]: 0 : if (idx >= ICE_AQC_DRIVER_PARAM_MAX)
5980 : : return ICE_ERR_OUT_OF_RANGE;
5981 : :
5982 : : cmd = &desc.params.drv_shared_params;
5983 : :
5984 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_driver_shared_params);
5985 : :
5986 : 0 : cmd->set_or_get_op = ICE_AQC_DRIVER_PARAM_GET;
5987 : 0 : cmd->param_indx = (u8)idx;
5988 : :
5989 : 0 : status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
5990 [ # # ]: 0 : if (status)
5991 : : return status;
5992 : :
5993 : 0 : *value = LE32_TO_CPU(cmd->param_val);
5994 : :
5995 : 0 : return 0;
5996 : : }
5997 : :
5998 : : /**
5999 : : * ice_aq_set_gpio
6000 : : * @hw: pointer to the hw struct
6001 : : * @gpio_ctrl_handle: GPIO controller node handle
6002 : : * @pin_idx: IO Number of the GPIO that needs to be set
6003 : : * @value: SW provide IO value to set in the LSB
6004 : : * @cd: pointer to command details structure or NULL
6005 : : *
6006 : : * Sends 0x06EC AQ command to set the GPIO pin state that's part of the topology
6007 : : */
6008 : : int
6009 : 0 : ice_aq_set_gpio(struct ice_hw *hw, u16 gpio_ctrl_handle, u8 pin_idx, bool value,
6010 : : struct ice_sq_cd *cd)
6011 : : {
6012 : : struct ice_aqc_gpio *cmd;
6013 : : struct ice_aq_desc desc;
6014 : :
6015 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_gpio);
6016 : : cmd = &desc.params.read_write_gpio;
6017 : 0 : cmd->gpio_ctrl_handle = CPU_TO_LE16(gpio_ctrl_handle);
6018 : 0 : cmd->gpio_num = pin_idx;
6019 : 0 : cmd->gpio_val = value ? 1 : 0;
6020 : :
6021 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
6022 : : }
6023 : :
6024 : : /**
6025 : : * ice_aq_get_gpio
6026 : : * @hw: pointer to the hw struct
6027 : : * @gpio_ctrl_handle: GPIO controller node handle
6028 : : * @pin_idx: IO Number of the GPIO that needs to be set
6029 : : * @value: IO value read
6030 : : * @cd: pointer to command details structure or NULL
6031 : : *
6032 : : * Sends 0x06ED AQ command to get the value of a GPIO signal which is part of
6033 : : * the topology
6034 : : */
6035 : : int
6036 : 0 : ice_aq_get_gpio(struct ice_hw *hw, u16 gpio_ctrl_handle, u8 pin_idx,
6037 : : bool *value, struct ice_sq_cd *cd)
6038 : : {
6039 : : struct ice_aqc_gpio *cmd;
6040 : : struct ice_aq_desc desc;
6041 : : int status;
6042 : :
6043 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_gpio);
6044 : : cmd = &desc.params.read_write_gpio;
6045 : 0 : cmd->gpio_ctrl_handle = CPU_TO_LE16(gpio_ctrl_handle);
6046 : 0 : cmd->gpio_num = pin_idx;
6047 : :
6048 : 0 : status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
6049 [ # # ]: 0 : if (status)
6050 : : return status;
6051 : :
6052 : 0 : *value = !!cmd->gpio_val;
6053 : 0 : return 0;
6054 : : }
6055 : :
6056 : : /**
6057 : : * ice_is_fw_api_min_ver
6058 : : * @hw: pointer to the hardware structure
6059 : : * @maj: major version
6060 : : * @min: minor version
6061 : : * @patch: patch version
6062 : : *
6063 : : * Checks if the firmware is minimum version
6064 : : */
6065 : : static bool ice_is_fw_api_min_ver(struct ice_hw *hw, u8 maj, u8 min, u8 patch)
6066 : : {
6067 [ # # ]: 0 : if (hw->api_maj_ver == maj) {
6068 [ # # # # : 0 : if (hw->api_min_ver > min)
# # ]
6069 : : return true;
6070 [ # # # # : 0 : if (hw->api_min_ver == min && hw->api_patch >= patch)
# # # # #
# # # ]
6071 : 0 : return true;
6072 [ # # # # : 0 : } else if (hw->api_maj_ver > maj) {
# # ]
6073 : 0 : return true;
6074 : : }
6075 : :
6076 : : return false;
6077 : : }
6078 : :
6079 : : /**
6080 : : * ice_is_fw_min_ver
6081 : : * @hw: pointer to the hardware structure
6082 : : * @branch: branch version
6083 : : * @maj: major version
6084 : : * @min: minor version
6085 : : * @patch: patch version
6086 : : *
6087 : : * Checks if the firmware is minimum version
6088 : : */
6089 : : static bool ice_is_fw_min_ver(struct ice_hw *hw, u8 branch, u8 maj, u8 min,
6090 : : u8 patch)
6091 : : {
6092 [ # # # # ]: 0 : if (hw->fw_branch == branch) {
6093 [ # # # # ]: 0 : if (hw->fw_maj_ver > maj)
6094 : : return true;
6095 [ # # # # ]: 0 : if (hw->fw_maj_ver == maj) {
6096 [ # # # # ]: 0 : if (hw->fw_min_ver > min)
6097 : : return true;
6098 [ # # # # : 0 : if (hw->fw_min_ver == min && hw->fw_patch >= patch)
# # ]
6099 : : return true;
6100 : : }
6101 : : }
6102 : :
6103 : : return false;
6104 : : }
6105 : :
6106 : : /**
6107 : : * ice_fw_supports_link_override
6108 : : * @hw: pointer to the hardware structure
6109 : : *
6110 : : * Checks if the firmware supports link override
6111 : : */
6112 [ # # ]: 0 : bool ice_fw_supports_link_override(struct ice_hw *hw)
6113 : : {
6114 : 0 : return ice_is_fw_api_min_ver(hw, ICE_FW_API_LINK_OVERRIDE_MAJ,
6115 : : ICE_FW_API_LINK_OVERRIDE_MIN,
6116 : : ICE_FW_API_LINK_OVERRIDE_PATCH);
6117 : : }
6118 : :
6119 : : /**
6120 : : * ice_get_link_default_override
6121 : : * @ldo: pointer to the link default override struct
6122 : : * @pi: pointer to the port info struct
6123 : : *
6124 : : * Gets the link default override for a port
6125 : : */
6126 : : int
6127 : 0 : ice_get_link_default_override(struct ice_link_default_override_tlv *ldo,
6128 : : struct ice_port_info *pi)
6129 : : {
6130 : : u16 i, tlv, tlv_len, tlv_start, buf, offset;
6131 : 0 : struct ice_hw *hw = pi->hw;
6132 : : int status;
6133 : :
6134 : 0 : status = ice_get_pfa_module_tlv(hw, &tlv, &tlv_len,
6135 : : ICE_SR_LINK_DEFAULT_OVERRIDE_PTR);
6136 [ # # ]: 0 : if (status) {
6137 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "Failed to read link override TLV.\n");
6138 : 0 : return status;
6139 : : }
6140 : :
6141 : : /* Each port has its own config; calculate for our port */
6142 : 0 : tlv_start = tlv + pi->lport * ICE_SR_PFA_LINK_OVERRIDE_WORDS +
6143 : : ICE_SR_PFA_LINK_OVERRIDE_OFFSET;
6144 : :
6145 : : /* link options first */
6146 : 0 : status = ice_read_sr_word(hw, tlv_start, &buf);
6147 [ # # ]: 0 : if (status) {
6148 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "Failed to read override link options.\n");
6149 : 0 : return status;
6150 : : }
6151 : 0 : ldo->options = buf & ICE_LINK_OVERRIDE_OPT_M;
6152 : 0 : ldo->phy_config = (buf & ICE_LINK_OVERRIDE_PHY_CFG_M) >>
6153 : : ICE_LINK_OVERRIDE_PHY_CFG_S;
6154 : :
6155 : : /* link PHY config */
6156 : 0 : offset = tlv_start + ICE_SR_PFA_LINK_OVERRIDE_FEC_OFFSET;
6157 : 0 : status = ice_read_sr_word(hw, offset, &buf);
6158 [ # # ]: 0 : if (status) {
6159 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "Failed to read override phy config.\n");
6160 : 0 : return status;
6161 : : }
6162 : 0 : ldo->fec_options = buf & ICE_LINK_OVERRIDE_FEC_OPT_M;
6163 : :
6164 : : /* PHY types low */
6165 : 0 : offset = tlv_start + ICE_SR_PFA_LINK_OVERRIDE_PHY_OFFSET;
6166 [ # # ]: 0 : for (i = 0; i < ICE_SR_PFA_LINK_OVERRIDE_PHY_WORDS; i++) {
6167 : 0 : status = ice_read_sr_word(hw, (offset + i), &buf);
6168 [ # # ]: 0 : if (status) {
6169 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "Failed to read override link options.\n");
6170 : 0 : return status;
6171 : : }
6172 : : /* shift 16 bits at a time to fill 64 bits */
6173 : 0 : ldo->phy_type_low |= ((u64)buf << (i * 16));
6174 : : }
6175 : :
6176 : : /* PHY types high */
6177 : 0 : offset = tlv_start + ICE_SR_PFA_LINK_OVERRIDE_PHY_OFFSET +
6178 : : ICE_SR_PFA_LINK_OVERRIDE_PHY_WORDS;
6179 [ # # ]: 0 : for (i = 0; i < ICE_SR_PFA_LINK_OVERRIDE_PHY_WORDS; i++) {
6180 : 0 : status = ice_read_sr_word(hw, (offset + i), &buf);
6181 [ # # ]: 0 : if (status) {
6182 [ # # ]: 0 : ice_debug(hw, ICE_DBG_INIT, "Failed to read override link options.\n");
6183 : 0 : return status;
6184 : : }
6185 : : /* shift 16 bits at a time to fill 64 bits */
6186 : 0 : ldo->phy_type_high |= ((u64)buf << (i * 16));
6187 : : }
6188 : :
6189 : : return status;
6190 : : }
6191 : :
6192 : : /**
6193 : : * ice_is_phy_caps_an_enabled - check if PHY capabilities autoneg is enabled
6194 : : * @caps: get PHY capability data
6195 : : */
6196 : 0 : bool ice_is_phy_caps_an_enabled(struct ice_aqc_get_phy_caps_data *caps)
6197 : : {
6198 [ # # ]: 0 : if (caps->caps & ICE_AQC_PHY_AN_MODE ||
6199 [ # # ]: 0 : caps->low_power_ctrl_an & (ICE_AQC_PHY_AN_EN_CLAUSE28 |
6200 : : ICE_AQC_PHY_AN_EN_CLAUSE73 |
6201 : : ICE_AQC_PHY_AN_EN_CLAUSE37))
6202 : 0 : return true;
6203 : :
6204 : : return false;
6205 : : }
6206 : :
6207 : : /**
6208 : : * ice_aq_get_port_options
6209 : : * @hw: pointer to the hw struct
6210 : : * @options: buffer for the resultant port options
6211 : : * @option_count: input - size of the buffer in port options structures,
6212 : : * output - number of returned port options
6213 : : * @lport: logical port to call the command with (optional)
6214 : : * @lport_valid: when false, FW uses port owned by the PF instead of lport,
6215 : : * when PF owns more than 1 port it must be true
6216 : : * @active_option_idx: index of active port option in returned buffer
6217 : : * @active_option_valid: active option in returned buffer is valid
6218 : : * @pending_option_idx: index of pending port option in returned buffer
6219 : : * @pending_option_valid: pending option in returned buffer is valid
6220 : : *
6221 : : * Calls Get Port Options AQC (0x06ea) and verifies result.
6222 : : */
6223 : : int
6224 : 0 : ice_aq_get_port_options(struct ice_hw *hw,
6225 : : struct ice_aqc_get_port_options_elem *options,
6226 : : u8 *option_count, u8 lport, bool lport_valid,
6227 : : u8 *active_option_idx, bool *active_option_valid,
6228 : : u8 *pending_option_idx, bool *pending_option_valid)
6229 : : {
6230 : : struct ice_aqc_get_port_options *cmd;
6231 : : struct ice_aq_desc desc;
6232 : : int status;
6233 : : u8 i;
6234 : :
6235 : : /* options buffer shall be able to hold max returned options */
6236 [ # # ]: 0 : if (*option_count < ICE_AQC_PORT_OPT_COUNT_M)
6237 : : return ICE_ERR_PARAM;
6238 : :
6239 : : cmd = &desc.params.get_port_options;
6240 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_port_options);
6241 : :
6242 : 0 : cmd->lport_num = lport;
6243 : 0 : cmd->lport_num_valid = lport_valid;
6244 : :
6245 : 0 : status = ice_aq_send_cmd(hw, &desc, options,
6246 : 0 : *option_count * sizeof(*options), NULL);
6247 [ # # ]: 0 : if (status)
6248 : : return status;
6249 : :
6250 : : /* verify direct FW response & set output parameters */
6251 : 0 : *option_count = cmd->port_options_count & ICE_AQC_PORT_OPT_COUNT_M;
6252 [ # # ]: 0 : ice_debug(hw, ICE_DBG_PHY, "options: %x\n", *option_count);
6253 : 0 : *active_option_valid = cmd->port_options & ICE_AQC_PORT_OPT_VALID;
6254 [ # # ]: 0 : if (*active_option_valid) {
6255 : 0 : *active_option_idx = cmd->port_options &
6256 : : ICE_AQC_PORT_OPT_ACTIVE_M;
6257 [ # # ]: 0 : if (*active_option_idx > (*option_count - 1))
6258 : : return ICE_ERR_OUT_OF_RANGE;
6259 [ # # ]: 0 : ice_debug(hw, ICE_DBG_PHY, "active idx: %x\n",
6260 : : *active_option_idx);
6261 : : }
6262 : :
6263 : 0 : *pending_option_valid = cmd->pending_port_option_status &
6264 : : ICE_AQC_PENDING_PORT_OPT_VALID;
6265 [ # # ]: 0 : if (*pending_option_valid) {
6266 : 0 : *pending_option_idx = cmd->pending_port_option_status &
6267 : : ICE_AQC_PENDING_PORT_OPT_IDX_M;
6268 [ # # ]: 0 : if (*pending_option_idx > (*option_count - 1))
6269 : : return ICE_ERR_OUT_OF_RANGE;
6270 [ # # ]: 0 : ice_debug(hw, ICE_DBG_PHY, "pending idx: %x\n",
6271 : : *pending_option_idx);
6272 : : }
6273 : :
6274 : : /* mask output options fields */
6275 [ # # ]: 0 : for (i = 0; i < *option_count; i++) {
6276 : 0 : options[i].pmd &= ICE_AQC_PORT_OPT_PMD_COUNT_M;
6277 : 0 : options[i].max_lane_speed &= ICE_AQC_PORT_OPT_MAX_LANE_M;
6278 [ # # ]: 0 : ice_debug(hw, ICE_DBG_PHY, "pmds: %x max speed: %x\n",
6279 : : options[i].pmd, options[i].max_lane_speed);
6280 : : }
6281 : :
6282 : : return 0;
6283 : : }
6284 : :
6285 : : /**
6286 : : * ice_aq_set_port_option
6287 : : * @hw: pointer to the hw struct
6288 : : * @lport: logical port to call the command with
6289 : : * @lport_valid: when false, FW uses port owned by the PF instead of lport,
6290 : : * when PF owns more than 1 port it must be true
6291 : : * @new_option: new port option to be written
6292 : : *
6293 : : * Calls Set Port Options AQC (0x06eb).
6294 : : */
6295 : : int
6296 : 0 : ice_aq_set_port_option(struct ice_hw *hw, u8 lport, u8 lport_valid,
6297 : : u8 new_option)
6298 : : {
6299 : : struct ice_aqc_set_port_option *cmd;
6300 : : struct ice_aq_desc desc;
6301 : :
6302 [ # # ]: 0 : if (new_option >= ICE_AQC_PORT_OPT_COUNT_M)
6303 : : return ICE_ERR_PARAM;
6304 : :
6305 : : cmd = &desc.params.set_port_option;
6306 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_port_option);
6307 : :
6308 : 0 : cmd->lport_num = lport;
6309 : :
6310 : 0 : cmd->lport_num_valid = lport_valid;
6311 : 0 : cmd->selected_port_option = new_option;
6312 : :
6313 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
6314 : : }
6315 : :
6316 : : /**
6317 : : * ice_aq_set_lldp_mib - Set the LLDP MIB
6318 : : * @hw: pointer to the HW struct
6319 : : * @mib_type: Local, Remote or both Local and Remote MIBs
6320 : : * @buf: pointer to the caller-supplied buffer to store the MIB block
6321 : : * @buf_size: size of the buffer (in bytes)
6322 : : * @cd: pointer to command details structure or NULL
6323 : : *
6324 : : * Set the LLDP MIB. (0x0A08)
6325 : : */
6326 : : int
6327 : 0 : ice_aq_set_lldp_mib(struct ice_hw *hw, u8 mib_type, void *buf, u16 buf_size,
6328 : : struct ice_sq_cd *cd)
6329 : : {
6330 : : struct ice_aqc_lldp_set_local_mib *cmd;
6331 : : struct ice_aq_desc desc;
6332 : :
6333 : : cmd = &desc.params.lldp_set_mib;
6334 : :
6335 [ # # ]: 0 : if (buf_size == 0 || !buf)
6336 : : return ICE_ERR_PARAM;
6337 : :
6338 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_lldp_set_local_mib);
6339 : :
6340 : 0 : desc.flags |= CPU_TO_LE16((u16)ICE_AQ_FLAG_RD);
6341 : 0 : desc.datalen = CPU_TO_LE16(buf_size);
6342 : :
6343 : 0 : cmd->type = mib_type;
6344 : 0 : cmd->length = CPU_TO_LE16(buf_size);
6345 : :
6346 : 0 : return ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
6347 : : }
6348 : :
6349 : : /**
6350 : : * ice_fw_supports_lldp_fltr_ctrl - check NVM version supports lldp_fltr_ctrl
6351 : : * @hw: pointer to HW struct
6352 : : */
6353 : 0 : bool ice_fw_supports_lldp_fltr_ctrl(struct ice_hw *hw)
6354 : : {
6355 [ # # ]: 0 : if (hw->mac_type != ICE_MAC_E810 && hw->mac_type != ICE_MAC_GENERIC)
6356 : : return false;
6357 : :
6358 : : return ice_is_fw_api_min_ver(hw, ICE_FW_API_LLDP_FLTR_MAJ,
6359 : : ICE_FW_API_LLDP_FLTR_MIN,
6360 : : ICE_FW_API_LLDP_FLTR_PATCH);
6361 : : }
6362 : :
6363 : : /**
6364 : : * ice_lldp_fltr_add_remove - add or remove a LLDP Rx switch filter
6365 : : * @hw: pointer to HW struct
6366 : : * @vsi_num: absolute HW index for VSI
6367 : : * @add: boolean for if adding or removing a filter
6368 : : */
6369 : : int
6370 : 0 : ice_lldp_fltr_add_remove(struct ice_hw *hw, u16 vsi_num, bool add)
6371 : : {
6372 : : struct ice_aqc_lldp_filter_ctrl *cmd;
6373 : : struct ice_aq_desc desc;
6374 : :
6375 : : cmd = &desc.params.lldp_filter_ctrl;
6376 : :
6377 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_lldp_filter_ctrl);
6378 : :
6379 [ # # ]: 0 : if (add)
6380 : 0 : cmd->cmd_flags = ICE_AQC_LLDP_FILTER_ACTION_ADD;
6381 : : else
6382 : 0 : cmd->cmd_flags = ICE_AQC_LLDP_FILTER_ACTION_DELETE;
6383 : :
6384 : 0 : cmd->vsi_num = CPU_TO_LE16(vsi_num);
6385 : :
6386 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
6387 : : }
6388 : :
6389 : : /**
6390 : : * ice_lldp_execute_pending_mib - execute LLDP pending MIB request
6391 : : * @hw: pointer to HW struct
6392 : : */
6393 : 0 : int ice_lldp_execute_pending_mib(struct ice_hw *hw)
6394 : : {
6395 : : struct ice_aq_desc desc;
6396 : :
6397 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_execute_pending_lldp_mib);
6398 : :
6399 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
6400 : : }
6401 : :
6402 : : /**
6403 : : * ice_fw_supports_report_dflt_cfg
6404 : : * @hw: pointer to the hardware structure
6405 : : *
6406 : : * Checks if the firmware supports report default configuration
6407 : : */
6408 [ # # ]: 0 : bool ice_fw_supports_report_dflt_cfg(struct ice_hw *hw)
6409 : : {
6410 : 0 : return ice_is_fw_api_min_ver(hw, ICE_FW_API_REPORT_DFLT_CFG_MAJ,
6411 : : ICE_FW_API_REPORT_DFLT_CFG_MIN,
6412 : : ICE_FW_API_REPORT_DFLT_CFG_PATCH);
6413 : : }
6414 : :
6415 : : /* each of the indexes into the following array match the speed of a return
6416 : : * value from the list of AQ returned speeds like the range:
6417 : : * ICE_AQ_LINK_SPEED_10MB .. ICE_AQ_LINK_SPEED_100GB excluding
6418 : : * ICE_AQ_LINK_SPEED_UNKNOWN which is BIT(15) The array is defined as 15
6419 : : * elements long because the link_speed returned by the firmware is a 16 bit
6420 : : * value, but is indexed by [fls(speed) - 1]
6421 : : */
6422 : : static const u32 ice_aq_to_link_speed[] = {
6423 : : ICE_LINK_SPEED_10MBPS, /* BIT(0) */
6424 : : ICE_LINK_SPEED_100MBPS,
6425 : : ICE_LINK_SPEED_1000MBPS,
6426 : : ICE_LINK_SPEED_2500MBPS,
6427 : : ICE_LINK_SPEED_5000MBPS,
6428 : : ICE_LINK_SPEED_10000MBPS,
6429 : : ICE_LINK_SPEED_20000MBPS,
6430 : : ICE_LINK_SPEED_25000MBPS,
6431 : : ICE_LINK_SPEED_40000MBPS,
6432 : : ICE_LINK_SPEED_50000MBPS,
6433 : : ICE_LINK_SPEED_100000MBPS, /* BIT(10) */
6434 : : ICE_LINK_SPEED_200000MBPS,
6435 : : };
6436 : :
6437 : : /**
6438 : : * ice_get_link_speed - get integer speed from table
6439 : : * @index: array index from fls(aq speed) - 1
6440 : : *
6441 : : * Returns: u32 value containing integer speed
6442 : : */
6443 : 0 : u32 ice_get_link_speed(u16 index)
6444 : : {
6445 [ # # ]: 0 : if (index >= ARRAY_SIZE(ice_aq_to_link_speed))
6446 : : return ICE_LINK_SPEED_UNKNOWN;
6447 : :
6448 : 0 : return ice_aq_to_link_speed[index];
6449 : : }
6450 : :
6451 : : /**
6452 : : * ice_fw_supports_fec_dis_auto
6453 : : * @hw: pointer to the hardware structure
6454 : : *
6455 : : * Checks if the firmware supports FEC disable in Auto FEC mode
6456 : : */
6457 : 0 : bool ice_fw_supports_fec_dis_auto(struct ice_hw *hw)
6458 : : {
6459 [ # # ]: 0 : if (ice_is_e830(hw))
6460 : : return true;
6461 : : return ice_is_fw_min_ver(hw, ICE_FW_VER_BRANCH_E810,
6462 : : ICE_FW_FEC_DIS_AUTO_MAJ,
6463 : : ICE_FW_FEC_DIS_AUTO_MIN,
6464 : 0 : ICE_FW_FEC_DIS_AUTO_PATCH) ||
6465 : : ice_is_fw_min_ver(hw, ICE_FW_VER_BRANCH_E82X,
6466 : : ICE_FW_FEC_DIS_AUTO_MAJ_E82X,
6467 : : ICE_FW_FEC_DIS_AUTO_MIN_E82X,
6468 : : ICE_FW_FEC_DIS_AUTO_PATCH_E82X);
6469 : : }
6470 : :
6471 : : /**
6472 : : * ice_is_fw_auto_drop_supported
6473 : : * @hw: pointer to the hardware structure
6474 : : *
6475 : : * Checks if the firmware supports auto drop feature
6476 : : */
6477 : 0 : bool ice_is_fw_auto_drop_supported(struct ice_hw *hw)
6478 : : {
6479 [ # # ]: 0 : if (hw->api_maj_ver >= ICE_FW_API_AUTO_DROP_MAJ &&
6480 [ # # ]: 0 : hw->api_min_ver >= ICE_FW_API_AUTO_DROP_MIN)
6481 : 0 : return true;
6482 : : return false;
6483 : : }
|