xref: /freebsd/sys/dev/ice/ice_lib.c (revision b1c5f60ce87cc2f179dfb81de507d9b7bf59564c)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /*  Copyright (c) 2021, Intel Corporation
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *
8  *   1. Redistributions of source code must retain the above copyright notice,
9  *      this list of conditions and the following disclaimer.
10  *
11  *   2. Redistributions in binary form must reproduce the above copyright
12  *      notice, this list of conditions and the following disclaimer in the
13  *      documentation and/or other materials provided with the distribution.
14  *
15  *   3. Neither the name of the Intel Corporation nor the names of its
16  *      contributors may be used to endorse or promote products derived from
17  *      this software without specific prior written permission.
18  *
19  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  *  POSSIBILITY OF SUCH DAMAGE.
30  */
31 /*$FreeBSD$*/
32 
33 /**
34  * @file ice_lib.c
35  * @brief Generic device setup and sysctl functions
36  *
37  * Library of generic device functions not specific to the networking stack.
38  *
39  * This includes hardware initialization functions, as well as handlers for
40  * many of the device sysctls used to probe driver status or tune specific
41  * behaviors.
42  */
43 
44 #include "ice_lib.h"
45 #include "ice_iflib.h"
46 #include <dev/pci/pcivar.h>
47 #include <dev/pci/pcireg.h>
48 #include <machine/resource.h>
49 #include <net/if_dl.h>
50 #include <sys/firmware.h>
51 #include <sys/priv.h>
52 #include <sys/limits.h>
53 
54 /**
55  * @var M_ICE
56  * @brief main ice driver allocation type
57  *
58  * malloc(9) allocation type used by the majority of memory allocations in the
59  * ice driver.
60  */
61 MALLOC_DEFINE(M_ICE, "ice", "Intel(R) 100Gb Network Driver lib allocations");
62 
63 /*
64  * Helper function prototypes
65  */
66 static int ice_get_next_vsi(struct ice_vsi **all_vsi, int size);
67 static void ice_set_default_vsi_ctx(struct ice_vsi_ctx *ctx);
68 static void ice_set_rss_vsi_ctx(struct ice_vsi_ctx *ctx, enum ice_vsi_type type);
69 static int ice_setup_vsi_qmap(struct ice_vsi *vsi, struct ice_vsi_ctx *ctx);
70 static int ice_setup_tx_ctx(struct ice_tx_queue *txq,
71 			    struct ice_tlan_ctx *tlan_ctx, u16 pf_q);
72 static int ice_setup_rx_ctx(struct ice_rx_queue *rxq);
73 static int ice_is_rxq_ready(struct ice_hw *hw, int pf_q, u32 *reg);
74 static void ice_free_fltr_list(struct ice_list_head *list);
75 static int ice_add_mac_to_list(struct ice_vsi *vsi, struct ice_list_head *list,
76 			       const u8 *addr, enum ice_sw_fwd_act_type action);
77 static void ice_check_ctrlq_errors(struct ice_softc *sc, const char *qname,
78 				   struct ice_ctl_q_info *cq);
79 static void ice_process_link_event(struct ice_softc *sc, struct ice_rq_event_info *e);
80 static void ice_process_ctrlq_event(struct ice_softc *sc, const char *qname,
81 				    struct ice_rq_event_info *event);
82 static void ice_nvm_version_str(struct ice_hw *hw, struct sbuf *buf);
83 static void ice_active_pkg_version_str(struct ice_hw *hw, struct sbuf *buf);
84 static void ice_os_pkg_version_str(struct ice_hw *hw, struct sbuf *buf);
85 static bool ice_filter_is_mcast(struct ice_vsi *vsi, struct ice_fltr_info *info);
86 static u_int ice_sync_one_mcast_filter(void *p, struct sockaddr_dl *sdl, u_int errors);
87 static void ice_add_debug_tunables(struct ice_softc *sc);
88 static void ice_add_debug_sysctls(struct ice_softc *sc);
89 static void ice_vsi_set_rss_params(struct ice_vsi *vsi);
90 static void ice_get_default_rss_key(u8 *seed);
91 static int  ice_set_rss_key(struct ice_vsi *vsi);
92 static int  ice_set_rss_lut(struct ice_vsi *vsi);
93 static void ice_set_rss_flow_flds(struct ice_vsi *vsi);
94 static void ice_clean_vsi_rss_cfg(struct ice_vsi *vsi);
95 static const char *ice_aq_speed_to_str(struct ice_port_info *pi);
96 static const char *ice_requested_fec_mode(struct ice_port_info *pi);
97 static const char *ice_negotiated_fec_mode(struct ice_port_info *pi);
98 static const char *ice_autoneg_mode(struct ice_port_info *pi);
99 static const char *ice_flowcontrol_mode(struct ice_port_info *pi);
100 static void ice_print_bus_link_data(device_t dev, struct ice_hw *hw);
101 static void ice_set_pci_link_status_data(struct ice_hw *hw, u16 link_status);
102 static uint8_t ice_pcie_bandwidth_check(struct ice_softc *sc);
103 static uint64_t ice_pcie_bus_speed_to_rate(enum ice_pcie_bus_speed speed);
104 static int ice_pcie_lnk_width_to_int(enum ice_pcie_link_width width);
105 static uint64_t ice_phy_types_to_max_rate(struct ice_port_info *pi);
106 static void ice_add_sysctls_sw_stats(struct ice_vsi *vsi,
107 				     struct sysctl_ctx_list *ctx,
108 				     struct sysctl_oid *parent);
109 static void
110 ice_add_sysctls_mac_pfc_one_stat(struct sysctl_ctx_list *ctx,
111 				 struct sysctl_oid_list *parent_list,
112 				 u64* pfc_stat_location,
113 				 const char *node_name,
114 				 const char *descr);
115 static void ice_add_sysctls_mac_pfc_stats(struct sysctl_ctx_list *ctx,
116 					  struct sysctl_oid *parent,
117 					  struct ice_hw_port_stats *stats);
118 static void ice_setup_vsi_common(struct ice_softc *sc, struct ice_vsi *vsi,
119 				 enum ice_vsi_type type, int idx,
120 				 bool dynamic);
121 static void ice_handle_mib_change_event(struct ice_softc *sc,
122 				 struct ice_rq_event_info *event);
123 static void
124 ice_handle_lan_overflow_event(struct ice_softc *sc,
125 			      struct ice_rq_event_info *event);
126 static int ice_add_ethertype_to_list(struct ice_vsi *vsi,
127 				     struct ice_list_head *list,
128 				     u16 ethertype, u16 direction,
129 				     enum ice_sw_fwd_act_type action);
130 static void ice_add_rx_lldp_filter(struct ice_softc *sc);
131 static void ice_del_rx_lldp_filter(struct ice_softc *sc);
132 static u16 ice_aq_phy_types_to_link_speeds(u64 phy_type_low,
133 					   u64 phy_type_high);
134 struct ice_phy_data;
135 static int
136 ice_intersect_phy_types_and_speeds(struct ice_softc *sc,
137 				   struct ice_phy_data *phy_data);
138 static int
139 ice_apply_saved_phy_req_to_cfg(struct ice_softc *sc,
140 			       struct ice_aqc_set_phy_cfg_data *cfg);
141 static int
142 ice_apply_saved_fec_req_to_cfg(struct ice_softc *sc,
143 			       struct ice_aqc_set_phy_cfg_data *cfg);
144 static void
145 ice_apply_saved_fc_req_to_cfg(struct ice_port_info *pi,
146 			      struct ice_aqc_set_phy_cfg_data *cfg);
147 static void
148 ice_print_ldo_tlv(struct ice_softc *sc,
149 		  struct ice_link_default_override_tlv *tlv);
150 static void
151 ice_sysctl_speeds_to_aq_phy_types(u16 sysctl_speeds, u64 *phy_type_low,
152 				  u64 *phy_type_high);
153 static u16 ice_apply_supported_speed_filter(u16 report_speeds, u8 mod_type);
154 static void
155 ice_handle_health_status_event(struct ice_softc *sc,
156 			       struct ice_rq_event_info *event);
157 static void
158 ice_print_health_status_string(device_t dev,
159 			       struct ice_aqc_health_status_elem *elem);
160 static void
161 ice_debug_print_mib_change_event(struct ice_softc *sc,
162 				 struct ice_rq_event_info *event);
163 static bool ice_check_ets_bw(u8 *table);
164 static bool
165 ice_dcb_needs_reconfig(struct ice_softc *sc, struct ice_dcbx_cfg *old_cfg,
166 		       struct ice_dcbx_cfg *new_cfg);
167 static void ice_dcb_recfg(struct ice_softc *sc);
168 static u8 ice_dcb_num_tc(u8 tc_map);
169 static int ice_ets_str_to_tbl(const char *str, u8 *table, u8 limit);
170 static int ice_pf_vsi_cfg_tc(struct ice_softc *sc, u8 tc_map);
171 static void ice_sbuf_print_ets_cfg(struct sbuf *sbuf, const char *name,
172 				   struct ice_dcb_ets_cfg *ets);
173 static void ice_stop_pf_vsi(struct ice_softc *sc);
174 static void ice_vsi_setup_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt);
175 static void ice_do_dcb_reconfig(struct ice_softc *sc);
176 static int ice_config_pfc(struct ice_softc *sc, u8 new_mode);
177 static u8 ice_dcb_get_tc_map(const struct ice_dcbx_cfg *dcbcfg);
178 
179 static int ice_module_init(void);
180 static int ice_module_exit(void);
181 
182 /*
183  * package version comparison functions
184  */
185 static bool pkg_ver_empty(struct ice_pkg_ver *pkg_ver, u8 *pkg_name);
186 static int pkg_ver_compatible(struct ice_pkg_ver *pkg_ver);
187 
188 /*
189  * dynamic sysctl handlers
190  */
191 static int ice_sysctl_show_fw(SYSCTL_HANDLER_ARGS);
192 static int ice_sysctl_pkg_version(SYSCTL_HANDLER_ARGS);
193 static int ice_sysctl_os_pkg_version(SYSCTL_HANDLER_ARGS);
194 static int ice_sysctl_dump_mac_filters(SYSCTL_HANDLER_ARGS);
195 static int ice_sysctl_dump_vlan_filters(SYSCTL_HANDLER_ARGS);
196 static int ice_sysctl_dump_ethertype_filters(SYSCTL_HANDLER_ARGS);
197 static int ice_sysctl_dump_ethertype_mac_filters(SYSCTL_HANDLER_ARGS);
198 static int ice_sysctl_current_speed(SYSCTL_HANDLER_ARGS);
199 static int ice_sysctl_request_reset(SYSCTL_HANDLER_ARGS);
200 static int ice_sysctl_dump_state_flags(SYSCTL_HANDLER_ARGS);
201 static int ice_sysctl_fec_config(SYSCTL_HANDLER_ARGS);
202 static int ice_sysctl_fc_config(SYSCTL_HANDLER_ARGS);
203 static int ice_sysctl_negotiated_fc(SYSCTL_HANDLER_ARGS);
204 static int ice_sysctl_negotiated_fec(SYSCTL_HANDLER_ARGS);
205 static int ice_sysctl_phy_type_low(SYSCTL_HANDLER_ARGS);
206 static int ice_sysctl_phy_type_high(SYSCTL_HANDLER_ARGS);
207 static int __ice_sysctl_phy_type_handler(SYSCTL_HANDLER_ARGS,
208 					 bool is_phy_type_high);
209 static int ice_sysctl_advertise_speed(SYSCTL_HANDLER_ARGS);
210 static int ice_sysctl_rx_itr(SYSCTL_HANDLER_ARGS);
211 static int ice_sysctl_tx_itr(SYSCTL_HANDLER_ARGS);
212 static int ice_sysctl_fw_lldp_agent(SYSCTL_HANDLER_ARGS);
213 static int ice_sysctl_fw_cur_lldp_persist_status(SYSCTL_HANDLER_ARGS);
214 static int ice_sysctl_fw_dflt_lldp_persist_status(SYSCTL_HANDLER_ARGS);
215 static int ice_sysctl_phy_caps(SYSCTL_HANDLER_ARGS, u8 report_mode);
216 static int ice_sysctl_phy_sw_caps(SYSCTL_HANDLER_ARGS);
217 static int ice_sysctl_phy_nvm_caps(SYSCTL_HANDLER_ARGS);
218 static int ice_sysctl_phy_topo_caps(SYSCTL_HANDLER_ARGS);
219 static int ice_sysctl_phy_link_status(SYSCTL_HANDLER_ARGS);
220 static int ice_sysctl_read_i2c_diag_data(SYSCTL_HANDLER_ARGS);
221 static int ice_sysctl_tx_cso_stat(SYSCTL_HANDLER_ARGS);
222 static int ice_sysctl_rx_cso_stat(SYSCTL_HANDLER_ARGS);
223 static int ice_sysctl_pba_number(SYSCTL_HANDLER_ARGS);
224 static int ice_sysctl_rx_errors_stat(SYSCTL_HANDLER_ARGS);
225 static int ice_sysctl_dump_dcbx_cfg(SYSCTL_HANDLER_ARGS);
226 static int ice_sysctl_dump_vsi_cfg(SYSCTL_HANDLER_ARGS);
227 static int ice_sysctl_ets_min_rate(SYSCTL_HANDLER_ARGS);
228 static int ice_sysctl_up2tc_map(SYSCTL_HANDLER_ARGS);
229 static int ice_sysctl_pfc_config(SYSCTL_HANDLER_ARGS);
230 static int ice_sysctl_query_port_ets(SYSCTL_HANDLER_ARGS);
231 
232 /**
233  * ice_map_bar - Map PCIe BAR memory
234  * @dev: the PCIe device
235  * @bar: the BAR info structure
236  * @bar_num: PCIe BAR number
237  *
238  * Maps the specified PCIe BAR. Stores the mapping data in struct
239  * ice_bar_info.
240  */
241 int
242 ice_map_bar(device_t dev, struct ice_bar_info *bar, int bar_num)
243 {
244 	if (bar->res != NULL) {
245 		device_printf(dev, "PCI BAR%d already mapped\n", bar_num);
246 		return (EDOOFUS);
247 	}
248 
249 	bar->rid = PCIR_BAR(bar_num);
250 	bar->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &bar->rid,
251 					  RF_ACTIVE);
252 	if (!bar->res) {
253 		device_printf(dev, "PCI BAR%d mapping failed\n", bar_num);
254 		return (ENXIO);
255 	}
256 
257 	bar->tag = rman_get_bustag(bar->res);
258 	bar->handle = rman_get_bushandle(bar->res);
259 	bar->size = rman_get_size(bar->res);
260 
261 	return (0);
262 }
263 
264 /**
265  * ice_free_bar - Free PCIe BAR memory
266  * @dev: the PCIe device
267  * @bar: the BAR info structure
268  *
269  * Frees the specified PCIe BAR, releasing its resources.
270  */
271 void
272 ice_free_bar(device_t dev, struct ice_bar_info *bar)
273 {
274 	if (bar->res != NULL)
275 		bus_release_resource(dev, SYS_RES_MEMORY, bar->rid, bar->res);
276 	bar->res = NULL;
277 }
278 
279 /**
280  * ice_set_ctrlq_len - Configure ctrlq lengths for a device
281  * @hw: the device hardware structure
282  *
283  * Configures the control queues for the given device, setting up the
284  * specified lengths, prior to initializing hardware.
285  */
286 void
287 ice_set_ctrlq_len(struct ice_hw *hw)
288 {
289 	hw->adminq.num_rq_entries = ICE_AQ_LEN;
290 	hw->adminq.num_sq_entries = ICE_AQ_LEN;
291 	hw->adminq.rq_buf_size = ICE_AQ_MAX_BUF_LEN;
292 	hw->adminq.sq_buf_size = ICE_AQ_MAX_BUF_LEN;
293 
294 	hw->mailboxq.num_rq_entries = ICE_MBXQ_LEN;
295 	hw->mailboxq.num_sq_entries = ICE_MBXQ_LEN;
296 	hw->mailboxq.rq_buf_size = ICE_MBXQ_MAX_BUF_LEN;
297 	hw->mailboxq.sq_buf_size = ICE_MBXQ_MAX_BUF_LEN;
298 
299 }
300 
301 /**
302  * ice_get_next_vsi - Get the next available VSI slot
303  * @all_vsi: the VSI list
304  * @size: the size of the VSI list
305  *
306  * Returns the index to the first available VSI slot. Will return size (one
307  * past the last index) if there are no slots available.
308  */
309 static int
310 ice_get_next_vsi(struct ice_vsi **all_vsi, int size)
311 {
312 	int i;
313 
314 	for (i = 0; i < size; i++) {
315 		if (all_vsi[i] == NULL)
316 			return i;
317 	}
318 
319 	return size;
320 }
321 
322 /**
323  * ice_setup_vsi_common - Common VSI setup for both dynamic and static VSIs
324  * @sc: the device private softc structure
325  * @vsi: the VSI to setup
326  * @type: the VSI type of the new VSI
327  * @idx: the index in the all_vsi array to use
328  * @dynamic: whether this VSI memory was dynamically allocated
329  *
330  * Perform setup for a VSI that is common to both dynamically allocated VSIs
331  * and the static PF VSI which is embedded in the softc structure.
332  */
333 static void
334 ice_setup_vsi_common(struct ice_softc *sc, struct ice_vsi *vsi,
335 		     enum ice_vsi_type type, int idx, bool dynamic)
336 {
337 	/* Store important values in VSI struct */
338 	vsi->type = type;
339 	vsi->sc = sc;
340 	vsi->idx = idx;
341 	sc->all_vsi[idx] = vsi;
342 	vsi->dynamic = dynamic;
343 
344 	/* Setup the VSI tunables now */
345 	ice_add_vsi_tunables(vsi, sc->vsi_sysctls);
346 }
347 
348 /**
349  * ice_alloc_vsi - Allocate a dynamic VSI
350  * @sc: device softc structure
351  * @type: VSI type
352  *
353  * Allocates a new dynamic VSI structure and inserts it into the VSI list.
354  */
355 struct ice_vsi *
356 ice_alloc_vsi(struct ice_softc *sc, enum ice_vsi_type type)
357 {
358 	struct ice_vsi *vsi;
359 	int idx;
360 
361 	/* Find an open index for a new VSI to be allocated. If the returned
362 	 * index is >= the num_available_vsi then it means no slot is
363 	 * available.
364 	 */
365 	idx = ice_get_next_vsi(sc->all_vsi, sc->num_available_vsi);
366 	if (idx >= sc->num_available_vsi) {
367 		device_printf(sc->dev, "No available VSI slots\n");
368 		return NULL;
369 	}
370 
371 	vsi = (struct ice_vsi *)malloc(sizeof(*vsi), M_ICE, M_WAITOK|M_ZERO);
372 	if (!vsi) {
373 		device_printf(sc->dev, "Unable to allocate VSI memory\n");
374 		return NULL;
375 	}
376 
377 	ice_setup_vsi_common(sc, vsi, type, idx, true);
378 
379 	return vsi;
380 }
381 
382 /**
383  * ice_setup_pf_vsi - Setup the PF VSI
384  * @sc: the device private softc
385  *
386  * Setup the PF VSI structure which is embedded as sc->pf_vsi in the device
387  * private softc. Unlike other VSIs, the PF VSI memory is allocated as part of
388  * the softc memory, instead of being dynamically allocated at creation.
389  */
390 void
391 ice_setup_pf_vsi(struct ice_softc *sc)
392 {
393 	ice_setup_vsi_common(sc, &sc->pf_vsi, ICE_VSI_PF, 0, false);
394 }
395 
396 /**
397  * ice_alloc_vsi_qmap
398  * @vsi: VSI structure
399  * @max_tx_queues: Number of transmit queues to identify
400  * @max_rx_queues: Number of receive queues to identify
401  *
402  * Allocates a max_[t|r]x_queues array of words for the VSI where each
403  * word contains the index of the queue it represents.  In here, all
404  * words are initialized to an index of ICE_INVALID_RES_IDX, indicating
405  * all queues for this VSI are not yet assigned an index and thus,
406  * not ready for use.
407  *
408  * Returns an error code on failure.
409  */
410 int
411 ice_alloc_vsi_qmap(struct ice_vsi *vsi, const int max_tx_queues,
412 		   const int max_rx_queues)
413 {
414 	struct ice_softc *sc = vsi->sc;
415 	int i;
416 
417 	MPASS(max_tx_queues > 0);
418 	MPASS(max_rx_queues > 0);
419 
420 	/* Allocate Tx queue mapping memory */
421 	if (!(vsi->tx_qmap =
422 	      (u16 *) malloc(sizeof(u16) * max_tx_queues, M_ICE, M_WAITOK))) {
423 		device_printf(sc->dev, "Unable to allocate Tx qmap memory\n");
424 		return (ENOMEM);
425 	}
426 
427 	/* Allocate Rx queue mapping memory */
428 	if (!(vsi->rx_qmap =
429 	      (u16 *) malloc(sizeof(u16) * max_rx_queues, M_ICE, M_WAITOK))) {
430 		device_printf(sc->dev, "Unable to allocate Rx qmap memory\n");
431 		goto free_tx_qmap;
432 	}
433 
434 	/* Mark every queue map as invalid to start with */
435 	for (i = 0; i < max_tx_queues; i++) {
436 		vsi->tx_qmap[i] = ICE_INVALID_RES_IDX;
437 	}
438 	for (i = 0; i < max_rx_queues; i++) {
439 		vsi->rx_qmap[i] = ICE_INVALID_RES_IDX;
440 	}
441 
442 	return 0;
443 
444 free_tx_qmap:
445 	free(vsi->tx_qmap, M_ICE);
446 	vsi->tx_qmap = NULL;
447 
448 	return (ENOMEM);
449 }
450 
451 /**
452  * ice_free_vsi_qmaps - Free the PF qmaps associated with a VSI
453  * @vsi: the VSI private structure
454  *
455  * Frees the PF qmaps associated with the given VSI. Generally this will be
456  * called by ice_release_vsi, but may need to be called during attach cleanup,
457  * depending on when the qmaps were allocated.
458  */
459 void
460 ice_free_vsi_qmaps(struct ice_vsi *vsi)
461 {
462 	struct ice_softc *sc = vsi->sc;
463 
464 	if (vsi->tx_qmap) {
465 		ice_resmgr_release_map(&sc->tx_qmgr, vsi->tx_qmap,
466 					   vsi->num_tx_queues);
467 		free(vsi->tx_qmap, M_ICE);
468 		vsi->tx_qmap = NULL;
469 	}
470 
471 	if (vsi->rx_qmap) {
472 		ice_resmgr_release_map(&sc->rx_qmgr, vsi->rx_qmap,
473 					   vsi->num_rx_queues);
474 		free(vsi->rx_qmap, M_ICE);
475 		vsi->rx_qmap = NULL;
476 	}
477 }
478 
479 /**
480  * ice_set_default_vsi_ctx - Setup default VSI context parameters
481  * @ctx: the VSI context to initialize
482  *
483  * Initialize and prepare a default VSI context for configuring a new VSI.
484  */
485 static void
486 ice_set_default_vsi_ctx(struct ice_vsi_ctx *ctx)
487 {
488 	u32 table = 0;
489 
490 	memset(&ctx->info, 0, sizeof(ctx->info));
491 	/* VSI will be allocated from shared pool */
492 	ctx->alloc_from_pool = true;
493 	/* Enable source pruning by default */
494 	ctx->info.sw_flags = ICE_AQ_VSI_SW_FLAG_SRC_PRUNE;
495 	/* Traffic from VSI can be sent to LAN */
496 	ctx->info.sw_flags2 = ICE_AQ_VSI_SW_FLAG_LAN_ENA;
497 	/* Allow all packets untagged/tagged */
498 	ctx->info.inner_vlan_flags = ((ICE_AQ_VSI_INNER_VLAN_TX_MODE_ALL &
499 				       ICE_AQ_VSI_INNER_VLAN_TX_MODE_M) >>
500 				       ICE_AQ_VSI_INNER_VLAN_TX_MODE_S);
501 	/* Show VLAN/UP from packets in Rx descriptors */
502 	ctx->info.inner_vlan_flags |= ((ICE_AQ_VSI_INNER_VLAN_EMODE_STR_BOTH &
503 					ICE_AQ_VSI_INNER_VLAN_EMODE_M) >>
504 					ICE_AQ_VSI_INNER_VLAN_EMODE_S);
505 	/* Have 1:1 UP mapping for both ingress/egress tables */
506 	table |= ICE_UP_TABLE_TRANSLATE(0, 0);
507 	table |= ICE_UP_TABLE_TRANSLATE(1, 1);
508 	table |= ICE_UP_TABLE_TRANSLATE(2, 2);
509 	table |= ICE_UP_TABLE_TRANSLATE(3, 3);
510 	table |= ICE_UP_TABLE_TRANSLATE(4, 4);
511 	table |= ICE_UP_TABLE_TRANSLATE(5, 5);
512 	table |= ICE_UP_TABLE_TRANSLATE(6, 6);
513 	table |= ICE_UP_TABLE_TRANSLATE(7, 7);
514 	ctx->info.ingress_table = CPU_TO_LE32(table);
515 	ctx->info.egress_table = CPU_TO_LE32(table);
516 	/* Have 1:1 UP mapping for outer to inner UP table */
517 	ctx->info.outer_up_table = CPU_TO_LE32(table);
518 	/* No Outer tag support, so outer_vlan_flags remains zero */
519 }
520 
521 /**
522  * ice_set_rss_vsi_ctx - Setup VSI context parameters for RSS
523  * @ctx: the VSI context to configure
524  * @type: the VSI type
525  *
526  * Configures the VSI context for RSS, based on the VSI type.
527  */
528 static void
529 ice_set_rss_vsi_ctx(struct ice_vsi_ctx *ctx, enum ice_vsi_type type)
530 {
531 	u8 lut_type, hash_type;
532 
533 	switch (type) {
534 	case ICE_VSI_PF:
535 		lut_type = ICE_AQ_VSI_Q_OPT_RSS_LUT_PF;
536 		hash_type = ICE_AQ_VSI_Q_OPT_RSS_TPLZ;
537 		break;
538 	case ICE_VSI_VF:
539 		lut_type = ICE_AQ_VSI_Q_OPT_RSS_LUT_VSI;
540 		hash_type = ICE_AQ_VSI_Q_OPT_RSS_TPLZ;
541 		break;
542 	default:
543 		/* Other VSI types do not support RSS */
544 		return;
545 	}
546 
547 	ctx->info.q_opt_rss = (((lut_type << ICE_AQ_VSI_Q_OPT_RSS_LUT_S) &
548 				 ICE_AQ_VSI_Q_OPT_RSS_LUT_M) |
549 				((hash_type << ICE_AQ_VSI_Q_OPT_RSS_HASH_S) &
550 				 ICE_AQ_VSI_Q_OPT_RSS_HASH_M));
551 }
552 
553 /**
554  * ice_setup_vsi_qmap - Setup the queue mapping for a VSI
555  * @vsi: the VSI to configure
556  * @ctx: the VSI context to configure
557  *
558  * Configures the context for the given VSI, setting up how the firmware
559  * should map the queues for this VSI.
560  */
561 static int
562 ice_setup_vsi_qmap(struct ice_vsi *vsi, struct ice_vsi_ctx *ctx)
563 {
564 	int pow = 0;
565 	u16 qmap;
566 
567 	MPASS(vsi->rx_qmap != NULL);
568 
569 	/* TODO:
570 	 * Handle multiple Traffic Classes
571 	 * Handle scattered queues (for VFs)
572 	 */
573 	if (vsi->qmap_type != ICE_RESMGR_ALLOC_CONTIGUOUS)
574 		return (EOPNOTSUPP);
575 
576 	ctx->info.mapping_flags |= CPU_TO_LE16(ICE_AQ_VSI_Q_MAP_CONTIG);
577 
578 	ctx->info.q_mapping[0] = CPU_TO_LE16(vsi->rx_qmap[0]);
579 	ctx->info.q_mapping[1] = CPU_TO_LE16(vsi->num_rx_queues);
580 
581 
582 	/* Calculate the next power-of-2 of number of queues */
583 	if (vsi->num_rx_queues)
584 		pow = flsl(vsi->num_rx_queues - 1);
585 
586 	/* Assign all the queues to traffic class zero */
587 	qmap = (pow << ICE_AQ_VSI_TC_Q_NUM_S) & ICE_AQ_VSI_TC_Q_NUM_M;
588 	ctx->info.tc_mapping[0] = CPU_TO_LE16(qmap);
589 
590 	return 0;
591 }
592 
593 /**
594  * ice_initialize_vsi - Initialize a VSI for use
595  * @vsi: the vsi to initialize
596  *
597  * Initialize a VSI over the adminq and prepare it for operation.
598  */
599 int
600 ice_initialize_vsi(struct ice_vsi *vsi)
601 {
602 	struct ice_vsi_ctx ctx = { 0 };
603 	struct ice_hw *hw = &vsi->sc->hw;
604 	u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 };
605 	enum ice_status status;
606 	int err;
607 
608 	/* For now, we only have code supporting PF VSIs */
609 	switch (vsi->type) {
610 	case ICE_VSI_PF:
611 		ctx.flags = ICE_AQ_VSI_TYPE_PF;
612 		break;
613 	default:
614 		return (ENODEV);
615 	}
616 
617 	ice_set_default_vsi_ctx(&ctx);
618 	ice_set_rss_vsi_ctx(&ctx, vsi->type);
619 
620 	/* XXX: VSIs of other types may need different port info? */
621 	ctx.info.sw_id = hw->port_info->sw_id;
622 
623 	/* Set some RSS parameters based on the VSI type */
624 	ice_vsi_set_rss_params(vsi);
625 
626 	/* Initialize the Rx queue mapping for this VSI */
627 	err = ice_setup_vsi_qmap(vsi, &ctx);
628 	if (err) {
629 		return err;
630 	}
631 
632 	/* (Re-)add VSI to HW VSI handle list */
633 	status = ice_add_vsi(hw, vsi->idx, &ctx, NULL);
634 	if (status != 0) {
635 		device_printf(vsi->sc->dev,
636 		    "Add VSI AQ call failed, err %s aq_err %s\n",
637 		    ice_status_str(status),
638 		    ice_aq_str(hw->adminq.sq_last_status));
639 		return (EIO);
640 	}
641 	vsi->info = ctx.info;
642 
643 	/* Initialize VSI with just 1 TC to start */
644 	max_txqs[0] = vsi->num_tx_queues;
645 
646 	status = ice_cfg_vsi_lan(hw->port_info, vsi->idx,
647 			      ICE_DFLT_TRAFFIC_CLASS, max_txqs);
648 	if (status) {
649 		device_printf(vsi->sc->dev,
650 		    "Failed VSI lan queue config, err %s aq_err %s\n",
651 		    ice_status_str(status),
652 		    ice_aq_str(hw->adminq.sq_last_status));
653 		ice_deinit_vsi(vsi);
654 		return (ENODEV);
655 	}
656 
657 	/* Reset VSI stats */
658 	ice_reset_vsi_stats(vsi);
659 
660 	return 0;
661 }
662 
663 /**
664  * ice_deinit_vsi - Tell firmware to release resources for a VSI
665  * @vsi: the VSI to release
666  *
667  * Helper function which requests the firmware to release the hardware
668  * resources associated with a given VSI.
669  */
670 void
671 ice_deinit_vsi(struct ice_vsi *vsi)
672 {
673 	struct ice_vsi_ctx ctx = { 0 };
674 	struct ice_softc *sc = vsi->sc;
675 	struct ice_hw *hw = &sc->hw;
676 	enum ice_status status;
677 
678 	/* Assert that the VSI pointer matches in the list */
679 	MPASS(vsi == sc->all_vsi[vsi->idx]);
680 
681 	ctx.info = vsi->info;
682 
683 	status = ice_rm_vsi_lan_cfg(hw->port_info, vsi->idx);
684 	if (status) {
685 		/*
686 		 * This should only fail if the VSI handle is invalid, or if
687 		 * any of the nodes have leaf nodes which are still in use.
688 		 */
689 		device_printf(sc->dev,
690 			      "Unable to remove scheduler nodes for VSI %d, err %s\n",
691 			      vsi->idx, ice_status_str(status));
692 	}
693 
694 	/* Tell firmware to release the VSI resources */
695 	status = ice_free_vsi(hw, vsi->idx, &ctx, false, NULL);
696 	if (status != 0) {
697 		device_printf(sc->dev,
698 		    "Free VSI %u AQ call failed, err %s aq_err %s\n",
699 		    vsi->idx, ice_status_str(status),
700 		    ice_aq_str(hw->adminq.sq_last_status));
701 	}
702 }
703 
704 /**
705  * ice_release_vsi - Release resources associated with a VSI
706  * @vsi: the VSI to release
707  *
708  * Release software and firmware resources associated with a VSI. Release the
709  * queue managers associated with this VSI. Also free the VSI structure memory
710  * if the VSI was allocated dynamically using ice_alloc_vsi().
711  */
712 void
713 ice_release_vsi(struct ice_vsi *vsi)
714 {
715 	struct ice_softc *sc = vsi->sc;
716 	int idx = vsi->idx;
717 
718 	/* Assert that the VSI pointer matches in the list */
719 	MPASS(vsi == sc->all_vsi[idx]);
720 
721 	/* Cleanup RSS configuration */
722 	if (ice_is_bit_set(sc->feat_en, ICE_FEATURE_RSS))
723 		ice_clean_vsi_rss_cfg(vsi);
724 
725 	ice_del_vsi_sysctl_ctx(vsi);
726 
727 	/*
728 	 * If we unload the driver after a reset fails, we do not need to do
729 	 * this step.
730 	 */
731 	if (!ice_test_state(&sc->state, ICE_STATE_RESET_FAILED))
732 		ice_deinit_vsi(vsi);
733 
734 	ice_free_vsi_qmaps(vsi);
735 
736 	if (vsi->dynamic) {
737 		free(sc->all_vsi[idx], M_ICE);
738 	}
739 
740 	sc->all_vsi[idx] = NULL;
741 }
742 
743 /**
744  * ice_aq_speed_to_rate - Convert AdminQ speed enum to baudrate
745  * @pi: port info data
746  *
747  * Returns the baudrate value for the current link speed of a given port.
748  */
749 uint64_t
750 ice_aq_speed_to_rate(struct ice_port_info *pi)
751 {
752 	switch (pi->phy.link_info.link_speed) {
753 	case ICE_AQ_LINK_SPEED_100GB:
754 		return IF_Gbps(100);
755 	case ICE_AQ_LINK_SPEED_50GB:
756 		return IF_Gbps(50);
757 	case ICE_AQ_LINK_SPEED_40GB:
758 		return IF_Gbps(40);
759 	case ICE_AQ_LINK_SPEED_25GB:
760 		return IF_Gbps(25);
761 	case ICE_AQ_LINK_SPEED_10GB:
762 		return IF_Gbps(10);
763 	case ICE_AQ_LINK_SPEED_5GB:
764 		return IF_Gbps(5);
765 	case ICE_AQ_LINK_SPEED_2500MB:
766 		return IF_Mbps(2500);
767 	case ICE_AQ_LINK_SPEED_1000MB:
768 		return IF_Mbps(1000);
769 	case ICE_AQ_LINK_SPEED_100MB:
770 		return IF_Mbps(100);
771 	case ICE_AQ_LINK_SPEED_10MB:
772 		return IF_Mbps(10);
773 	case ICE_AQ_LINK_SPEED_UNKNOWN:
774 	default:
775 		/* return 0 if we don't know the link speed */
776 		return 0;
777 	}
778 }
779 
780 /**
781  * ice_aq_speed_to_str - Convert AdminQ speed enum to string representation
782  * @pi: port info data
783  *
784  * Returns the string representation of the current link speed for a given
785  * port.
786  */
787 static const char *
788 ice_aq_speed_to_str(struct ice_port_info *pi)
789 {
790 	switch (pi->phy.link_info.link_speed) {
791 	case ICE_AQ_LINK_SPEED_100GB:
792 		return "100 Gbps";
793 	case ICE_AQ_LINK_SPEED_50GB:
794 		return "50 Gbps";
795 	case ICE_AQ_LINK_SPEED_40GB:
796 		return "40 Gbps";
797 	case ICE_AQ_LINK_SPEED_25GB:
798 		return "25 Gbps";
799 	case ICE_AQ_LINK_SPEED_20GB:
800 		return "20 Gbps";
801 	case ICE_AQ_LINK_SPEED_10GB:
802 		return "10 Gbps";
803 	case ICE_AQ_LINK_SPEED_5GB:
804 		return "5 Gbps";
805 	case ICE_AQ_LINK_SPEED_2500MB:
806 		return "2.5 Gbps";
807 	case ICE_AQ_LINK_SPEED_1000MB:
808 		return "1 Gbps";
809 	case ICE_AQ_LINK_SPEED_100MB:
810 		return "100 Mbps";
811 	case ICE_AQ_LINK_SPEED_10MB:
812 		return "10 Mbps";
813 	case ICE_AQ_LINK_SPEED_UNKNOWN:
814 	default:
815 		return "Unknown speed";
816 	}
817 }
818 
819 /**
820  * ice_get_phy_type_low - Get media associated with phy_type_low
821  * @phy_type_low: the low 64bits of phy_type from the AdminQ
822  *
823  * Given the lower 64bits of the phy_type from the hardware, return the
824  * ifm_active bit associated. Return IFM_UNKNOWN when phy_type_low is unknown.
825  * Note that only one of ice_get_phy_type_low or ice_get_phy_type_high should
826  * be called. If phy_type_low is zero, call ice_phy_type_high.
827  */
828 int
829 ice_get_phy_type_low(uint64_t phy_type_low)
830 {
831 	switch (phy_type_low) {
832 	case ICE_PHY_TYPE_LOW_100BASE_TX:
833 		return IFM_100_TX;
834 	case ICE_PHY_TYPE_LOW_100M_SGMII:
835 		return IFM_100_SGMII;
836 	case ICE_PHY_TYPE_LOW_1000BASE_T:
837 		return IFM_1000_T;
838 	case ICE_PHY_TYPE_LOW_1000BASE_SX:
839 		return IFM_1000_SX;
840 	case ICE_PHY_TYPE_LOW_1000BASE_LX:
841 		return IFM_1000_LX;
842 	case ICE_PHY_TYPE_LOW_1000BASE_KX:
843 		return IFM_1000_KX;
844 	case ICE_PHY_TYPE_LOW_1G_SGMII:
845 		return IFM_1000_SGMII;
846 	case ICE_PHY_TYPE_LOW_2500BASE_T:
847 		return IFM_2500_T;
848 	case ICE_PHY_TYPE_LOW_2500BASE_X:
849 		return IFM_2500_X;
850 	case ICE_PHY_TYPE_LOW_2500BASE_KX:
851 		return IFM_2500_KX;
852 	case ICE_PHY_TYPE_LOW_5GBASE_T:
853 		return IFM_5000_T;
854 	case ICE_PHY_TYPE_LOW_5GBASE_KR:
855 		return IFM_5000_KR;
856 	case ICE_PHY_TYPE_LOW_10GBASE_T:
857 		return IFM_10G_T;
858 	case ICE_PHY_TYPE_LOW_10G_SFI_DA:
859 		return IFM_10G_TWINAX;
860 	case ICE_PHY_TYPE_LOW_10GBASE_SR:
861 		return IFM_10G_SR;
862 	case ICE_PHY_TYPE_LOW_10GBASE_LR:
863 		return IFM_10G_LR;
864 	case ICE_PHY_TYPE_LOW_10GBASE_KR_CR1:
865 		return IFM_10G_KR;
866 	case ICE_PHY_TYPE_LOW_10G_SFI_AOC_ACC:
867 		return IFM_10G_AOC;
868 	case ICE_PHY_TYPE_LOW_10G_SFI_C2C:
869 		return IFM_10G_SFI;
870 	case ICE_PHY_TYPE_LOW_25GBASE_T:
871 		return IFM_25G_T;
872 	case ICE_PHY_TYPE_LOW_25GBASE_CR:
873 		return IFM_25G_CR;
874 	case ICE_PHY_TYPE_LOW_25GBASE_CR_S:
875 		return IFM_25G_CR_S;
876 	case ICE_PHY_TYPE_LOW_25GBASE_CR1:
877 		return IFM_25G_CR1;
878 	case ICE_PHY_TYPE_LOW_25GBASE_SR:
879 		return IFM_25G_SR;
880 	case ICE_PHY_TYPE_LOW_25GBASE_LR:
881 		return IFM_25G_LR;
882 	case ICE_PHY_TYPE_LOW_25GBASE_KR:
883 		return IFM_25G_KR;
884 	case ICE_PHY_TYPE_LOW_25GBASE_KR_S:
885 		return IFM_25G_KR_S;
886 	case ICE_PHY_TYPE_LOW_25GBASE_KR1:
887 		return IFM_25G_KR1;
888 	case ICE_PHY_TYPE_LOW_25G_AUI_AOC_ACC:
889 		return IFM_25G_AOC;
890 	case ICE_PHY_TYPE_LOW_25G_AUI_C2C:
891 		return IFM_25G_AUI;
892 	case ICE_PHY_TYPE_LOW_40GBASE_CR4:
893 		return IFM_40G_CR4;
894 	case ICE_PHY_TYPE_LOW_40GBASE_SR4:
895 		return IFM_40G_SR4;
896 	case ICE_PHY_TYPE_LOW_40GBASE_LR4:
897 		return IFM_40G_LR4;
898 	case ICE_PHY_TYPE_LOW_40GBASE_KR4:
899 		return IFM_40G_KR4;
900 	case ICE_PHY_TYPE_LOW_40G_XLAUI_AOC_ACC:
901 		return IFM_40G_XLAUI_AC;
902 	case ICE_PHY_TYPE_LOW_40G_XLAUI:
903 		return IFM_40G_XLAUI;
904 	case ICE_PHY_TYPE_LOW_50GBASE_CR2:
905 		return IFM_50G_CR2;
906 	case ICE_PHY_TYPE_LOW_50GBASE_SR2:
907 		return IFM_50G_SR2;
908 	case ICE_PHY_TYPE_LOW_50GBASE_LR2:
909 		return IFM_50G_LR2;
910 	case ICE_PHY_TYPE_LOW_50GBASE_KR2:
911 		return IFM_50G_KR2;
912 	case ICE_PHY_TYPE_LOW_50G_LAUI2_AOC_ACC:
913 		return IFM_50G_LAUI2_AC;
914 	case ICE_PHY_TYPE_LOW_50G_LAUI2:
915 		return IFM_50G_LAUI2;
916 	case ICE_PHY_TYPE_LOW_50G_AUI2_AOC_ACC:
917 		return IFM_50G_AUI2_AC;
918 	case ICE_PHY_TYPE_LOW_50G_AUI2:
919 		return IFM_50G_AUI2;
920 	case ICE_PHY_TYPE_LOW_50GBASE_CP:
921 		return IFM_50G_CP;
922 	case ICE_PHY_TYPE_LOW_50GBASE_SR:
923 		return IFM_50G_SR;
924 	case ICE_PHY_TYPE_LOW_50GBASE_FR:
925 		return IFM_50G_FR;
926 	case ICE_PHY_TYPE_LOW_50GBASE_LR:
927 		return IFM_50G_LR;
928 	case ICE_PHY_TYPE_LOW_50GBASE_KR_PAM4:
929 		return IFM_50G_KR_PAM4;
930 	case ICE_PHY_TYPE_LOW_50G_AUI1_AOC_ACC:
931 		return IFM_50G_AUI1_AC;
932 	case ICE_PHY_TYPE_LOW_50G_AUI1:
933 		return IFM_50G_AUI1;
934 	case ICE_PHY_TYPE_LOW_100GBASE_CR4:
935 		return IFM_100G_CR4;
936 	case ICE_PHY_TYPE_LOW_100GBASE_SR4:
937 		return IFM_100G_SR4;
938 	case ICE_PHY_TYPE_LOW_100GBASE_LR4:
939 		return IFM_100G_LR4;
940 	case ICE_PHY_TYPE_LOW_100GBASE_KR4:
941 		return IFM_100G_KR4;
942 	case ICE_PHY_TYPE_LOW_100G_CAUI4_AOC_ACC:
943 		return IFM_100G_CAUI4_AC;
944 	case ICE_PHY_TYPE_LOW_100G_CAUI4:
945 		return IFM_100G_CAUI4;
946 	case ICE_PHY_TYPE_LOW_100G_AUI4_AOC_ACC:
947 		return IFM_100G_AUI4_AC;
948 	case ICE_PHY_TYPE_LOW_100G_AUI4:
949 		return IFM_100G_AUI4;
950 	case ICE_PHY_TYPE_LOW_100GBASE_CR_PAM4:
951 		return IFM_100G_CR_PAM4;
952 	case ICE_PHY_TYPE_LOW_100GBASE_KR_PAM4:
953 		return IFM_100G_KR_PAM4;
954 	case ICE_PHY_TYPE_LOW_100GBASE_CP2:
955 		return IFM_100G_CP2;
956 	case ICE_PHY_TYPE_LOW_100GBASE_SR2:
957 		return IFM_100G_SR2;
958 	case ICE_PHY_TYPE_LOW_100GBASE_DR:
959 		return IFM_100G_DR;
960 	default:
961 		return IFM_UNKNOWN;
962 	}
963 }
964 
965 /**
966  * ice_get_phy_type_high - Get media associated with phy_type_high
967  * @phy_type_high: the upper 64bits of phy_type from the AdminQ
968  *
969  * Given the upper 64bits of the phy_type from the hardware, return the
970  * ifm_active bit associated. Return IFM_UNKNOWN on an unknown value. Note
971  * that only one of ice_get_phy_type_low or ice_get_phy_type_high should be
972  * called. If phy_type_high is zero, call ice_get_phy_type_low.
973  */
974 int
975 ice_get_phy_type_high(uint64_t phy_type_high)
976 {
977 	switch (phy_type_high) {
978 	case ICE_PHY_TYPE_HIGH_100GBASE_KR2_PAM4:
979 		return IFM_100G_KR2_PAM4;
980 	case ICE_PHY_TYPE_HIGH_100G_CAUI2_AOC_ACC:
981 		return IFM_100G_CAUI2_AC;
982 	case ICE_PHY_TYPE_HIGH_100G_CAUI2:
983 		return IFM_100G_CAUI2;
984 	case ICE_PHY_TYPE_HIGH_100G_AUI2_AOC_ACC:
985 		return IFM_100G_AUI2_AC;
986 	case ICE_PHY_TYPE_HIGH_100G_AUI2:
987 		return IFM_100G_AUI2;
988 	default:
989 		return IFM_UNKNOWN;
990 	}
991 }
992 
993 /**
994  * ice_phy_types_to_max_rate - Returns port's max supported baudrate
995  * @pi: port info struct
996  *
997  * ice_aq_get_phy_caps() w/ ICE_AQC_REPORT_TOPO_CAP_MEDIA parameter needs
998  * to have been called before this function for it to work.
999  */
1000 static uint64_t
1001 ice_phy_types_to_max_rate(struct ice_port_info *pi)
1002 {
1003 	uint64_t phy_low = pi->phy.phy_type_low;
1004 	uint64_t phy_high = pi->phy.phy_type_high;
1005 	uint64_t max_rate = 0;
1006 	int bit;
1007 
1008 	/*
1009 	 * These are based on the indices used in the BIT() macros for
1010 	 * ICE_PHY_TYPE_LOW_*
1011 	 */
1012 	static const uint64_t phy_rates[] = {
1013 	    IF_Mbps(100),
1014 	    IF_Mbps(100),
1015 	    IF_Gbps(1ULL),
1016 	    IF_Gbps(1ULL),
1017 	    IF_Gbps(1ULL),
1018 	    IF_Gbps(1ULL),
1019 	    IF_Gbps(1ULL),
1020 	    IF_Mbps(2500ULL),
1021 	    IF_Mbps(2500ULL),
1022 	    IF_Mbps(2500ULL),
1023 	    IF_Gbps(5ULL),
1024 	    IF_Gbps(5ULL),
1025 	    IF_Gbps(10ULL),
1026 	    IF_Gbps(10ULL),
1027 	    IF_Gbps(10ULL),
1028 	    IF_Gbps(10ULL),
1029 	    IF_Gbps(10ULL),
1030 	    IF_Gbps(10ULL),
1031 	    IF_Gbps(10ULL),
1032 	    IF_Gbps(25ULL),
1033 	    IF_Gbps(25ULL),
1034 	    IF_Gbps(25ULL),
1035 	    IF_Gbps(25ULL),
1036 	    IF_Gbps(25ULL),
1037 	    IF_Gbps(25ULL),
1038 	    IF_Gbps(25ULL),
1039 	    IF_Gbps(25ULL),
1040 	    IF_Gbps(25ULL),
1041 	    IF_Gbps(25ULL),
1042 	    IF_Gbps(25ULL),
1043 	    IF_Gbps(40ULL),
1044 	    IF_Gbps(40ULL),
1045 	    IF_Gbps(40ULL),
1046 	    IF_Gbps(40ULL),
1047 	    IF_Gbps(40ULL),
1048 	    IF_Gbps(40ULL),
1049 	    IF_Gbps(50ULL),
1050 	    IF_Gbps(50ULL),
1051 	    IF_Gbps(50ULL),
1052 	    IF_Gbps(50ULL),
1053 	    IF_Gbps(50ULL),
1054 	    IF_Gbps(50ULL),
1055 	    IF_Gbps(50ULL),
1056 	    IF_Gbps(50ULL),
1057 	    IF_Gbps(50ULL),
1058 	    IF_Gbps(50ULL),
1059 	    IF_Gbps(50ULL),
1060 	    IF_Gbps(50ULL),
1061 	    IF_Gbps(50ULL),
1062 	    IF_Gbps(50ULL),
1063 	    IF_Gbps(50ULL),
1064 	    IF_Gbps(100ULL),
1065 	    IF_Gbps(100ULL),
1066 	    IF_Gbps(100ULL),
1067 	    IF_Gbps(100ULL),
1068 	    IF_Gbps(100ULL),
1069 	    IF_Gbps(100ULL),
1070 	    IF_Gbps(100ULL),
1071 	    IF_Gbps(100ULL),
1072 	    IF_Gbps(100ULL),
1073 	    IF_Gbps(100ULL),
1074 	    IF_Gbps(100ULL),
1075 	    IF_Gbps(100ULL),
1076 	    IF_Gbps(100ULL),
1077 	    /* These rates are for ICE_PHY_TYPE_HIGH_* */
1078 	    IF_Gbps(100ULL),
1079 	    IF_Gbps(100ULL),
1080 	    IF_Gbps(100ULL),
1081 	    IF_Gbps(100ULL),
1082 	    IF_Gbps(100ULL)
1083 	};
1084 
1085 	/* coverity[address_of] */
1086 	for_each_set_bit(bit, &phy_high, 64)
1087 		if ((bit + 64) < (int)ARRAY_SIZE(phy_rates))
1088 			max_rate = uqmax(max_rate, phy_rates[(bit + 64)]);
1089 
1090 	/* coverity[address_of] */
1091 	for_each_set_bit(bit, &phy_low, 64)
1092 		max_rate = uqmax(max_rate, phy_rates[bit]);
1093 
1094 	return (max_rate);
1095 }
1096 
1097 /* The if_media type is split over the original 5 bit media variant field,
1098  * along with extended types using up extra bits in the options section.
1099  * We want to convert this split number into a bitmap index, so we reverse the
1100  * calculation of IFM_X here.
1101  */
1102 #define IFM_IDX(x) (((x) & IFM_TMASK) | \
1103 		    (((x) & IFM_ETH_XTYPE) >> IFM_ETH_XSHIFT))
1104 
1105 /**
1106  * ice_add_media_types - Add supported media types to the media structure
1107  * @sc: ice private softc structure
1108  * @media: ifmedia structure to setup
1109  *
1110  * Looks up the supported phy types, and initializes the various media types
1111  * available.
1112  *
1113  * @pre this function must be protected from being called while another thread
1114  * is accessing the ifmedia types.
1115  */
1116 enum ice_status
1117 ice_add_media_types(struct ice_softc *sc, struct ifmedia *media)
1118 {
1119 	struct ice_aqc_get_phy_caps_data pcaps = { 0 };
1120 	struct ice_port_info *pi = sc->hw.port_info;
1121 	enum ice_status status;
1122 	uint64_t phy_low, phy_high;
1123 	int bit;
1124 
1125 	ASSERT_CFG_LOCKED(sc);
1126 
1127 	/* the maximum possible media type index is 511. We probably don't
1128 	 * need most of this space, but this ensures future compatibility when
1129 	 * additional media types are used.
1130 	 */
1131 	ice_declare_bitmap(already_added, 511);
1132 
1133 	/* Remove all previous media types */
1134 	ifmedia_removeall(media);
1135 
1136 	status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_ACTIVE_CFG,
1137 				     &pcaps, NULL);
1138 	if (status != ICE_SUCCESS) {
1139 		device_printf(sc->dev,
1140 		    "%s: ice_aq_get_phy_caps (ACTIVE) failed; status %s, aq_err %s\n",
1141 		    __func__, ice_status_str(status),
1142 		    ice_aq_str(sc->hw.adminq.sq_last_status));
1143 		return (status);
1144 	}
1145 	phy_low = le64toh(pcaps.phy_type_low);
1146 	phy_high = le64toh(pcaps.phy_type_high);
1147 
1148 	/* make sure the added bitmap is zero'd */
1149 	memset(already_added, 0, sizeof(already_added));
1150 
1151 	/* coverity[address_of] */
1152 	for_each_set_bit(bit, &phy_low, 64) {
1153 		uint64_t type = BIT_ULL(bit);
1154 		int ostype;
1155 
1156 		/* get the OS media type */
1157 		ostype = ice_get_phy_type_low(type);
1158 
1159 		/* don't bother adding the unknown type */
1160 		if (ostype == IFM_UNKNOWN)
1161 			continue;
1162 
1163 		/* only add each media type to the list once */
1164 		if (ice_is_bit_set(already_added, IFM_IDX(ostype)))
1165 			continue;
1166 
1167 		ifmedia_add(media, IFM_ETHER | ostype, 0, NULL);
1168 		ice_set_bit(IFM_IDX(ostype), already_added);
1169 	}
1170 
1171 	/* coverity[address_of] */
1172 	for_each_set_bit(bit, &phy_high, 64) {
1173 		uint64_t type = BIT_ULL(bit);
1174 		int ostype;
1175 
1176 		/* get the OS media type */
1177 		ostype = ice_get_phy_type_high(type);
1178 
1179 		/* don't bother adding the unknown type */
1180 		if (ostype == IFM_UNKNOWN)
1181 			continue;
1182 
1183 		/* only add each media type to the list once */
1184 		if (ice_is_bit_set(already_added, IFM_IDX(ostype)))
1185 			continue;
1186 
1187 		ifmedia_add(media, IFM_ETHER | ostype, 0, NULL);
1188 		ice_set_bit(IFM_IDX(ostype), already_added);
1189 	}
1190 
1191 	/* Use autoselect media by default */
1192 	ifmedia_add(media, IFM_ETHER | IFM_AUTO, 0, NULL);
1193 	ifmedia_set(media, IFM_ETHER | IFM_AUTO);
1194 
1195 	return (ICE_SUCCESS);
1196 }
1197 
1198 /**
1199  * ice_configure_rxq_interrupts - Configure HW Rx queues for MSI-X interrupts
1200  * @vsi: the VSI to configure
1201  *
1202  * Called when setting up MSI-X interrupts to configure the Rx hardware queues.
1203  */
1204 void
1205 ice_configure_rxq_interrupts(struct ice_vsi *vsi)
1206 {
1207 	struct ice_hw *hw = &vsi->sc->hw;
1208 	int i;
1209 
1210 	for (i = 0; i < vsi->num_rx_queues; i++) {
1211 		struct ice_rx_queue *rxq = &vsi->rx_queues[i];
1212 		u32 val;
1213 
1214 		val = (QINT_RQCTL_CAUSE_ENA_M |
1215 		       (ICE_RX_ITR << QINT_RQCTL_ITR_INDX_S) |
1216 		       (rxq->irqv->me << QINT_RQCTL_MSIX_INDX_S));
1217 		wr32(hw, QINT_RQCTL(vsi->rx_qmap[rxq->me]), val);
1218 	}
1219 
1220 	ice_flush(hw);
1221 }
1222 
1223 /**
1224  * ice_configure_txq_interrupts - Configure HW Tx queues for MSI-X interrupts
1225  * @vsi: the VSI to configure
1226  *
1227  * Called when setting up MSI-X interrupts to configure the Tx hardware queues.
1228  */
1229 void
1230 ice_configure_txq_interrupts(struct ice_vsi *vsi)
1231 {
1232 	struct ice_hw *hw = &vsi->sc->hw;
1233 	int i;
1234 
1235 	for (i = 0; i < vsi->num_tx_queues; i++) {
1236 		struct ice_tx_queue *txq = &vsi->tx_queues[i];
1237 		u32 val;
1238 
1239 		val = (QINT_TQCTL_CAUSE_ENA_M |
1240 		       (ICE_TX_ITR << QINT_TQCTL_ITR_INDX_S) |
1241 		       (txq->irqv->me << QINT_TQCTL_MSIX_INDX_S));
1242 		wr32(hw, QINT_TQCTL(vsi->tx_qmap[txq->me]), val);
1243 	}
1244 
1245 	ice_flush(hw);
1246 }
1247 
1248 /**
1249  * ice_flush_rxq_interrupts - Unconfigure Hw Rx queues MSI-X interrupt cause
1250  * @vsi: the VSI to configure
1251  *
1252  * Unset the CAUSE_ENA flag of the TQCTL register for each queue, then trigger
1253  * a software interrupt on that cause. This is required as part of the Rx
1254  * queue disable logic to dissociate the Rx queue from the interrupt.
1255  *
1256  * Note: this function must be called prior to disabling Rx queues with
1257  * ice_control_rx_queues, otherwise the Rx queue may not be disabled properly.
1258  */
1259 void
1260 ice_flush_rxq_interrupts(struct ice_vsi *vsi)
1261 {
1262 	struct ice_hw *hw = &vsi->sc->hw;
1263 	int i;
1264 
1265 	for (i = 0; i < vsi->num_rx_queues; i++) {
1266 		struct ice_rx_queue *rxq = &vsi->rx_queues[i];
1267 		u32 reg, val;
1268 
1269 		/* Clear the CAUSE_ENA flag */
1270 		reg = vsi->rx_qmap[rxq->me];
1271 		val = rd32(hw, QINT_RQCTL(reg));
1272 		val &= ~QINT_RQCTL_CAUSE_ENA_M;
1273 		wr32(hw, QINT_RQCTL(reg), val);
1274 
1275 		ice_flush(hw);
1276 
1277 		/* Trigger a software interrupt to complete interrupt
1278 		 * dissociation.
1279 		 */
1280 		wr32(hw, GLINT_DYN_CTL(rxq->irqv->me),
1281 		     GLINT_DYN_CTL_SWINT_TRIG_M | GLINT_DYN_CTL_INTENA_MSK_M);
1282 	}
1283 }
1284 
1285 /**
1286  * ice_flush_txq_interrupts - Unconfigure Hw Tx queues MSI-X interrupt cause
1287  * @vsi: the VSI to configure
1288  *
1289  * Unset the CAUSE_ENA flag of the TQCTL register for each queue, then trigger
1290  * a software interrupt on that cause. This is required as part of the Tx
1291  * queue disable logic to dissociate the Tx queue from the interrupt.
1292  *
1293  * Note: this function must be called prior to ice_vsi_disable_tx, otherwise
1294  * the Tx queue disable may not complete properly.
1295  */
1296 void
1297 ice_flush_txq_interrupts(struct ice_vsi *vsi)
1298 {
1299 	struct ice_hw *hw = &vsi->sc->hw;
1300 	int i;
1301 
1302 	for (i = 0; i < vsi->num_tx_queues; i++) {
1303 		struct ice_tx_queue *txq = &vsi->tx_queues[i];
1304 		u32 reg, val;
1305 
1306 		/* Clear the CAUSE_ENA flag */
1307 		reg = vsi->tx_qmap[txq->me];
1308 		val = rd32(hw, QINT_TQCTL(reg));
1309 		val &= ~QINT_TQCTL_CAUSE_ENA_M;
1310 		wr32(hw, QINT_TQCTL(reg), val);
1311 
1312 		ice_flush(hw);
1313 
1314 		/* Trigger a software interrupt to complete interrupt
1315 		 * dissociation.
1316 		 */
1317 		wr32(hw, GLINT_DYN_CTL(txq->irqv->me),
1318 		     GLINT_DYN_CTL_SWINT_TRIG_M | GLINT_DYN_CTL_INTENA_MSK_M);
1319 	}
1320 }
1321 
1322 /**
1323  * ice_configure_rx_itr - Configure the Rx ITR settings for this VSI
1324  * @vsi: the VSI to configure
1325  *
1326  * Program the hardware ITR registers with the settings for this VSI.
1327  */
1328 void
1329 ice_configure_rx_itr(struct ice_vsi *vsi)
1330 {
1331 	struct ice_hw *hw = &vsi->sc->hw;
1332 	int i;
1333 
1334 	/* TODO: Handle per-queue/per-vector ITR? */
1335 
1336 	for (i = 0; i < vsi->num_rx_queues; i++) {
1337 		struct ice_rx_queue *rxq = &vsi->rx_queues[i];
1338 
1339 		wr32(hw, GLINT_ITR(ICE_RX_ITR, rxq->irqv->me),
1340 		     ice_itr_to_reg(hw, vsi->rx_itr));
1341 	}
1342 
1343 	ice_flush(hw);
1344 }
1345 
1346 /**
1347  * ice_configure_tx_itr - Configure the Tx ITR settings for this VSI
1348  * @vsi: the VSI to configure
1349  *
1350  * Program the hardware ITR registers with the settings for this VSI.
1351  */
1352 void
1353 ice_configure_tx_itr(struct ice_vsi *vsi)
1354 {
1355 	struct ice_hw *hw = &vsi->sc->hw;
1356 	int i;
1357 
1358 	/* TODO: Handle per-queue/per-vector ITR? */
1359 
1360 	for (i = 0; i < vsi->num_tx_queues; i++) {
1361 		struct ice_tx_queue *txq = &vsi->tx_queues[i];
1362 
1363 		wr32(hw, GLINT_ITR(ICE_TX_ITR, txq->irqv->me),
1364 		     ice_itr_to_reg(hw, vsi->tx_itr));
1365 	}
1366 
1367 	ice_flush(hw);
1368 }
1369 
1370 /**
1371  * ice_setup_tx_ctx - Setup an ice_tlan_ctx structure for a queue
1372  * @txq: the Tx queue to configure
1373  * @tlan_ctx: the Tx LAN queue context structure to initialize
1374  * @pf_q: real queue number
1375  */
1376 static int
1377 ice_setup_tx_ctx(struct ice_tx_queue *txq, struct ice_tlan_ctx *tlan_ctx, u16 pf_q)
1378 {
1379 	struct ice_vsi *vsi = txq->vsi;
1380 	struct ice_softc *sc = vsi->sc;
1381 	struct ice_hw *hw = &sc->hw;
1382 
1383 	tlan_ctx->port_num = hw->port_info->lport;
1384 
1385 	/* number of descriptors in the queue */
1386 	tlan_ctx->qlen = txq->desc_count;
1387 
1388 	/* set the transmit queue base address, defined in 128 byte units */
1389 	tlan_ctx->base = txq->tx_paddr >> 7;
1390 
1391 	tlan_ctx->pf_num = hw->pf_id;
1392 
1393 	/* For now, we only have code supporting PF VSIs */
1394 	switch (vsi->type) {
1395 	case ICE_VSI_PF:
1396 		tlan_ctx->vmvf_type = ICE_TLAN_CTX_VMVF_TYPE_PF;
1397 		break;
1398 	default:
1399 		return (ENODEV);
1400 	}
1401 
1402 	tlan_ctx->src_vsi = ice_get_hw_vsi_num(hw, vsi->idx);
1403 
1404 	/* Enable TSO */
1405 	tlan_ctx->tso_ena = 1;
1406 	tlan_ctx->internal_usage_flag = 1;
1407 
1408 	tlan_ctx->tso_qnum = pf_q;
1409 
1410 	/*
1411 	 * Stick with the older legacy Tx queue interface, instead of the new
1412 	 * advanced queue interface.
1413 	 */
1414 	tlan_ctx->legacy_int = 1;
1415 
1416 	/* Descriptor WB mode */
1417 	tlan_ctx->wb_mode = 0;
1418 
1419 	return (0);
1420 }
1421 
1422 /**
1423  * ice_cfg_vsi_for_tx - Configure the hardware for Tx
1424  * @vsi: the VSI to configure
1425  *
1426  * Configure the device Tx queues through firmware AdminQ commands. After
1427  * this, Tx queues will be ready for transmit.
1428  */
1429 int
1430 ice_cfg_vsi_for_tx(struct ice_vsi *vsi)
1431 {
1432 	struct ice_aqc_add_tx_qgrp *qg;
1433 	struct ice_hw *hw = &vsi->sc->hw;
1434 	device_t dev = vsi->sc->dev;
1435 	enum ice_status status;
1436 	int i;
1437 	int err = 0;
1438 	u16 qg_size, pf_q;
1439 
1440 	qg_size = ice_struct_size(qg, txqs, 1);
1441 	qg = (struct ice_aqc_add_tx_qgrp *)malloc(qg_size, M_ICE, M_NOWAIT|M_ZERO);
1442 	if (!qg)
1443 		return (ENOMEM);
1444 
1445 	qg->num_txqs = 1;
1446 
1447 	for (i = 0; i < vsi->num_tx_queues; i++) {
1448 		struct ice_tlan_ctx tlan_ctx = { 0 };
1449 		struct ice_tx_queue *txq = &vsi->tx_queues[i];
1450 
1451 		pf_q = vsi->tx_qmap[txq->me];
1452 		qg->txqs[0].txq_id = htole16(pf_q);
1453 
1454 		err = ice_setup_tx_ctx(txq, &tlan_ctx, pf_q);
1455 		if (err)
1456 			goto free_txqg;
1457 
1458 		ice_set_ctx(hw, (u8 *)&tlan_ctx, qg->txqs[0].txq_ctx,
1459 			    ice_tlan_ctx_info);
1460 
1461 		status = ice_ena_vsi_txq(hw->port_info, vsi->idx, txq->tc,
1462 					 txq->q_handle, 1, qg, qg_size, NULL);
1463 		if (status) {
1464 			device_printf(dev,
1465 				      "Failed to set LAN Tx queue %d (TC %d, handle %d) context, err %s aq_err %s\n",
1466 				      i, txq->tc, txq->q_handle,
1467 				      ice_status_str(status),
1468 				      ice_aq_str(hw->adminq.sq_last_status));
1469 			err = ENODEV;
1470 			goto free_txqg;
1471 		}
1472 
1473 		/* Keep track of the Tx queue TEID */
1474 		if (pf_q == le16toh(qg->txqs[0].txq_id))
1475 			txq->q_teid = le32toh(qg->txqs[0].q_teid);
1476 	}
1477 
1478 free_txqg:
1479 	free(qg, M_ICE);
1480 
1481 	return (err);
1482 }
1483 
1484 /**
1485  * ice_setup_rx_ctx - Setup an Rx context structure for a receive queue
1486  * @rxq: the receive queue to program
1487  *
1488  * Setup an Rx queue context structure and program it into the hardware
1489  * registers. This is a necessary step for enabling the Rx queue.
1490  *
1491  * @pre the VSI associated with this queue must have initialized mbuf_sz
1492  */
1493 static int
1494 ice_setup_rx_ctx(struct ice_rx_queue *rxq)
1495 {
1496 	struct ice_rlan_ctx rlan_ctx = {0};
1497 	struct ice_vsi *vsi = rxq->vsi;
1498 	struct ice_softc *sc = vsi->sc;
1499 	struct ice_hw *hw = &sc->hw;
1500 	enum ice_status status;
1501 	u32 rxdid = ICE_RXDID_FLEX_NIC;
1502 	u32 regval;
1503 	u16 pf_q;
1504 
1505 	pf_q = vsi->rx_qmap[rxq->me];
1506 
1507 	/* set the receive queue base address, defined in 128 byte units */
1508 	rlan_ctx.base = rxq->rx_paddr >> 7;
1509 
1510 	rlan_ctx.qlen = rxq->desc_count;
1511 
1512 	rlan_ctx.dbuf = vsi->mbuf_sz >> ICE_RLAN_CTX_DBUF_S;
1513 
1514 	/* use 32 byte descriptors */
1515 	rlan_ctx.dsize = 1;
1516 
1517 	/* Strip the Ethernet CRC bytes before the packet is posted to the
1518 	 * host memory.
1519 	 */
1520 	rlan_ctx.crcstrip = 1;
1521 
1522 	rlan_ctx.l2tsel = 1;
1523 
1524 	/* don't do header splitting */
1525 	rlan_ctx.dtype = ICE_RX_DTYPE_NO_SPLIT;
1526 	rlan_ctx.hsplit_0 = ICE_RLAN_RX_HSPLIT_0_NO_SPLIT;
1527 	rlan_ctx.hsplit_1 = ICE_RLAN_RX_HSPLIT_1_NO_SPLIT;
1528 
1529 	/* strip VLAN from inner headers */
1530 	rlan_ctx.showiv = 1;
1531 
1532 	rlan_ctx.rxmax = min(vsi->max_frame_size,
1533 			     ICE_MAX_RX_SEGS * vsi->mbuf_sz);
1534 
1535 	rlan_ctx.lrxqthresh = 1;
1536 
1537 	if (vsi->type != ICE_VSI_VF) {
1538 		regval = rd32(hw, QRXFLXP_CNTXT(pf_q));
1539 		regval &= ~QRXFLXP_CNTXT_RXDID_IDX_M;
1540 		regval |= (rxdid << QRXFLXP_CNTXT_RXDID_IDX_S) &
1541 			QRXFLXP_CNTXT_RXDID_IDX_M;
1542 
1543 		regval &= ~QRXFLXP_CNTXT_RXDID_PRIO_M;
1544 		regval |= (0x03 << QRXFLXP_CNTXT_RXDID_PRIO_S) &
1545 			QRXFLXP_CNTXT_RXDID_PRIO_M;
1546 
1547 		wr32(hw, QRXFLXP_CNTXT(pf_q), regval);
1548 	}
1549 
1550 	status = ice_write_rxq_ctx(hw, &rlan_ctx, pf_q);
1551 	if (status) {
1552 		device_printf(sc->dev,
1553 			      "Failed to set LAN Rx queue context, err %s aq_err %s\n",
1554 			      ice_status_str(status), ice_aq_str(hw->adminq.sq_last_status));
1555 		return (EIO);
1556 	}
1557 
1558 	wr32(hw, rxq->tail, 0);
1559 
1560 	return 0;
1561 }
1562 
1563 /**
1564  * ice_cfg_vsi_for_rx - Configure the hardware for Rx
1565  * @vsi: the VSI to configure
1566  *
1567  * Prepare an Rx context descriptor and configure the device to receive
1568  * traffic.
1569  *
1570  * @pre the VSI must have initialized mbuf_sz
1571  */
1572 int
1573 ice_cfg_vsi_for_rx(struct ice_vsi *vsi)
1574 {
1575 	int i, err;
1576 
1577 	for (i = 0; i < vsi->num_rx_queues; i++) {
1578 		MPASS(vsi->mbuf_sz > 0);
1579 		err = ice_setup_rx_ctx(&vsi->rx_queues[i]);
1580 		if (err)
1581 			return err;
1582 	}
1583 
1584 	return (0);
1585 }
1586 
1587 /**
1588  * ice_is_rxq_ready - Check if an Rx queue is ready
1589  * @hw: ice hw structure
1590  * @pf_q: absolute PF queue index to check
1591  * @reg: on successful return, contains qrx_ctrl contents
1592  *
1593  * Reads the QRX_CTRL register and verifies if the queue is in a consistent
1594  * state. That is, QENA_REQ matches QENA_STAT. Used to check before making
1595  * a request to change the queue, as well as to verify the request has
1596  * finished. The queue should change status within a few microseconds, so we
1597  * use a small delay while polling the register.
1598  *
1599  * Returns an error code if the queue does not update after a few retries.
1600  */
1601 static int
1602 ice_is_rxq_ready(struct ice_hw *hw, int pf_q, u32 *reg)
1603 {
1604 	u32 qrx_ctrl, qena_req, qena_stat;
1605 	int i;
1606 
1607 	for (i = 0; i < ICE_Q_WAIT_RETRY_LIMIT; i++) {
1608 		qrx_ctrl = rd32(hw, QRX_CTRL(pf_q));
1609 		qena_req = (qrx_ctrl >> QRX_CTRL_QENA_REQ_S) & 1;
1610 		qena_stat = (qrx_ctrl >> QRX_CTRL_QENA_STAT_S) & 1;
1611 
1612 		/* if the request and status bits equal, then the queue is
1613 		 * fully disabled or enabled.
1614 		 */
1615 		if (qena_req == qena_stat) {
1616 			*reg = qrx_ctrl;
1617 			return (0);
1618 		}
1619 
1620 		/* wait a few microseconds before we check again */
1621 		DELAY(10);
1622 	}
1623 
1624 	return (ETIMEDOUT);
1625 }
1626 
1627 /**
1628  * ice_control_rx_queues - Configure hardware to start or stop the Rx queues
1629  * @vsi: VSI to enable/disable queues
1630  * @enable: true to enable queues, false to disable
1631  *
1632  * Control the Rx queues through the QRX_CTRL register, enabling or disabling
1633  * them. Wait for the appropriate time to ensure that the queues have actually
1634  * reached the expected state.
1635  */
1636 int
1637 ice_control_rx_queues(struct ice_vsi *vsi, bool enable)
1638 {
1639 	struct ice_hw *hw = &vsi->sc->hw;
1640 	device_t dev = vsi->sc->dev;
1641 	u32 qrx_ctrl = 0;
1642 	int i, err;
1643 
1644 	/* TODO: amortize waits by changing all queues up front and then
1645 	 * checking their status afterwards. This will become more necessary
1646 	 * when we have a large number of queues.
1647 	 */
1648 	for (i = 0; i < vsi->num_rx_queues; i++) {
1649 		struct ice_rx_queue *rxq = &vsi->rx_queues[i];
1650 		int pf_q = vsi->rx_qmap[rxq->me];
1651 
1652 		err = ice_is_rxq_ready(hw, pf_q, &qrx_ctrl);
1653 		if (err) {
1654 			device_printf(dev,
1655 				      "Rx queue %d is not ready\n",
1656 				      pf_q);
1657 			return err;
1658 		}
1659 
1660 		/* Skip if the queue is already in correct state */
1661 		if (enable == !!(qrx_ctrl & QRX_CTRL_QENA_STAT_M))
1662 			continue;
1663 
1664 		if (enable)
1665 			qrx_ctrl |= QRX_CTRL_QENA_REQ_M;
1666 		else
1667 			qrx_ctrl &= ~QRX_CTRL_QENA_REQ_M;
1668 		wr32(hw, QRX_CTRL(pf_q), qrx_ctrl);
1669 
1670 		/* wait for the queue to finalize the request */
1671 		err = ice_is_rxq_ready(hw, pf_q, &qrx_ctrl);
1672 		if (err) {
1673 			device_printf(dev,
1674 				      "Rx queue %d %sable timeout\n",
1675 				      pf_q, (enable ? "en" : "dis"));
1676 			return err;
1677 		}
1678 
1679 		/* this should never happen */
1680 		if (enable != !!(qrx_ctrl & QRX_CTRL_QENA_STAT_M)) {
1681 			device_printf(dev,
1682 				      "Rx queue %d invalid state\n",
1683 				      pf_q);
1684 			return (EDOOFUS);
1685 		}
1686 	}
1687 
1688 	return (0);
1689 }
1690 
1691 /**
1692  * ice_add_mac_to_list - Add MAC filter to a MAC filter list
1693  * @vsi: the VSI to forward to
1694  * @list: list which contains MAC filter entries
1695  * @addr: the MAC address to be added
1696  * @action: filter action to perform on match
1697  *
1698  * Adds a MAC address filter to the list which will be forwarded to firmware
1699  * to add a series of MAC address filters.
1700  *
1701  * Returns 0 on success, and an error code on failure.
1702  *
1703  */
1704 static int
1705 ice_add_mac_to_list(struct ice_vsi *vsi, struct ice_list_head *list,
1706 		    const u8 *addr, enum ice_sw_fwd_act_type action)
1707 {
1708 	struct ice_fltr_list_entry *entry;
1709 
1710 	entry = (__typeof(entry))malloc(sizeof(*entry), M_ICE, M_NOWAIT|M_ZERO);
1711 	if (!entry)
1712 		return (ENOMEM);
1713 
1714 	entry->fltr_info.flag = ICE_FLTR_TX;
1715 	entry->fltr_info.src_id = ICE_SRC_ID_VSI;
1716 	entry->fltr_info.lkup_type = ICE_SW_LKUP_MAC;
1717 	entry->fltr_info.fltr_act = action;
1718 	entry->fltr_info.vsi_handle = vsi->idx;
1719 	bcopy(addr, entry->fltr_info.l_data.mac.mac_addr, ETHER_ADDR_LEN);
1720 
1721 	LIST_ADD(&entry->list_entry, list);
1722 
1723 	return 0;
1724 }
1725 
1726 /**
1727  * ice_free_fltr_list - Free memory associated with a MAC address list
1728  * @list: the list to free
1729  *
1730  * Free the memory of each entry associated with the list.
1731  */
1732 static void
1733 ice_free_fltr_list(struct ice_list_head *list)
1734 {
1735 	struct ice_fltr_list_entry *e, *tmp;
1736 
1737 	LIST_FOR_EACH_ENTRY_SAFE(e, tmp, list, ice_fltr_list_entry, list_entry) {
1738 		LIST_DEL(&e->list_entry);
1739 		free(e, M_ICE);
1740 	}
1741 }
1742 
1743 /**
1744  * ice_add_vsi_mac_filter - Add a MAC address filter for a VSI
1745  * @vsi: the VSI to add the filter for
1746  * @addr: MAC address to add a filter for
1747  *
1748  * Add a MAC address filter for a given VSI. This is a wrapper around
1749  * ice_add_mac to simplify the interface. First, it only accepts a single
1750  * address, so we don't have to mess around with the list setup in other
1751  * functions. Second, it ignores the ICE_ERR_ALREADY_EXIST error, so that
1752  * callers don't need to worry about attempting to add the same filter twice.
1753  */
1754 int
1755 ice_add_vsi_mac_filter(struct ice_vsi *vsi, const u8 *addr)
1756 {
1757 	struct ice_list_head mac_addr_list;
1758 	struct ice_hw *hw = &vsi->sc->hw;
1759 	device_t dev = vsi->sc->dev;
1760 	enum ice_status status;
1761 	int err = 0;
1762 
1763 	INIT_LIST_HEAD(&mac_addr_list);
1764 
1765 	err = ice_add_mac_to_list(vsi, &mac_addr_list, addr, ICE_FWD_TO_VSI);
1766 	if (err)
1767 		goto free_mac_list;
1768 
1769 	status = ice_add_mac(hw, &mac_addr_list);
1770 	if (status == ICE_ERR_ALREADY_EXISTS) {
1771 		; /* Don't complain if we try to add a filter that already exists */
1772 	} else if (status) {
1773 		device_printf(dev,
1774 			      "Failed to add a filter for MAC %6D, err %s aq_err %s\n",
1775 			      addr, ":",
1776 			      ice_status_str(status),
1777 			      ice_aq_str(hw->adminq.sq_last_status));
1778 		err = (EIO);
1779 	}
1780 
1781 free_mac_list:
1782 	ice_free_fltr_list(&mac_addr_list);
1783 	return err;
1784 }
1785 
1786 /**
1787  * ice_cfg_pf_default_mac_filters - Setup default unicast and broadcast addrs
1788  * @sc: device softc structure
1789  *
1790  * Program the default unicast and broadcast filters for the PF VSI.
1791  */
1792 int
1793 ice_cfg_pf_default_mac_filters(struct ice_softc *sc)
1794 {
1795 	struct ice_vsi *vsi = &sc->pf_vsi;
1796 	struct ice_hw *hw = &sc->hw;
1797 	int err;
1798 
1799 	/* Add the LAN MAC address */
1800 	err = ice_add_vsi_mac_filter(vsi, hw->port_info->mac.lan_addr);
1801 	if (err)
1802 		return err;
1803 
1804 	/* Add the broadcast address */
1805 	err = ice_add_vsi_mac_filter(vsi, broadcastaddr);
1806 	if (err)
1807 		return err;
1808 
1809 	return (0);
1810 }
1811 
1812 /**
1813  * ice_remove_vsi_mac_filter - Remove a MAC address filter for a VSI
1814  * @vsi: the VSI to add the filter for
1815  * @addr: MAC address to remove a filter for
1816  *
1817  * Remove a MAC address filter from a given VSI. This is a wrapper around
1818  * ice_remove_mac to simplify the interface. First, it only accepts a single
1819  * address, so we don't have to mess around with the list setup in other
1820  * functions. Second, it ignores the ICE_ERR_DOES_NOT_EXIST error, so that
1821  * callers don't need to worry about attempting to remove filters which
1822  * haven't yet been added.
1823  */
1824 int
1825 ice_remove_vsi_mac_filter(struct ice_vsi *vsi, const u8 *addr)
1826 {
1827 	struct ice_list_head mac_addr_list;
1828 	struct ice_hw *hw = &vsi->sc->hw;
1829 	device_t dev = vsi->sc->dev;
1830 	enum ice_status status;
1831 	int err = 0;
1832 
1833 	INIT_LIST_HEAD(&mac_addr_list);
1834 
1835 	err = ice_add_mac_to_list(vsi, &mac_addr_list, addr, ICE_FWD_TO_VSI);
1836 	if (err)
1837 		goto free_mac_list;
1838 
1839 	status = ice_remove_mac(hw, &mac_addr_list);
1840 	if (status == ICE_ERR_DOES_NOT_EXIST) {
1841 		; /* Don't complain if we try to remove a filter that doesn't exist */
1842 	} else if (status) {
1843 		device_printf(dev,
1844 			      "Failed to remove a filter for MAC %6D, err %s aq_err %s\n",
1845 			      addr, ":",
1846 			      ice_status_str(status),
1847 			      ice_aq_str(hw->adminq.sq_last_status));
1848 		err = (EIO);
1849 	}
1850 
1851 free_mac_list:
1852 	ice_free_fltr_list(&mac_addr_list);
1853 	return err;
1854 }
1855 
1856 /**
1857  * ice_rm_pf_default_mac_filters - Remove default unicast and broadcast addrs
1858  * @sc: device softc structure
1859  *
1860  * Remove the default unicast and broadcast filters from the PF VSI.
1861  */
1862 int
1863 ice_rm_pf_default_mac_filters(struct ice_softc *sc)
1864 {
1865 	struct ice_vsi *vsi = &sc->pf_vsi;
1866 	struct ice_hw *hw = &sc->hw;
1867 	int err;
1868 
1869 	/* Remove the LAN MAC address */
1870 	err = ice_remove_vsi_mac_filter(vsi, hw->port_info->mac.lan_addr);
1871 	if (err)
1872 		return err;
1873 
1874 	/* Remove the broadcast address */
1875 	err = ice_remove_vsi_mac_filter(vsi, broadcastaddr);
1876 	if (err)
1877 		return (EIO);
1878 
1879 	return (0);
1880 }
1881 
1882 /**
1883  * ice_check_ctrlq_errors - Check for and report controlq errors
1884  * @sc: device private structure
1885  * @qname: name of the controlq
1886  * @cq: the controlq to check
1887  *
1888  * Check and report controlq errors. Currently all we do is report them to the
1889  * kernel message log, but we might want to improve this in the future, such
1890  * as to keep track of statistics.
1891  */
1892 static void
1893 ice_check_ctrlq_errors(struct ice_softc *sc, const char *qname,
1894 		       struct ice_ctl_q_info *cq)
1895 {
1896 	struct ice_hw *hw = &sc->hw;
1897 	u32 val;
1898 
1899 	/* Check for error indications. Note that all the controlqs use the
1900 	 * same register layout, so we use the PF_FW_AxQLEN defines only.
1901 	 */
1902 	val = rd32(hw, cq->rq.len);
1903 	if (val & (PF_FW_ARQLEN_ARQVFE_M | PF_FW_ARQLEN_ARQOVFL_M |
1904 		   PF_FW_ARQLEN_ARQCRIT_M)) {
1905 		if (val & PF_FW_ARQLEN_ARQVFE_M)
1906 			device_printf(sc->dev,
1907 				"%s Receive Queue VF Error detected\n", qname);
1908 		if (val & PF_FW_ARQLEN_ARQOVFL_M)
1909 			device_printf(sc->dev,
1910 				"%s Receive Queue Overflow Error detected\n",
1911 				qname);
1912 		if (val & PF_FW_ARQLEN_ARQCRIT_M)
1913 			device_printf(sc->dev,
1914 				"%s Receive Queue Critical Error detected\n",
1915 				qname);
1916 		val &= ~(PF_FW_ARQLEN_ARQVFE_M | PF_FW_ARQLEN_ARQOVFL_M |
1917 			 PF_FW_ARQLEN_ARQCRIT_M);
1918 		wr32(hw, cq->rq.len, val);
1919 	}
1920 
1921 	val = rd32(hw, cq->sq.len);
1922 	if (val & (PF_FW_ATQLEN_ATQVFE_M | PF_FW_ATQLEN_ATQOVFL_M |
1923 		   PF_FW_ATQLEN_ATQCRIT_M)) {
1924 		if (val & PF_FW_ATQLEN_ATQVFE_M)
1925 			device_printf(sc->dev,
1926 				"%s Send Queue VF Error detected\n", qname);
1927 		if (val & PF_FW_ATQLEN_ATQOVFL_M)
1928 			device_printf(sc->dev,
1929 				"%s Send Queue Overflow Error detected\n",
1930 				qname);
1931 		if (val & PF_FW_ATQLEN_ATQCRIT_M)
1932 			device_printf(sc->dev,
1933 				"%s Send Queue Critical Error detected\n",
1934 				qname);
1935 		val &= ~(PF_FW_ATQLEN_ATQVFE_M | PF_FW_ATQLEN_ATQOVFL_M |
1936 			 PF_FW_ATQLEN_ATQCRIT_M);
1937 		wr32(hw, cq->sq.len, val);
1938 	}
1939 }
1940 
1941 /**
1942  * ice_process_link_event - Process a link event indication from firmware
1943  * @sc: device softc structure
1944  * @e: the received event data
1945  *
1946  * Gets the current link status from hardware, and may print a message if an
1947  * unqualified is detected.
1948  */
1949 static void
1950 ice_process_link_event(struct ice_softc *sc,
1951 		       struct ice_rq_event_info __invariant_only *e)
1952 {
1953 	struct ice_port_info *pi = sc->hw.port_info;
1954 	struct ice_hw *hw = &sc->hw;
1955 	device_t dev = sc->dev;
1956 	enum ice_status status;
1957 
1958 	/* Sanity check that the data length matches */
1959 	MPASS(le16toh(e->desc.datalen) == sizeof(struct ice_aqc_get_link_status_data));
1960 
1961 	/*
1962 	 * Even though the adapter gets link status information inside the
1963 	 * event, it needs to send a Get Link Status AQ command in order
1964 	 * to re-enable link events.
1965 	 */
1966 	pi->phy.get_link_info = true;
1967 	ice_get_link_status(pi, &sc->link_up);
1968 
1969 	if (pi->phy.link_info.topo_media_conflict &
1970 	   (ICE_AQ_LINK_TOPO_CONFLICT | ICE_AQ_LINK_MEDIA_CONFLICT |
1971 	    ICE_AQ_LINK_TOPO_CORRUPT))
1972 		device_printf(dev,
1973 		    "Possible mis-configuration of the Ethernet port detected; please use the Intel (R) Ethernet Port Configuration Tool utility to address the issue.\n");
1974 
1975 	if ((pi->phy.link_info.link_info & ICE_AQ_MEDIA_AVAILABLE) &&
1976 	    !(pi->phy.link_info.link_info & ICE_AQ_LINK_UP)) {
1977 		if (!(pi->phy.link_info.an_info & ICE_AQ_QUALIFIED_MODULE))
1978 			device_printf(dev,
1979 			    "Link is disabled on this device because an unsupported module type was detected! Refer to the Intel (R) Ethernet Adapters and Devices User Guide for a list of supported modules.\n");
1980 		if (pi->phy.link_info.link_cfg_err & ICE_AQ_LINK_MODULE_POWER_UNSUPPORTED)
1981 			device_printf(dev,
1982 			    "The module's power requirements exceed the device's power supply. Cannot start link.\n");
1983 		if (pi->phy.link_info.link_cfg_err & ICE_AQ_LINK_INVAL_MAX_POWER_LIMIT)
1984 			device_printf(dev,
1985 			    "The installed module is incompatible with the device's NVM image. Cannot start link.\n");
1986 	}
1987 
1988 	if (!(pi->phy.link_info.link_info & ICE_AQ_MEDIA_AVAILABLE)) {
1989 		if (!ice_testandset_state(&sc->state, ICE_STATE_NO_MEDIA)) {
1990 			status = ice_aq_set_link_restart_an(pi, false, NULL);
1991 			if (status != ICE_SUCCESS)
1992 				device_printf(dev,
1993 				    "%s: ice_aq_set_link_restart_an: status %s, aq_err %s\n",
1994 				    __func__, ice_status_str(status),
1995 				    ice_aq_str(hw->adminq.sq_last_status));
1996 		}
1997 	}
1998 	/* ICE_STATE_NO_MEDIA is cleared when polling task detects media */
1999 
2000 	/* Indicate that link status must be reported again */
2001 	ice_clear_state(&sc->state, ICE_STATE_LINK_STATUS_REPORTED);
2002 
2003 	/* OS link info is updated elsewhere */
2004 }
2005 
2006 /**
2007  * ice_process_ctrlq_event - Respond to a controlq event
2008  * @sc: device private structure
2009  * @qname: the name for this controlq
2010  * @event: the event to process
2011  *
2012  * Perform actions in response to various controlq event notifications.
2013  */
2014 static void
2015 ice_process_ctrlq_event(struct ice_softc *sc, const char *qname,
2016 			struct ice_rq_event_info *event)
2017 {
2018 	u16 opcode;
2019 
2020 	opcode = le16toh(event->desc.opcode);
2021 
2022 	switch (opcode) {
2023 	case ice_aqc_opc_get_link_status:
2024 		ice_process_link_event(sc, event);
2025 		break;
2026 	case ice_mbx_opc_send_msg_to_pf:
2027 		/* TODO: handle IOV event */
2028 		break;
2029 	case ice_aqc_opc_fw_logs_event:
2030 		ice_handle_fw_log_event(sc, &event->desc, event->msg_buf);
2031 		break;
2032 	case ice_aqc_opc_lldp_set_mib_change:
2033 		ice_handle_mib_change_event(sc, event);
2034 		break;
2035 	case ice_aqc_opc_event_lan_overflow:
2036 		ice_handle_lan_overflow_event(sc, event);
2037 		break;
2038 	case ice_aqc_opc_get_health_status:
2039 		ice_handle_health_status_event(sc, event);
2040 		break;
2041 	default:
2042 		device_printf(sc->dev,
2043 			      "%s Receive Queue unhandled event 0x%04x ignored\n",
2044 			      qname, opcode);
2045 	}
2046 }
2047 
2048 /**
2049  * ice_process_ctrlq - helper function to process controlq rings
2050  * @sc: device private structure
2051  * @q_type: specific control queue type
2052  * @pending: return parameter to track remaining events
2053  *
2054  * Process controlq events for a given control queue type. Returns zero on
2055  * success, and an error code on failure. If successful, pending is the number
2056  * of remaining events left in the queue.
2057  */
2058 int
2059 ice_process_ctrlq(struct ice_softc *sc, enum ice_ctl_q q_type, u16 *pending)
2060 {
2061 	struct ice_rq_event_info event = { { 0 } };
2062 	struct ice_hw *hw = &sc->hw;
2063 	struct ice_ctl_q_info *cq;
2064 	enum ice_status status;
2065 	const char *qname;
2066 	int loop = 0;
2067 
2068 	switch (q_type) {
2069 	case ICE_CTL_Q_ADMIN:
2070 		cq = &hw->adminq;
2071 		qname = "Admin";
2072 		break;
2073 	case ICE_CTL_Q_MAILBOX:
2074 		cq = &hw->mailboxq;
2075 		qname = "Mailbox";
2076 		break;
2077 	default:
2078 		device_printf(sc->dev,
2079 			      "Unknown control queue type 0x%x\n",
2080 			      q_type);
2081 		return 0;
2082 	}
2083 
2084 	ice_check_ctrlq_errors(sc, qname, cq);
2085 
2086 	/*
2087 	 * Control queue processing happens during the admin task which may be
2088 	 * holding a non-sleepable lock, so we *must* use M_NOWAIT here.
2089 	 */
2090 	event.buf_len = cq->rq_buf_size;
2091 	event.msg_buf = (u8 *)malloc(event.buf_len, M_ICE, M_ZERO | M_NOWAIT);
2092 	if (!event.msg_buf) {
2093 		device_printf(sc->dev,
2094 			      "Unable to allocate memory for %s Receive Queue event\n",
2095 			      qname);
2096 		return (ENOMEM);
2097 	}
2098 
2099 	do {
2100 		status = ice_clean_rq_elem(hw, cq, &event, pending);
2101 		if (status == ICE_ERR_AQ_NO_WORK)
2102 			break;
2103 		if (status) {
2104 			if (q_type == ICE_CTL_Q_ADMIN)
2105 				device_printf(sc->dev,
2106 					      "%s Receive Queue event error %s\n",
2107 					      qname, ice_status_str(status));
2108 			else
2109 				device_printf(sc->dev,
2110 					      "%s Receive Queue event error %s\n",
2111 					      qname, ice_status_str(status));
2112 			free(event.msg_buf, M_ICE);
2113 			return (EIO);
2114 		}
2115 		/* XXX should we separate this handler by controlq type? */
2116 		ice_process_ctrlq_event(sc, qname, &event);
2117 	} while (*pending && (++loop < ICE_CTRLQ_WORK_LIMIT));
2118 
2119 	free(event.msg_buf, M_ICE);
2120 
2121 	return 0;
2122 }
2123 
2124 /**
2125  * pkg_ver_empty - Check if a package version is empty
2126  * @pkg_ver: the package version to check
2127  * @pkg_name: the package name to check
2128  *
2129  * Checks if the package version structure is empty. We consider a package
2130  * version as empty if none of the versions are non-zero and the name string
2131  * is null as well.
2132  *
2133  * This is used to check if the package version was initialized by the driver,
2134  * as we do not expect an actual DDP package file to have a zero'd version and
2135  * name.
2136  *
2137  * @returns true if the package version is valid, or false otherwise.
2138  */
2139 static bool
2140 pkg_ver_empty(struct ice_pkg_ver *pkg_ver, u8 *pkg_name)
2141 {
2142 	return (pkg_name[0] == '\0' &&
2143 		pkg_ver->major == 0 &&
2144 		pkg_ver->minor == 0 &&
2145 		pkg_ver->update == 0 &&
2146 		pkg_ver->draft == 0);
2147 }
2148 
2149 /**
2150  * pkg_ver_compatible - Check if the package version is compatible
2151  * @pkg_ver: the package version to check
2152  *
2153  * Compares the package version number to the driver's expected major/minor
2154  * version. Returns an integer indicating whether the version is older, newer,
2155  * or compatible with the driver.
2156  *
2157  * @returns 0 if the package version is compatible, -1 if the package version
2158  * is older, and 1 if the package version is newer than the driver version.
2159  */
2160 static int
2161 pkg_ver_compatible(struct ice_pkg_ver *pkg_ver)
2162 {
2163 	if (pkg_ver->major > ICE_PKG_SUPP_VER_MAJ)
2164 		return (1); /* newer */
2165 	else if ((pkg_ver->major == ICE_PKG_SUPP_VER_MAJ) &&
2166 		 (pkg_ver->minor > ICE_PKG_SUPP_VER_MNR))
2167 		return (1); /* newer */
2168 	else if ((pkg_ver->major == ICE_PKG_SUPP_VER_MAJ) &&
2169 		 (pkg_ver->minor == ICE_PKG_SUPP_VER_MNR))
2170 		return (0); /* compatible */
2171 	else
2172 		return (-1); /* older */
2173 }
2174 
2175 /**
2176  * ice_os_pkg_version_str - Format OS package version info into a sbuf
2177  * @hw: device hw structure
2178  * @buf: string buffer to store name/version string
2179  *
2180  * Formats the name and version of the OS DDP package as found in the ice_ddp
2181  * module into a string.
2182  *
2183  * @remark This will almost always be the same as the active package, but
2184  * could be different in some cases. Use ice_active_pkg_version_str to get the
2185  * version of the active DDP package.
2186  */
2187 static void
2188 ice_os_pkg_version_str(struct ice_hw *hw, struct sbuf *buf)
2189 {
2190 	char name_buf[ICE_PKG_NAME_SIZE];
2191 
2192 	/* If the OS DDP package info is empty, use "None" */
2193 	if (pkg_ver_empty(&hw->pkg_ver, hw->pkg_name)) {
2194 		sbuf_printf(buf, "None");
2195 		return;
2196 	}
2197 
2198 	/*
2199 	 * This should already be null-terminated, but since this is a raw
2200 	 * value from an external source, strlcpy() into a new buffer to
2201 	 * make sure.
2202 	 */
2203 	bzero(name_buf, sizeof(name_buf));
2204 	strlcpy(name_buf, (char *)hw->pkg_name, ICE_PKG_NAME_SIZE);
2205 
2206 	sbuf_printf(buf, "%s version %u.%u.%u.%u",
2207 	    name_buf,
2208 	    hw->pkg_ver.major,
2209 	    hw->pkg_ver.minor,
2210 	    hw->pkg_ver.update,
2211 	    hw->pkg_ver.draft);
2212 }
2213 
2214 /**
2215  * ice_active_pkg_version_str - Format active package version info into a sbuf
2216  * @hw: device hw structure
2217  * @buf: string buffer to store name/version string
2218  *
2219  * Formats the name and version of the active DDP package info into a string
2220  * buffer for use.
2221  */
2222 static void
2223 ice_active_pkg_version_str(struct ice_hw *hw, struct sbuf *buf)
2224 {
2225 	char name_buf[ICE_PKG_NAME_SIZE];
2226 
2227 	/* If the active DDP package info is empty, use "None" */
2228 	if (pkg_ver_empty(&hw->active_pkg_ver, hw->active_pkg_name)) {
2229 		sbuf_printf(buf, "None");
2230 		return;
2231 	}
2232 
2233 	/*
2234 	 * This should already be null-terminated, but since this is a raw
2235 	 * value from an external source, strlcpy() into a new buffer to
2236 	 * make sure.
2237 	 */
2238 	bzero(name_buf, sizeof(name_buf));
2239 	strlcpy(name_buf, (char *)hw->active_pkg_name, ICE_PKG_NAME_SIZE);
2240 
2241 	sbuf_printf(buf, "%s version %u.%u.%u.%u",
2242 	    name_buf,
2243 	    hw->active_pkg_ver.major,
2244 	    hw->active_pkg_ver.minor,
2245 	    hw->active_pkg_ver.update,
2246 	    hw->active_pkg_ver.draft);
2247 
2248 	if (hw->active_track_id != 0)
2249 		sbuf_printf(buf, ", track id 0x%08x", hw->active_track_id);
2250 }
2251 
2252 /**
2253  * ice_nvm_version_str - Format the NVM version information into a sbuf
2254  * @hw: device hw structure
2255  * @buf: string buffer to store version string
2256  *
2257  * Formats the NVM information including firmware version, API version, NVM
2258  * version, the EETRACK id, and OEM specific version information into a string
2259  * buffer.
2260  */
2261 static void
2262 ice_nvm_version_str(struct ice_hw *hw, struct sbuf *buf)
2263 {
2264 	struct ice_nvm_info *nvm = &hw->flash.nvm;
2265 	struct ice_orom_info *orom = &hw->flash.orom;
2266 	struct ice_netlist_info *netlist = &hw->flash.netlist;
2267 
2268 	/* Note that the netlist versions are stored in packed Binary Coded
2269 	 * Decimal format. The use of '%x' will correctly display these as
2270 	 * decimal numbers. This works because every 4 bits will be displayed
2271 	 * as a hexadecimal digit, and the BCD format will only use the values
2272 	 * 0-9.
2273 	 */
2274 	sbuf_printf(buf,
2275 		    "fw %u.%u.%u api %u.%u nvm %x.%02x etid %08x netlist %x.%x.%x-%x.%x.%x.%04x oem %u.%u.%u",
2276 		    hw->fw_maj_ver, hw->fw_min_ver, hw->fw_patch,
2277 		    hw->api_maj_ver, hw->api_min_ver,
2278 		    nvm->major, nvm->minor, nvm->eetrack,
2279 		    netlist->major, netlist->minor,
2280 		    netlist->type >> 16, netlist->type & 0xFFFF,
2281 		    netlist->rev, netlist->cust_ver, netlist->hash,
2282 		    orom->major, orom->build, orom->patch);
2283 }
2284 
2285 /**
2286  * ice_print_nvm_version - Print the NVM info to the kernel message log
2287  * @sc: the device softc structure
2288  *
2289  * Format and print an NVM version string using ice_nvm_version_str().
2290  */
2291 void
2292 ice_print_nvm_version(struct ice_softc *sc)
2293 {
2294 	struct ice_hw *hw = &sc->hw;
2295 	device_t dev = sc->dev;
2296 	struct sbuf *sbuf;
2297 
2298 	sbuf = sbuf_new_auto();
2299 	ice_nvm_version_str(hw, sbuf);
2300 	sbuf_finish(sbuf);
2301 	device_printf(dev, "%s\n", sbuf_data(sbuf));
2302 	sbuf_delete(sbuf);
2303 }
2304 
2305 /**
2306  * ice_update_vsi_hw_stats - Update VSI-specific ethernet statistics counters
2307  * @vsi: the VSI to be updated
2308  *
2309  * Reads hardware stats and updates the ice_vsi_hw_stats tracking structure with
2310  * the updated values.
2311  */
2312 void
2313 ice_update_vsi_hw_stats(struct ice_vsi *vsi)
2314 {
2315 	struct ice_eth_stats *prev_es, *cur_es;
2316 	struct ice_hw *hw = &vsi->sc->hw;
2317 	u16 vsi_num;
2318 
2319 	if (!ice_is_vsi_valid(hw, vsi->idx))
2320 		return;
2321 
2322 	vsi_num = ice_get_hw_vsi_num(hw, vsi->idx); /* HW absolute index of a VSI */
2323 	prev_es = &vsi->hw_stats.prev;
2324 	cur_es = &vsi->hw_stats.cur;
2325 
2326 #define ICE_VSI_STAT40(name, location) \
2327 	ice_stat_update40(hw, name ## L(vsi_num), \
2328 			  vsi->hw_stats.offsets_loaded, \
2329 			  &prev_es->location, &cur_es->location)
2330 
2331 #define ICE_VSI_STAT32(name, location) \
2332 	ice_stat_update32(hw, name(vsi_num), \
2333 			  vsi->hw_stats.offsets_loaded, \
2334 			  &prev_es->location, &cur_es->location)
2335 
2336 	ICE_VSI_STAT40(GLV_GORC, rx_bytes);
2337 	ICE_VSI_STAT40(GLV_UPRC, rx_unicast);
2338 	ICE_VSI_STAT40(GLV_MPRC, rx_multicast);
2339 	ICE_VSI_STAT40(GLV_BPRC, rx_broadcast);
2340 	ICE_VSI_STAT32(GLV_RDPC, rx_discards);
2341 	ICE_VSI_STAT40(GLV_GOTC, tx_bytes);
2342 	ICE_VSI_STAT40(GLV_UPTC, tx_unicast);
2343 	ICE_VSI_STAT40(GLV_MPTC, tx_multicast);
2344 	ICE_VSI_STAT40(GLV_BPTC, tx_broadcast);
2345 	ICE_VSI_STAT32(GLV_TEPC, tx_errors);
2346 
2347 	ice_stat_update_repc(hw, vsi->idx, vsi->hw_stats.offsets_loaded,
2348 			     cur_es);
2349 
2350 #undef ICE_VSI_STAT40
2351 #undef ICE_VSI_STAT32
2352 
2353 	vsi->hw_stats.offsets_loaded = true;
2354 }
2355 
2356 /**
2357  * ice_reset_vsi_stats - Reset VSI statistics counters
2358  * @vsi: VSI structure
2359  *
2360  * Resets the software tracking counters for the VSI statistics, and indicate
2361  * that the offsets haven't been loaded. This is intended to be called
2362  * post-reset so that VSI statistics count from zero again.
2363  */
2364 void
2365 ice_reset_vsi_stats(struct ice_vsi *vsi)
2366 {
2367 	/* Reset HW stats */
2368 	memset(&vsi->hw_stats.prev, 0, sizeof(vsi->hw_stats.prev));
2369 	memset(&vsi->hw_stats.cur, 0, sizeof(vsi->hw_stats.cur));
2370 	vsi->hw_stats.offsets_loaded = false;
2371 }
2372 
2373 /**
2374  * ice_update_pf_stats - Update port stats counters
2375  * @sc: device private softc structure
2376  *
2377  * Reads hardware statistics registers and updates the software tracking
2378  * structure with new values.
2379  */
2380 void
2381 ice_update_pf_stats(struct ice_softc *sc)
2382 {
2383 	struct ice_hw_port_stats *prev_ps, *cur_ps;
2384 	struct ice_hw *hw = &sc->hw;
2385 	u8 lport;
2386 
2387 	MPASS(hw->port_info);
2388 
2389 	prev_ps = &sc->stats.prev;
2390 	cur_ps = &sc->stats.cur;
2391 	lport = hw->port_info->lport;
2392 
2393 #define ICE_PF_STAT_PFC(name, location, index) \
2394 	ice_stat_update40(hw, name(lport, index), \
2395 			  sc->stats.offsets_loaded, \
2396 			  &prev_ps->location[index], &cur_ps->location[index])
2397 
2398 #define ICE_PF_STAT40(name, location) \
2399 	ice_stat_update40(hw, name ## L(lport), \
2400 			  sc->stats.offsets_loaded, \
2401 			  &prev_ps->location, &cur_ps->location)
2402 
2403 #define ICE_PF_STAT32(name, location) \
2404 	ice_stat_update32(hw, name(lport), \
2405 			  sc->stats.offsets_loaded, \
2406 			  &prev_ps->location, &cur_ps->location)
2407 
2408 	ICE_PF_STAT40(GLPRT_GORC, eth.rx_bytes);
2409 	ICE_PF_STAT40(GLPRT_UPRC, eth.rx_unicast);
2410 	ICE_PF_STAT40(GLPRT_MPRC, eth.rx_multicast);
2411 	ICE_PF_STAT40(GLPRT_BPRC, eth.rx_broadcast);
2412 	ICE_PF_STAT40(GLPRT_GOTC, eth.tx_bytes);
2413 	ICE_PF_STAT40(GLPRT_UPTC, eth.tx_unicast);
2414 	ICE_PF_STAT40(GLPRT_MPTC, eth.tx_multicast);
2415 	ICE_PF_STAT40(GLPRT_BPTC, eth.tx_broadcast);
2416 	/* This stat register doesn't have an lport */
2417 	ice_stat_update32(hw, PRTRPB_RDPC,
2418 			  sc->stats.offsets_loaded,
2419 			  &prev_ps->eth.rx_discards, &cur_ps->eth.rx_discards);
2420 
2421 	ICE_PF_STAT32(GLPRT_TDOLD, tx_dropped_link_down);
2422 	ICE_PF_STAT40(GLPRT_PRC64, rx_size_64);
2423 	ICE_PF_STAT40(GLPRT_PRC127, rx_size_127);
2424 	ICE_PF_STAT40(GLPRT_PRC255, rx_size_255);
2425 	ICE_PF_STAT40(GLPRT_PRC511, rx_size_511);
2426 	ICE_PF_STAT40(GLPRT_PRC1023, rx_size_1023);
2427 	ICE_PF_STAT40(GLPRT_PRC1522, rx_size_1522);
2428 	ICE_PF_STAT40(GLPRT_PRC9522, rx_size_big);
2429 	ICE_PF_STAT40(GLPRT_PTC64, tx_size_64);
2430 	ICE_PF_STAT40(GLPRT_PTC127, tx_size_127);
2431 	ICE_PF_STAT40(GLPRT_PTC255, tx_size_255);
2432 	ICE_PF_STAT40(GLPRT_PTC511, tx_size_511);
2433 	ICE_PF_STAT40(GLPRT_PTC1023, tx_size_1023);
2434 	ICE_PF_STAT40(GLPRT_PTC1522, tx_size_1522);
2435 	ICE_PF_STAT40(GLPRT_PTC9522, tx_size_big);
2436 
2437 	/* Update Priority Flow Control Stats */
2438 	for (int i = 0; i <= GLPRT_PXOFFRXC_MAX_INDEX; i++) {
2439 		ICE_PF_STAT_PFC(GLPRT_PXONRXC, priority_xon_rx, i);
2440 		ICE_PF_STAT_PFC(GLPRT_PXOFFRXC, priority_xoff_rx, i);
2441 		ICE_PF_STAT_PFC(GLPRT_PXONTXC, priority_xon_tx, i);
2442 		ICE_PF_STAT_PFC(GLPRT_PXOFFTXC, priority_xoff_tx, i);
2443 		ICE_PF_STAT_PFC(GLPRT_RXON2OFFCNT, priority_xon_2_xoff, i);
2444 	}
2445 
2446 	ICE_PF_STAT32(GLPRT_LXONRXC, link_xon_rx);
2447 	ICE_PF_STAT32(GLPRT_LXOFFRXC, link_xoff_rx);
2448 	ICE_PF_STAT32(GLPRT_LXONTXC, link_xon_tx);
2449 	ICE_PF_STAT32(GLPRT_LXOFFTXC, link_xoff_tx);
2450 	ICE_PF_STAT32(GLPRT_CRCERRS, crc_errors);
2451 	ICE_PF_STAT32(GLPRT_ILLERRC, illegal_bytes);
2452 	ICE_PF_STAT32(GLPRT_MLFC, mac_local_faults);
2453 	ICE_PF_STAT32(GLPRT_MRFC, mac_remote_faults);
2454 	ICE_PF_STAT32(GLPRT_RLEC, rx_len_errors);
2455 	ICE_PF_STAT32(GLPRT_RUC, rx_undersize);
2456 	ICE_PF_STAT32(GLPRT_RFC, rx_fragments);
2457 	ICE_PF_STAT32(GLPRT_ROC, rx_oversize);
2458 	ICE_PF_STAT32(GLPRT_RJC, rx_jabber);
2459 
2460 #undef ICE_PF_STAT40
2461 #undef ICE_PF_STAT32
2462 #undef ICE_PF_STAT_PFC
2463 
2464 	sc->stats.offsets_loaded = true;
2465 }
2466 
2467 /**
2468  * ice_reset_pf_stats - Reset port stats counters
2469  * @sc: Device private softc structure
2470  *
2471  * Reset software tracking values for statistics to zero, and indicate that
2472  * offsets haven't been loaded. Intended to be called after a device reset so
2473  * that statistics count from zero again.
2474  */
2475 void
2476 ice_reset_pf_stats(struct ice_softc *sc)
2477 {
2478 	memset(&sc->stats.prev, 0, sizeof(sc->stats.prev));
2479 	memset(&sc->stats.cur, 0, sizeof(sc->stats.cur));
2480 	sc->stats.offsets_loaded = false;
2481 }
2482 
2483 /**
2484  * ice_sysctl_show_fw - sysctl callback to show firmware information
2485  * @oidp: sysctl oid structure
2486  * @arg1: pointer to private data structure
2487  * @arg2: unused
2488  * @req: sysctl request pointer
2489  *
2490  * Callback for the fw_version sysctl, to display the current firmware
2491  * information found at hardware init time.
2492  */
2493 static int
2494 ice_sysctl_show_fw(SYSCTL_HANDLER_ARGS)
2495 {
2496 	struct ice_softc *sc = (struct ice_softc *)arg1;
2497 	struct ice_hw *hw = &sc->hw;
2498 	struct sbuf *sbuf;
2499 
2500 	UNREFERENCED_PARAMETER(oidp);
2501 	UNREFERENCED_PARAMETER(arg2);
2502 
2503 	if (ice_driver_is_detaching(sc))
2504 		return (ESHUTDOWN);
2505 
2506 	sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
2507 	ice_nvm_version_str(hw, sbuf);
2508 	sbuf_finish(sbuf);
2509 	sbuf_delete(sbuf);
2510 
2511 	return (0);
2512 }
2513 
2514 /**
2515  * ice_sysctl_pba_number - sysctl callback to show PBA number
2516  * @oidp: sysctl oid structure
2517  * @arg1: pointer to private data structure
2518  * @arg2: unused
2519  * @req: sysctl request pointer
2520  *
2521  * Callback for the pba_number sysctl, used to read the Product Board Assembly
2522  * number for this device.
2523  */
2524 static int
2525 ice_sysctl_pba_number(SYSCTL_HANDLER_ARGS)
2526 {
2527 	struct ice_softc *sc = (struct ice_softc *)arg1;
2528 	struct ice_hw *hw = &sc->hw;
2529 	device_t dev = sc->dev;
2530 	u8 pba_string[32] = "";
2531 	enum ice_status status;
2532 
2533 	UNREFERENCED_PARAMETER(arg2);
2534 
2535 	if (ice_driver_is_detaching(sc))
2536 		return (ESHUTDOWN);
2537 
2538 	status = ice_read_pba_string(hw, pba_string, sizeof(pba_string));
2539 	if (status) {
2540 		device_printf(dev,
2541 		    "%s: failed to read PBA string from NVM; status %s, aq_err %s\n",
2542 		    __func__, ice_status_str(status),
2543 		    ice_aq_str(hw->adminq.sq_last_status));
2544 		return (EIO);
2545 	}
2546 
2547 	return sysctl_handle_string(oidp, pba_string, sizeof(pba_string), req);
2548 }
2549 
2550 /**
2551  * ice_sysctl_pkg_version - sysctl to show the active package version info
2552  * @oidp: sysctl oid structure
2553  * @arg1: pointer to private data structure
2554  * @arg2: unused
2555  * @req: sysctl request pointer
2556  *
2557  * Callback for the pkg_version sysctl, to display the active DDP package name
2558  * and version information.
2559  */
2560 static int
2561 ice_sysctl_pkg_version(SYSCTL_HANDLER_ARGS)
2562 {
2563 	struct ice_softc *sc = (struct ice_softc *)arg1;
2564 	struct ice_hw *hw = &sc->hw;
2565 	struct sbuf *sbuf;
2566 
2567 	UNREFERENCED_PARAMETER(oidp);
2568 	UNREFERENCED_PARAMETER(arg2);
2569 
2570 	if (ice_driver_is_detaching(sc))
2571 		return (ESHUTDOWN);
2572 
2573 	sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
2574 	ice_active_pkg_version_str(hw, sbuf);
2575 	sbuf_finish(sbuf);
2576 	sbuf_delete(sbuf);
2577 
2578 	return (0);
2579 }
2580 
2581 /**
2582  * ice_sysctl_os_pkg_version - sysctl to show the OS package version info
2583  * @oidp: sysctl oid structure
2584  * @arg1: pointer to private data structure
2585  * @arg2: unused
2586  * @req: sysctl request pointer
2587  *
2588  * Callback for the pkg_version sysctl, to display the OS DDP package name and
2589  * version info found in the ice_ddp module.
2590  */
2591 static int
2592 ice_sysctl_os_pkg_version(SYSCTL_HANDLER_ARGS)
2593 {
2594 	struct ice_softc *sc = (struct ice_softc *)arg1;
2595 	struct ice_hw *hw = &sc->hw;
2596 	struct sbuf *sbuf;
2597 
2598 	UNREFERENCED_PARAMETER(oidp);
2599 	UNREFERENCED_PARAMETER(arg2);
2600 
2601 	if (ice_driver_is_detaching(sc))
2602 		return (ESHUTDOWN);
2603 
2604 	sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
2605 	ice_os_pkg_version_str(hw, sbuf);
2606 	sbuf_finish(sbuf);
2607 	sbuf_delete(sbuf);
2608 
2609 	return (0);
2610 }
2611 
2612 /**
2613  * ice_sysctl_current_speed - sysctl callback to show current link speed
2614  * @oidp: sysctl oid structure
2615  * @arg1: pointer to private data structure
2616  * @arg2: unused
2617  * @req: sysctl request pointer
2618  *
2619  * Callback for the current_speed sysctl, to display the string representing
2620  * the current link speed.
2621  */
2622 static int
2623 ice_sysctl_current_speed(SYSCTL_HANDLER_ARGS)
2624 {
2625 	struct ice_softc *sc = (struct ice_softc *)arg1;
2626 	struct ice_hw *hw = &sc->hw;
2627 	struct sbuf *sbuf;
2628 
2629 	UNREFERENCED_PARAMETER(oidp);
2630 	UNREFERENCED_PARAMETER(arg2);
2631 
2632 	if (ice_driver_is_detaching(sc))
2633 		return (ESHUTDOWN);
2634 
2635 	sbuf = sbuf_new_for_sysctl(NULL, NULL, 10, req);
2636 	sbuf_printf(sbuf, "%s", ice_aq_speed_to_str(hw->port_info));
2637 	sbuf_finish(sbuf);
2638 	sbuf_delete(sbuf);
2639 
2640 	return (0);
2641 }
2642 
2643 /**
2644  * @var phy_link_speeds
2645  * @brief PHY link speed conversion array
2646  *
2647  * Array of link speeds to convert ICE_PHY_TYPE_LOW and ICE_PHY_TYPE_HIGH into
2648  * link speeds used by the link speed sysctls.
2649  *
2650  * @remark these are based on the indices used in the BIT() macros for the
2651  * ICE_PHY_TYPE_LOW_* and ICE_PHY_TYPE_HIGH_* definitions.
2652  */
2653 static const uint16_t phy_link_speeds[] = {
2654     ICE_AQ_LINK_SPEED_100MB,
2655     ICE_AQ_LINK_SPEED_100MB,
2656     ICE_AQ_LINK_SPEED_1000MB,
2657     ICE_AQ_LINK_SPEED_1000MB,
2658     ICE_AQ_LINK_SPEED_1000MB,
2659     ICE_AQ_LINK_SPEED_1000MB,
2660     ICE_AQ_LINK_SPEED_1000MB,
2661     ICE_AQ_LINK_SPEED_2500MB,
2662     ICE_AQ_LINK_SPEED_2500MB,
2663     ICE_AQ_LINK_SPEED_2500MB,
2664     ICE_AQ_LINK_SPEED_5GB,
2665     ICE_AQ_LINK_SPEED_5GB,
2666     ICE_AQ_LINK_SPEED_10GB,
2667     ICE_AQ_LINK_SPEED_10GB,
2668     ICE_AQ_LINK_SPEED_10GB,
2669     ICE_AQ_LINK_SPEED_10GB,
2670     ICE_AQ_LINK_SPEED_10GB,
2671     ICE_AQ_LINK_SPEED_10GB,
2672     ICE_AQ_LINK_SPEED_10GB,
2673     ICE_AQ_LINK_SPEED_25GB,
2674     ICE_AQ_LINK_SPEED_25GB,
2675     ICE_AQ_LINK_SPEED_25GB,
2676     ICE_AQ_LINK_SPEED_25GB,
2677     ICE_AQ_LINK_SPEED_25GB,
2678     ICE_AQ_LINK_SPEED_25GB,
2679     ICE_AQ_LINK_SPEED_25GB,
2680     ICE_AQ_LINK_SPEED_25GB,
2681     ICE_AQ_LINK_SPEED_25GB,
2682     ICE_AQ_LINK_SPEED_25GB,
2683     ICE_AQ_LINK_SPEED_25GB,
2684     ICE_AQ_LINK_SPEED_40GB,
2685     ICE_AQ_LINK_SPEED_40GB,
2686     ICE_AQ_LINK_SPEED_40GB,
2687     ICE_AQ_LINK_SPEED_40GB,
2688     ICE_AQ_LINK_SPEED_40GB,
2689     ICE_AQ_LINK_SPEED_40GB,
2690     ICE_AQ_LINK_SPEED_50GB,
2691     ICE_AQ_LINK_SPEED_50GB,
2692     ICE_AQ_LINK_SPEED_50GB,
2693     ICE_AQ_LINK_SPEED_50GB,
2694     ICE_AQ_LINK_SPEED_50GB,
2695     ICE_AQ_LINK_SPEED_50GB,
2696     ICE_AQ_LINK_SPEED_50GB,
2697     ICE_AQ_LINK_SPEED_50GB,
2698     ICE_AQ_LINK_SPEED_50GB,
2699     ICE_AQ_LINK_SPEED_50GB,
2700     ICE_AQ_LINK_SPEED_50GB,
2701     ICE_AQ_LINK_SPEED_50GB,
2702     ICE_AQ_LINK_SPEED_50GB,
2703     ICE_AQ_LINK_SPEED_50GB,
2704     ICE_AQ_LINK_SPEED_50GB,
2705     ICE_AQ_LINK_SPEED_100GB,
2706     ICE_AQ_LINK_SPEED_100GB,
2707     ICE_AQ_LINK_SPEED_100GB,
2708     ICE_AQ_LINK_SPEED_100GB,
2709     ICE_AQ_LINK_SPEED_100GB,
2710     ICE_AQ_LINK_SPEED_100GB,
2711     ICE_AQ_LINK_SPEED_100GB,
2712     ICE_AQ_LINK_SPEED_100GB,
2713     ICE_AQ_LINK_SPEED_100GB,
2714     ICE_AQ_LINK_SPEED_100GB,
2715     ICE_AQ_LINK_SPEED_100GB,
2716     ICE_AQ_LINK_SPEED_100GB,
2717     ICE_AQ_LINK_SPEED_100GB,
2718     /* These rates are for ICE_PHY_TYPE_HIGH_* */
2719     ICE_AQ_LINK_SPEED_100GB,
2720     ICE_AQ_LINK_SPEED_100GB,
2721     ICE_AQ_LINK_SPEED_100GB,
2722     ICE_AQ_LINK_SPEED_100GB,
2723     ICE_AQ_LINK_SPEED_100GB
2724 };
2725 
2726 #define ICE_SYSCTL_HELP_ADVERTISE_SPEED		\
2727 "\nControl advertised link speed."		\
2728 "\nFlags:"					\
2729 "\n\t   0x0 - Auto"				\
2730 "\n\t   0x1 - 10 Mb"				\
2731 "\n\t   0x2 - 100 Mb"				\
2732 "\n\t   0x4 - 1G"				\
2733 "\n\t   0x8 - 2.5G"				\
2734 "\n\t  0x10 - 5G"				\
2735 "\n\t  0x20 - 10G"				\
2736 "\n\t  0x40 - 20G"				\
2737 "\n\t  0x80 - 25G"				\
2738 "\n\t 0x100 - 40G"				\
2739 "\n\t 0x200 - 50G"				\
2740 "\n\t 0x400 - 100G"				\
2741 "\n\t0x8000 - Unknown"				\
2742 "\n\t"						\
2743 "\nUse \"sysctl -x\" to view flags properly."
2744 
2745 #define ICE_PHYS_100MB			\
2746     (ICE_PHY_TYPE_LOW_100BASE_TX |	\
2747      ICE_PHY_TYPE_LOW_100M_SGMII)
2748 #define ICE_PHYS_1000MB			\
2749     (ICE_PHY_TYPE_LOW_1000BASE_T |	\
2750      ICE_PHY_TYPE_LOW_1000BASE_SX |	\
2751      ICE_PHY_TYPE_LOW_1000BASE_LX |	\
2752      ICE_PHY_TYPE_LOW_1000BASE_KX |	\
2753      ICE_PHY_TYPE_LOW_1G_SGMII)
2754 #define ICE_PHYS_2500MB			\
2755     (ICE_PHY_TYPE_LOW_2500BASE_T |	\
2756      ICE_PHY_TYPE_LOW_2500BASE_X |	\
2757      ICE_PHY_TYPE_LOW_2500BASE_KX)
2758 #define ICE_PHYS_5GB			\
2759     (ICE_PHY_TYPE_LOW_5GBASE_T |	\
2760      ICE_PHY_TYPE_LOW_5GBASE_KR)
2761 #define ICE_PHYS_10GB			\
2762     (ICE_PHY_TYPE_LOW_10GBASE_T |	\
2763      ICE_PHY_TYPE_LOW_10G_SFI_DA |	\
2764      ICE_PHY_TYPE_LOW_10GBASE_SR |	\
2765      ICE_PHY_TYPE_LOW_10GBASE_LR |	\
2766      ICE_PHY_TYPE_LOW_10GBASE_KR_CR1 |	\
2767      ICE_PHY_TYPE_LOW_10G_SFI_AOC_ACC |	\
2768      ICE_PHY_TYPE_LOW_10G_SFI_C2C)
2769 #define ICE_PHYS_25GB			\
2770     (ICE_PHY_TYPE_LOW_25GBASE_T |	\
2771      ICE_PHY_TYPE_LOW_25GBASE_CR |	\
2772      ICE_PHY_TYPE_LOW_25GBASE_CR_S |	\
2773      ICE_PHY_TYPE_LOW_25GBASE_CR1 |	\
2774      ICE_PHY_TYPE_LOW_25GBASE_SR |	\
2775      ICE_PHY_TYPE_LOW_25GBASE_LR |	\
2776      ICE_PHY_TYPE_LOW_25GBASE_KR |	\
2777      ICE_PHY_TYPE_LOW_25GBASE_KR_S |	\
2778      ICE_PHY_TYPE_LOW_25GBASE_KR1 |	\
2779      ICE_PHY_TYPE_LOW_25G_AUI_AOC_ACC |	\
2780      ICE_PHY_TYPE_LOW_25G_AUI_C2C)
2781 #define ICE_PHYS_40GB			\
2782     (ICE_PHY_TYPE_LOW_40GBASE_CR4 |	\
2783      ICE_PHY_TYPE_LOW_40GBASE_SR4 |	\
2784      ICE_PHY_TYPE_LOW_40GBASE_LR4 |	\
2785      ICE_PHY_TYPE_LOW_40GBASE_KR4 |	\
2786      ICE_PHY_TYPE_LOW_40G_XLAUI_AOC_ACC | \
2787      ICE_PHY_TYPE_LOW_40G_XLAUI)
2788 #define ICE_PHYS_50GB			\
2789     (ICE_PHY_TYPE_LOW_50GBASE_CR2 |	\
2790      ICE_PHY_TYPE_LOW_50GBASE_SR2 |	\
2791      ICE_PHY_TYPE_LOW_50GBASE_LR2 |	\
2792      ICE_PHY_TYPE_LOW_50GBASE_KR2 |	\
2793      ICE_PHY_TYPE_LOW_50G_LAUI2_AOC_ACC | \
2794      ICE_PHY_TYPE_LOW_50G_LAUI2 |	\
2795      ICE_PHY_TYPE_LOW_50G_AUI2_AOC_ACC | \
2796      ICE_PHY_TYPE_LOW_50G_AUI2 |	\
2797      ICE_PHY_TYPE_LOW_50GBASE_CP |	\
2798      ICE_PHY_TYPE_LOW_50GBASE_SR |	\
2799      ICE_PHY_TYPE_LOW_50GBASE_FR |	\
2800      ICE_PHY_TYPE_LOW_50GBASE_LR |	\
2801      ICE_PHY_TYPE_LOW_50GBASE_KR_PAM4 |	\
2802      ICE_PHY_TYPE_LOW_50G_AUI1_AOC_ACC | \
2803      ICE_PHY_TYPE_LOW_50G_AUI1)
2804 #define ICE_PHYS_100GB_LOW		\
2805     (ICE_PHY_TYPE_LOW_100GBASE_CR4 |	\
2806      ICE_PHY_TYPE_LOW_100GBASE_SR4 |	\
2807      ICE_PHY_TYPE_LOW_100GBASE_LR4 |	\
2808      ICE_PHY_TYPE_LOW_100GBASE_KR4 |	\
2809      ICE_PHY_TYPE_LOW_100G_CAUI4_AOC_ACC | \
2810      ICE_PHY_TYPE_LOW_100G_CAUI4 |	\
2811      ICE_PHY_TYPE_LOW_100G_AUI4_AOC_ACC | \
2812      ICE_PHY_TYPE_LOW_100G_AUI4 |	\
2813      ICE_PHY_TYPE_LOW_100GBASE_CR_PAM4 | \
2814      ICE_PHY_TYPE_LOW_100GBASE_KR_PAM4 | \
2815      ICE_PHY_TYPE_LOW_100GBASE_CP2 |	\
2816      ICE_PHY_TYPE_LOW_100GBASE_SR2 |	\
2817      ICE_PHY_TYPE_LOW_100GBASE_DR)
2818 #define ICE_PHYS_100GB_HIGH		\
2819     (ICE_PHY_TYPE_HIGH_100GBASE_KR2_PAM4 | \
2820      ICE_PHY_TYPE_HIGH_100G_CAUI2_AOC_ACC | \
2821      ICE_PHY_TYPE_HIGH_100G_CAUI2 |	\
2822      ICE_PHY_TYPE_HIGH_100G_AUI2_AOC_ACC | \
2823      ICE_PHY_TYPE_HIGH_100G_AUI2)
2824 
2825 /**
2826  * ice_aq_phy_types_to_link_speeds - Convert the PHY Types to speeds
2827  * @phy_type_low: lower 64-bit PHY Type bitmask
2828  * @phy_type_high: upper 64-bit PHY Type bitmask
2829  *
2830  * Convert the PHY Type fields from Get PHY Abilities and Set PHY Config into
2831  * link speed flags. If phy_type_high has an unknown PHY type, then the return
2832  * value will include the "ICE_AQ_LINK_SPEED_UNKNOWN" flag as well.
2833  */
2834 static u16
2835 ice_aq_phy_types_to_link_speeds(u64 phy_type_low, u64 phy_type_high)
2836 {
2837 	u16 sysctl_speeds = 0;
2838 	int bit;
2839 
2840 	/* coverity[address_of] */
2841 	for_each_set_bit(bit, &phy_type_low, 64)
2842 		sysctl_speeds |= phy_link_speeds[bit];
2843 
2844 	/* coverity[address_of] */
2845 	for_each_set_bit(bit, &phy_type_high, 64) {
2846 		if ((bit + 64) < (int)ARRAY_SIZE(phy_link_speeds))
2847 			sysctl_speeds |= phy_link_speeds[bit + 64];
2848 		else
2849 			sysctl_speeds |= ICE_AQ_LINK_SPEED_UNKNOWN;
2850 	}
2851 
2852 	return (sysctl_speeds);
2853 }
2854 
2855 /**
2856  * ice_sysctl_speeds_to_aq_phy_types - Convert sysctl speed flags to AQ PHY flags
2857  * @sysctl_speeds: 16-bit sysctl speeds or AQ_LINK_SPEED flags
2858  * @phy_type_low: output parameter for lower AQ PHY flags
2859  * @phy_type_high: output parameter for higher AQ PHY flags
2860  *
2861  * Converts the given link speed flags into AQ PHY type flag sets appropriate
2862  * for use in a Set PHY Config command.
2863  */
2864 static void
2865 ice_sysctl_speeds_to_aq_phy_types(u16 sysctl_speeds, u64 *phy_type_low,
2866 				  u64 *phy_type_high)
2867 {
2868 	*phy_type_low = 0, *phy_type_high = 0;
2869 
2870 	if (sysctl_speeds & ICE_AQ_LINK_SPEED_100MB)
2871 		*phy_type_low |= ICE_PHYS_100MB;
2872 	if (sysctl_speeds & ICE_AQ_LINK_SPEED_1000MB)
2873 		*phy_type_low |= ICE_PHYS_1000MB;
2874 	if (sysctl_speeds & ICE_AQ_LINK_SPEED_2500MB)
2875 		*phy_type_low |= ICE_PHYS_2500MB;
2876 	if (sysctl_speeds & ICE_AQ_LINK_SPEED_5GB)
2877 		*phy_type_low |= ICE_PHYS_5GB;
2878 	if (sysctl_speeds & ICE_AQ_LINK_SPEED_10GB)
2879 		*phy_type_low |= ICE_PHYS_10GB;
2880 	if (sysctl_speeds & ICE_AQ_LINK_SPEED_25GB)
2881 		*phy_type_low |= ICE_PHYS_25GB;
2882 	if (sysctl_speeds & ICE_AQ_LINK_SPEED_40GB)
2883 		*phy_type_low |= ICE_PHYS_40GB;
2884 	if (sysctl_speeds & ICE_AQ_LINK_SPEED_50GB)
2885 		*phy_type_low |= ICE_PHYS_50GB;
2886 	if (sysctl_speeds & ICE_AQ_LINK_SPEED_100GB) {
2887 		*phy_type_low |= ICE_PHYS_100GB_LOW;
2888 		*phy_type_high |= ICE_PHYS_100GB_HIGH;
2889 	}
2890 }
2891 
2892 /**
2893  * @struct ice_phy_data
2894  * @brief PHY caps and link speeds
2895  *
2896  * Buffer providing report mode and user speeds;
2897  * returning intersection of PHY types and speeds.
2898  */
2899 struct ice_phy_data {
2900 	u64 phy_low_orig;     /* PHY low quad from report */
2901 	u64 phy_high_orig;    /* PHY high quad from report */
2902 	u64 phy_low_intr;     /* PHY low quad intersection with user speeds */
2903 	u64 phy_high_intr;    /* PHY high quad intersection with user speeds */
2904 	u16 user_speeds_orig; /* Input from caller - See ICE_AQ_LINK_SPEED_* */
2905 	u16 user_speeds_intr; /* Intersect with report speeds */
2906 	u8 report_mode;       /* See ICE_AQC_REPORT_* */
2907 };
2908 
2909 /**
2910  * ice_intersect_phy_types_and_speeds - Return intersection of link speeds
2911  * @sc: device private structure
2912  * @phy_data: device PHY data
2913  *
2914  * On read: Displays the currently supported speeds
2915  * On write: Sets the device's supported speeds
2916  * Valid input flags: see ICE_SYSCTL_HELP_ADVERTISE_SPEED
2917  */
2918 static int
2919 ice_intersect_phy_types_and_speeds(struct ice_softc *sc,
2920 				   struct ice_phy_data *phy_data)
2921 {
2922 	struct ice_aqc_get_phy_caps_data pcaps = { 0 };
2923 	const char *report_types[5] = { "w/o MEDIA",
2924 					"w/MEDIA",
2925 					"ACTIVE",
2926 					"EDOOFUS", /* Not used */
2927 					"DFLT" };
2928 	struct ice_hw *hw = &sc->hw;
2929 	struct ice_port_info *pi = hw->port_info;
2930 	enum ice_status status;
2931 	u16 report_speeds, temp_speeds;
2932 	u8 report_type;
2933 	bool apply_speed_filter = false;
2934 
2935 	switch (phy_data->report_mode) {
2936 	case ICE_AQC_REPORT_TOPO_CAP_NO_MEDIA:
2937 	case ICE_AQC_REPORT_TOPO_CAP_MEDIA:
2938 	case ICE_AQC_REPORT_ACTIVE_CFG:
2939 	case ICE_AQC_REPORT_DFLT_CFG:
2940 		report_type = phy_data->report_mode >> 1;
2941 		break;
2942 	default:
2943 		device_printf(sc->dev,
2944 		    "%s: phy_data.report_mode \"%u\" doesn't exist\n",
2945 		    __func__, phy_data->report_mode);
2946 		return (EINVAL);
2947 	}
2948 
2949 	/* 0 is treated as "Auto"; the driver will handle selecting the
2950 	 * correct speeds. Including, in some cases, applying an override
2951 	 * if provided.
2952 	 */
2953 	if (phy_data->user_speeds_orig == 0)
2954 		phy_data->user_speeds_orig = USHRT_MAX;
2955 	else if (ice_is_bit_set(sc->feat_en, ICE_FEATURE_LENIENT_LINK_MODE))
2956 		apply_speed_filter = true;
2957 
2958 	status = ice_aq_get_phy_caps(pi, false, phy_data->report_mode, &pcaps, NULL);
2959 	if (status != ICE_SUCCESS) {
2960 		device_printf(sc->dev,
2961 		    "%s: ice_aq_get_phy_caps (%s) failed; status %s, aq_err %s\n",
2962 		    __func__, report_types[report_type],
2963 		    ice_status_str(status),
2964 		    ice_aq_str(sc->hw.adminq.sq_last_status));
2965 		return (EIO);
2966 	}
2967 
2968 	phy_data->phy_low_orig = le64toh(pcaps.phy_type_low);
2969 	phy_data->phy_high_orig = le64toh(pcaps.phy_type_high);
2970 	report_speeds = ice_aq_phy_types_to_link_speeds(phy_data->phy_low_orig,
2971 	    phy_data->phy_high_orig);
2972 	if (apply_speed_filter) {
2973 		temp_speeds = ice_apply_supported_speed_filter(report_speeds,
2974 		    pcaps.module_type[0]);
2975 		if ((phy_data->user_speeds_orig & temp_speeds) == 0) {
2976 			device_printf(sc->dev,
2977 			    "User-specified speeds (\"0x%04X\") not supported\n",
2978 			    phy_data->user_speeds_orig);
2979 			return (EINVAL);
2980 		}
2981 		report_speeds = temp_speeds;
2982 	}
2983 	ice_sysctl_speeds_to_aq_phy_types(phy_data->user_speeds_orig,
2984 	    &phy_data->phy_low_intr, &phy_data->phy_high_intr);
2985 	phy_data->user_speeds_intr = phy_data->user_speeds_orig & report_speeds;
2986 	phy_data->phy_low_intr &= phy_data->phy_low_orig;
2987 	phy_data->phy_high_intr &= phy_data->phy_high_orig;
2988 
2989 	return (0);
2990  }
2991 
2992 /**
2993  * ice_sysctl_advertise_speed - Display/change link speeds supported by port
2994  * @oidp: sysctl oid structure
2995  * @arg1: pointer to private data structure
2996  * @arg2: unused
2997  * @req: sysctl request pointer
2998  *
2999  * On read: Displays the currently supported speeds
3000  * On write: Sets the device's supported speeds
3001  * Valid input flags: see ICE_SYSCTL_HELP_ADVERTISE_SPEED
3002  */
3003 static int
3004 ice_sysctl_advertise_speed(SYSCTL_HANDLER_ARGS)
3005 {
3006 	struct ice_softc *sc = (struct ice_softc *)arg1;
3007 	struct ice_port_info *pi = sc->hw.port_info;
3008 	struct ice_phy_data phy_data = { 0 };
3009 	device_t dev = sc->dev;
3010 	u16 sysctl_speeds;
3011 	int ret;
3012 
3013 	UNREFERENCED_PARAMETER(arg2);
3014 
3015 	if (ice_driver_is_detaching(sc))
3016 		return (ESHUTDOWN);
3017 
3018 	/* Get the current speeds from the adapter's "active" configuration. */
3019 	phy_data.report_mode = ICE_AQC_REPORT_ACTIVE_CFG;
3020 	ret = ice_intersect_phy_types_and_speeds(sc, &phy_data);
3021 	if (ret) {
3022 		/* Error message already printed within function */
3023 		return (ret);
3024 	}
3025 
3026 	sysctl_speeds = phy_data.user_speeds_intr;
3027 
3028 	ret = sysctl_handle_16(oidp, &sysctl_speeds, 0, req);
3029 	if ((ret) || (req->newptr == NULL))
3030 		return (ret);
3031 
3032 	if (sysctl_speeds > 0x7FF) {
3033 		device_printf(dev,
3034 			      "%s: \"%u\" is outside of the range of acceptable values.\n",
3035 			      __func__, sysctl_speeds);
3036 		return (EINVAL);
3037 	}
3038 
3039 	pi->phy.curr_user_speed_req = sysctl_speeds;
3040 
3041 	/* Apply settings requested by user */
3042 	return ice_apply_saved_phy_cfg(sc, ICE_APPLY_LS);
3043 }
3044 
3045 #define ICE_SYSCTL_HELP_FEC_CONFIG			\
3046 "\nDisplay or set the port's requested FEC mode."	\
3047 "\n\tauto - " ICE_FEC_STRING_AUTO			\
3048 "\n\tfc - " ICE_FEC_STRING_BASER			\
3049 "\n\trs - " ICE_FEC_STRING_RS				\
3050 "\n\tnone - " ICE_FEC_STRING_NONE			\
3051 "\nEither of the left or right strings above can be used to set the requested mode."
3052 
3053 /**
3054  * ice_sysctl_fec_config - Display/change the configured FEC mode
3055  * @oidp: sysctl oid structure
3056  * @arg1: pointer to private data structure
3057  * @arg2: unused
3058  * @req: sysctl request pointer
3059  *
3060  * On read: Displays the configured FEC mode
3061  * On write: Sets the device's FEC mode to the input string, if it's valid.
3062  * Valid input strings: see ICE_SYSCTL_HELP_FEC_CONFIG
3063  */
3064 static int
3065 ice_sysctl_fec_config(SYSCTL_HANDLER_ARGS)
3066 {
3067 	struct ice_softc *sc = (struct ice_softc *)arg1;
3068 	struct ice_port_info *pi = sc->hw.port_info;
3069 	enum ice_fec_mode new_mode;
3070 	device_t dev = sc->dev;
3071 	char req_fec[32];
3072 	int ret;
3073 
3074 	UNREFERENCED_PARAMETER(arg2);
3075 
3076 	if (ice_driver_is_detaching(sc))
3077 		return (ESHUTDOWN);
3078 
3079 	bzero(req_fec, sizeof(req_fec));
3080 	strlcpy(req_fec, ice_requested_fec_mode(pi), sizeof(req_fec));
3081 
3082 	ret = sysctl_handle_string(oidp, req_fec, sizeof(req_fec), req);
3083 	if ((ret) || (req->newptr == NULL))
3084 		return (ret);
3085 
3086 	if (strcmp(req_fec, "auto") == 0 ||
3087 	    strcmp(req_fec, ice_fec_str(ICE_FEC_AUTO)) == 0) {
3088 		new_mode = ICE_FEC_AUTO;
3089 	} else if (strcmp(req_fec, "fc") == 0 ||
3090 	    strcmp(req_fec, ice_fec_str(ICE_FEC_BASER)) == 0) {
3091 		new_mode = ICE_FEC_BASER;
3092 	} else if (strcmp(req_fec, "rs") == 0 ||
3093 	    strcmp(req_fec, ice_fec_str(ICE_FEC_RS)) == 0) {
3094 		new_mode = ICE_FEC_RS;
3095 	} else if (strcmp(req_fec, "none") == 0 ||
3096 	    strcmp(req_fec, ice_fec_str(ICE_FEC_NONE)) == 0) {
3097 		new_mode = ICE_FEC_NONE;
3098 	} else {
3099 		device_printf(dev,
3100 		    "%s: \"%s\" is not a valid FEC mode\n",
3101 		    __func__, req_fec);
3102 		return (EINVAL);
3103 	}
3104 
3105 	/* Cache user FEC mode for later link ups */
3106 	pi->phy.curr_user_fec_req = new_mode;
3107 
3108 	/* Apply settings requested by user */
3109 	return ice_apply_saved_phy_cfg(sc, ICE_APPLY_FEC);
3110 }
3111 
3112 /**
3113  * ice_sysctl_negotiated_fec - Display the negotiated FEC mode on the link
3114  * @oidp: sysctl oid structure
3115  * @arg1: pointer to private data structure
3116  * @arg2: unused
3117  * @req: sysctl request pointer
3118  *
3119  * On read: Displays the negotiated FEC mode, in a string
3120  */
3121 static int
3122 ice_sysctl_negotiated_fec(SYSCTL_HANDLER_ARGS)
3123 {
3124 	struct ice_softc *sc = (struct ice_softc *)arg1;
3125 	struct ice_hw *hw = &sc->hw;
3126 	char neg_fec[32];
3127 	int ret;
3128 
3129 	UNREFERENCED_PARAMETER(arg2);
3130 
3131 	if (ice_driver_is_detaching(sc))
3132 		return (ESHUTDOWN);
3133 
3134 	/* Copy const string into a buffer to drop const qualifier */
3135 	bzero(neg_fec, sizeof(neg_fec));
3136 	strlcpy(neg_fec, ice_negotiated_fec_mode(hw->port_info), sizeof(neg_fec));
3137 
3138 	ret = sysctl_handle_string(oidp, neg_fec, 0, req);
3139 	if (req->newptr != NULL)
3140 		return (EPERM);
3141 
3142 	return (ret);
3143 }
3144 
3145 #define ICE_SYSCTL_HELP_FC_CONFIG				\
3146 "\nDisplay or set the port's advertised flow control mode.\n"	\
3147 "\t0 - " ICE_FC_STRING_NONE					\
3148 "\n\t1 - " ICE_FC_STRING_RX					\
3149 "\n\t2 - " ICE_FC_STRING_TX					\
3150 "\n\t3 - " ICE_FC_STRING_FULL					\
3151 "\nEither the numbers or the strings above can be used to set the advertised mode."
3152 
3153 /**
3154  * ice_sysctl_fc_config - Display/change the advertised flow control mode
3155  * @oidp: sysctl oid structure
3156  * @arg1: pointer to private data structure
3157  * @arg2: unused
3158  * @req: sysctl request pointer
3159  *
3160  * On read: Displays the configured flow control mode
3161  * On write: Sets the device's flow control mode to the input, if it's valid.
3162  * Valid input strings: see ICE_SYSCTL_HELP_FC_CONFIG
3163  */
3164 static int
3165 ice_sysctl_fc_config(SYSCTL_HANDLER_ARGS)
3166 {
3167 	struct ice_softc *sc = (struct ice_softc *)arg1;
3168 	struct ice_port_info *pi = sc->hw.port_info;
3169 	struct ice_aqc_get_phy_caps_data pcaps = { 0 };
3170 	enum ice_fc_mode old_mode, new_mode;
3171 	struct ice_hw *hw = &sc->hw;
3172 	device_t dev = sc->dev;
3173 	enum ice_status status;
3174 	int ret, fc_num;
3175 	bool mode_set = false;
3176 	struct sbuf buf;
3177 	char *fc_str_end;
3178 	char fc_str[32];
3179 
3180 	UNREFERENCED_PARAMETER(arg2);
3181 
3182 	if (ice_driver_is_detaching(sc))
3183 		return (ESHUTDOWN);
3184 
3185 	status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_ACTIVE_CFG,
3186 				     &pcaps, NULL);
3187 	if (status != ICE_SUCCESS) {
3188 		device_printf(dev,
3189 		    "%s: ice_aq_get_phy_caps failed; status %s, aq_err %s\n",
3190 		    __func__, ice_status_str(status),
3191 		    ice_aq_str(hw->adminq.sq_last_status));
3192 		return (EIO);
3193 	}
3194 
3195 	/* Convert HW response format to SW enum value */
3196 	if ((pcaps.caps & ICE_AQC_PHY_EN_TX_LINK_PAUSE) &&
3197 	    (pcaps.caps & ICE_AQC_PHY_EN_RX_LINK_PAUSE))
3198 		old_mode = ICE_FC_FULL;
3199 	else if (pcaps.caps & ICE_AQC_PHY_EN_TX_LINK_PAUSE)
3200 		old_mode = ICE_FC_TX_PAUSE;
3201 	else if (pcaps.caps & ICE_AQC_PHY_EN_RX_LINK_PAUSE)
3202 		old_mode = ICE_FC_RX_PAUSE;
3203 	else
3204 		old_mode = ICE_FC_NONE;
3205 
3206 	/* Create "old" string for output */
3207 	bzero(fc_str, sizeof(fc_str));
3208 	sbuf_new_for_sysctl(&buf, fc_str, sizeof(fc_str), req);
3209 	sbuf_printf(&buf, "%d<%s>", old_mode, ice_fc_str(old_mode));
3210 	sbuf_finish(&buf);
3211 	sbuf_delete(&buf);
3212 
3213 	ret = sysctl_handle_string(oidp, fc_str, sizeof(fc_str), req);
3214 	if ((ret) || (req->newptr == NULL))
3215 		return (ret);
3216 
3217 	/* Try to parse input as a string, first */
3218 	if (strcasecmp(ice_fc_str(ICE_FC_FULL), fc_str) == 0) {
3219 		new_mode = ICE_FC_FULL;
3220 		mode_set = true;
3221 	}
3222 	else if (strcasecmp(ice_fc_str(ICE_FC_TX_PAUSE), fc_str) == 0) {
3223 		new_mode = ICE_FC_TX_PAUSE;
3224 		mode_set = true;
3225 	}
3226 	else if (strcasecmp(ice_fc_str(ICE_FC_RX_PAUSE), fc_str) == 0) {
3227 		new_mode = ICE_FC_RX_PAUSE;
3228 		mode_set = true;
3229 	}
3230 	else if (strcasecmp(ice_fc_str(ICE_FC_NONE), fc_str) == 0) {
3231 		new_mode = ICE_FC_NONE;
3232 		mode_set = true;
3233 	}
3234 
3235 	/*
3236 	 * Then check if it's an integer, for compatibility with the method
3237 	 * used in older drivers.
3238 	 */
3239 	if (!mode_set) {
3240 		fc_num = strtol(fc_str, &fc_str_end, 0);
3241 		if (fc_str_end == fc_str)
3242 			fc_num = -1;
3243 		switch (fc_num) {
3244 		case 3:
3245 			new_mode = ICE_FC_FULL;
3246 			break;
3247 		case 2:
3248 			new_mode = ICE_FC_TX_PAUSE;
3249 			break;
3250 		case 1:
3251 			new_mode = ICE_FC_RX_PAUSE;
3252 			break;
3253 		case 0:
3254 			new_mode = ICE_FC_NONE;
3255 			break;
3256 		default:
3257 			device_printf(dev,
3258 			    "%s: \"%s\" is not a valid flow control mode\n",
3259 			    __func__, fc_str);
3260 			return (EINVAL);
3261 		}
3262 	}
3263 
3264 	/* Save flow control mode from user */
3265 	pi->phy.curr_user_fc_req = new_mode;
3266 
3267 	/* Turn off Priority Flow Control when Link Flow Control is enabled */
3268 	if ((hw->port_info->qos_cfg.is_sw_lldp) &&
3269 	    (hw->port_info->qos_cfg.local_dcbx_cfg.pfc.pfcena != 0) &&
3270 	    (new_mode != ICE_FC_NONE)) {
3271 		ret = ice_config_pfc(sc, 0x0);
3272 		if (ret)
3273 			return (ret);
3274 	}
3275 
3276 	/* Apply settings requested by user */
3277 	return ice_apply_saved_phy_cfg(sc, ICE_APPLY_FC);
3278 }
3279 
3280 /**
3281  * ice_sysctl_negotiated_fc - Display currently negotiated FC mode
3282  * @oidp: sysctl oid structure
3283  * @arg1: pointer to private data structure
3284  * @arg2: unused
3285  * @req: sysctl request pointer
3286  *
3287  * On read: Displays the currently negotiated flow control settings.
3288  *
3289  * If link is not established, this will report ICE_FC_NONE, as no flow
3290  * control is negotiated while link is down.
3291  */
3292 static int
3293 ice_sysctl_negotiated_fc(SYSCTL_HANDLER_ARGS)
3294 {
3295 	struct ice_softc *sc = (struct ice_softc *)arg1;
3296 	struct ice_port_info *pi = sc->hw.port_info;
3297 	const char *negotiated_fc;
3298 
3299 	UNREFERENCED_PARAMETER(arg2);
3300 
3301 	if (ice_driver_is_detaching(sc))
3302 		return (ESHUTDOWN);
3303 
3304 	negotiated_fc = ice_flowcontrol_mode(pi);
3305 
3306 	return sysctl_handle_string(oidp, __DECONST(char *, negotiated_fc), 0, req);
3307 }
3308 
3309 /**
3310  * __ice_sysctl_phy_type_handler - Display/change supported PHY types/speeds
3311  * @oidp: sysctl oid structure
3312  * @arg1: pointer to private data structure
3313  * @arg2: unused
3314  * @req: sysctl request pointer
3315  * @is_phy_type_high: if true, handle the high PHY type instead of the low PHY type
3316  *
3317  * Private handler for phy_type_high and phy_type_low sysctls.
3318  */
3319 static int
3320 __ice_sysctl_phy_type_handler(SYSCTL_HANDLER_ARGS, bool is_phy_type_high)
3321 {
3322 	struct ice_softc *sc = (struct ice_softc *)arg1;
3323 	struct ice_aqc_get_phy_caps_data pcaps = { 0 };
3324 	struct ice_aqc_set_phy_cfg_data cfg = { 0 };
3325 	struct ice_hw *hw = &sc->hw;
3326 	device_t dev = sc->dev;
3327 	enum ice_status status;
3328 	uint64_t types;
3329 	int ret;
3330 
3331 	UNREFERENCED_PARAMETER(arg2);
3332 
3333 	if (ice_driver_is_detaching(sc))
3334 		return (ESHUTDOWN);
3335 
3336 	status = ice_aq_get_phy_caps(hw->port_info, false, ICE_AQC_REPORT_ACTIVE_CFG,
3337 				     &pcaps, NULL);
3338 	if (status != ICE_SUCCESS) {
3339 		device_printf(dev,
3340 		    "%s: ice_aq_get_phy_caps failed; status %s, aq_err %s\n",
3341 		    __func__, ice_status_str(status),
3342 		    ice_aq_str(hw->adminq.sq_last_status));
3343 		return (EIO);
3344 	}
3345 
3346 	if (is_phy_type_high)
3347 		types = pcaps.phy_type_high;
3348 	else
3349 		types = pcaps.phy_type_low;
3350 
3351 	ret = sysctl_handle_64(oidp, &types, sizeof(types), req);
3352 	if ((ret) || (req->newptr == NULL))
3353 		return (ret);
3354 
3355 	ice_copy_phy_caps_to_cfg(hw->port_info, &pcaps, &cfg);
3356 
3357 	if (is_phy_type_high)
3358 		cfg.phy_type_high = types & hw->port_info->phy.phy_type_high;
3359 	else
3360 		cfg.phy_type_low = types & hw->port_info->phy.phy_type_low;
3361 	cfg.caps |= ICE_AQ_PHY_ENA_AUTO_LINK_UPDT;
3362 
3363 	status = ice_aq_set_phy_cfg(hw, hw->port_info, &cfg, NULL);
3364 	if (status != ICE_SUCCESS) {
3365 		device_printf(dev,
3366 		    "%s: ice_aq_set_phy_cfg failed; status %s, aq_err %s\n",
3367 		    __func__, ice_status_str(status),
3368 		    ice_aq_str(hw->adminq.sq_last_status));
3369 		return (EIO);
3370 	}
3371 
3372 	return (0);
3373 
3374 }
3375 
3376 /**
3377  * ice_sysctl_phy_type_low - Display/change supported lower PHY types/speeds
3378  * @oidp: sysctl oid structure
3379  * @arg1: pointer to private data structure
3380  * @arg2: unused
3381  * @req: sysctl request pointer
3382  *
3383  * On read: Displays the currently supported lower PHY types
3384  * On write: Sets the device's supported low PHY types
3385  */
3386 static int
3387 ice_sysctl_phy_type_low(SYSCTL_HANDLER_ARGS)
3388 {
3389 	return __ice_sysctl_phy_type_handler(oidp, arg1, arg2, req, false);
3390 }
3391 
3392 /**
3393  * ice_sysctl_phy_type_high - Display/change supported higher PHY types/speeds
3394  * @oidp: sysctl oid structure
3395  * @arg1: pointer to private data structure
3396  * @arg2: unused
3397  * @req: sysctl request pointer
3398  *
3399  * On read: Displays the currently supported higher PHY types
3400  * On write: Sets the device's supported high PHY types
3401  */
3402 static int
3403 ice_sysctl_phy_type_high(SYSCTL_HANDLER_ARGS)
3404 {
3405 	return __ice_sysctl_phy_type_handler(oidp, arg1, arg2, req, true);
3406 }
3407 
3408 /**
3409  * ice_sysctl_phy_caps - Display response from Get PHY abililties
3410  * @oidp: sysctl oid structure
3411  * @arg1: pointer to private data structure
3412  * @arg2: unused
3413  * @req: sysctl request pointer
3414  * @report_mode: the mode to report
3415  *
3416  * On read: Display the response from Get PHY abillities with the given report
3417  * mode.
3418  */
3419 static int
3420 ice_sysctl_phy_caps(SYSCTL_HANDLER_ARGS, u8 report_mode)
3421 {
3422 	struct ice_softc *sc = (struct ice_softc *)arg1;
3423 	struct ice_aqc_get_phy_caps_data pcaps = { 0 };
3424 	struct ice_hw *hw = &sc->hw;
3425 	struct ice_port_info *pi = hw->port_info;
3426 	device_t dev = sc->dev;
3427 	enum ice_status status;
3428 	int ret;
3429 
3430 	UNREFERENCED_PARAMETER(arg2);
3431 
3432 	ret = priv_check(curthread, PRIV_DRIVER);
3433 	if (ret)
3434 		return (ret);
3435 
3436 	if (ice_driver_is_detaching(sc))
3437 		return (ESHUTDOWN);
3438 
3439 	status = ice_aq_get_phy_caps(pi, true, report_mode, &pcaps, NULL);
3440 	if (status != ICE_SUCCESS) {
3441 		device_printf(dev,
3442 		    "%s: ice_aq_get_phy_caps failed; status %s, aq_err %s\n",
3443 		    __func__, ice_status_str(status),
3444 		    ice_aq_str(hw->adminq.sq_last_status));
3445 		return (EIO);
3446 	}
3447 
3448 	ret = sysctl_handle_opaque(oidp, &pcaps, sizeof(pcaps), req);
3449 	if (req->newptr != NULL)
3450 		return (EPERM);
3451 
3452 	return (ret);
3453 }
3454 
3455 /**
3456  * ice_sysctl_phy_sw_caps - Display response from Get PHY abililties
3457  * @oidp: sysctl oid structure
3458  * @arg1: pointer to private data structure
3459  * @arg2: unused
3460  * @req: sysctl request pointer
3461  *
3462  * On read: Display the response from Get PHY abillities reporting the last
3463  * software configuration.
3464  */
3465 static int
3466 ice_sysctl_phy_sw_caps(SYSCTL_HANDLER_ARGS)
3467 {
3468 	return ice_sysctl_phy_caps(oidp, arg1, arg2, req,
3469 				   ICE_AQC_REPORT_ACTIVE_CFG);
3470 }
3471 
3472 /**
3473  * ice_sysctl_phy_nvm_caps - Display response from Get PHY abililties
3474  * @oidp: sysctl oid structure
3475  * @arg1: pointer to private data structure
3476  * @arg2: unused
3477  * @req: sysctl request pointer
3478  *
3479  * On read: Display the response from Get PHY abillities reporting the NVM
3480  * configuration.
3481  */
3482 static int
3483 ice_sysctl_phy_nvm_caps(SYSCTL_HANDLER_ARGS)
3484 {
3485 	return ice_sysctl_phy_caps(oidp, arg1, arg2, req,
3486 				   ICE_AQC_REPORT_TOPO_CAP_NO_MEDIA);
3487 }
3488 
3489 /**
3490  * ice_sysctl_phy_topo_caps - Display response from Get PHY abililties
3491  * @oidp: sysctl oid structure
3492  * @arg1: pointer to private data structure
3493  * @arg2: unused
3494  * @req: sysctl request pointer
3495  *
3496  * On read: Display the response from Get PHY abillities reporting the
3497  * topology configuration.
3498  */
3499 static int
3500 ice_sysctl_phy_topo_caps(SYSCTL_HANDLER_ARGS)
3501 {
3502 	return ice_sysctl_phy_caps(oidp, arg1, arg2, req,
3503 				   ICE_AQC_REPORT_TOPO_CAP_MEDIA);
3504 }
3505 
3506 /**
3507  * ice_sysctl_phy_link_status - Display response from Get Link Status
3508  * @oidp: sysctl oid structure
3509  * @arg1: pointer to private data structure
3510  * @arg2: unused
3511  * @req: sysctl request pointer
3512  *
3513  * On read: Display the response from firmware for the Get Link Status
3514  * request.
3515  */
3516 static int
3517 ice_sysctl_phy_link_status(SYSCTL_HANDLER_ARGS)
3518 {
3519 	struct ice_aqc_get_link_status_data link_data = { 0 };
3520 	struct ice_softc *sc = (struct ice_softc *)arg1;
3521 	struct ice_hw *hw = &sc->hw;
3522 	struct ice_port_info *pi = hw->port_info;
3523 	struct ice_aqc_get_link_status *resp;
3524 	struct ice_aq_desc desc;
3525 	device_t dev = sc->dev;
3526 	enum ice_status status;
3527 	int ret;
3528 
3529 	UNREFERENCED_PARAMETER(arg2);
3530 
3531 	/*
3532 	 * Ensure that only contexts with driver privilege are allowed to
3533 	 * access this information
3534 	 */
3535 	ret = priv_check(curthread, PRIV_DRIVER);
3536 	if (ret)
3537 		return (ret);
3538 
3539 	if (ice_driver_is_detaching(sc))
3540 		return (ESHUTDOWN);
3541 
3542 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_link_status);
3543 	resp = &desc.params.get_link_status;
3544 	resp->lport_num = pi->lport;
3545 
3546 	status = ice_aq_send_cmd(hw, &desc, &link_data, sizeof(link_data), NULL);
3547 	if (status != ICE_SUCCESS) {
3548 		device_printf(dev,
3549 		    "%s: ice_aq_send_cmd failed; status %s, aq_err %s\n",
3550 		    __func__, ice_status_str(status),
3551 		    ice_aq_str(hw->adminq.sq_last_status));
3552 		return (EIO);
3553 	}
3554 
3555 	ret = sysctl_handle_opaque(oidp, &link_data, sizeof(link_data), req);
3556 	if (req->newptr != NULL)
3557 		return (EPERM);
3558 
3559 	return (ret);
3560 }
3561 
3562 /**
3563  * ice_sysctl_fw_cur_lldp_persist_status - Display current FW LLDP status
3564  * @oidp: sysctl oid structure
3565  * @arg1: pointer to private softc structure
3566  * @arg2: unused
3567  * @req: sysctl request pointer
3568  *
3569  * On read: Displays current persistent LLDP status.
3570  */
3571 static int
3572 ice_sysctl_fw_cur_lldp_persist_status(SYSCTL_HANDLER_ARGS)
3573 {
3574 	struct ice_softc *sc = (struct ice_softc *)arg1;
3575 	struct ice_hw *hw = &sc->hw;
3576 	device_t dev = sc->dev;
3577 	enum ice_status status;
3578 	struct sbuf *sbuf;
3579 	u32 lldp_state;
3580 
3581 	UNREFERENCED_PARAMETER(arg2);
3582 	UNREFERENCED_PARAMETER(oidp);
3583 
3584 	if (ice_driver_is_detaching(sc))
3585 		return (ESHUTDOWN);
3586 
3587 	status = ice_get_cur_lldp_persist_status(hw, &lldp_state);
3588 	if (status) {
3589 		device_printf(dev,
3590 		    "Could not acquire current LLDP persistence status, err %s aq_err %s\n",
3591 		    ice_status_str(status), ice_aq_str(hw->adminq.sq_last_status));
3592 		return (EIO);
3593 	}
3594 
3595 	sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
3596 	sbuf_printf(sbuf, "%s", ice_fw_lldp_status(lldp_state));
3597 	sbuf_finish(sbuf);
3598 	sbuf_delete(sbuf);
3599 
3600 	return (0);
3601 }
3602 
3603 /**
3604  * ice_sysctl_fw_dflt_lldp_persist_status - Display default FW LLDP status
3605  * @oidp: sysctl oid structure
3606  * @arg1: pointer to private softc structure
3607  * @arg2: unused
3608  * @req: sysctl request pointer
3609  *
3610  * On read: Displays default persistent LLDP status.
3611  */
3612 static int
3613 ice_sysctl_fw_dflt_lldp_persist_status(SYSCTL_HANDLER_ARGS)
3614 {
3615 	struct ice_softc *sc = (struct ice_softc *)arg1;
3616 	struct ice_hw *hw = &sc->hw;
3617 	device_t dev = sc->dev;
3618 	enum ice_status status;
3619 	struct sbuf *sbuf;
3620 	u32 lldp_state;
3621 
3622 	UNREFERENCED_PARAMETER(arg2);
3623 	UNREFERENCED_PARAMETER(oidp);
3624 
3625 	if (ice_driver_is_detaching(sc))
3626 		return (ESHUTDOWN);
3627 
3628 	status = ice_get_dflt_lldp_persist_status(hw, &lldp_state);
3629 	if (status) {
3630 		device_printf(dev,
3631 		    "Could not acquire default LLDP persistence status, err %s aq_err %s\n",
3632 		    ice_status_str(status), ice_aq_str(hw->adminq.sq_last_status));
3633 		return (EIO);
3634 	}
3635 
3636 	sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
3637 	sbuf_printf(sbuf, "%s", ice_fw_lldp_status(lldp_state));
3638 	sbuf_finish(sbuf);
3639 	sbuf_delete(sbuf);
3640 
3641 	return (0);
3642 }
3643 
3644 #define ICE_SYSCTL_HELP_FW_LLDP_AGENT	\
3645 "\nDisplay or change FW LLDP agent state:" \
3646 "\n\t0 - disabled"			\
3647 "\n\t1 - enabled"
3648 
3649 /**
3650  * ice_sysctl_fw_lldp_agent - Display or change the FW LLDP agent status
3651  * @oidp: sysctl oid structure
3652  * @arg1: pointer to private softc structure
3653  * @arg2: unused
3654  * @req: sysctl request pointer
3655  *
3656  * On read: Displays whether the FW LLDP agent is running
3657  * On write: Persistently enables or disables the FW LLDP agent
3658  */
3659 static int
3660 ice_sysctl_fw_lldp_agent(SYSCTL_HANDLER_ARGS)
3661 {
3662 	struct ice_softc *sc = (struct ice_softc *)arg1;
3663 	struct ice_hw *hw = &sc->hw;
3664 	device_t dev = sc->dev;
3665 	enum ice_status status;
3666 	int ret;
3667 	u32 old_state;
3668 	u8 fw_lldp_enabled;
3669 	bool retried_start_lldp = false;
3670 
3671 	UNREFERENCED_PARAMETER(arg2);
3672 
3673 	if (ice_driver_is_detaching(sc))
3674 		return (ESHUTDOWN);
3675 
3676 	status = ice_get_cur_lldp_persist_status(hw, &old_state);
3677 	if (status) {
3678 		device_printf(dev,
3679 		    "Could not acquire current LLDP persistence status, err %s aq_err %s\n",
3680 		    ice_status_str(status), ice_aq_str(hw->adminq.sq_last_status));
3681 		return (EIO);
3682 	}
3683 
3684 	if (old_state > ICE_LLDP_ADMINSTATUS_ENA_RXTX) {
3685 		status = ice_get_dflt_lldp_persist_status(hw, &old_state);
3686 		if (status) {
3687 			device_printf(dev,
3688 			    "Could not acquire default LLDP persistence status, err %s aq_err %s\n",
3689 			    ice_status_str(status),
3690 			    ice_aq_str(hw->adminq.sq_last_status));
3691 			return (EIO);
3692 		}
3693 	}
3694 	if (old_state == 0)
3695 		fw_lldp_enabled = false;
3696 	else
3697 		fw_lldp_enabled = true;
3698 
3699 	ret = sysctl_handle_bool(oidp, &fw_lldp_enabled, 0, req);
3700 	if ((ret) || (req->newptr == NULL))
3701 		return (ret);
3702 
3703 	if (old_state == 0 && fw_lldp_enabled == false)
3704 		return (0);
3705 
3706 	if (old_state != 0 && fw_lldp_enabled == true)
3707 		return (0);
3708 
3709 	if (fw_lldp_enabled == false) {
3710 		status = ice_aq_stop_lldp(hw, true, true, NULL);
3711 		/* EPERM is returned if the LLDP agent is already shutdown */
3712 		if (status && hw->adminq.sq_last_status != ICE_AQ_RC_EPERM) {
3713 			device_printf(dev,
3714 			    "%s: ice_aq_stop_lldp failed; status %s, aq_err %s\n",
3715 			    __func__, ice_status_str(status),
3716 			    ice_aq_str(hw->adminq.sq_last_status));
3717 			return (EIO);
3718 		}
3719 		ice_aq_set_dcb_parameters(hw, true, NULL);
3720 		hw->port_info->qos_cfg.is_sw_lldp = true;
3721 		ice_add_rx_lldp_filter(sc);
3722 	} else {
3723 		ice_del_rx_lldp_filter(sc);
3724 retry_start_lldp:
3725 		status = ice_aq_start_lldp(hw, true, NULL);
3726 		if (status) {
3727 			switch (hw->adminq.sq_last_status) {
3728 			/* EEXIST is returned if the LLDP agent is already started */
3729 			case ICE_AQ_RC_EEXIST:
3730 				break;
3731 			case ICE_AQ_RC_EAGAIN:
3732 				/* Retry command after a 2 second wait */
3733 				if (retried_start_lldp == false) {
3734 					retried_start_lldp = true;
3735 					pause("slldp", ICE_START_LLDP_RETRY_WAIT);
3736 					goto retry_start_lldp;
3737 				}
3738 				/* Fallthrough */
3739 			default:
3740 				device_printf(dev,
3741 				    "%s: ice_aq_start_lldp failed; status %s, aq_err %s\n",
3742 				    __func__, ice_status_str(status),
3743 				    ice_aq_str(hw->adminq.sq_last_status));
3744 				return (EIO);
3745 			}
3746 		}
3747 		hw->port_info->qos_cfg.is_sw_lldp = false;
3748 	}
3749 
3750 	return (ret);
3751 }
3752 
3753 #define ICE_SYSCTL_HELP_ETS_MIN_RATE \
3754 "\nIn FW DCB mode (fw_lldp_agent=1), displays the current ETS bandwidth table." \
3755 "\nIn SW DCB mode, displays and allows setting the table." \
3756 "\nInput must be in the format e.g. 30,10,10,10,10,10,10,10" \
3757 "\nWhere the bandwidth total must add up to 100"
3758 
3759 /**
3760  * ice_sysctl_ets_min_rate - Report/configure ETS bandwidth
3761  * @oidp: sysctl oid structure
3762  * @arg1: pointer to private data structure
3763  * @arg2: unused
3764  * @req: sysctl request pointer
3765  *
3766  * Returns the current ETS TC bandwidth table
3767  * cached by the driver.
3768  *
3769  * In SW DCB mode this sysctl also accepts a value that will
3770  * be sent to the firmware for configuration.
3771  */
3772 static int
3773 ice_sysctl_ets_min_rate(SYSCTL_HANDLER_ARGS)
3774 {
3775 	struct ice_softc *sc = (struct ice_softc *)arg1;
3776 	struct ice_dcbx_cfg *local_dcbx_cfg;
3777 	struct ice_port_info *pi;
3778 	struct ice_hw *hw = &sc->hw;
3779 	device_t dev = sc->dev;
3780 	enum ice_status status;
3781 	struct sbuf *sbuf;
3782 	int ret;
3783 
3784 	/* Store input rates from user */
3785 	char ets_user_buf[128] = "";
3786 	u8 new_ets_table[ICE_MAX_TRAFFIC_CLASS] = {};
3787 
3788 	UNREFERENCED_PARAMETER(arg2);
3789 
3790 	if (ice_driver_is_detaching(sc))
3791 		return (ESHUTDOWN);
3792 
3793 	if (req->oldptr == NULL && req->newptr == NULL) {
3794 		ret = SYSCTL_OUT(req, 0, 128);
3795 		return (ret);
3796 	}
3797 
3798 	pi = hw->port_info;
3799 	local_dcbx_cfg = &pi->qos_cfg.local_dcbx_cfg;
3800 
3801 	sbuf = sbuf_new(NULL, ets_user_buf, 128, SBUF_FIXEDLEN | SBUF_INCLUDENUL);
3802 
3803 	/* Format ETS BW data for output */
3804 	for (int i = 0; i < ICE_MAX_TRAFFIC_CLASS; i++) {
3805 		sbuf_printf(sbuf, "%d", local_dcbx_cfg->etscfg.tcbwtable[i]);
3806 		if (i != ICE_MAX_TRAFFIC_CLASS - 1)
3807 			sbuf_printf(sbuf, ",");
3808 	}
3809 
3810 	sbuf_finish(sbuf);
3811 	sbuf_delete(sbuf);
3812 
3813 	/* Read in the new ETS values */
3814 	ret = sysctl_handle_string(oidp, ets_user_buf, sizeof(ets_user_buf), req);
3815 	if ((ret) || (req->newptr == NULL))
3816 		return (ret);
3817 
3818 	/* Don't allow setting changes in FW DCB mode */
3819 	if (!hw->port_info->qos_cfg.is_sw_lldp)
3820 		return (EPERM);
3821 
3822 	ret = ice_ets_str_to_tbl(ets_user_buf, new_ets_table, 100);
3823 	if (ret) {
3824 		device_printf(dev, "%s: Could not parse input BW table: %s\n",
3825 		    __func__, ets_user_buf);
3826 		return (ret);
3827 	}
3828 
3829 	if (!ice_check_ets_bw(new_ets_table)) {
3830 		device_printf(dev, "%s: Bandwidth sum does not equal 100: %s\n",
3831 		    __func__, ets_user_buf);
3832 		return (EINVAL);
3833 	}
3834 
3835 	memcpy(local_dcbx_cfg->etscfg.tcbwtable, new_ets_table,
3836 	    sizeof(new_ets_table));
3837 
3838 	/* If BW > 0, then set TSA entry to 2 */
3839 	for (int i = 0; i < ICE_MAX_TRAFFIC_CLASS; i++) {
3840 		if (new_ets_table[i] > 0)
3841 			local_dcbx_cfg->etscfg.tsatable[i] = 2;
3842 		else
3843 			local_dcbx_cfg->etscfg.tsatable[i] = 0;
3844 	}
3845 	local_dcbx_cfg->etscfg.willing = 0;
3846 	local_dcbx_cfg->etsrec = local_dcbx_cfg->etscfg;
3847 	local_dcbx_cfg->app_mode = ICE_DCBX_APPS_NON_WILLING;
3848 
3849 	status = ice_set_dcb_cfg(pi);
3850 	if (status) {
3851 		device_printf(dev,
3852 		    "%s: Failed to set DCB config; status %s, aq_err %s\n",
3853 		    __func__, ice_status_str(status),
3854 		    ice_aq_str(hw->adminq.sq_last_status));
3855 		return (EIO);
3856 	}
3857 
3858 	ice_do_dcb_reconfig(sc);
3859 
3860 	return (0);
3861 }
3862 
3863 #define ICE_SYSCTL_HELP_UP2TC_MAP \
3864 "\nIn FW DCB mode (fw_lldp_agent=1), displays the current ETS priority assignment table." \
3865 "\nIn SW DCB mode, displays and allows setting the table." \
3866 "\nInput must be in this format: 0,1,2,3,4,5,6,7" \
3867 "\nWhere the 1st number is the TC for UP0, 2nd number is the TC for UP1, etc"
3868 
3869 /**
3870  * ice_sysctl_up2tc_map - Report or configure UP2TC mapping
3871  * @oidp: sysctl oid structure
3872  * @arg1: pointer to private data structure
3873  * @arg2: unused
3874  * @req: sysctl request pointer
3875  *
3876  * In FW DCB mode, returns the current ETS prio table /
3877  * UP2TC mapping from the local MIB.
3878  *
3879  * In SW DCB mode this sysctl also accepts a value that will
3880  * be sent to the firmware for configuration.
3881  */
3882 static int
3883 ice_sysctl_up2tc_map(SYSCTL_HANDLER_ARGS)
3884 {
3885 	struct ice_softc *sc = (struct ice_softc *)arg1;
3886 	struct ice_dcbx_cfg *local_dcbx_cfg;
3887 	struct ice_port_info *pi;
3888 	struct ice_hw *hw = &sc->hw;
3889 	device_t dev = sc->dev;
3890 	enum ice_status status;
3891 	struct sbuf *sbuf;
3892 	int ret;
3893 
3894 	/* Store input rates from user */
3895 	char up2tc_user_buf[128] = "";
3896 	/* This array is indexed by UP, not TC */
3897 	u8 new_up2tc[ICE_MAX_TRAFFIC_CLASS] = {};
3898 
3899 	UNREFERENCED_PARAMETER(arg2);
3900 
3901 	if (ice_driver_is_detaching(sc))
3902 		return (ESHUTDOWN);
3903 
3904 	if (req->oldptr == NULL && req->newptr == NULL) {
3905 		ret = SYSCTL_OUT(req, 0, 128);
3906 		return (ret);
3907 	}
3908 
3909 	pi = hw->port_info;
3910 	local_dcbx_cfg = &pi->qos_cfg.local_dcbx_cfg;
3911 
3912 	sbuf = sbuf_new(NULL, up2tc_user_buf, 128, SBUF_FIXEDLEN | SBUF_INCLUDENUL);
3913 
3914 	/* Format ETS Priority Mapping Table for output */
3915 	for (int i = 0; i < ICE_MAX_TRAFFIC_CLASS; i++) {
3916 		sbuf_printf(sbuf, "%d", local_dcbx_cfg->etscfg.prio_table[i]);
3917 		if (i != ICE_MAX_TRAFFIC_CLASS - 1)
3918 			sbuf_printf(sbuf, ",");
3919 	}
3920 
3921 	sbuf_finish(sbuf);
3922 	sbuf_delete(sbuf);
3923 
3924 	/* Read in the new ETS priority mapping */
3925 	ret = sysctl_handle_string(oidp, up2tc_user_buf, sizeof(up2tc_user_buf), req);
3926 	if ((ret) || (req->newptr == NULL))
3927 		return (ret);
3928 
3929 	/* Don't allow setting changes in FW DCB mode */
3930 	if (!hw->port_info->qos_cfg.is_sw_lldp)
3931 		return (EPERM);
3932 
3933 	ret = ice_ets_str_to_tbl(up2tc_user_buf, new_up2tc, 7);
3934 	if (ret) {
3935 		device_printf(dev, "%s: Could not parse input priority assignment table: %s\n",
3936 		    __func__, up2tc_user_buf);
3937 		return (ret);
3938 	}
3939 
3940 	/* Prepare updated ETS TLV */
3941 	memcpy(local_dcbx_cfg->etscfg.prio_table, new_up2tc,
3942 	    sizeof(new_up2tc));
3943 
3944 	status = ice_set_dcb_cfg(pi);
3945 	if (status) {
3946 		device_printf(dev,
3947 		    "%s: Failed to set DCB config; status %s, aq_err %s\n",
3948 		    __func__, ice_status_str(status),
3949 		    ice_aq_str(hw->adminq.sq_last_status));
3950 		return (EIO);
3951 	}
3952 
3953 	ice_do_dcb_reconfig(sc);
3954 
3955 	return (0);
3956 }
3957 
3958 /**
3959  * ice_config_pfc - helper function to set PFC config in FW
3960  * @sc: device private structure
3961  * @new_mode: bit flags indicating PFC status for TCs
3962  *
3963  * @pre must be in SW DCB mode
3964  *
3965  * Configures the driver's local PFC TLV and sends it to the
3966  * FW for configuration, then reconfigures the driver/VSI
3967  * for DCB if needed.
3968  */
3969 static int
3970 ice_config_pfc(struct ice_softc *sc, u8 new_mode)
3971 {
3972 	struct ice_dcbx_cfg *local_dcbx_cfg;
3973 	struct ice_hw *hw = &sc->hw;
3974 	struct ice_port_info *pi;
3975 	device_t dev = sc->dev;
3976 	enum ice_status status;
3977 
3978 	pi = hw->port_info;
3979 	local_dcbx_cfg = &pi->qos_cfg.local_dcbx_cfg;
3980 
3981 	/* Prepare updated PFC TLV */
3982 	local_dcbx_cfg->pfc.pfcena = new_mode;
3983 	local_dcbx_cfg->pfc.pfccap = ICE_MAX_TRAFFIC_CLASS;
3984 	local_dcbx_cfg->pfc.willing = 0;
3985 	local_dcbx_cfg->pfc.mbc = 0;
3986 
3987 	status = ice_set_dcb_cfg(pi);
3988 	if (status) {
3989 		device_printf(dev,
3990 		    "%s: Failed to set DCB config; status %s, aq_err %s\n",
3991 		    __func__, ice_status_str(status),
3992 		    ice_aq_str(hw->adminq.sq_last_status));
3993 		return (EIO);
3994 	}
3995 
3996 	ice_do_dcb_reconfig(sc);
3997 
3998 	return (0);
3999 }
4000 
4001 #define ICE_SYSCTL_HELP_PFC_CONFIG \
4002 "\nIn FW DCB mode (fw_lldp_agent=1), displays the current Priority Flow Control configuration" \
4003 "\nIn SW DCB mode, displays and allows setting the configuration" \
4004 "\nInput/Output is in this format: 0xff" \
4005 "\nWhere bit position # enables/disables PFC for that Traffic Class #"
4006 
4007 /**
4008  * ice_sysctl_pfc_config - Report or configure enabled PFC TCs
4009  * @oidp: sysctl oid structure
4010  * @arg1: pointer to private data structure
4011  * @arg2: unused
4012  * @req: sysctl request pointer
4013  *
4014  * In FW DCB mode, returns a bitmap containing the current TCs
4015  * that have PFC enabled on them.
4016  *
4017  * In SW DCB mode this sysctl also accepts a value that will
4018  * be sent to the firmware for configuration.
4019  */
4020 static int
4021 ice_sysctl_pfc_config(SYSCTL_HANDLER_ARGS)
4022 {
4023 	struct ice_softc *sc = (struct ice_softc *)arg1;
4024 	struct ice_dcbx_cfg *local_dcbx_cfg;
4025 	struct ice_port_info *pi;
4026 	struct ice_hw *hw = &sc->hw;
4027 	int ret;
4028 
4029 	/* Store input flags from user */
4030 	u8 user_pfc;
4031 
4032 	UNREFERENCED_PARAMETER(arg2);
4033 
4034 	if (ice_driver_is_detaching(sc))
4035 		return (ESHUTDOWN);
4036 
4037 	if (req->oldptr == NULL && req->newptr == NULL) {
4038 		ret = SYSCTL_OUT(req, 0, sizeof(u8));
4039 		return (ret);
4040 	}
4041 
4042 	pi = hw->port_info;
4043 	local_dcbx_cfg = &pi->qos_cfg.local_dcbx_cfg;
4044 
4045 	/* Format current PFC enable setting for output */
4046 	user_pfc = local_dcbx_cfg->pfc.pfcena;
4047 
4048 	/* Read in the new PFC config */
4049 	ret = sysctl_handle_8(oidp, &user_pfc, 0, req);
4050 	if ((ret) || (req->newptr == NULL))
4051 		return (ret);
4052 
4053 	/* Don't allow setting changes in FW DCB mode */
4054 	if (!hw->port_info->qos_cfg.is_sw_lldp)
4055 		return (EPERM);
4056 
4057 	/* If LFC is active and PFC is going to be turned on, turn LFC off */
4058 	if (user_pfc != 0 && pi->phy.curr_user_fc_req != ICE_FC_NONE) {
4059 		pi->phy.curr_user_fc_req = ICE_FC_NONE;
4060 		ret = ice_apply_saved_phy_cfg(sc, ICE_APPLY_FC);
4061 		if (ret)
4062 			return (ret);
4063 	}
4064 
4065 	return ice_config_pfc(sc, user_pfc);
4066 }
4067 
4068 /**
4069  * ice_add_device_sysctls - add device specific dynamic sysctls
4070  * @sc: device private structure
4071  *
4072  * Add per-device dynamic sysctls which show device configuration or enable
4073  * configuring device functionality. For tunable values which can be set prior
4074  * to load, see ice_add_device_tunables.
4075  *
4076  * This function depends on the sysctl layout setup by ice_add_device_tunables,
4077  * and likely should be called near the end of the attach process.
4078  */
4079 void
4080 ice_add_device_sysctls(struct ice_softc *sc)
4081 {
4082 	struct sysctl_oid *hw_node;
4083 	device_t dev = sc->dev;
4084 
4085 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
4086 	struct sysctl_oid_list *ctx_list =
4087 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
4088 
4089 	SYSCTL_ADD_PROC(ctx, ctx_list,
4090 	    OID_AUTO, "fw_version", CTLTYPE_STRING | CTLFLAG_RD,
4091 	    sc, 0, ice_sysctl_show_fw, "A", "Firmware version");
4092 
4093 	if (ice_is_bit_set(sc->feat_en, ICE_FEATURE_HAS_PBA)) {
4094 		SYSCTL_ADD_PROC(ctx, ctx_list,
4095 		    OID_AUTO, "pba_number", CTLTYPE_STRING | CTLFLAG_RD, sc, 0,
4096 		    ice_sysctl_pba_number, "A", "Product Board Assembly Number");
4097 	}
4098 
4099 	SYSCTL_ADD_PROC(ctx, ctx_list,
4100 	    OID_AUTO, "ddp_version", CTLTYPE_STRING | CTLFLAG_RD,
4101 	    sc, 0, ice_sysctl_pkg_version, "A", "Active DDP package name and version");
4102 
4103 	SYSCTL_ADD_PROC(ctx, ctx_list,
4104 	    OID_AUTO, "current_speed", CTLTYPE_STRING | CTLFLAG_RD,
4105 	    sc, 0, ice_sysctl_current_speed, "A", "Current Port Link Speed");
4106 
4107 	SYSCTL_ADD_PROC(ctx, ctx_list,
4108 	    OID_AUTO, "requested_fec", CTLTYPE_STRING | CTLFLAG_RW,
4109 	    sc, 0, ice_sysctl_fec_config, "A", ICE_SYSCTL_HELP_FEC_CONFIG);
4110 
4111 	SYSCTL_ADD_PROC(ctx, ctx_list,
4112 	    OID_AUTO, "negotiated_fec", CTLTYPE_STRING | CTLFLAG_RD,
4113 	    sc, 0, ice_sysctl_negotiated_fec, "A", "Current Negotiated FEC mode");
4114 
4115 	SYSCTL_ADD_PROC(ctx, ctx_list,
4116 	    OID_AUTO, "fc", CTLTYPE_STRING | CTLFLAG_RW,
4117 	    sc, 0, ice_sysctl_fc_config, "A", ICE_SYSCTL_HELP_FC_CONFIG);
4118 
4119 	SYSCTL_ADD_PROC(ctx, ctx_list,
4120 	    OID_AUTO, "advertise_speed", CTLTYPE_U16 | CTLFLAG_RW,
4121 	    sc, 0, ice_sysctl_advertise_speed, "SU", ICE_SYSCTL_HELP_ADVERTISE_SPEED);
4122 
4123 	SYSCTL_ADD_PROC(ctx, ctx_list,
4124 	    OID_AUTO, "fw_lldp_agent", CTLTYPE_U8 | CTLFLAG_RWTUN,
4125 	    sc, 0, ice_sysctl_fw_lldp_agent, "CU", ICE_SYSCTL_HELP_FW_LLDP_AGENT);
4126 
4127 	SYSCTL_ADD_PROC(ctx, ctx_list,
4128 	    OID_AUTO, "ets_min_rate", CTLTYPE_STRING | CTLFLAG_RW,
4129 	    sc, 0, ice_sysctl_ets_min_rate, "A", ICE_SYSCTL_HELP_ETS_MIN_RATE);
4130 
4131 	SYSCTL_ADD_PROC(ctx, ctx_list,
4132 	    OID_AUTO, "up2tc_map", CTLTYPE_STRING | CTLFLAG_RW,
4133 	    sc, 0, ice_sysctl_up2tc_map, "A", ICE_SYSCTL_HELP_UP2TC_MAP);
4134 
4135 	SYSCTL_ADD_PROC(ctx, ctx_list,
4136 	    OID_AUTO, "pfc", CTLTYPE_U8 | CTLFLAG_RW,
4137 	    sc, 0, ice_sysctl_pfc_config, "CU", ICE_SYSCTL_HELP_PFC_CONFIG);
4138 
4139 	/* Differentiate software and hardware statistics, by keeping hw stats
4140 	 * in their own node. This isn't in ice_add_device_tunables, because
4141 	 * we won't have any CTLFLAG_TUN sysctls under this node.
4142 	 */
4143 	hw_node = SYSCTL_ADD_NODE(ctx, ctx_list, OID_AUTO, "hw", CTLFLAG_RD,
4144 				  NULL, "Port Hardware Statistics");
4145 
4146 	ice_add_sysctls_mac_stats(ctx, hw_node, &sc->stats.cur);
4147 
4148 	/* Add the main PF VSI stats now. Other VSIs will add their own stats
4149 	 * during creation
4150 	 */
4151 	ice_add_vsi_sysctls(&sc->pf_vsi);
4152 
4153 	/* Add sysctls related to debugging the device driver. This includes
4154 	 * sysctls which display additional internal driver state for use in
4155 	 * understanding what is happening within the driver.
4156 	 */
4157 	ice_add_debug_sysctls(sc);
4158 }
4159 
4160 /**
4161  * @enum hmc_error_type
4162  * @brief enumeration of HMC errors
4163  *
4164  * Enumeration defining the possible HMC errors that might occur.
4165  */
4166 enum hmc_error_type {
4167 	HMC_ERR_PMF_INVALID = 0,
4168 	HMC_ERR_VF_IDX_INVALID = 1,
4169 	HMC_ERR_VF_PARENT_PF_INVALID = 2,
4170 	/* 3 is reserved */
4171 	HMC_ERR_INDEX_TOO_BIG = 4,
4172 	HMC_ERR_ADDRESS_TOO_LARGE = 5,
4173 	HMC_ERR_SEGMENT_DESC_INVALID = 6,
4174 	HMC_ERR_SEGMENT_DESC_TOO_SMALL = 7,
4175 	HMC_ERR_PAGE_DESC_INVALID = 8,
4176 	HMC_ERR_UNSUPPORTED_REQUEST_COMPLETION = 9,
4177 	/* 10 is reserved */
4178 	HMC_ERR_INVALID_OBJECT_TYPE = 11,
4179 	/* 12 is reserved */
4180 };
4181 
4182 /**
4183  * ice_log_hmc_error - Log an HMC error message
4184  * @hw: device hw structure
4185  * @dev: the device to pass to device_printf()
4186  *
4187  * Log a message when an HMC error interrupt is triggered.
4188  */
4189 void
4190 ice_log_hmc_error(struct ice_hw *hw, device_t dev)
4191 {
4192 	u32 info, data;
4193 	u8 index, errtype, objtype;
4194 	bool isvf;
4195 
4196 	info = rd32(hw, PFHMC_ERRORINFO);
4197 	data = rd32(hw, PFHMC_ERRORDATA);
4198 
4199 	index = (u8)(info & PFHMC_ERRORINFO_PMF_INDEX_M);
4200 	errtype = (u8)((info & PFHMC_ERRORINFO_HMC_ERROR_TYPE_M) >>
4201 		       PFHMC_ERRORINFO_HMC_ERROR_TYPE_S);
4202 	objtype = (u8)((info & PFHMC_ERRORINFO_HMC_OBJECT_TYPE_M) >>
4203 		       PFHMC_ERRORINFO_HMC_OBJECT_TYPE_S);
4204 
4205 	isvf = info & PFHMC_ERRORINFO_PMF_ISVF_M;
4206 
4207 	device_printf(dev, "%s HMC Error detected on PMF index %d:\n",
4208 		      isvf ? "VF" : "PF", index);
4209 
4210 	device_printf(dev, "error type %d, object type %d, data 0x%08x\n",
4211 		      errtype, objtype, data);
4212 
4213 	switch (errtype) {
4214 	case HMC_ERR_PMF_INVALID:
4215 		device_printf(dev, "Private Memory Function is not valid\n");
4216 		break;
4217 	case HMC_ERR_VF_IDX_INVALID:
4218 		device_printf(dev, "Invalid Private Memory Function index for PE enabled VF\n");
4219 		break;
4220 	case HMC_ERR_VF_PARENT_PF_INVALID:
4221 		device_printf(dev, "Invalid parent PF for PE enabled VF\n");
4222 		break;
4223 	case HMC_ERR_INDEX_TOO_BIG:
4224 		device_printf(dev, "Object index too big\n");
4225 		break;
4226 	case HMC_ERR_ADDRESS_TOO_LARGE:
4227 		device_printf(dev, "Address extends beyond segment descriptor limit\n");
4228 		break;
4229 	case HMC_ERR_SEGMENT_DESC_INVALID:
4230 		device_printf(dev, "Segment descriptor is invalid\n");
4231 		break;
4232 	case HMC_ERR_SEGMENT_DESC_TOO_SMALL:
4233 		device_printf(dev, "Segment descriptor is too small\n");
4234 		break;
4235 	case HMC_ERR_PAGE_DESC_INVALID:
4236 		device_printf(dev, "Page descriptor is invalid\n");
4237 		break;
4238 	case HMC_ERR_UNSUPPORTED_REQUEST_COMPLETION:
4239 		device_printf(dev, "Unsupported Request completion received from PCIe\n");
4240 		break;
4241 	case HMC_ERR_INVALID_OBJECT_TYPE:
4242 		device_printf(dev, "Invalid object type\n");
4243 		break;
4244 	default:
4245 		device_printf(dev, "Unknown HMC error\n");
4246 	}
4247 
4248 	/* Clear the error indication */
4249 	wr32(hw, PFHMC_ERRORINFO, 0);
4250 }
4251 
4252 /**
4253  * @struct ice_sysctl_info
4254  * @brief sysctl information
4255  *
4256  * Structure used to simplify the process of defining the many similar
4257  * statistics sysctls.
4258  */
4259 struct ice_sysctl_info {
4260 	u64		*stat;
4261 	const char	*name;
4262 	const char	*description;
4263 };
4264 
4265 /**
4266  * ice_add_sysctls_eth_stats - Add sysctls for ethernet statistics
4267  * @ctx: sysctl ctx to use
4268  * @parent: the parent node to add sysctls under
4269  * @stats: the ethernet stats structure to source values from
4270  *
4271  * Adds statistics sysctls for the ethernet statistics of the MAC or a VSI.
4272  * Will add them under the parent node specified.
4273  *
4274  * Note that tx_errors is only meaningful for VSIs and not the global MAC/PF
4275  * statistics, so it is not included here. Similarly, rx_discards has different
4276  * descriptions for VSIs and MAC/PF stats, so it is also not included here.
4277  */
4278 void
4279 ice_add_sysctls_eth_stats(struct sysctl_ctx_list *ctx,
4280 			  struct sysctl_oid *parent,
4281 			  struct ice_eth_stats *stats)
4282 {
4283 	const struct ice_sysctl_info ctls[] = {
4284 		/* Rx Stats */
4285 		{ &stats->rx_bytes, "good_octets_rcvd", "Good Octets Received" },
4286 		{ &stats->rx_unicast, "ucast_pkts_rcvd", "Unicast Packets Received" },
4287 		{ &stats->rx_multicast, "mcast_pkts_rcvd", "Multicast Packets Received" },
4288 		{ &stats->rx_broadcast, "bcast_pkts_rcvd", "Broadcast Packets Received" },
4289 		/* Tx Stats */
4290 		{ &stats->tx_bytes, "good_octets_txd", "Good Octets Transmitted" },
4291 		{ &stats->tx_unicast, "ucast_pkts_txd", "Unicast Packets Transmitted" },
4292 		{ &stats->tx_multicast, "mcast_pkts_txd", "Multicast Packets Transmitted" },
4293 		{ &stats->tx_broadcast, "bcast_pkts_txd", "Broadcast Packets Transmitted" },
4294 		/* End */
4295 		{ 0, 0, 0 }
4296 	};
4297 
4298 	struct sysctl_oid_list *parent_list = SYSCTL_CHILDREN(parent);
4299 
4300 	const struct ice_sysctl_info *entry = ctls;
4301 	while (entry->stat != 0) {
4302 		SYSCTL_ADD_U64(ctx, parent_list, OID_AUTO, entry->name,
4303 			       CTLFLAG_RD | CTLFLAG_STATS, entry->stat, 0,
4304 			       entry->description);
4305 		entry++;
4306 	}
4307 }
4308 
4309 /**
4310  * ice_sysctl_tx_cso_stat - Display Tx checksum offload statistic
4311  * @oidp: sysctl oid structure
4312  * @arg1: pointer to private data structure
4313  * @arg2: Tx CSO stat to read
4314  * @req: sysctl request pointer
4315  *
4316  * On read: Sums the per-queue Tx CSO stat and displays it.
4317  */
4318 static int
4319 ice_sysctl_tx_cso_stat(SYSCTL_HANDLER_ARGS)
4320 {
4321 	struct ice_vsi *vsi = (struct ice_vsi *)arg1;
4322 	enum ice_tx_cso_stat type = (enum ice_tx_cso_stat)arg2;
4323 	u64 stat = 0;
4324 	int i;
4325 
4326 	if (ice_driver_is_detaching(vsi->sc))
4327 		return (ESHUTDOWN);
4328 
4329 	/* Check that the type is valid */
4330 	if (type >= ICE_CSO_STAT_TX_COUNT)
4331 		return (EDOOFUS);
4332 
4333 	/* Sum the stat for each of the Tx queues */
4334 	for (i = 0; i < vsi->num_tx_queues; i++)
4335 		stat += vsi->tx_queues[i].stats.cso[type];
4336 
4337 	return sysctl_handle_64(oidp, NULL, stat, req);
4338 }
4339 
4340 /**
4341  * ice_sysctl_rx_cso_stat - Display Rx checksum offload statistic
4342  * @oidp: sysctl oid structure
4343  * @arg1: pointer to private data structure
4344  * @arg2: Rx CSO stat to read
4345  * @req: sysctl request pointer
4346  *
4347  * On read: Sums the per-queue Rx CSO stat and displays it.
4348  */
4349 static int
4350 ice_sysctl_rx_cso_stat(SYSCTL_HANDLER_ARGS)
4351 {
4352 	struct ice_vsi *vsi = (struct ice_vsi *)arg1;
4353 	enum ice_rx_cso_stat type = (enum ice_rx_cso_stat)arg2;
4354 	u64 stat = 0;
4355 	int i;
4356 
4357 	if (ice_driver_is_detaching(vsi->sc))
4358 		return (ESHUTDOWN);
4359 
4360 	/* Check that the type is valid */
4361 	if (type >= ICE_CSO_STAT_RX_COUNT)
4362 		return (EDOOFUS);
4363 
4364 	/* Sum the stat for each of the Rx queues */
4365 	for (i = 0; i < vsi->num_rx_queues; i++)
4366 		stat += vsi->rx_queues[i].stats.cso[type];
4367 
4368 	return sysctl_handle_64(oidp, NULL, stat, req);
4369 }
4370 
4371 /**
4372  * ice_sysctl_rx_errors_stat - Display aggregate of Rx errors
4373  * @oidp: sysctl oid structure
4374  * @arg1: pointer to private data structure
4375  * @arg2: unused
4376  * @req: sysctl request pointer
4377  *
4378  * On read: Sums current values of Rx error statistics and
4379  * displays it.
4380  */
4381 static int
4382 ice_sysctl_rx_errors_stat(SYSCTL_HANDLER_ARGS)
4383 {
4384 	struct ice_vsi *vsi = (struct ice_vsi *)arg1;
4385 	struct ice_hw_port_stats *hs = &vsi->sc->stats.cur;
4386 	u64 stat = 0;
4387 	int i, type;
4388 
4389 	UNREFERENCED_PARAMETER(arg2);
4390 
4391 	if (ice_driver_is_detaching(vsi->sc))
4392 		return (ESHUTDOWN);
4393 
4394 	stat += hs->rx_undersize;
4395 	stat += hs->rx_fragments;
4396 	stat += hs->rx_oversize;
4397 	stat += hs->rx_jabber;
4398 	stat += hs->rx_len_errors;
4399 	stat += hs->crc_errors;
4400 	stat += hs->illegal_bytes;
4401 
4402 	/* Checksum error stats */
4403 	for (i = 0; i < vsi->num_rx_queues; i++)
4404 		for (type = ICE_CSO_STAT_RX_IP4_ERR;
4405 		     type < ICE_CSO_STAT_RX_COUNT;
4406 		     type++)
4407 			stat += vsi->rx_queues[i].stats.cso[type];
4408 
4409 	return sysctl_handle_64(oidp, NULL, stat, req);
4410 }
4411 
4412 /**
4413  * @struct ice_rx_cso_stat_info
4414  * @brief sysctl information for an Rx checksum offload statistic
4415  *
4416  * Structure used to simplify the process of defining the checksum offload
4417  * statistics.
4418  */
4419 struct ice_rx_cso_stat_info {
4420 	enum ice_rx_cso_stat	type;
4421 	const char		*name;
4422 	const char		*description;
4423 };
4424 
4425 /**
4426  * @struct ice_tx_cso_stat_info
4427  * @brief sysctl information for a Tx checksum offload statistic
4428  *
4429  * Structure used to simplify the process of defining the checksum offload
4430  * statistics.
4431  */
4432 struct ice_tx_cso_stat_info {
4433 	enum ice_tx_cso_stat	type;
4434 	const char		*name;
4435 	const char		*description;
4436 };
4437 
4438 /**
4439  * ice_add_sysctls_sw_stats - Add sysctls for software statistics
4440  * @vsi: pointer to the VSI to add sysctls for
4441  * @ctx: sysctl ctx to use
4442  * @parent: the parent node to add sysctls under
4443  *
4444  * Add statistics sysctls for software tracked statistics of a VSI.
4445  *
4446  * Currently this only adds checksum offload statistics, but more counters may
4447  * be added in the future.
4448  */
4449 static void
4450 ice_add_sysctls_sw_stats(struct ice_vsi *vsi,
4451 			 struct sysctl_ctx_list *ctx,
4452 			 struct sysctl_oid *parent)
4453 {
4454 	struct sysctl_oid *cso_node;
4455 	struct sysctl_oid_list *cso_list;
4456 
4457 	/* Tx CSO Stats */
4458 	const struct ice_tx_cso_stat_info tx_ctls[] = {
4459 		{ ICE_CSO_STAT_TX_TCP, "tx_tcp", "Transmit TCP Packets marked for HW checksum" },
4460 		{ ICE_CSO_STAT_TX_UDP, "tx_udp", "Transmit UDP Packets marked for HW checksum" },
4461 		{ ICE_CSO_STAT_TX_SCTP, "tx_sctp", "Transmit SCTP Packets marked for HW checksum" },
4462 		{ ICE_CSO_STAT_TX_IP4, "tx_ip4", "Transmit IPv4 Packets marked for HW checksum" },
4463 		{ ICE_CSO_STAT_TX_IP6, "tx_ip6", "Transmit IPv6 Packets marked for HW checksum" },
4464 		{ ICE_CSO_STAT_TX_L3_ERR, "tx_l3_err", "Transmit packets that driver failed to set L3 HW CSO bits for" },
4465 		{ ICE_CSO_STAT_TX_L4_ERR, "tx_l4_err", "Transmit packets that driver failed to set L4 HW CSO bits for" },
4466 		/* End */
4467 		{ ICE_CSO_STAT_TX_COUNT, 0, 0 }
4468 	};
4469 
4470 	/* Rx CSO Stats */
4471 	const struct ice_rx_cso_stat_info rx_ctls[] = {
4472 		{ ICE_CSO_STAT_RX_IP4_ERR, "rx_ip4_err", "Received packets with invalid IPv4 checksum indicated by HW" },
4473 		{ ICE_CSO_STAT_RX_IP6_ERR, "rx_ip6_err", "Received IPv6 packets with extension headers" },
4474 		{ ICE_CSO_STAT_RX_L3_ERR, "rx_l3_err", "Received packets with an unexpected invalid L3 checksum indicated by HW" },
4475 		{ ICE_CSO_STAT_RX_TCP_ERR, "rx_tcp_err", "Received packets with invalid TCP checksum indicated by HW" },
4476 		{ ICE_CSO_STAT_RX_UDP_ERR, "rx_udp_err", "Received packets with invalid UDP checksum indicated by HW" },
4477 		{ ICE_CSO_STAT_RX_SCTP_ERR, "rx_sctp_err", "Received packets with invalid SCTP checksum indicated by HW" },
4478 		{ ICE_CSO_STAT_RX_L4_ERR, "rx_l4_err", "Received packets with an unexpected invalid L4 checksum indicated by HW" },
4479 		/* End */
4480 		{ ICE_CSO_STAT_RX_COUNT, 0, 0 }
4481 	};
4482 
4483 	struct sysctl_oid_list *parent_list = SYSCTL_CHILDREN(parent);
4484 
4485 	/* Add a node for statistics tracked by software. */
4486 	cso_node = SYSCTL_ADD_NODE(ctx, parent_list, OID_AUTO, "cso", CTLFLAG_RD,
4487 				  NULL, "Checksum offload Statistics");
4488 	cso_list = SYSCTL_CHILDREN(cso_node);
4489 
4490 	const struct ice_tx_cso_stat_info *tx_entry = tx_ctls;
4491 	while (tx_entry->name && tx_entry->description) {
4492 		SYSCTL_ADD_PROC(ctx, cso_list, OID_AUTO, tx_entry->name,
4493 				CTLTYPE_U64 | CTLFLAG_RD | CTLFLAG_STATS,
4494 				vsi, tx_entry->type, ice_sysctl_tx_cso_stat, "QU",
4495 				tx_entry->description);
4496 		tx_entry++;
4497 	}
4498 
4499 	const struct ice_rx_cso_stat_info *rx_entry = rx_ctls;
4500 	while (rx_entry->name && rx_entry->description) {
4501 		SYSCTL_ADD_PROC(ctx, cso_list, OID_AUTO, rx_entry->name,
4502 				CTLTYPE_U64 | CTLFLAG_RD | CTLFLAG_STATS,
4503 				vsi, rx_entry->type, ice_sysctl_rx_cso_stat, "QU",
4504 				rx_entry->description);
4505 		rx_entry++;
4506 	}
4507 }
4508 
4509 /**
4510  * ice_add_vsi_sysctls - Add sysctls for a VSI
4511  * @vsi: pointer to VSI structure
4512  *
4513  * Add various sysctls for a given VSI.
4514  */
4515 void
4516 ice_add_vsi_sysctls(struct ice_vsi *vsi)
4517 {
4518 	struct sysctl_ctx_list *ctx = &vsi->ctx;
4519 	struct sysctl_oid *hw_node, *sw_node;
4520 	struct sysctl_oid_list *vsi_list, *hw_list;
4521 
4522 	vsi_list = SYSCTL_CHILDREN(vsi->vsi_node);
4523 
4524 	/* Keep hw stats in their own node. */
4525 	hw_node = SYSCTL_ADD_NODE(ctx, vsi_list, OID_AUTO, "hw", CTLFLAG_RD,
4526 				  NULL, "VSI Hardware Statistics");
4527 	hw_list = SYSCTL_CHILDREN(hw_node);
4528 
4529 	/* Add the ethernet statistics for this VSI */
4530 	ice_add_sysctls_eth_stats(ctx, hw_node, &vsi->hw_stats.cur);
4531 
4532 	SYSCTL_ADD_U64(ctx, hw_list, OID_AUTO, "rx_discards",
4533 			CTLFLAG_RD | CTLFLAG_STATS, &vsi->hw_stats.cur.rx_discards,
4534 			0, "Discarded Rx Packets (see rx_errors or rx_no_desc)");
4535 
4536 	SYSCTL_ADD_PROC(ctx, hw_list, OID_AUTO, "rx_errors",
4537 			CTLTYPE_U64 | CTLFLAG_RD | CTLFLAG_STATS,
4538 			vsi, 0, ice_sysctl_rx_errors_stat, "QU",
4539 			"Aggregate of all Rx errors");
4540 
4541 	SYSCTL_ADD_U64(ctx, hw_list, OID_AUTO, "rx_no_desc",
4542 		       CTLFLAG_RD | CTLFLAG_STATS, &vsi->hw_stats.cur.rx_no_desc,
4543 		       0, "Rx Packets Discarded Due To Lack Of Descriptors");
4544 
4545 	SYSCTL_ADD_U64(ctx, hw_list, OID_AUTO, "tx_errors",
4546 			CTLFLAG_RD | CTLFLAG_STATS, &vsi->hw_stats.cur.tx_errors,
4547 			0, "Tx Packets Discarded Due To Error");
4548 
4549 	/* Add a node for statistics tracked by software. */
4550 	sw_node = SYSCTL_ADD_NODE(ctx, vsi_list, OID_AUTO, "sw", CTLFLAG_RD,
4551 				  NULL, "VSI Software Statistics");
4552 
4553 	ice_add_sysctls_sw_stats(vsi, ctx, sw_node);
4554 }
4555 
4556 /**
4557  * ice_add_sysctls_mac_pfc_one_stat - Add sysctl node for a PFC statistic
4558  * @ctx: sysctl ctx to use
4559  * @parent_list: parent sysctl list to add sysctls under
4560  * @pfc_stat_location: address of statistic for sysctl to display
4561  * @node_name: Name for statistic node
4562  * @descr: Description used for nodes added in this function
4563  *
4564  * A helper function for ice_add_sysctls_mac_pfc_stats that adds a node
4565  * for a stat and leaves for each traffic class for that stat.
4566  */
4567 static void
4568 ice_add_sysctls_mac_pfc_one_stat(struct sysctl_ctx_list *ctx,
4569 				 struct sysctl_oid_list *parent_list,
4570 				 u64* pfc_stat_location,
4571 				 const char *node_name,
4572 				 const char *descr)
4573 {
4574 	struct sysctl_oid_list *node_list;
4575 	struct sysctl_oid *node;
4576 	struct sbuf *namebuf, *descbuf;
4577 
4578 	node = SYSCTL_ADD_NODE(ctx, parent_list, OID_AUTO, node_name, CTLFLAG_RD,
4579 				   NULL, descr);
4580 	node_list = SYSCTL_CHILDREN(node);
4581 
4582 	namebuf = sbuf_new_auto();
4583 	descbuf = sbuf_new_auto();
4584 	for (int i = 0; i < ICE_MAX_DCB_TCS; i++) {
4585 		sbuf_clear(namebuf);
4586 		sbuf_clear(descbuf);
4587 
4588 		sbuf_printf(namebuf, "%d", i);
4589 		sbuf_printf(descbuf, "%s for TC %d", descr, i);
4590 
4591 		sbuf_finish(namebuf);
4592 		sbuf_finish(descbuf);
4593 
4594 		SYSCTL_ADD_U64(ctx, node_list, OID_AUTO, sbuf_data(namebuf),
4595 			CTLFLAG_RD | CTLFLAG_STATS, &pfc_stat_location[i], 0,
4596 			sbuf_data(descbuf));
4597 	}
4598 
4599 	sbuf_delete(namebuf);
4600 	sbuf_delete(descbuf);
4601 }
4602 
4603 /**
4604  * ice_add_sysctls_mac_pfc_stats - Add sysctls for MAC PFC statistics
4605  * @ctx: the sysctl ctx to use
4606  * @parent: parent node to add the sysctls under
4607  * @stats: the hw ports stat structure to pull values from
4608  *
4609  * Add global Priority Flow Control MAC statistics sysctls. These are
4610  * structured as a node with the PFC statistic, where there are eight
4611  * nodes for each traffic class.
4612  */
4613 static void
4614 ice_add_sysctls_mac_pfc_stats(struct sysctl_ctx_list *ctx,
4615 			      struct sysctl_oid *parent,
4616 			      struct ice_hw_port_stats *stats)
4617 {
4618 	struct sysctl_oid_list *parent_list;
4619 
4620 	parent_list = SYSCTL_CHILDREN(parent);
4621 
4622 	ice_add_sysctls_mac_pfc_one_stat(ctx, parent_list, stats->priority_xon_rx,
4623 	    "p_xon_recvd", "PFC XON received");
4624 	ice_add_sysctls_mac_pfc_one_stat(ctx, parent_list, stats->priority_xoff_rx,
4625 	    "p_xoff_recvd", "PFC XOFF received");
4626 	ice_add_sysctls_mac_pfc_one_stat(ctx, parent_list, stats->priority_xon_tx,
4627 	    "p_xon_txd", "PFC XON transmitted");
4628 	ice_add_sysctls_mac_pfc_one_stat(ctx, parent_list, stats->priority_xoff_tx,
4629 	    "p_xoff_txd", "PFC XOFF transmitted");
4630 	ice_add_sysctls_mac_pfc_one_stat(ctx, parent_list, stats->priority_xon_2_xoff,
4631 	    "p_xon2xoff", "PFC XON to XOFF transitions");
4632 }
4633 
4634 /**
4635  * ice_add_sysctls_mac_stats - Add sysctls for global MAC statistics
4636  * @ctx: the sysctl ctx to use
4637  * @parent: parent node to add the sysctls under
4638  * @stats: the hw ports stat structure to pull values from
4639  *
4640  * Add global MAC statistics sysctls.
4641  */
4642 void
4643 ice_add_sysctls_mac_stats(struct sysctl_ctx_list *ctx,
4644 			  struct sysctl_oid *parent,
4645 			  struct ice_hw_port_stats *stats)
4646 {
4647 	struct sysctl_oid *mac_node;
4648 	struct sysctl_oid_list *parent_list, *mac_list;
4649 
4650 	parent_list = SYSCTL_CHILDREN(parent);
4651 
4652 	mac_node = SYSCTL_ADD_NODE(ctx, parent_list, OID_AUTO, "mac", CTLFLAG_RD,
4653 				   NULL, "Mac Hardware Statistics");
4654 	mac_list = SYSCTL_CHILDREN(mac_node);
4655 
4656 	/* Add the ethernet statistics common to VSI and MAC */
4657 	ice_add_sysctls_eth_stats(ctx, mac_node, &stats->eth);
4658 
4659 	/* Add PFC stats that add per-TC counters */
4660 	ice_add_sysctls_mac_pfc_stats(ctx, mac_node, stats);
4661 
4662 	const struct ice_sysctl_info ctls[] = {
4663 		/* Packet Reception Stats */
4664 		{&stats->rx_size_64, "rx_frames_64", "64 byte frames received"},
4665 		{&stats->rx_size_127, "rx_frames_65_127", "65-127 byte frames received"},
4666 		{&stats->rx_size_255, "rx_frames_128_255", "128-255 byte frames received"},
4667 		{&stats->rx_size_511, "rx_frames_256_511", "256-511 byte frames received"},
4668 		{&stats->rx_size_1023, "rx_frames_512_1023", "512-1023 byte frames received"},
4669 		{&stats->rx_size_1522, "rx_frames_1024_1522", "1024-1522 byte frames received"},
4670 		{&stats->rx_size_big, "rx_frames_big", "1523-9522 byte frames received"},
4671 		{&stats->rx_undersize, "rx_undersize", "Undersized packets received"},
4672 		{&stats->rx_fragments, "rx_fragmented", "Fragmented packets received"},
4673 		{&stats->rx_oversize, "rx_oversized", "Oversized packets received"},
4674 		{&stats->rx_jabber, "rx_jabber", "Received Jabber"},
4675 		{&stats->rx_len_errors, "rx_length_errors", "Receive Length Errors"},
4676 		{&stats->eth.rx_discards, "rx_discards",
4677 		    "Discarded Rx Packets by Port (shortage of storage space)"},
4678 		/* Packet Transmission Stats */
4679 		{&stats->tx_size_64, "tx_frames_64", "64 byte frames transmitted"},
4680 		{&stats->tx_size_127, "tx_frames_65_127", "65-127 byte frames transmitted"},
4681 		{&stats->tx_size_255, "tx_frames_128_255", "128-255 byte frames transmitted"},
4682 		{&stats->tx_size_511, "tx_frames_256_511", "256-511 byte frames transmitted"},
4683 		{&stats->tx_size_1023, "tx_frames_512_1023", "512-1023 byte frames transmitted"},
4684 		{&stats->tx_size_1522, "tx_frames_1024_1522", "1024-1522 byte frames transmitted"},
4685 		{&stats->tx_size_big, "tx_frames_big", "1523-9522 byte frames transmitted"},
4686 		{&stats->tx_dropped_link_down, "tx_dropped", "Tx Dropped Due To Link Down"},
4687 		/* Flow control */
4688 		{&stats->link_xon_tx, "xon_txd", "Link XON transmitted"},
4689 		{&stats->link_xon_rx, "xon_recvd", "Link XON received"},
4690 		{&stats->link_xoff_tx, "xoff_txd", "Link XOFF transmitted"},
4691 		{&stats->link_xoff_rx, "xoff_recvd", "Link XOFF received"},
4692 		/* Other */
4693 		{&stats->crc_errors, "crc_errors", "CRC Errors"},
4694 		{&stats->illegal_bytes, "illegal_bytes", "Illegal Byte Errors"},
4695 		{&stats->mac_local_faults, "local_faults", "MAC Local Faults"},
4696 		{&stats->mac_remote_faults, "remote_faults", "MAC Remote Faults"},
4697 		/* End */
4698 		{ 0, 0, 0 }
4699 	};
4700 
4701 	const struct ice_sysctl_info *entry = ctls;
4702 	while (entry->stat != 0) {
4703 		SYSCTL_ADD_U64(ctx, mac_list, OID_AUTO, entry->name,
4704 			CTLFLAG_RD | CTLFLAG_STATS, entry->stat, 0,
4705 			entry->description);
4706 		entry++;
4707 	}
4708 }
4709 
4710 /**
4711  * ice_configure_misc_interrupts - enable 'other' interrupt causes
4712  * @sc: pointer to device private softc
4713  *
4714  * Enable various "other" interrupt causes, and associate them to interrupt 0,
4715  * which is our administrative interrupt.
4716  */
4717 void
4718 ice_configure_misc_interrupts(struct ice_softc *sc)
4719 {
4720 	struct ice_hw *hw = &sc->hw;
4721 	u32 val;
4722 
4723 	/* Read the OICR register to clear it */
4724 	rd32(hw, PFINT_OICR);
4725 
4726 	/* Enable useful "other" interrupt causes */
4727 	val = (PFINT_OICR_ECC_ERR_M |
4728 	       PFINT_OICR_MAL_DETECT_M |
4729 	       PFINT_OICR_GRST_M |
4730 	       PFINT_OICR_PCI_EXCEPTION_M |
4731 	       PFINT_OICR_VFLR_M |
4732 	       PFINT_OICR_HMC_ERR_M |
4733 	       PFINT_OICR_PE_CRITERR_M);
4734 
4735 	wr32(hw, PFINT_OICR_ENA, val);
4736 
4737 	/* Note that since we're using MSI-X index 0, and ITR index 0, we do
4738 	 * not explicitly program them when writing to the PFINT_*_CTL
4739 	 * registers. Nevertheless, these writes are associating the
4740 	 * interrupts with the ITR 0 vector
4741 	 */
4742 
4743 	/* Associate the OICR interrupt with ITR 0, and enable it */
4744 	wr32(hw, PFINT_OICR_CTL, PFINT_OICR_CTL_CAUSE_ENA_M);
4745 
4746 	/* Associate the Mailbox interrupt with ITR 0, and enable it */
4747 	wr32(hw, PFINT_MBX_CTL, PFINT_MBX_CTL_CAUSE_ENA_M);
4748 
4749 	/* Associate the AdminQ interrupt with ITR 0, and enable it */
4750 	wr32(hw, PFINT_FW_CTL, PFINT_FW_CTL_CAUSE_ENA_M);
4751 }
4752 
4753 /**
4754  * ice_filter_is_mcast - Check if info is a multicast filter
4755  * @vsi: vsi structure addresses are targeted towards
4756  * @info: filter info
4757  *
4758  * @returns true if the provided info is a multicast filter, and false
4759  * otherwise.
4760  */
4761 static bool
4762 ice_filter_is_mcast(struct ice_vsi *vsi, struct ice_fltr_info *info)
4763 {
4764 	const u8 *addr = info->l_data.mac.mac_addr;
4765 
4766 	/*
4767 	 * Check if this info matches a multicast filter added by
4768 	 * ice_add_mac_to_list
4769 	 */
4770 	if ((info->flag == ICE_FLTR_TX) &&
4771 	    (info->src_id == ICE_SRC_ID_VSI) &&
4772 	    (info->lkup_type == ICE_SW_LKUP_MAC) &&
4773 	    (info->vsi_handle == vsi->idx) &&
4774 	    ETHER_IS_MULTICAST(addr) && !ETHER_IS_BROADCAST(addr))
4775 		return true;
4776 
4777 	return false;
4778 }
4779 
4780 /**
4781  * @struct ice_mcast_sync_data
4782  * @brief data used by ice_sync_one_mcast_filter function
4783  *
4784  * Structure used to store data needed for processing by the
4785  * ice_sync_one_mcast_filter. This structure contains a linked list of filters
4786  * to be added, an error indication, and a pointer to the device softc.
4787  */
4788 struct ice_mcast_sync_data {
4789 	struct ice_list_head add_list;
4790 	struct ice_softc *sc;
4791 	int err;
4792 };
4793 
4794 /**
4795  * ice_sync_one_mcast_filter - Check if we need to program the filter
4796  * @p: void pointer to algorithm data
4797  * @sdl: link level socket address
4798  * @count: unused count value
4799  *
4800  * Called by if_foreach_llmaddr to operate on each filter in the ifp filter
4801  * list. For the given address, search our internal list to see if we have
4802  * found the filter. If not, add it to our list of filters that need to be
4803  * programmed.
4804  *
4805  * @returns (1) if we've actually setup the filter to be added
4806  */
4807 static u_int
4808 ice_sync_one_mcast_filter(void *p, struct sockaddr_dl *sdl,
4809 			  u_int __unused count)
4810 {
4811 	struct ice_mcast_sync_data *data = (struct ice_mcast_sync_data *)p;
4812 	struct ice_softc *sc = data->sc;
4813 	struct ice_hw *hw = &sc->hw;
4814 	struct ice_switch_info *sw = hw->switch_info;
4815 	const u8 *sdl_addr = (const u8 *)LLADDR(sdl);
4816 	struct ice_fltr_mgmt_list_entry *itr;
4817 	struct ice_list_head *rules;
4818 	int err;
4819 
4820 	rules = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;
4821 
4822 	/*
4823 	 * If a previous filter already indicated an error, there is no need
4824 	 * for us to finish processing the rest of the filters.
4825 	 */
4826 	if (data->err)
4827 		return (0);
4828 
4829 	/* See if this filter has already been programmed */
4830 	LIST_FOR_EACH_ENTRY(itr, rules, ice_fltr_mgmt_list_entry, list_entry) {
4831 		struct ice_fltr_info *info = &itr->fltr_info;
4832 		const u8 *addr = info->l_data.mac.mac_addr;
4833 
4834 		/* Only check multicast filters */
4835 		if (!ice_filter_is_mcast(&sc->pf_vsi, info))
4836 			continue;
4837 
4838 		/*
4839 		 * If this filter matches, mark the internal filter as
4840 		 * "found", and exit.
4841 		 */
4842 		if (bcmp(addr, sdl_addr, ETHER_ADDR_LEN) == 0) {
4843 			itr->marker = ICE_FLTR_FOUND;
4844 			return (1);
4845 		}
4846 	}
4847 
4848 	/*
4849 	 * If we failed to locate the filter in our internal list, we need to
4850 	 * place it into our add list.
4851 	 */
4852 	err = ice_add_mac_to_list(&sc->pf_vsi, &data->add_list, sdl_addr,
4853 				  ICE_FWD_TO_VSI);
4854 	if (err) {
4855 		device_printf(sc->dev,
4856 			      "Failed to place MAC %6D onto add list, err %s\n",
4857 			      sdl_addr, ":", ice_err_str(err));
4858 		data->err = err;
4859 
4860 		return (0);
4861 	}
4862 
4863 	return (1);
4864 }
4865 
4866 /**
4867  * ice_sync_multicast_filters - Synchronize OS and internal filter list
4868  * @sc: device private structure
4869  *
4870  * Called in response to SIOCDELMULTI to synchronize the operating system
4871  * multicast address list with the internal list of filters programmed to
4872  * firmware.
4873  *
4874  * Works in one phase to find added and deleted filters using a marker bit on
4875  * the internal list.
4876  *
4877  * First, a loop over the internal list clears the marker bit. Second, for
4878  * each filter in the ifp list is checked. If we find it in the internal list,
4879  * the marker bit is set. Otherwise, the filter is added to the add list.
4880  * Third, a loop over the internal list determines if any filters have not
4881  * been found. Each of these is added to the delete list. Finally, the add and
4882  * delete lists are programmed to firmware to update the filters.
4883  *
4884  * @returns zero on success or an integer error code on failure.
4885  */
4886 int
4887 ice_sync_multicast_filters(struct ice_softc *sc)
4888 {
4889 	struct ice_hw *hw = &sc->hw;
4890 	struct ice_switch_info *sw = hw->switch_info;
4891 	struct ice_fltr_mgmt_list_entry *itr;
4892 	struct ice_mcast_sync_data data = {};
4893 	struct ice_list_head *rules, remove_list;
4894 	enum ice_status status;
4895 	int err = 0;
4896 
4897 	INIT_LIST_HEAD(&data.add_list);
4898 	INIT_LIST_HEAD(&remove_list);
4899 	data.sc = sc;
4900 	data.err = 0;
4901 
4902 	rules = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;
4903 
4904 	/* Acquire the lock for the entire duration */
4905 	ice_acquire_lock(&sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock);
4906 
4907 	/* (1) Reset the marker state for all filters */
4908 	LIST_FOR_EACH_ENTRY(itr, rules, ice_fltr_mgmt_list_entry, list_entry)
4909 		itr->marker = ICE_FLTR_NOT_FOUND;
4910 
4911 	/* (2) determine which filters need to be added and removed */
4912 	if_foreach_llmaddr(sc->ifp, ice_sync_one_mcast_filter, (void *)&data);
4913 	if (data.err) {
4914 		/* ice_sync_one_mcast_filter already prints an error */
4915 		err = data.err;
4916 		ice_release_lock(&sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock);
4917 		goto free_filter_lists;
4918 	}
4919 
4920 	LIST_FOR_EACH_ENTRY(itr, rules, ice_fltr_mgmt_list_entry, list_entry) {
4921 		struct ice_fltr_info *info = &itr->fltr_info;
4922 		const u8 *addr = info->l_data.mac.mac_addr;
4923 
4924 		/* Only check multicast filters */
4925 		if (!ice_filter_is_mcast(&sc->pf_vsi, info))
4926 			continue;
4927 
4928 		/*
4929 		 * If the filter is not marked as found, then it must no
4930 		 * longer be in the ifp address list, so we need to remove it.
4931 		 */
4932 		if (itr->marker == ICE_FLTR_NOT_FOUND) {
4933 			err = ice_add_mac_to_list(&sc->pf_vsi, &remove_list,
4934 						  addr, ICE_FWD_TO_VSI);
4935 			if (err) {
4936 				device_printf(sc->dev,
4937 					      "Failed to place MAC %6D onto remove list, err %s\n",
4938 					      addr, ":", ice_err_str(err));
4939 				ice_release_lock(&sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock);
4940 				goto free_filter_lists;
4941 			}
4942 		}
4943 	}
4944 
4945 	ice_release_lock(&sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock);
4946 
4947 	status = ice_add_mac(hw, &data.add_list);
4948 	if (status) {
4949 		device_printf(sc->dev,
4950 			      "Could not add new MAC filters, err %s aq_err %s\n",
4951 			      ice_status_str(status), ice_aq_str(hw->adminq.sq_last_status));
4952 		err = (EIO);
4953 		goto free_filter_lists;
4954 	}
4955 
4956 	status = ice_remove_mac(hw, &remove_list);
4957 	if (status) {
4958 		device_printf(sc->dev,
4959 			      "Could not remove old MAC filters, err %s aq_err %s\n",
4960 			      ice_status_str(status), ice_aq_str(hw->adminq.sq_last_status));
4961 		err = (EIO);
4962 		goto free_filter_lists;
4963 	}
4964 
4965 free_filter_lists:
4966 	ice_free_fltr_list(&data.add_list);
4967 	ice_free_fltr_list(&remove_list);
4968 
4969 	return (err);
4970 }
4971 
4972 /**
4973  * ice_add_vlan_hw_filter - Add a VLAN filter for a given VSI
4974  * @vsi: The VSI to add the filter for
4975  * @vid: VLAN to add
4976  *
4977  * Programs a HW filter so that the given VSI will receive the specified VLAN.
4978  */
4979 enum ice_status
4980 ice_add_vlan_hw_filter(struct ice_vsi *vsi, u16 vid)
4981 {
4982 	struct ice_hw *hw = &vsi->sc->hw;
4983 	struct ice_list_head vlan_list;
4984 	struct ice_fltr_list_entry vlan_entry;
4985 
4986 	INIT_LIST_HEAD(&vlan_list);
4987 	memset(&vlan_entry, 0, sizeof(vlan_entry));
4988 
4989 	vlan_entry.fltr_info.lkup_type = ICE_SW_LKUP_VLAN;
4990 	vlan_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
4991 	vlan_entry.fltr_info.flag = ICE_FLTR_TX;
4992 	vlan_entry.fltr_info.src_id = ICE_SRC_ID_VSI;
4993 	vlan_entry.fltr_info.vsi_handle = vsi->idx;
4994 	vlan_entry.fltr_info.l_data.vlan.vlan_id = vid;
4995 
4996 	LIST_ADD(&vlan_entry.list_entry, &vlan_list);
4997 
4998 	return ice_add_vlan(hw, &vlan_list);
4999 }
5000 
5001 /**
5002  * ice_remove_vlan_hw_filter - Remove a VLAN filter for a given VSI
5003  * @vsi: The VSI to add the filter for
5004  * @vid: VLAN to remove
5005  *
5006  * Removes a previously programmed HW filter for the specified VSI.
5007  */
5008 enum ice_status
5009 ice_remove_vlan_hw_filter(struct ice_vsi *vsi, u16 vid)
5010 {
5011 	struct ice_hw *hw = &vsi->sc->hw;
5012 	struct ice_list_head vlan_list;
5013 	struct ice_fltr_list_entry vlan_entry;
5014 
5015 	INIT_LIST_HEAD(&vlan_list);
5016 	memset(&vlan_entry, 0, sizeof(vlan_entry));
5017 
5018 	vlan_entry.fltr_info.lkup_type = ICE_SW_LKUP_VLAN;
5019 	vlan_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
5020 	vlan_entry.fltr_info.flag = ICE_FLTR_TX;
5021 	vlan_entry.fltr_info.src_id = ICE_SRC_ID_VSI;
5022 	vlan_entry.fltr_info.vsi_handle = vsi->idx;
5023 	vlan_entry.fltr_info.l_data.vlan.vlan_id = vid;
5024 
5025 	LIST_ADD(&vlan_entry.list_entry, &vlan_list);
5026 
5027 	return ice_remove_vlan(hw, &vlan_list);
5028 }
5029 
5030 #define ICE_SYSCTL_HELP_RX_ITR			\
5031 "\nControl Rx interrupt throttle rate."		\
5032 "\n\t0-8160 - sets interrupt rate in usecs"	\
5033 "\n\t    -1 - reset the Rx itr to default"
5034 
5035 /**
5036  * ice_sysctl_rx_itr - Display or change the Rx ITR for a VSI
5037  * @oidp: sysctl oid structure
5038  * @arg1: pointer to private data structure
5039  * @arg2: unused
5040  * @req: sysctl request pointer
5041  *
5042  * On read: Displays the current Rx ITR value
5043  * on write: Sets the Rx ITR value, reconfiguring device if it is up
5044  */
5045 static int
5046 ice_sysctl_rx_itr(SYSCTL_HANDLER_ARGS)
5047 {
5048 	struct ice_vsi *vsi = (struct ice_vsi *)arg1;
5049 	struct ice_softc *sc = vsi->sc;
5050 	int increment, ret;
5051 
5052 	UNREFERENCED_PARAMETER(arg2);
5053 
5054 	if (ice_driver_is_detaching(sc))
5055 		return (ESHUTDOWN);
5056 
5057 	ret = sysctl_handle_16(oidp, &vsi->rx_itr, 0, req);
5058 	if ((ret) || (req->newptr == NULL))
5059 		return (ret);
5060 
5061 	if (vsi->rx_itr < 0)
5062 		vsi->rx_itr = ICE_DFLT_RX_ITR;
5063 	if (vsi->rx_itr > ICE_ITR_MAX)
5064 		vsi->rx_itr = ICE_ITR_MAX;
5065 
5066 	/* Assume 2usec increment if it hasn't been loaded yet */
5067 	increment = sc->hw.itr_gran ? : 2;
5068 
5069 	/* We need to round the value to the hardware's ITR granularity */
5070 	vsi->rx_itr = (vsi->rx_itr / increment ) * increment;
5071 
5072 	/* If the driver has finished initializing, then we need to reprogram
5073 	 * the ITR registers now. Otherwise, they will be programmed during
5074 	 * driver initialization.
5075 	 */
5076 	if (ice_test_state(&sc->state, ICE_STATE_DRIVER_INITIALIZED))
5077 		ice_configure_rx_itr(vsi);
5078 
5079 	return (0);
5080 }
5081 
5082 #define ICE_SYSCTL_HELP_TX_ITR			\
5083 "\nControl Tx interrupt throttle rate."		\
5084 "\n\t0-8160 - sets interrupt rate in usecs"	\
5085 "\n\t    -1 - reset the Tx itr to default"
5086 
5087 /**
5088  * ice_sysctl_tx_itr - Display or change the Tx ITR for a VSI
5089  * @oidp: sysctl oid structure
5090  * @arg1: pointer to private data structure
5091  * @arg2: unused
5092  * @req: sysctl request pointer
5093  *
5094  * On read: Displays the current Tx ITR value
5095  * on write: Sets the Tx ITR value, reconfiguring device if it is up
5096  */
5097 static int
5098 ice_sysctl_tx_itr(SYSCTL_HANDLER_ARGS)
5099 {
5100 	struct ice_vsi *vsi = (struct ice_vsi *)arg1;
5101 	struct ice_softc *sc = vsi->sc;
5102 	int increment, ret;
5103 
5104 	UNREFERENCED_PARAMETER(arg2);
5105 
5106 	if (ice_driver_is_detaching(sc))
5107 		return (ESHUTDOWN);
5108 
5109 	ret = sysctl_handle_16(oidp, &vsi->tx_itr, 0, req);
5110 	if ((ret) || (req->newptr == NULL))
5111 		return (ret);
5112 
5113 	/* Allow configuring a negative value to reset to the default */
5114 	if (vsi->tx_itr < 0)
5115 		vsi->tx_itr = ICE_DFLT_TX_ITR;
5116 	if (vsi->tx_itr > ICE_ITR_MAX)
5117 		vsi->tx_itr = ICE_ITR_MAX;
5118 
5119 	/* Assume 2usec increment if it hasn't been loaded yet */
5120 	increment = sc->hw.itr_gran ? : 2;
5121 
5122 	/* We need to round the value to the hardware's ITR granularity */
5123 	vsi->tx_itr = (vsi->tx_itr / increment ) * increment;
5124 
5125 	/* If the driver has finished initializing, then we need to reprogram
5126 	 * the ITR registers now. Otherwise, they will be programmed during
5127 	 * driver initialization.
5128 	 */
5129 	if (ice_test_state(&sc->state, ICE_STATE_DRIVER_INITIALIZED))
5130 		ice_configure_tx_itr(vsi);
5131 
5132 	return (0);
5133 }
5134 
5135 /**
5136  * ice_add_vsi_tunables - Add tunables and nodes for a VSI
5137  * @vsi: pointer to VSI structure
5138  * @parent: parent node to add the tunables under
5139  *
5140  * Create a sysctl context for the VSI, so that sysctls for the VSI can be
5141  * dynamically removed upon VSI removal.
5142  *
5143  * Add various tunables and set up the basic node structure for the VSI. Must
5144  * be called *prior* to ice_add_vsi_sysctls. It should be called as soon as
5145  * possible after the VSI memory is initialized.
5146  *
5147  * VSI specific sysctls with CTLFLAG_TUN should be initialized here so that
5148  * their values can be read from loader.conf prior to their first use in the
5149  * driver.
5150  */
5151 void
5152 ice_add_vsi_tunables(struct ice_vsi *vsi, struct sysctl_oid *parent)
5153 {
5154 	struct sysctl_oid_list *vsi_list;
5155 	char vsi_name[32], vsi_desc[32];
5156 
5157 	struct sysctl_oid_list *parent_list = SYSCTL_CHILDREN(parent);
5158 
5159 	/* Initialize the sysctl context for this VSI */
5160 	sysctl_ctx_init(&vsi->ctx);
5161 
5162 	/* Add a node to collect this VSI's statistics together */
5163 	snprintf(vsi_name, sizeof(vsi_name), "%u", vsi->idx);
5164 	snprintf(vsi_desc, sizeof(vsi_desc), "VSI %u", vsi->idx);
5165 	vsi->vsi_node = SYSCTL_ADD_NODE(&vsi->ctx, parent_list, OID_AUTO, vsi_name,
5166 					CTLFLAG_RD, NULL, vsi_desc);
5167 	vsi_list = SYSCTL_CHILDREN(vsi->vsi_node);
5168 
5169 	vsi->rx_itr = ICE_DFLT_TX_ITR;
5170 	SYSCTL_ADD_PROC(&vsi->ctx, vsi_list, OID_AUTO, "rx_itr",
5171 			CTLTYPE_S16 | CTLFLAG_RWTUN,
5172 			vsi, 0, ice_sysctl_rx_itr, "S",
5173 			ICE_SYSCTL_HELP_RX_ITR);
5174 
5175 	vsi->tx_itr = ICE_DFLT_TX_ITR;
5176 	SYSCTL_ADD_PROC(&vsi->ctx, vsi_list, OID_AUTO, "tx_itr",
5177 			CTLTYPE_S16 | CTLFLAG_RWTUN,
5178 			vsi, 0, ice_sysctl_tx_itr, "S",
5179 			ICE_SYSCTL_HELP_TX_ITR);
5180 }
5181 
5182 /**
5183  * ice_del_vsi_sysctl_ctx - Delete the sysctl context(s) of a VSI
5184  * @vsi: the VSI to remove contexts for
5185  *
5186  * Free the context for the VSI sysctls. This includes the main context, as
5187  * well as the per-queue sysctls.
5188  */
5189 void
5190 ice_del_vsi_sysctl_ctx(struct ice_vsi *vsi)
5191 {
5192 	device_t dev = vsi->sc->dev;
5193 	int err;
5194 
5195 	if (vsi->vsi_node) {
5196 		err = sysctl_ctx_free(&vsi->ctx);
5197 		if (err)
5198 			device_printf(dev, "failed to free VSI %d sysctl context, err %s\n",
5199 				      vsi->idx, ice_err_str(err));
5200 		vsi->vsi_node = NULL;
5201 	}
5202 }
5203 
5204 /**
5205  * ice_add_device_tunables - Add early tunable sysctls and sysctl nodes
5206  * @sc: device private structure
5207  *
5208  * Add per-device dynamic tunable sysctls, and setup the general sysctl trees
5209  * for re-use by ice_add_device_sysctls.
5210  *
5211  * In order for the sysctl fields to be initialized before use, this function
5212  * should be called as early as possible during attach activities.
5213  *
5214  * Any non-global sysctl marked as CTLFLAG_TUN should likely be initialized
5215  * here in this function, rather than later in ice_add_device_sysctls.
5216  *
5217  * To make things easier, this function is also expected to setup the various
5218  * sysctl nodes in addition to tunables so that other sysctls which can't be
5219  * initialized early can hook into the same nodes.
5220  */
5221 void
5222 ice_add_device_tunables(struct ice_softc *sc)
5223 {
5224 	device_t dev = sc->dev;
5225 
5226 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
5227 	struct sysctl_oid_list *ctx_list =
5228 		SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
5229 
5230 	sc->enable_health_events = ice_enable_health_events;
5231 
5232 	SYSCTL_ADD_BOOL(ctx, ctx_list, OID_AUTO, "enable_health_events",
5233 			CTLFLAG_RDTUN, &sc->enable_health_events, 0,
5234 			"Enable FW health event reporting for this PF");
5235 
5236 	/* Add a node to track VSI sysctls. Keep track of the node in the
5237 	 * softc so that we can hook other sysctls into it later. This
5238 	 * includes both the VSI statistics, as well as potentially dynamic
5239 	 * VSIs in the future.
5240 	 */
5241 
5242 	sc->vsi_sysctls = SYSCTL_ADD_NODE(ctx, ctx_list, OID_AUTO, "vsi",
5243 					  CTLFLAG_RD, NULL, "VSI Configuration and Statistics");
5244 
5245 	/* Add debug tunables */
5246 	ice_add_debug_tunables(sc);
5247 }
5248 
5249 /**
5250  * ice_sysctl_dump_mac_filters - Dump a list of all HW MAC Filters
5251  * @oidp: sysctl oid structure
5252  * @arg1: pointer to private data structure
5253  * @arg2: unused
5254  * @req: sysctl request pointer
5255  *
5256  * Callback for "mac_filters" sysctl to dump the programmed MAC filters.
5257  */
5258 static int
5259 ice_sysctl_dump_mac_filters(SYSCTL_HANDLER_ARGS)
5260 {
5261 	struct ice_softc *sc = (struct ice_softc *)arg1;
5262 	struct ice_hw *hw = &sc->hw;
5263 	struct ice_switch_info *sw = hw->switch_info;
5264 	struct ice_fltr_mgmt_list_entry *fm_entry;
5265 	struct ice_list_head *rule_head;
5266 	struct ice_lock *rule_lock;
5267 	struct ice_fltr_info *fi;
5268 	struct sbuf *sbuf;
5269 	int ret;
5270 
5271 	UNREFERENCED_PARAMETER(oidp);
5272 	UNREFERENCED_PARAMETER(arg2);
5273 
5274 	if (ice_driver_is_detaching(sc))
5275 		return (ESHUTDOWN);
5276 
5277 	/* Wire the old buffer so we can take a non-sleepable lock */
5278 	ret = sysctl_wire_old_buffer(req, 0);
5279 	if (ret)
5280 		return (ret);
5281 
5282 	sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
5283 
5284 	rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
5285 	rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;
5286 
5287 	sbuf_printf(sbuf, "MAC Filter List");
5288 
5289 	ice_acquire_lock(rule_lock);
5290 
5291 	LIST_FOR_EACH_ENTRY(fm_entry, rule_head, ice_fltr_mgmt_list_entry, list_entry) {
5292 		fi = &fm_entry->fltr_info;
5293 
5294 		sbuf_printf(sbuf,
5295 			    "\nmac = %6D, vsi_handle = %3d, fw_act_flag = %5s, lb_en = %1d, lan_en = %1d, fltr_act = %15s, fltr_rule_id = %d",
5296 			    fi->l_data.mac.mac_addr, ":", fi->vsi_handle,
5297 			    ice_fltr_flag_str(fi->flag), fi->lb_en, fi->lan_en,
5298 			    ice_fwd_act_str(fi->fltr_act), fi->fltr_rule_id);
5299 
5300 		/* if we have a vsi_list_info, print some information about that */
5301 		if (fm_entry->vsi_list_info) {
5302 			sbuf_printf(sbuf,
5303 				    ", vsi_count = %3d, vsi_list_id = %3d, ref_cnt = %3d",
5304 				    fm_entry->vsi_count,
5305 				    fm_entry->vsi_list_info->vsi_list_id,
5306 				    fm_entry->vsi_list_info->ref_cnt);
5307 		}
5308 	}
5309 
5310 	ice_release_lock(rule_lock);
5311 
5312 	sbuf_finish(sbuf);
5313 	sbuf_delete(sbuf);
5314 
5315 	return (0);
5316 }
5317 
5318 /**
5319  * ice_sysctl_dump_vlan_filters - Dump a list of all HW VLAN Filters
5320  * @oidp: sysctl oid structure
5321  * @arg1: pointer to private data structure
5322  * @arg2: unused
5323  * @req: sysctl request pointer
5324  *
5325  * Callback for "vlan_filters" sysctl to dump the programmed VLAN filters.
5326  */
5327 static int
5328 ice_sysctl_dump_vlan_filters(SYSCTL_HANDLER_ARGS)
5329 {
5330 	struct ice_softc *sc = (struct ice_softc *)arg1;
5331 	struct ice_hw *hw = &sc->hw;
5332 	struct ice_switch_info *sw = hw->switch_info;
5333 	struct ice_fltr_mgmt_list_entry *fm_entry;
5334 	struct ice_list_head *rule_head;
5335 	struct ice_lock *rule_lock;
5336 	struct ice_fltr_info *fi;
5337 	struct sbuf *sbuf;
5338 	int ret;
5339 
5340 	UNREFERENCED_PARAMETER(oidp);
5341 	UNREFERENCED_PARAMETER(arg2);
5342 
5343 	if (ice_driver_is_detaching(sc))
5344 		return (ESHUTDOWN);
5345 
5346 	/* Wire the old buffer so we can take a non-sleepable lock */
5347 	ret = sysctl_wire_old_buffer(req, 0);
5348 	if (ret)
5349 		return (ret);
5350 
5351 	sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
5352 
5353 	rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
5354 	rule_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules;
5355 
5356 	sbuf_printf(sbuf, "VLAN Filter List");
5357 
5358 	ice_acquire_lock(rule_lock);
5359 
5360 	LIST_FOR_EACH_ENTRY(fm_entry, rule_head, ice_fltr_mgmt_list_entry, list_entry) {
5361 		fi = &fm_entry->fltr_info;
5362 
5363 		sbuf_printf(sbuf,
5364 			    "\nvlan_id = %4d, vsi_handle = %3d, fw_act_flag = %5s, lb_en = %1d, lan_en = %1d, fltr_act = %15s, fltr_rule_id = %4d",
5365 			    fi->l_data.vlan.vlan_id, fi->vsi_handle,
5366 			    ice_fltr_flag_str(fi->flag), fi->lb_en, fi->lan_en,
5367 			    ice_fwd_act_str(fi->fltr_act), fi->fltr_rule_id);
5368 
5369 		/* if we have a vsi_list_info, print some information about that */
5370 		if (fm_entry->vsi_list_info) {
5371 			sbuf_printf(sbuf,
5372 				    ", vsi_count = %3d, vsi_list_id = %3d, ref_cnt = %3d",
5373 				    fm_entry->vsi_count,
5374 				    fm_entry->vsi_list_info->vsi_list_id,
5375 				    fm_entry->vsi_list_info->ref_cnt);
5376 		}
5377 	}
5378 
5379 	ice_release_lock(rule_lock);
5380 
5381 	sbuf_finish(sbuf);
5382 	sbuf_delete(sbuf);
5383 
5384 	return (0);
5385 }
5386 
5387 /**
5388  * ice_sysctl_dump_ethertype_filters - Dump a list of all HW Ethertype filters
5389  * @oidp: sysctl oid structure
5390  * @arg1: pointer to private data structure
5391  * @arg2: unused
5392  * @req: sysctl request pointer
5393  *
5394  * Callback for "ethertype_filters" sysctl to dump the programmed Ethertype
5395  * filters.
5396  */
5397 static int
5398 ice_sysctl_dump_ethertype_filters(SYSCTL_HANDLER_ARGS)
5399 {
5400 	struct ice_softc *sc = (struct ice_softc *)arg1;
5401 	struct ice_hw *hw = &sc->hw;
5402 	struct ice_switch_info *sw = hw->switch_info;
5403 	struct ice_fltr_mgmt_list_entry *fm_entry;
5404 	struct ice_list_head *rule_head;
5405 	struct ice_lock *rule_lock;
5406 	struct ice_fltr_info *fi;
5407 	struct sbuf *sbuf;
5408 	int ret;
5409 
5410 	UNREFERENCED_PARAMETER(oidp);
5411 	UNREFERENCED_PARAMETER(arg2);
5412 
5413 	if (ice_driver_is_detaching(sc))
5414 		return (ESHUTDOWN);
5415 
5416 	/* Wire the old buffer so we can take a non-sleepable lock */
5417 	ret = sysctl_wire_old_buffer(req, 0);
5418 	if (ret)
5419 		return (ret);
5420 
5421 	sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
5422 
5423 	rule_lock = &sw->recp_list[ICE_SW_LKUP_ETHERTYPE].filt_rule_lock;
5424 	rule_head = &sw->recp_list[ICE_SW_LKUP_ETHERTYPE].filt_rules;
5425 
5426 	sbuf_printf(sbuf, "Ethertype Filter List");
5427 
5428 	ice_acquire_lock(rule_lock);
5429 
5430 	LIST_FOR_EACH_ENTRY(fm_entry, rule_head, ice_fltr_mgmt_list_entry, list_entry) {
5431 		fi = &fm_entry->fltr_info;
5432 
5433 		sbuf_printf(sbuf,
5434 			    "\nethertype = 0x%04x, vsi_handle = %3d, fw_act_flag = %5s, lb_en = %1d, lan_en = %1d, fltr_act = %15s, fltr_rule_id = %4d",
5435 			fi->l_data.ethertype_mac.ethertype,
5436 			fi->vsi_handle, ice_fltr_flag_str(fi->flag),
5437 			fi->lb_en, fi->lan_en, ice_fwd_act_str(fi->fltr_act),
5438 			fi->fltr_rule_id);
5439 
5440 		/* if we have a vsi_list_info, print some information about that */
5441 		if (fm_entry->vsi_list_info) {
5442 			sbuf_printf(sbuf,
5443 				    ", vsi_count = %3d, vsi_list_id = %3d, ref_cnt = %3d",
5444 				    fm_entry->vsi_count,
5445 				    fm_entry->vsi_list_info->vsi_list_id,
5446 				    fm_entry->vsi_list_info->ref_cnt);
5447 		}
5448 	}
5449 
5450 	ice_release_lock(rule_lock);
5451 
5452 	sbuf_finish(sbuf);
5453 	sbuf_delete(sbuf);
5454 
5455 	return (0);
5456 }
5457 
5458 /**
5459  * ice_sysctl_dump_ethertype_mac_filters - Dump a list of all HW Ethertype/MAC filters
5460  * @oidp: sysctl oid structure
5461  * @arg1: pointer to private data structure
5462  * @arg2: unused
5463  * @req: sysctl request pointer
5464  *
5465  * Callback for "ethertype_mac_filters" sysctl to dump the programmed
5466  * Ethertype/MAC filters.
5467  */
5468 static int
5469 ice_sysctl_dump_ethertype_mac_filters(SYSCTL_HANDLER_ARGS)
5470 {
5471 	struct ice_softc *sc = (struct ice_softc *)arg1;
5472 	struct ice_hw *hw = &sc->hw;
5473 	struct ice_switch_info *sw = hw->switch_info;
5474 	struct ice_fltr_mgmt_list_entry *fm_entry;
5475 	struct ice_list_head *rule_head;
5476 	struct ice_lock *rule_lock;
5477 	struct ice_fltr_info *fi;
5478 	struct sbuf *sbuf;
5479 	int ret;
5480 
5481 	UNREFERENCED_PARAMETER(oidp);
5482 	UNREFERENCED_PARAMETER(arg2);
5483 
5484 	if (ice_driver_is_detaching(sc))
5485 		return (ESHUTDOWN);
5486 
5487 	/* Wire the old buffer so we can take a non-sleepable lock */
5488 	ret = sysctl_wire_old_buffer(req, 0);
5489 	if (ret)
5490 		return (ret);
5491 
5492 	sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
5493 
5494 	rule_lock = &sw->recp_list[ICE_SW_LKUP_ETHERTYPE_MAC].filt_rule_lock;
5495 	rule_head = &sw->recp_list[ICE_SW_LKUP_ETHERTYPE_MAC].filt_rules;
5496 
5497 	sbuf_printf(sbuf, "Ethertype/MAC Filter List");
5498 
5499 	ice_acquire_lock(rule_lock);
5500 
5501 	LIST_FOR_EACH_ENTRY(fm_entry, rule_head, ice_fltr_mgmt_list_entry, list_entry) {
5502 		fi = &fm_entry->fltr_info;
5503 
5504 		sbuf_printf(sbuf,
5505 			    "\nethertype = 0x%04x, mac = %6D, vsi_handle = %3d, fw_act_flag = %5s, lb_en = %1d, lan_en = %1d, fltr_act = %15s, fltr_rule_id = %4d",
5506 			    fi->l_data.ethertype_mac.ethertype,
5507 			    fi->l_data.ethertype_mac.mac_addr, ":",
5508 			    fi->vsi_handle, ice_fltr_flag_str(fi->flag),
5509 			    fi->lb_en, fi->lan_en, ice_fwd_act_str(fi->fltr_act),
5510 			    fi->fltr_rule_id);
5511 
5512 		/* if we have a vsi_list_info, print some information about that */
5513 		if (fm_entry->vsi_list_info) {
5514 			sbuf_printf(sbuf,
5515 				    ", vsi_count = %3d, vsi_list_id = %3d, ref_cnt = %3d",
5516 				    fm_entry->vsi_count,
5517 				    fm_entry->vsi_list_info->vsi_list_id,
5518 				    fm_entry->vsi_list_info->ref_cnt);
5519 		}
5520 	}
5521 
5522 	ice_release_lock(rule_lock);
5523 
5524 	sbuf_finish(sbuf);
5525 	sbuf_delete(sbuf);
5526 
5527 	return (0);
5528 }
5529 
5530 /**
5531  * ice_sysctl_dump_state_flags - Dump device driver state flags
5532  * @oidp: sysctl oid structure
5533  * @arg1: pointer to private data structure
5534  * @arg2: unused
5535  * @req: sysctl request pointer
5536  *
5537  * Callback for "state" sysctl to display currently set driver state flags.
5538  */
5539 static int
5540 ice_sysctl_dump_state_flags(SYSCTL_HANDLER_ARGS)
5541 {
5542 	struct ice_softc *sc = (struct ice_softc *)arg1;
5543 	struct sbuf *sbuf;
5544 	u32 copied_state;
5545 	unsigned int i;
5546 	bool at_least_one = false;
5547 
5548 	UNREFERENCED_PARAMETER(oidp);
5549 	UNREFERENCED_PARAMETER(arg2);
5550 
5551 	if (ice_driver_is_detaching(sc))
5552 		return (ESHUTDOWN);
5553 
5554 	/* Make a copy of the state to ensure we display coherent values */
5555 	copied_state = atomic_load_acq_32(&sc->state);
5556 
5557 	sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
5558 
5559 	/* Add the string for each set state to the sbuf */
5560 	for (i = 0; i < 32; i++) {
5561 		if (copied_state & BIT(i)) {
5562 			const char *str = ice_state_to_str((enum ice_state)i);
5563 
5564 			at_least_one = true;
5565 
5566 			if (str)
5567 				sbuf_printf(sbuf, "\n%s", str);
5568 			else
5569 				sbuf_printf(sbuf, "\nBIT(%u)", i);
5570 		}
5571 	}
5572 
5573 	if (!at_least_one)
5574 		sbuf_printf(sbuf, "Nothing set");
5575 
5576 	sbuf_finish(sbuf);
5577 	sbuf_delete(sbuf);
5578 
5579 	return (0);
5580 }
5581 
5582 /**
5583  * ice_add_debug_tunables - Add tunables helpful for debugging the device driver
5584  * @sc: device private structure
5585  *
5586  * Add sysctl tunable values related to debugging the device driver. For now,
5587  * this means a tunable to set the debug mask early during driver load.
5588  *
5589  * The debug node will be marked CTLFLAG_SKIP unless INVARIANTS is defined, so
5590  * that in normal kernel builds, these will all be hidden, but on a debug
5591  * kernel they will be more easily visible.
5592  */
5593 static void
5594 ice_add_debug_tunables(struct ice_softc *sc)
5595 {
5596 	struct sysctl_oid_list *debug_list;
5597 	device_t dev = sc->dev;
5598 
5599 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
5600 	struct sysctl_oid_list *ctx_list =
5601 	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
5602 
5603 	sc->debug_sysctls = SYSCTL_ADD_NODE(ctx, ctx_list, OID_AUTO, "debug",
5604 					    ICE_CTLFLAG_DEBUG | CTLFLAG_RD,
5605 					    NULL, "Debug Sysctls");
5606 	debug_list = SYSCTL_CHILDREN(sc->debug_sysctls);
5607 
5608 	SYSCTL_ADD_U64(ctx, debug_list, OID_AUTO, "debug_mask",
5609 		       ICE_CTLFLAG_DEBUG | CTLFLAG_RW | CTLFLAG_TUN,
5610 		       &sc->hw.debug_mask, 0,
5611 		       "Debug message enable/disable mask");
5612 
5613 	/* Load the default value from the global sysctl first */
5614 	sc->enable_tx_fc_filter = ice_enable_tx_fc_filter;
5615 
5616 	SYSCTL_ADD_BOOL(ctx, debug_list, OID_AUTO, "enable_tx_fc_filter",
5617 			ICE_CTLFLAG_DEBUG | CTLFLAG_RDTUN,
5618 			&sc->enable_tx_fc_filter, 0,
5619 			"Drop Ethertype 0x8808 control frames originating from software on this PF");
5620 
5621 	/* Load the default value from the global sysctl first */
5622 	sc->enable_tx_lldp_filter = ice_enable_tx_lldp_filter;
5623 
5624 	SYSCTL_ADD_BOOL(ctx, debug_list, OID_AUTO, "enable_tx_lldp_filter",
5625 			ICE_CTLFLAG_DEBUG | CTLFLAG_RDTUN,
5626 			&sc->enable_tx_lldp_filter, 0,
5627 			"Drop Ethertype 0x88cc LLDP frames originating from software on this PF");
5628 
5629 	ice_add_fw_logging_tunables(sc, sc->debug_sysctls);
5630 }
5631 
5632 #define ICE_SYSCTL_HELP_REQUEST_RESET		\
5633 "\nRequest the driver to initiate a reset."	\
5634 "\n\tpfr - Initiate a PF reset"			\
5635 "\n\tcorer - Initiate a CORE reset"		\
5636 "\n\tglobr - Initiate a GLOBAL reset"
5637 
5638 /**
5639  * @var rl_sysctl_ticks
5640  * @brief timestamp for latest reset request sysctl call
5641  *
5642  * Helps rate-limit the call to the sysctl which resets the device
5643  */
5644 int rl_sysctl_ticks = 0;
5645 
5646 /**
5647  * ice_sysctl_request_reset - Request that the driver initiate a reset
5648  * @oidp: sysctl oid structure
5649  * @arg1: pointer to private data structure
5650  * @arg2: unused
5651  * @req: sysctl request pointer
5652  *
5653  * Callback for "request_reset" sysctl to request that the driver initiate
5654  * a reset. Expects to be passed one of the following strings
5655  *
5656  * "pfr" - Initiate a PF reset
5657  * "corer" - Initiate a CORE reset
5658  * "globr" - Initiate a Global reset
5659  */
5660 static int
5661 ice_sysctl_request_reset(SYSCTL_HANDLER_ARGS)
5662 {
5663 	struct ice_softc *sc = (struct ice_softc *)arg1;
5664 	struct ice_hw *hw = &sc->hw;
5665 	enum ice_status status;
5666 	enum ice_reset_req reset_type = ICE_RESET_INVAL;
5667 	const char *reset_message;
5668 	int ret;
5669 
5670 	/* Buffer to store the requested reset string. Must contain enough
5671 	 * space to store the largest expected reset string, which currently
5672 	 * means 6 bytes of space.
5673 	 */
5674 	char reset[6] = "";
5675 
5676 	UNREFERENCED_PARAMETER(arg2);
5677 
5678 	ret = priv_check(curthread, PRIV_DRIVER);
5679 	if (ret)
5680 		return (ret);
5681 
5682 	if (ice_driver_is_detaching(sc))
5683 		return (ESHUTDOWN);
5684 
5685 	/* Read in the requested reset type. */
5686 	ret = sysctl_handle_string(oidp, reset, sizeof(reset), req);
5687 	if ((ret) || (req->newptr == NULL))
5688 		return (ret);
5689 
5690 	if (strcmp(reset, "pfr") == 0) {
5691 		reset_message = "Requesting a PF reset";
5692 		reset_type = ICE_RESET_PFR;
5693 	} else if (strcmp(reset, "corer") == 0) {
5694 		reset_message = "Initiating a CORE reset";
5695 		reset_type = ICE_RESET_CORER;
5696 	} else if (strcmp(reset, "globr") == 0) {
5697 		reset_message = "Initiating a GLOBAL reset";
5698 		reset_type = ICE_RESET_GLOBR;
5699 	} else if (strcmp(reset, "empr") == 0) {
5700 		device_printf(sc->dev, "Triggering an EMP reset via software is not currently supported\n");
5701 		return (EOPNOTSUPP);
5702 	}
5703 
5704 	if (reset_type == ICE_RESET_INVAL) {
5705 		device_printf(sc->dev, "%s is not a valid reset request\n", reset);
5706 		return (EINVAL);
5707 	}
5708 
5709 	/*
5710 	 * Rate-limit the frequency at which this function is called.
5711 	 * Assuming this is called successfully once, typically,
5712 	 * everything should be handled within the allotted time frame.
5713 	 * However, in the odd setup situations, we've also put in
5714 	 * guards for when the reset has finished, but we're in the
5715 	 * process of rebuilding. And instead of queueing an intent,
5716 	 * simply error out and let the caller retry, if so desired.
5717 	 */
5718 	if (TICKS_2_MSEC(ticks - rl_sysctl_ticks) < 500) {
5719 		device_printf(sc->dev,
5720 		    "Call frequency too high. Operation aborted.\n");
5721 		return (EBUSY);
5722 	}
5723 	rl_sysctl_ticks = ticks;
5724 
5725 	if (TICKS_2_MSEC(ticks - sc->rebuild_ticks) < 100) {
5726 		device_printf(sc->dev, "Device rebuilding. Operation aborted.\n");
5727 		return (EBUSY);
5728 	}
5729 
5730 	if (rd32(hw, GLGEN_RSTAT) & GLGEN_RSTAT_DEVSTATE_M) {
5731 		device_printf(sc->dev, "Device in reset. Operation aborted.\n");
5732 		return (EBUSY);
5733 	}
5734 
5735 	device_printf(sc->dev, "%s\n", reset_message);
5736 
5737 	/* Initiate the PF reset during the admin status task */
5738 	if (reset_type == ICE_RESET_PFR) {
5739 		ice_set_state(&sc->state, ICE_STATE_RESET_PFR_REQ);
5740 		return (0);
5741 	}
5742 
5743 	/*
5744 	 * Other types of resets including CORE and GLOBAL resets trigger an
5745 	 * interrupt on all PFs. Initiate the reset now. Preparation and
5746 	 * rebuild logic will be handled by the admin status task.
5747 	 */
5748 	status = ice_reset(hw, reset_type);
5749 
5750 	/*
5751 	 * Resets can take a long time and we still don't want another call
5752 	 * to this function before we settle down.
5753 	 */
5754 	rl_sysctl_ticks = ticks;
5755 
5756 	if (status) {
5757 		device_printf(sc->dev, "failed to initiate device reset, err %s\n",
5758 			      ice_status_str(status));
5759 		ice_set_state(&sc->state, ICE_STATE_RESET_FAILED);
5760 		return (EFAULT);
5761 	}
5762 
5763 	return (0);
5764 }
5765 
5766 /**
5767  * ice_add_debug_sysctls - Add sysctls helpful for debugging the device driver
5768  * @sc: device private structure
5769  *
5770  * Add sysctls related to debugging the device driver. Generally these should
5771  * simply be sysctls which dump internal driver state, to aid in understanding
5772  * what the driver is doing.
5773  */
5774 static void
5775 ice_add_debug_sysctls(struct ice_softc *sc)
5776 {
5777 	struct sysctl_oid *sw_node;
5778 	struct sysctl_oid_list *debug_list, *sw_list;
5779 	device_t dev = sc->dev;
5780 
5781 	struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
5782 
5783 	debug_list = SYSCTL_CHILDREN(sc->debug_sysctls);
5784 
5785 	SYSCTL_ADD_PROC(ctx, debug_list, OID_AUTO, "request_reset",
5786 			ICE_CTLFLAG_DEBUG | CTLTYPE_STRING | CTLFLAG_WR, sc, 0,
5787 			ice_sysctl_request_reset, "A",
5788 			ICE_SYSCTL_HELP_REQUEST_RESET);
5789 
5790 	SYSCTL_ADD_U32(ctx, debug_list, OID_AUTO, "pfr_count",
5791 		       ICE_CTLFLAG_DEBUG | CTLFLAG_RD,
5792 		       &sc->soft_stats.pfr_count, 0,
5793 		       "# of PF resets handled");
5794 
5795 	SYSCTL_ADD_U32(ctx, debug_list, OID_AUTO, "corer_count",
5796 		       ICE_CTLFLAG_DEBUG | CTLFLAG_RD,
5797 		       &sc->soft_stats.corer_count, 0,
5798 		       "# of CORE resets handled");
5799 
5800 	SYSCTL_ADD_U32(ctx, debug_list, OID_AUTO, "globr_count",
5801 		       ICE_CTLFLAG_DEBUG | CTLFLAG_RD,
5802 		       &sc->soft_stats.globr_count, 0,
5803 		       "# of Global resets handled");
5804 
5805 	SYSCTL_ADD_U32(ctx, debug_list, OID_AUTO, "empr_count",
5806 		       ICE_CTLFLAG_DEBUG | CTLFLAG_RD,
5807 		       &sc->soft_stats.empr_count, 0,
5808 		       "# of EMP resets handled");
5809 
5810 	SYSCTL_ADD_U32(ctx, debug_list, OID_AUTO, "tx_mdd_count",
5811 		       ICE_CTLFLAG_DEBUG | CTLFLAG_RD,
5812 		       &sc->soft_stats.tx_mdd_count, 0,
5813 		       "# of Tx MDD events detected");
5814 
5815 	SYSCTL_ADD_U32(ctx, debug_list, OID_AUTO, "rx_mdd_count",
5816 		       ICE_CTLFLAG_DEBUG | CTLFLAG_RD,
5817 		       &sc->soft_stats.rx_mdd_count, 0,
5818 		       "# of Rx MDD events detected");
5819 
5820 	SYSCTL_ADD_PROC(ctx, debug_list, OID_AUTO, "state",
5821 			ICE_CTLFLAG_DEBUG | CTLTYPE_STRING | CTLFLAG_RD, sc, 0,
5822 			ice_sysctl_dump_state_flags, "A",
5823 			"Driver State Flags");
5824 
5825 	SYSCTL_ADD_PROC(ctx, debug_list, OID_AUTO, "phy_type_low",
5826 			ICE_CTLFLAG_DEBUG | CTLTYPE_U64 | CTLFLAG_RW, sc, 0,
5827 			ice_sysctl_phy_type_low, "QU",
5828 			"PHY type Low from Get PHY Caps/Set PHY Cfg");
5829 
5830 	SYSCTL_ADD_PROC(ctx, debug_list, OID_AUTO, "phy_type_high",
5831 			ICE_CTLFLAG_DEBUG | CTLTYPE_U64 | CTLFLAG_RW, sc, 0,
5832 			ice_sysctl_phy_type_high, "QU",
5833 			"PHY type High from Get PHY Caps/Set PHY Cfg");
5834 
5835 	SYSCTL_ADD_PROC(ctx, debug_list, OID_AUTO, "phy_sw_caps",
5836 			ICE_CTLFLAG_DEBUG | CTLTYPE_STRUCT | CTLFLAG_RD, sc, 0,
5837 			ice_sysctl_phy_sw_caps, "",
5838 			"Get PHY Capabilities (Software configuration)");
5839 
5840 	SYSCTL_ADD_PROC(ctx, debug_list, OID_AUTO, "phy_nvm_caps",
5841 			ICE_CTLFLAG_DEBUG | CTLTYPE_STRUCT | CTLFLAG_RD, sc, 0,
5842 			ice_sysctl_phy_nvm_caps, "",
5843 			"Get PHY Capabilities (NVM configuration)");
5844 
5845 	SYSCTL_ADD_PROC(ctx, debug_list, OID_AUTO, "phy_topo_caps",
5846 			ICE_CTLFLAG_DEBUG | CTLTYPE_STRUCT | CTLFLAG_RD, sc, 0,
5847 			ice_sysctl_phy_topo_caps, "",
5848 			"Get PHY Capabilities (Topology configuration)");
5849 
5850 	SYSCTL_ADD_PROC(ctx, debug_list, OID_AUTO, "phy_link_status",
5851 			ICE_CTLFLAG_DEBUG | CTLTYPE_STRUCT | CTLFLAG_RD, sc, 0,
5852 			ice_sysctl_phy_link_status, "",
5853 			"Get PHY Link Status");
5854 
5855 	SYSCTL_ADD_PROC(ctx, debug_list, OID_AUTO, "read_i2c_diag_data",
5856 			ICE_CTLFLAG_DEBUG | CTLTYPE_STRING | CTLFLAG_RD, sc, 0,
5857 			ice_sysctl_read_i2c_diag_data, "A",
5858 			"Dump selected diagnostic data from FW");
5859 
5860 	SYSCTL_ADD_U32(ctx, debug_list, OID_AUTO, "fw_build",
5861 		       ICE_CTLFLAG_DEBUG | CTLFLAG_RD, &sc->hw.fw_build, 0,
5862 		       "FW Build ID");
5863 
5864 	SYSCTL_ADD_PROC(ctx, debug_list, OID_AUTO, "os_ddp_version",
5865 			ICE_CTLFLAG_DEBUG | CTLTYPE_STRING | CTLFLAG_RD, sc, 0,
5866 			ice_sysctl_os_pkg_version, "A",
5867 			"DDP package name and version found in ice_ddp");
5868 
5869 	SYSCTL_ADD_PROC(ctx, debug_list, OID_AUTO, "cur_lldp_persist_status",
5870 			ICE_CTLFLAG_DEBUG | CTLTYPE_STRING | CTLFLAG_RD, sc, 0,
5871 			ice_sysctl_fw_cur_lldp_persist_status, "A",
5872 			"Current LLDP persistent status");
5873 
5874 	SYSCTL_ADD_PROC(ctx, debug_list, OID_AUTO, "dflt_lldp_persist_status",
5875 			ICE_CTLFLAG_DEBUG | CTLTYPE_STRING | CTLFLAG_RD, sc, 0,
5876 			ice_sysctl_fw_dflt_lldp_persist_status, "A",
5877 			"Default LLDP persistent status");
5878 
5879 	SYSCTL_ADD_PROC(ctx, debug_list, OID_AUTO, "negotiated_fc",
5880 			ICE_CTLFLAG_DEBUG | CTLTYPE_STRING | CTLFLAG_RD, sc, 0,
5881 			ice_sysctl_negotiated_fc, "A",
5882 			"Current Negotiated Flow Control mode");
5883 
5884 	SYSCTL_ADD_PROC(ctx, debug_list, OID_AUTO, "local_dcbx_cfg",
5885 			CTLTYPE_STRING | CTLFLAG_RD, sc, ICE_AQ_LLDP_MIB_LOCAL,
5886 			ice_sysctl_dump_dcbx_cfg, "A",
5887 			"Dumps Local MIB information from firmware");
5888 
5889 	SYSCTL_ADD_PROC(ctx, debug_list, OID_AUTO, "remote_dcbx_cfg",
5890 			CTLTYPE_STRING | CTLFLAG_RD, sc, ICE_AQ_LLDP_MIB_REMOTE,
5891 			ice_sysctl_dump_dcbx_cfg, "A",
5892 			"Dumps Remote MIB information from firmware");
5893 
5894 	SYSCTL_ADD_PROC(ctx, debug_list, OID_AUTO, "pf_vsi_cfg", CTLTYPE_STRING | CTLFLAG_RD,
5895 			sc, 0, ice_sysctl_dump_vsi_cfg, "A",
5896 			"Dumps Selected PF VSI parameters from firmware");
5897 
5898 	SYSCTL_ADD_PROC(ctx, debug_list, OID_AUTO, "query_port_ets", CTLTYPE_STRING | CTLFLAG_RD,
5899 			sc, 0, ice_sysctl_query_port_ets, "A",
5900 			"Prints selected output from Query Port ETS AQ command");
5901 
5902 	sw_node = SYSCTL_ADD_NODE(ctx, debug_list, OID_AUTO, "switch",
5903 				  ICE_CTLFLAG_DEBUG | CTLFLAG_RD, NULL,
5904 				  "Switch Configuration");
5905 	sw_list = SYSCTL_CHILDREN(sw_node);
5906 
5907 	SYSCTL_ADD_PROC(ctx, sw_list, OID_AUTO, "mac_filters",
5908 			ICE_CTLFLAG_DEBUG | CTLTYPE_STRING | CTLFLAG_RD, sc, 0,
5909 			ice_sysctl_dump_mac_filters, "A",
5910 			"MAC Filters");
5911 
5912 	SYSCTL_ADD_PROC(ctx, sw_list, OID_AUTO, "vlan_filters",
5913 			ICE_CTLFLAG_DEBUG | CTLTYPE_STRING | CTLFLAG_RD, sc, 0,
5914 			ice_sysctl_dump_vlan_filters, "A",
5915 			"VLAN Filters");
5916 
5917 	SYSCTL_ADD_PROC(ctx, sw_list, OID_AUTO, "ethertype_filters",
5918 			ICE_CTLFLAG_DEBUG | CTLTYPE_STRING | CTLFLAG_RD, sc, 0,
5919 			ice_sysctl_dump_ethertype_filters, "A",
5920 			"Ethertype Filters");
5921 
5922 	SYSCTL_ADD_PROC(ctx, sw_list, OID_AUTO, "ethertype_mac_filters",
5923 			ICE_CTLFLAG_DEBUG | CTLTYPE_STRING | CTLFLAG_RD, sc, 0,
5924 			ice_sysctl_dump_ethertype_mac_filters, "A",
5925 			"Ethertype/MAC Filters");
5926 
5927 }
5928 
5929 /**
5930  * ice_vsi_disable_tx - Disable (unconfigure) Tx queues for a VSI
5931  * @vsi: the VSI to disable
5932  *
5933  * Disables the Tx queues associated with this VSI. Essentially the opposite
5934  * of ice_cfg_vsi_for_tx.
5935  */
5936 int
5937 ice_vsi_disable_tx(struct ice_vsi *vsi)
5938 {
5939 	struct ice_softc *sc = vsi->sc;
5940 	struct ice_hw *hw = &sc->hw;
5941 	enum ice_status status;
5942 	u32 *q_teids;
5943 	u16 *q_ids, *q_handles;
5944 	size_t q_teids_size, q_ids_size, q_handles_size;
5945 	int tc, j, buf_idx, err = 0;
5946 
5947 	if (vsi->num_tx_queues > 255)
5948 		return (ENOSYS);
5949 
5950 	q_teids_size = sizeof(*q_teids) * vsi->num_tx_queues;
5951 	q_teids = (u32 *)malloc(q_teids_size, M_ICE, M_NOWAIT|M_ZERO);
5952 	if (!q_teids)
5953 		return (ENOMEM);
5954 
5955 	q_ids_size = sizeof(*q_ids) * vsi->num_tx_queues;
5956 	q_ids = (u16 *)malloc(q_ids_size, M_ICE, M_NOWAIT|M_ZERO);
5957 	if (!q_ids) {
5958 		err = (ENOMEM);
5959 		goto free_q_teids;
5960 	}
5961 
5962 	q_handles_size = sizeof(*q_handles) * vsi->num_tx_queues;
5963 	q_handles = (u16 *)malloc(q_handles_size, M_ICE, M_NOWAIT|M_ZERO);
5964 	if (!q_handles) {
5965 		err = (ENOMEM);
5966 		goto free_q_ids;
5967 	}
5968 
5969 	ice_for_each_traffic_class(tc) {
5970 		buf_idx = 0;
5971 		for (j = 0; j < vsi->num_tx_queues; j++) {
5972 			struct ice_tx_queue *txq = &vsi->tx_queues[j];
5973 
5974 			if (txq->tc != tc)
5975 				continue;
5976 
5977 			q_ids[buf_idx] = vsi->tx_qmap[j];
5978 			q_handles[buf_idx] = txq->q_handle;
5979 			q_teids[buf_idx] = txq->q_teid;
5980 			buf_idx++;
5981 		}
5982 		/* Skip TC if no queues belong to it */
5983 		if (buf_idx == 0)
5984 			continue;
5985 
5986 		status = ice_dis_vsi_txq(hw->port_info, vsi->idx, tc, buf_idx,
5987 					 q_handles, q_ids, q_teids, ICE_NO_RESET, 0, NULL);
5988 		if (status == ICE_ERR_DOES_NOT_EXIST) {
5989 			; /* Queues have already been disabled, no need to report this as an error */
5990 		} else if (status == ICE_ERR_RESET_ONGOING) {
5991 			device_printf(sc->dev,
5992 				      "Reset in progress. LAN Tx queues already disabled\n");
5993 			break;
5994 		} else if (status) {
5995 			device_printf(sc->dev,
5996 				      "Failed to disable LAN Tx queues: err %s aq_err %s\n",
5997 				      ice_status_str(status), ice_aq_str(hw->adminq.sq_last_status));
5998 			err = (ENODEV);
5999 			break;
6000 		}
6001 
6002 		/* Clear buffers */
6003 		memset(q_teids, 0, q_teids_size);
6004 		memset(q_ids, 0, q_ids_size);
6005 		memset(q_handles, 0, q_handles_size);
6006 	}
6007 
6008 /* free_q_handles: */
6009 	free(q_handles, M_ICE);
6010 free_q_ids:
6011 	free(q_ids, M_ICE);
6012 free_q_teids:
6013 	free(q_teids, M_ICE);
6014 
6015 	return err;
6016 }
6017 
6018 /**
6019  * ice_vsi_set_rss_params - Set the RSS parameters for the VSI
6020  * @vsi: the VSI to configure
6021  *
6022  * Sets the RSS table size and lookup table type for the VSI based on its
6023  * VSI type.
6024  */
6025 static void
6026 ice_vsi_set_rss_params(struct ice_vsi *vsi)
6027 {
6028 	struct ice_softc *sc = vsi->sc;
6029 	struct ice_hw_common_caps *cap;
6030 
6031 	cap = &sc->hw.func_caps.common_cap;
6032 
6033 	switch (vsi->type) {
6034 	case ICE_VSI_PF:
6035 		/* The PF VSI inherits RSS instance of the PF */
6036 		vsi->rss_table_size = cap->rss_table_size;
6037 		vsi->rss_lut_type = ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_PF;
6038 		break;
6039 	case ICE_VSI_VF:
6040 		vsi->rss_table_size = ICE_VSIQF_HLUT_ARRAY_SIZE;
6041 		vsi->rss_lut_type = ICE_AQC_GSET_RSS_LUT_TABLE_TYPE_VSI;
6042 		break;
6043 	default:
6044 		device_printf(sc->dev,
6045 			      "VSI %d: RSS not supported for VSI type %d\n",
6046 			      vsi->idx, vsi->type);
6047 		break;
6048 	}
6049 }
6050 
6051 /**
6052  * ice_vsi_add_txqs_ctx - Create a sysctl context and node to store txq sysctls
6053  * @vsi: The VSI to add the context for
6054  *
6055  * Creates a sysctl context for storing txq sysctls. Additionally creates
6056  * a node rooted at the given VSI's main sysctl node. This context will be
6057  * used to store per-txq sysctls which may need to be released during the
6058  * driver's lifetime.
6059  */
6060 void
6061 ice_vsi_add_txqs_ctx(struct ice_vsi *vsi)
6062 {
6063 	struct sysctl_oid_list *vsi_list;
6064 
6065 	sysctl_ctx_init(&vsi->txqs_ctx);
6066 
6067 	vsi_list = SYSCTL_CHILDREN(vsi->vsi_node);
6068 
6069 	vsi->txqs_node = SYSCTL_ADD_NODE(&vsi->txqs_ctx, vsi_list, OID_AUTO, "txqs",
6070 					 CTLFLAG_RD, NULL, "Tx Queues");
6071 }
6072 
6073 /**
6074  * ice_vsi_add_rxqs_ctx - Create a sysctl context and node to store rxq sysctls
6075  * @vsi: The VSI to add the context for
6076  *
6077  * Creates a sysctl context for storing rxq sysctls. Additionally creates
6078  * a node rooted at the given VSI's main sysctl node. This context will be
6079  * used to store per-rxq sysctls which may need to be released during the
6080  * driver's lifetime.
6081  */
6082 void
6083 ice_vsi_add_rxqs_ctx(struct ice_vsi *vsi)
6084 {
6085 	struct sysctl_oid_list *vsi_list;
6086 
6087 	sysctl_ctx_init(&vsi->rxqs_ctx);
6088 
6089 	vsi_list = SYSCTL_CHILDREN(vsi->vsi_node);
6090 
6091 	vsi->rxqs_node = SYSCTL_ADD_NODE(&vsi->rxqs_ctx, vsi_list, OID_AUTO, "rxqs",
6092 					 CTLFLAG_RD, NULL, "Rx Queues");
6093 }
6094 
6095 /**
6096  * ice_vsi_del_txqs_ctx - Delete the Tx queue sysctl context for this VSI
6097  * @vsi: The VSI to delete from
6098  *
6099  * Frees the txq sysctl context created for storing the per-queue Tx sysctls.
6100  * Must be called prior to freeing the Tx queue memory, in order to avoid
6101  * having sysctls point at stale memory.
6102  */
6103 void
6104 ice_vsi_del_txqs_ctx(struct ice_vsi *vsi)
6105 {
6106 	device_t dev = vsi->sc->dev;
6107 	int err;
6108 
6109 	if (vsi->txqs_node) {
6110 		err = sysctl_ctx_free(&vsi->txqs_ctx);
6111 		if (err)
6112 			device_printf(dev, "failed to free VSI %d txqs_ctx, err %s\n",
6113 				      vsi->idx, ice_err_str(err));
6114 		vsi->txqs_node = NULL;
6115 	}
6116 }
6117 
6118 /**
6119  * ice_vsi_del_rxqs_ctx - Delete the Rx queue sysctl context for this VSI
6120  * @vsi: The VSI to delete from
6121  *
6122  * Frees the rxq sysctl context created for storing the per-queue Rx sysctls.
6123  * Must be called prior to freeing the Rx queue memory, in order to avoid
6124  * having sysctls point at stale memory.
6125  */
6126 void
6127 ice_vsi_del_rxqs_ctx(struct ice_vsi *vsi)
6128 {
6129 	device_t dev = vsi->sc->dev;
6130 	int err;
6131 
6132 	if (vsi->rxqs_node) {
6133 		err = sysctl_ctx_free(&vsi->rxqs_ctx);
6134 		if (err)
6135 			device_printf(dev, "failed to free VSI %d rxqs_ctx, err %s\n",
6136 				      vsi->idx, ice_err_str(err));
6137 		vsi->rxqs_node = NULL;
6138 	}
6139 }
6140 
6141 /**
6142  * ice_add_txq_sysctls - Add per-queue sysctls for a Tx queue
6143  * @txq: pointer to the Tx queue
6144  *
6145 * Add per-queue sysctls for a given Tx queue. Can't be called during
6146 * ice_add_vsi_sysctls, since the queue memory has not yet been setup.
6147  */
6148 void
6149 ice_add_txq_sysctls(struct ice_tx_queue *txq)
6150 {
6151 	struct ice_vsi *vsi = txq->vsi;
6152 	struct sysctl_ctx_list *ctx = &vsi->txqs_ctx;
6153 	struct sysctl_oid_list *txqs_list, *this_txq_list;
6154 	struct sysctl_oid *txq_node;
6155 	char txq_name[32], txq_desc[32];
6156 
6157 	const struct ice_sysctl_info ctls[] = {
6158 		{ &txq->stats.tx_packets, "tx_packets", "Queue Packets Transmitted" },
6159 		{ &txq->stats.tx_bytes, "tx_bytes", "Queue Bytes Transmitted" },
6160 		{ &txq->stats.mss_too_small, "mss_too_small", "TSO sends with an MSS less than 64" },
6161 		{ 0, 0, 0 }
6162 	};
6163 
6164 	const struct ice_sysctl_info *entry = ctls;
6165 
6166 	txqs_list = SYSCTL_CHILDREN(vsi->txqs_node);
6167 
6168 	snprintf(txq_name, sizeof(txq_name), "%u", txq->me);
6169 	snprintf(txq_desc, sizeof(txq_desc), "Tx Queue %u", txq->me);
6170 	txq_node = SYSCTL_ADD_NODE(ctx, txqs_list, OID_AUTO, txq_name,
6171 				   CTLFLAG_RD, NULL, txq_desc);
6172 	this_txq_list = SYSCTL_CHILDREN(txq_node);
6173 
6174 	/* Add the Tx queue statistics */
6175 	while (entry->stat != 0) {
6176 		SYSCTL_ADD_U64(ctx, this_txq_list, OID_AUTO, entry->name,
6177 			       CTLFLAG_RD | CTLFLAG_STATS, entry->stat, 0,
6178 			       entry->description);
6179 		entry++;
6180 	}
6181 
6182 	SYSCTL_ADD_U8(ctx, this_txq_list, OID_AUTO, "tc",
6183 		       CTLFLAG_RD, &txq->tc, 0,
6184 		       "Traffic Class that Queue belongs to");
6185 }
6186 
6187 /**
6188  * ice_add_rxq_sysctls - Add per-queue sysctls for an Rx queue
6189  * @rxq: pointer to the Rx queue
6190  *
6191  * Add per-queue sysctls for a given Rx queue. Can't be called during
6192  * ice_add_vsi_sysctls, since the queue memory has not yet been setup.
6193  */
6194 void
6195 ice_add_rxq_sysctls(struct ice_rx_queue *rxq)
6196 {
6197 	struct ice_vsi *vsi = rxq->vsi;
6198 	struct sysctl_ctx_list *ctx = &vsi->rxqs_ctx;
6199 	struct sysctl_oid_list *rxqs_list, *this_rxq_list;
6200 	struct sysctl_oid *rxq_node;
6201 	char rxq_name[32], rxq_desc[32];
6202 
6203 	const struct ice_sysctl_info ctls[] = {
6204 		{ &rxq->stats.rx_packets, "rx_packets", "Queue Packets Received" },
6205 		{ &rxq->stats.rx_bytes, "rx_bytes", "Queue Bytes Received" },
6206 		{ &rxq->stats.desc_errs, "rx_desc_errs", "Queue Rx Descriptor Errors" },
6207 		{ 0, 0, 0 }
6208 	};
6209 
6210 	const struct ice_sysctl_info *entry = ctls;
6211 
6212 	rxqs_list = SYSCTL_CHILDREN(vsi->rxqs_node);
6213 
6214 	snprintf(rxq_name, sizeof(rxq_name), "%u", rxq->me);
6215 	snprintf(rxq_desc, sizeof(rxq_desc), "Rx Queue %u", rxq->me);
6216 	rxq_node = SYSCTL_ADD_NODE(ctx, rxqs_list, OID_AUTO, rxq_name,
6217 				   CTLFLAG_RD, NULL, rxq_desc);
6218 	this_rxq_list = SYSCTL_CHILDREN(rxq_node);
6219 
6220 	/* Add the Rx queue statistics */
6221 	while (entry->stat != 0) {
6222 		SYSCTL_ADD_U64(ctx, this_rxq_list, OID_AUTO, entry->name,
6223 			       CTLFLAG_RD | CTLFLAG_STATS, entry->stat, 0,
6224 			       entry->description);
6225 		entry++;
6226 	}
6227 
6228 	SYSCTL_ADD_U8(ctx, this_rxq_list, OID_AUTO, "tc",
6229 		       CTLFLAG_RD, &rxq->tc, 0,
6230 		       "Traffic Class that Queue belongs to");
6231 }
6232 
6233 /**
6234  * ice_get_default_rss_key - Obtain a default RSS key
6235  * @seed: storage for the RSS key data
6236  *
6237  * Copies a pre-generated RSS key into the seed memory. The seed pointer must
6238  * point to a block of memory that is at least 40 bytes in size.
6239  *
6240  * The key isn't randomly generated each time this function is called because
6241  * that makes the RSS key change every time we reconfigure RSS. This does mean
6242  * that we're hard coding a possibly 'well known' key. We might want to
6243  * investigate randomly generating this key once during the first call.
6244  */
6245 static void
6246 ice_get_default_rss_key(u8 *seed)
6247 {
6248 	const u8 default_seed[ICE_AQC_GET_SET_RSS_KEY_DATA_RSS_KEY_SIZE] = {
6249 		0x39, 0xed, 0xff, 0x4d, 0x43, 0x58, 0x42, 0xc3, 0x5f, 0xb8,
6250 		0xa5, 0x32, 0x95, 0x65, 0x81, 0xcd, 0x36, 0x79, 0x71, 0x97,
6251 		0xde, 0xa4, 0x41, 0x40, 0x6f, 0x27, 0xe9, 0x81, 0x13, 0xa0,
6252 		0x95, 0x93, 0x5b, 0x1e, 0x9d, 0x27, 0x9d, 0x24, 0x84, 0xb5,
6253 	};
6254 
6255 	bcopy(default_seed, seed, ICE_AQC_GET_SET_RSS_KEY_DATA_RSS_KEY_SIZE);
6256 }
6257 
6258 /**
6259  * ice_set_rss_key - Configure a given VSI with the default RSS key
6260  * @vsi: the VSI to configure
6261  *
6262  * Program the hardware RSS key. We use rss_getkey to grab the kernel RSS key.
6263  * If the kernel RSS interface is not available, this will fall back to our
6264  * pre-generated hash seed from ice_get_default_rss_key().
6265  */
6266 static int
6267 ice_set_rss_key(struct ice_vsi *vsi)
6268 {
6269 	struct ice_aqc_get_set_rss_keys keydata = { .standard_rss_key = {0} };
6270 	struct ice_softc *sc = vsi->sc;
6271 	struct ice_hw *hw = &sc->hw;
6272 	enum ice_status status;
6273 
6274 	/*
6275 	 * If the RSS kernel interface is disabled, this will return the
6276 	 * default RSS key above.
6277 	 */
6278 	rss_getkey(keydata.standard_rss_key);
6279 
6280 	status = ice_aq_set_rss_key(hw, vsi->idx, &keydata);
6281 	if (status) {
6282 		device_printf(sc->dev,
6283 			      "ice_aq_set_rss_key status %s, error %s\n",
6284 			      ice_status_str(status), ice_aq_str(hw->adminq.sq_last_status));
6285 		return (EIO);
6286 	}
6287 
6288 	return (0);
6289 }
6290 
6291 /**
6292  * ice_set_rss_flow_flds - Program the RSS hash flows after package init
6293  * @vsi: the VSI to configure
6294  *
6295  * If the package file is initialized, the default RSS flows are reset. We
6296  * need to reprogram the expected hash configuration. We'll use
6297  * rss_gethashconfig() to determine which flows to enable. If RSS kernel
6298  * support is not enabled, this macro will fall back to suitable defaults.
6299  */
6300 static void
6301 ice_set_rss_flow_flds(struct ice_vsi *vsi)
6302 {
6303 	struct ice_softc *sc = vsi->sc;
6304 	struct ice_hw *hw = &sc->hw;
6305 	struct ice_rss_hash_cfg rss_cfg = { 0, 0, ICE_RSS_ANY_HEADERS, false };
6306 	device_t dev = sc->dev;
6307 	enum ice_status status;
6308 	u_int rss_hash_config;
6309 
6310 	rss_hash_config = rss_gethashconfig();
6311 
6312 	if (rss_hash_config & RSS_HASHTYPE_RSS_IPV4) {
6313 		rss_cfg.addl_hdrs = ICE_FLOW_SEG_HDR_IPV4;
6314 		rss_cfg.hash_flds = ICE_FLOW_HASH_IPV4;
6315 		status = ice_add_rss_cfg(hw, vsi->idx, &rss_cfg);
6316 		if (status)
6317 			device_printf(dev,
6318 				      "ice_add_rss_cfg on VSI %d failed for ipv4 flow, err %s aq_err %s\n",
6319 				      vsi->idx, ice_status_str(status), ice_aq_str(hw->adminq.sq_last_status));
6320 	}
6321 	if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV4) {
6322 		rss_cfg.addl_hdrs = ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_TCP;
6323 		rss_cfg.hash_flds = ICE_HASH_TCP_IPV4;
6324 		status = ice_add_rss_cfg(hw, vsi->idx, &rss_cfg);
6325 		if (status)
6326 			device_printf(dev,
6327 				      "ice_add_rss_cfg on VSI %d failed for tcp4 flow, err %s aq_err %s\n",
6328 				      vsi->idx, ice_status_str(status), ice_aq_str(hw->adminq.sq_last_status));
6329 	}
6330 	if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV4) {
6331 		rss_cfg.addl_hdrs = ICE_FLOW_SEG_HDR_IPV4 | ICE_FLOW_SEG_HDR_UDP;
6332 		rss_cfg.hash_flds = ICE_HASH_UDP_IPV4;
6333 		status = ice_add_rss_cfg(hw, vsi->idx, &rss_cfg);
6334 		if (status)
6335 			device_printf(dev,
6336 				      "ice_add_rss_cfg on VSI %d failed for udp4 flow, err %s aq_err %s\n",
6337 				      vsi->idx, ice_status_str(status), ice_aq_str(hw->adminq.sq_last_status));
6338 	}
6339 	if (rss_hash_config & (RSS_HASHTYPE_RSS_IPV6 | RSS_HASHTYPE_RSS_IPV6_EX)) {
6340 		rss_cfg.addl_hdrs = ICE_FLOW_SEG_HDR_IPV6;
6341 		rss_cfg.hash_flds = ICE_FLOW_HASH_IPV6;
6342 		status = ice_add_rss_cfg(hw, vsi->idx, &rss_cfg);
6343 		if (status)
6344 			device_printf(dev,
6345 				      "ice_add_rss_cfg on VSI %d failed for ipv6 flow, err %s aq_err %s\n",
6346 				      vsi->idx, ice_status_str(status), ice_aq_str(hw->adminq.sq_last_status));
6347 	}
6348 	if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV6) {
6349 		rss_cfg.addl_hdrs = ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_TCP;
6350 		rss_cfg.hash_flds = ICE_HASH_TCP_IPV6;
6351 		status = ice_add_rss_cfg(hw, vsi->idx, &rss_cfg);
6352 		if (status)
6353 			device_printf(dev,
6354 				      "ice_add_rss_cfg on VSI %d failed for tcp6 flow, err %s aq_err %s\n",
6355 				      vsi->idx, ice_status_str(status), ice_aq_str(hw->adminq.sq_last_status));
6356 	}
6357 	if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV6) {
6358 		rss_cfg.addl_hdrs = ICE_FLOW_SEG_HDR_IPV6 | ICE_FLOW_SEG_HDR_UDP;
6359 		rss_cfg.hash_flds = ICE_HASH_UDP_IPV6;
6360 		status = ice_add_rss_cfg(hw, vsi->idx, &rss_cfg);
6361 		if (status)
6362 			device_printf(dev,
6363 				      "ice_add_rss_cfg on VSI %d failed for udp6 flow, err %s aq_err %s\n",
6364 				      vsi->idx, ice_status_str(status), ice_aq_str(hw->adminq.sq_last_status));
6365 	}
6366 
6367 	/* Warn about RSS hash types which are not supported */
6368 	/* coverity[dead_error_condition] */
6369 	if (rss_hash_config & ~ICE_DEFAULT_RSS_HASH_CONFIG) {
6370 		device_printf(dev,
6371 			      "ice_add_rss_cfg on VSI %d could not configure every requested hash type\n",
6372 			      vsi->idx);
6373 	}
6374 }
6375 
6376 /**
6377  * ice_set_rss_lut - Program the RSS lookup table for a VSI
6378  * @vsi: the VSI to configure
6379  *
6380  * Programs the RSS lookup table for a given VSI. We use
6381  * rss_get_indirection_to_bucket which will use the indirection table provided
6382  * by the kernel RSS interface when available. If the kernel RSS interface is
6383  * not available, we will fall back to a simple round-robin fashion queue
6384  * assignment.
6385  */
6386 static int
6387 ice_set_rss_lut(struct ice_vsi *vsi)
6388 {
6389 	struct ice_softc *sc = vsi->sc;
6390 	struct ice_hw *hw = &sc->hw;
6391 	device_t dev = sc->dev;
6392 	struct ice_aq_get_set_rss_lut_params lut_params;
6393 	enum ice_status status;
6394 	int i, err = 0;
6395 	u8 *lut;
6396 
6397 	lut = (u8 *)malloc(vsi->rss_table_size, M_ICE, M_NOWAIT|M_ZERO);
6398 	if (!lut) {
6399 		device_printf(dev, "Failed to allocate RSS lut memory\n");
6400 		return (ENOMEM);
6401 	}
6402 
6403 	/* Populate the LUT with max no. of queues. If the RSS kernel
6404 	 * interface is disabled, this will assign the lookup table in
6405 	 * a simple round robin fashion
6406 	 */
6407 	for (i = 0; i < vsi->rss_table_size; i++) {
6408 		/* XXX: this needs to be changed if num_rx_queues ever counts
6409 		 * more than just the RSS queues */
6410 		lut[i] = rss_get_indirection_to_bucket(i) % vsi->num_rx_queues;
6411 	}
6412 
6413 	lut_params.vsi_handle = vsi->idx;
6414 	lut_params.lut_size = vsi->rss_table_size;
6415 	lut_params.lut_type = vsi->rss_lut_type;
6416 	lut_params.lut = lut;
6417 	lut_params.global_lut_id = 0;
6418 	status = ice_aq_set_rss_lut(hw, &lut_params);
6419 	if (status) {
6420 		device_printf(dev,
6421 			      "Cannot set RSS lut, err %s aq_err %s\n",
6422 			      ice_status_str(status), ice_aq_str(hw->adminq.sq_last_status));
6423 		err = (EIO);
6424 	}
6425 
6426 	free(lut, M_ICE);
6427 	return err;
6428 }
6429 
6430 /**
6431  * ice_config_rss - Configure RSS for a VSI
6432  * @vsi: the VSI to configure
6433  *
6434  * If FEATURE_RSS is enabled, configures the RSS lookup table and hash key for
6435  * a given VSI.
6436  */
6437 int
6438 ice_config_rss(struct ice_vsi *vsi)
6439 {
6440 	int err;
6441 
6442 	/* Nothing to do, if RSS is not enabled */
6443 	if (!ice_is_bit_set(vsi->sc->feat_en, ICE_FEATURE_RSS))
6444 		return 0;
6445 
6446 	err = ice_set_rss_key(vsi);
6447 	if (err)
6448 		return err;
6449 
6450 	ice_set_rss_flow_flds(vsi);
6451 
6452 	return ice_set_rss_lut(vsi);
6453 }
6454 
6455 /**
6456  * ice_log_pkg_init - Log a message about status of DDP initialization
6457  * @sc: the device softc pointer
6458  * @pkg_status: the status result of ice_copy_and_init_pkg
6459  *
6460  * Called by ice_load_pkg after an attempt to download the DDP package
6461  * contents to the device. Determines whether the download was successful or
6462  * not and logs an appropriate message for the system administrator.
6463  *
6464  * @post if a DDP package was previously downloaded on another port and it
6465  * is not compatible with this driver, pkg_status will be updated to reflect
6466  * this, and the driver will transition to safe mode.
6467  */
6468 void
6469 ice_log_pkg_init(struct ice_softc *sc, enum ice_status *pkg_status)
6470 {
6471 	struct ice_hw *hw = &sc->hw;
6472 	device_t dev = sc->dev;
6473 	struct sbuf *active_pkg, *os_pkg;
6474 
6475 	active_pkg = sbuf_new_auto();
6476 	ice_active_pkg_version_str(hw, active_pkg);
6477 	sbuf_finish(active_pkg);
6478 
6479 	os_pkg = sbuf_new_auto();
6480 	ice_os_pkg_version_str(hw, os_pkg);
6481 	sbuf_finish(os_pkg);
6482 
6483 	switch (*pkg_status) {
6484 	case ICE_SUCCESS:
6485 		/* The package download AdminQ command returned success because
6486 		 * this download succeeded or ICE_ERR_AQ_NO_WORK since there is
6487 		 * already a package loaded on the device.
6488 		 */
6489 		if (hw->pkg_ver.major == hw->active_pkg_ver.major &&
6490 		    hw->pkg_ver.minor == hw->active_pkg_ver.minor &&
6491 		    hw->pkg_ver.update == hw->active_pkg_ver.update &&
6492 		    hw->pkg_ver.draft == hw->active_pkg_ver.draft &&
6493 		    !memcmp(hw->pkg_name, hw->active_pkg_name,
6494 			    sizeof(hw->pkg_name))) {
6495 			switch (hw->pkg_dwnld_status) {
6496 			case ICE_AQ_RC_OK:
6497 				device_printf(dev,
6498 					      "The DDP package was successfully loaded: %s.\n",
6499 					      sbuf_data(active_pkg));
6500 				break;
6501 			case ICE_AQ_RC_EEXIST:
6502 				device_printf(dev,
6503 					      "DDP package already present on device: %s.\n",
6504 					      sbuf_data(active_pkg));
6505 				break;
6506 			default:
6507 				/* We do not expect this to occur, but the
6508 				 * extra messaging is here in case something
6509 				 * changes in the ice_init_pkg flow.
6510 				 */
6511 				device_printf(dev,
6512 					      "DDP package already present on device: %s.  An unexpected error occurred, pkg_dwnld_status %s.\n",
6513 					      sbuf_data(active_pkg),
6514 					      ice_aq_str(hw->pkg_dwnld_status));
6515 				break;
6516 			}
6517 		} else if (pkg_ver_compatible(&hw->active_pkg_ver) == 0) {
6518 			device_printf(dev,
6519 				      "The driver could not load the DDP package file because a compatible DDP package is already present on the device.  The device has package %s.  The ice_ddp module has package: %s.\n",
6520 				      sbuf_data(active_pkg),
6521 				      sbuf_data(os_pkg));
6522 		} else if (pkg_ver_compatible(&hw->active_pkg_ver) > 0) {
6523 			device_printf(dev,
6524 				      "The device has a DDP package that is higher than the driver supports.  The device has package %s.  The driver requires version %d.%d.x.x.  Entering Safe Mode.\n",
6525 				      sbuf_data(active_pkg),
6526 				      ICE_PKG_SUPP_VER_MAJ, ICE_PKG_SUPP_VER_MNR);
6527 			*pkg_status = ICE_ERR_NOT_SUPPORTED;
6528 		} else {
6529 			device_printf(dev,
6530 				      "The device has a DDP package that is lower than the driver supports.  The device has package %s.  The driver requires version %d.%d.x.x.  Entering Safe Mode.\n",
6531 				      sbuf_data(active_pkg),
6532 				      ICE_PKG_SUPP_VER_MAJ, ICE_PKG_SUPP_VER_MNR);
6533 			*pkg_status = ICE_ERR_NOT_SUPPORTED;
6534 		}
6535 		break;
6536 	case ICE_ERR_NOT_SUPPORTED:
6537 		/*
6538 		 * This assumes that the active_pkg_ver will not be
6539 		 * initialized if the ice_ddp package version is not
6540 		 * supported.
6541 		 */
6542 		if (pkg_ver_empty(&hw->active_pkg_ver, hw->active_pkg_name)) {
6543 			/* The ice_ddp version is not supported */
6544 			if (pkg_ver_compatible(&hw->pkg_ver) > 0) {
6545 				device_printf(dev,
6546 					      "The DDP package in the ice_ddp module is higher than the driver supports.  The ice_ddp module has package %s.  The driver requires version %d.%d.x.x.  Please use an updated driver.  Entering Safe Mode.\n",
6547 					      sbuf_data(os_pkg),
6548 					      ICE_PKG_SUPP_VER_MAJ, ICE_PKG_SUPP_VER_MNR);
6549 			} else if (pkg_ver_compatible(&hw->pkg_ver) < 0) {
6550 				device_printf(dev,
6551 					      "The DDP package in the ice_ddp module is lower than the driver supports.  The ice_ddp module has package %s.  The driver requires version %d.%d.x.x.  Please use an updated ice_ddp module.  Entering Safe Mode.\n",
6552 					      sbuf_data(os_pkg),
6553 					      ICE_PKG_SUPP_VER_MAJ, ICE_PKG_SUPP_VER_MNR);
6554 			} else {
6555 				device_printf(dev,
6556 					      "An unknown error (%s aq_err %s) occurred when loading the DDP package.  The ice_ddp module has package %s.  The device has package %s.  The driver requires version %d.%d.x.x.  Entering Safe Mode.\n",
6557 					      ice_status_str(*pkg_status),
6558 					      ice_aq_str(hw->pkg_dwnld_status),
6559 					      sbuf_data(os_pkg),
6560 					      sbuf_data(active_pkg),
6561 					      ICE_PKG_SUPP_VER_MAJ, ICE_PKG_SUPP_VER_MNR);
6562 			}
6563 		} else {
6564 			if (pkg_ver_compatible(&hw->active_pkg_ver) > 0) {
6565 				device_printf(dev,
6566 					      "The device has a DDP package that is higher than the driver supports.  The device has package %s.  The driver requires version %d.%d.x.x.  Entering Safe Mode.\n",
6567 					      sbuf_data(active_pkg),
6568 					      ICE_PKG_SUPP_VER_MAJ, ICE_PKG_SUPP_VER_MNR);
6569 			} else if (pkg_ver_compatible(&hw->active_pkg_ver) < 0) {
6570 				device_printf(dev,
6571 					      "The device has a DDP package that is lower than the driver supports.  The device has package %s.  The driver requires version %d.%d.x.x.  Entering Safe Mode.\n",
6572 					      sbuf_data(active_pkg),
6573 					      ICE_PKG_SUPP_VER_MAJ, ICE_PKG_SUPP_VER_MNR);
6574 			} else {
6575 				device_printf(dev,
6576 					      "An unknown error (%s aq_err %s) occurred when loading the DDP package.  The ice_ddp module has package %s.  The device has package %s.  The driver requires version %d.%d.x.x.  Entering Safe Mode.\n",
6577 					      ice_status_str(*pkg_status),
6578 					      ice_aq_str(hw->pkg_dwnld_status),
6579 					      sbuf_data(os_pkg),
6580 					      sbuf_data(active_pkg),
6581 					      ICE_PKG_SUPP_VER_MAJ, ICE_PKG_SUPP_VER_MNR);
6582 			}
6583 		}
6584 		break;
6585 	case ICE_ERR_CFG:
6586 	case ICE_ERR_BUF_TOO_SHORT:
6587 	case ICE_ERR_PARAM:
6588 		device_printf(dev,
6589 			      "The DDP package in the ice_ddp module is invalid.  Entering Safe Mode\n");
6590 		break;
6591 	case ICE_ERR_FW_DDP_MISMATCH:
6592 		device_printf(dev,
6593 			      "The firmware loaded on the device is not compatible with the DDP package.  Please update the device's NVM.  Entering safe mode.\n");
6594 		break;
6595 	case ICE_ERR_AQ_ERROR:
6596 		switch (hw->pkg_dwnld_status) {
6597 		case ICE_AQ_RC_ENOSEC:
6598 		case ICE_AQ_RC_EBADSIG:
6599 			device_printf(dev,
6600 				 "The DDP package in the ice_ddp module cannot be loaded because its signature is not valid.  Please use a valid ice_ddp module.  Entering Safe Mode.\n");
6601 			goto free_sbufs;
6602 		case ICE_AQ_RC_ESVN:
6603 			device_printf(dev,
6604 				 "The DDP package in the ice_ddp module could not be loaded because its security revision is too low.  Please use an updated ice_ddp module.  Entering Safe Mode.\n");
6605 			goto free_sbufs;
6606 		case ICE_AQ_RC_EBADMAN:
6607 		case ICE_AQ_RC_EBADBUF:
6608 			device_printf(dev,
6609 				 "An error occurred on the device while loading the DDP package.  Entering Safe Mode.\n");
6610 			goto free_sbufs;
6611 		default:
6612 			break;
6613 		}
6614 		/* fall-through */
6615 	default:
6616 		device_printf(dev,
6617 			 "An unknown error (%s aq_err %s) occurred when loading the DDP package.  Entering Safe Mode.\n",
6618 			 ice_status_str(*pkg_status),
6619 			 ice_aq_str(hw->pkg_dwnld_status));
6620 		break;
6621 	}
6622 
6623 free_sbufs:
6624 	sbuf_delete(active_pkg);
6625 	sbuf_delete(os_pkg);
6626 }
6627 
6628 /**
6629  * ice_load_pkg_file - Load the DDP package file using firmware_get
6630  * @sc: device private softc
6631  *
6632  * Use firmware_get to load the DDP package memory and then request that
6633  * firmware download the package contents and program the relevant hardware
6634  * bits.
6635  *
6636  * This function makes a copy of the DDP package memory which is tracked in
6637  * the ice_hw structure. The copy will be managed and released by
6638  * ice_deinit_hw(). This allows the firmware reference to be immediately
6639  * released using firmware_put.
6640  */
6641 void
6642 ice_load_pkg_file(struct ice_softc *sc)
6643 {
6644 	struct ice_hw *hw = &sc->hw;
6645 	device_t dev = sc->dev;
6646 	enum ice_status status;
6647 	const struct firmware *pkg;
6648 
6649 	pkg = firmware_get("ice_ddp");
6650 	if (!pkg) {
6651 		device_printf(dev, "The DDP package module (ice_ddp) failed to load or could not be found. Entering Safe Mode.\n");
6652 		if (cold)
6653 			device_printf(dev,
6654 				      "The DDP package module cannot be automatically loaded while booting. You may want to specify ice_ddp_load=\"YES\" in your loader.conf\n");
6655 		ice_set_bit(ICE_FEATURE_SAFE_MODE, sc->feat_cap);
6656 		ice_set_bit(ICE_FEATURE_SAFE_MODE, sc->feat_en);
6657 		return;
6658 	}
6659 
6660 	/* Copy and download the pkg contents */
6661 	status = ice_copy_and_init_pkg(hw, (const u8 *)pkg->data, pkg->datasize);
6662 
6663 	/* Release the firmware reference */
6664 	firmware_put(pkg, FIRMWARE_UNLOAD);
6665 
6666 	/* Check the active DDP package version and log a message */
6667 	ice_log_pkg_init(sc, &status);
6668 
6669 	/* Place the driver into safe mode */
6670 	if (status != ICE_SUCCESS) {
6671 		ice_set_bit(ICE_FEATURE_SAFE_MODE, sc->feat_cap);
6672 		ice_set_bit(ICE_FEATURE_SAFE_MODE, sc->feat_en);
6673 	}
6674 }
6675 
6676 /**
6677  * ice_get_ifnet_counter - Retrieve counter value for a given ifnet counter
6678  * @vsi: the vsi to retrieve the value for
6679  * @counter: the counter type to retrieve
6680  *
6681  * Returns the value for a given ifnet counter. To do so, we calculate the
6682  * value based on the matching hardware statistics.
6683  */
6684 uint64_t
6685 ice_get_ifnet_counter(struct ice_vsi *vsi, ift_counter counter)
6686 {
6687 	struct ice_hw_port_stats *hs = &vsi->sc->stats.cur;
6688 	struct ice_eth_stats *es = &vsi->hw_stats.cur;
6689 
6690 	/* For some statistics, especially those related to error flows, we do
6691 	 * not have per-VSI counters. In this case, we just report the global
6692 	 * counters.
6693 	 */
6694 
6695 	switch (counter) {
6696 	case IFCOUNTER_IPACKETS:
6697 		return (es->rx_unicast + es->rx_multicast + es->rx_broadcast);
6698 	case IFCOUNTER_IERRORS:
6699 		return (hs->crc_errors + hs->illegal_bytes +
6700 			hs->mac_local_faults + hs->mac_remote_faults +
6701 			hs->rx_len_errors + hs->rx_undersize +
6702 			hs->rx_oversize + hs->rx_fragments + hs->rx_jabber);
6703 	case IFCOUNTER_OPACKETS:
6704 		return (es->tx_unicast + es->tx_multicast + es->tx_broadcast);
6705 	case IFCOUNTER_OERRORS:
6706 		return (es->tx_errors);
6707 	case IFCOUNTER_COLLISIONS:
6708 		return (0);
6709 	case IFCOUNTER_IBYTES:
6710 		return (es->rx_bytes);
6711 	case IFCOUNTER_OBYTES:
6712 		return (es->tx_bytes);
6713 	case IFCOUNTER_IMCASTS:
6714 		return (es->rx_multicast);
6715 	case IFCOUNTER_OMCASTS:
6716 		return (es->tx_multicast);
6717 	case IFCOUNTER_IQDROPS:
6718 		return (es->rx_discards);
6719 	case IFCOUNTER_OQDROPS:
6720 		return (hs->tx_dropped_link_down);
6721 	case IFCOUNTER_NOPROTO:
6722 		return (es->rx_unknown_protocol);
6723 	default:
6724 		return if_get_counter_default(vsi->sc->ifp, counter);
6725 	}
6726 }
6727 
6728 /**
6729  * ice_save_pci_info - Save PCI configuration fields in HW struct
6730  * @hw: the ice_hw struct to save the PCI information in
6731  * @dev: the device to get the PCI information from
6732  *
6733  * This should only be called once, early in the device attach
6734  * process.
6735  */
6736 void
6737 ice_save_pci_info(struct ice_hw *hw, device_t dev)
6738 {
6739 	hw->vendor_id = pci_get_vendor(dev);
6740 	hw->device_id = pci_get_device(dev);
6741 	hw->subsystem_vendor_id = pci_get_subvendor(dev);
6742 	hw->subsystem_device_id = pci_get_subdevice(dev);
6743 	hw->revision_id = pci_get_revid(dev);
6744 	hw->bus.device = pci_get_slot(dev);
6745 	hw->bus.func = pci_get_function(dev);
6746 }
6747 
6748 /**
6749  * ice_replay_all_vsi_cfg - Replace configuration for all VSIs after reset
6750  * @sc: the device softc
6751  *
6752  * Replace the configuration for each VSI, and then cleanup replay
6753  * information. Called after a hardware reset in order to reconfigure the
6754  * active VSIs.
6755  */
6756 int
6757 ice_replay_all_vsi_cfg(struct ice_softc *sc)
6758 {
6759 	struct ice_hw *hw = &sc->hw;
6760 	enum ice_status status;
6761 	int i;
6762 
6763 	for (i = 0 ; i < sc->num_available_vsi; i++) {
6764 		struct ice_vsi *vsi = sc->all_vsi[i];
6765 
6766 		if (!vsi)
6767 			continue;
6768 
6769 		status = ice_replay_vsi(hw, vsi->idx);
6770 		if (status) {
6771 			device_printf(sc->dev, "Failed to replay VSI %d, err %s aq_err %s\n",
6772 				      vsi->idx, ice_status_str(status),
6773 				      ice_aq_str(hw->adminq.sq_last_status));
6774 			return (EIO);
6775 		}
6776 	}
6777 
6778 	/* Cleanup replay filters after successful reconfiguration */
6779 	ice_replay_post(hw);
6780 	return (0);
6781 }
6782 
6783 /**
6784  * ice_clean_vsi_rss_cfg - Cleanup RSS configuration for a given VSI
6785  * @vsi: pointer to the VSI structure
6786  *
6787  * Cleanup the advanced RSS configuration for a given VSI. This is necessary
6788  * during driver removal to ensure that all RSS resources are properly
6789  * released.
6790  *
6791  * @remark this function doesn't report an error as it is expected to be
6792  * called during driver reset and unload, and there isn't much the driver can
6793  * do if freeing RSS resources fails.
6794  */
6795 static void
6796 ice_clean_vsi_rss_cfg(struct ice_vsi *vsi)
6797 {
6798 	struct ice_softc *sc = vsi->sc;
6799 	struct ice_hw *hw = &sc->hw;
6800 	device_t dev = sc->dev;
6801 	enum ice_status status;
6802 
6803 	status = ice_rem_vsi_rss_cfg(hw, vsi->idx);
6804 	if (status)
6805 		device_printf(dev,
6806 			      "Failed to remove RSS configuration for VSI %d, err %s\n",
6807 			      vsi->idx, ice_status_str(status));
6808 
6809 	/* Remove this VSI from the RSS list */
6810 	ice_rem_vsi_rss_list(hw, vsi->idx);
6811 }
6812 
6813 /**
6814  * ice_clean_all_vsi_rss_cfg - Cleanup RSS configuration for all VSIs
6815  * @sc: the device softc pointer
6816  *
6817  * Cleanup the advanced RSS configuration for all VSIs on a given PF
6818  * interface.
6819  *
6820  * @remark This should be called while preparing for a reset, to cleanup stale
6821  * RSS configuration for all VSIs.
6822  */
6823 void
6824 ice_clean_all_vsi_rss_cfg(struct ice_softc *sc)
6825 {
6826 	int i;
6827 
6828 	/* No need to cleanup if RSS is not enabled */
6829 	if (!ice_is_bit_set(sc->feat_en, ICE_FEATURE_RSS))
6830 		return;
6831 
6832 	for (i = 0; i < sc->num_available_vsi; i++) {
6833 		struct ice_vsi *vsi = sc->all_vsi[i];
6834 
6835 		if (vsi)
6836 			ice_clean_vsi_rss_cfg(vsi);
6837 	}
6838 }
6839 
6840 /**
6841  * ice_requested_fec_mode - Return the requested FEC mode as a string
6842  * @pi: The port info structure
6843  *
6844  * Return a string representing the requested FEC mode.
6845  */
6846 static const char *
6847 ice_requested_fec_mode(struct ice_port_info *pi)
6848 {
6849 	struct ice_aqc_get_phy_caps_data pcaps = { 0 };
6850 	enum ice_status status;
6851 
6852 	status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_ACTIVE_CFG,
6853 				     &pcaps, NULL);
6854 	if (status)
6855 		/* Just report unknown if we can't get capabilities */
6856 		return "Unknown";
6857 
6858 	/* Check if RS-FEC has been requested first */
6859 	if (pcaps.link_fec_options & (ICE_AQC_PHY_FEC_25G_RS_528_REQ |
6860 				      ICE_AQC_PHY_FEC_25G_RS_544_REQ))
6861 		return ice_fec_str(ICE_FEC_RS);
6862 
6863 	/* If RS FEC has not been requested, then check BASE-R */
6864 	if (pcaps.link_fec_options & (ICE_AQC_PHY_FEC_10G_KR_40G_KR4_REQ |
6865 				      ICE_AQC_PHY_FEC_25G_KR_REQ))
6866 		return ice_fec_str(ICE_FEC_BASER);
6867 
6868 	return ice_fec_str(ICE_FEC_NONE);
6869 }
6870 
6871 /**
6872  * ice_negotiated_fec_mode - Return the negotiated FEC mode as a string
6873  * @pi: The port info structure
6874  *
6875  * Return a string representing the current FEC mode.
6876  */
6877 static const char *
6878 ice_negotiated_fec_mode(struct ice_port_info *pi)
6879 {
6880 	/* First, check if RS has been requested first */
6881 	if (pi->phy.link_info.fec_info & (ICE_AQ_LINK_25G_RS_528_FEC_EN |
6882 					  ICE_AQ_LINK_25G_RS_544_FEC_EN))
6883 		return ice_fec_str(ICE_FEC_RS);
6884 
6885 	/* If RS FEC has not been requested, then check BASE-R */
6886 	if (pi->phy.link_info.fec_info & ICE_AQ_LINK_25G_KR_FEC_EN)
6887 		return ice_fec_str(ICE_FEC_BASER);
6888 
6889 	return ice_fec_str(ICE_FEC_NONE);
6890 }
6891 
6892 /**
6893  * ice_autoneg_mode - Return string indicating of autoneg completed
6894  * @pi: The port info structure
6895  *
6896  * Return "True" if autonegotiation is completed, "False" otherwise.
6897  */
6898 static const char *
6899 ice_autoneg_mode(struct ice_port_info *pi)
6900 {
6901 	if (pi->phy.link_info.an_info & ICE_AQ_AN_COMPLETED)
6902 		return "True";
6903 	else
6904 		return "False";
6905 }
6906 
6907 /**
6908  * ice_flowcontrol_mode - Return string indicating the Flow Control mode
6909  * @pi: The port info structure
6910  *
6911  * Returns the current Flow Control mode as a string.
6912  */
6913 static const char *
6914 ice_flowcontrol_mode(struct ice_port_info *pi)
6915 {
6916 	return ice_fc_str(pi->fc.current_mode);
6917 }
6918 
6919 /**
6920  * ice_link_up_msg - Log a link up message with associated info
6921  * @sc: the device private softc
6922  *
6923  * Log a link up message with LOG_NOTICE message level. Include information
6924  * about the duplex, FEC mode, autonegotiation and flow control.
6925  */
6926 void
6927 ice_link_up_msg(struct ice_softc *sc)
6928 {
6929 	struct ice_hw *hw = &sc->hw;
6930 	struct ifnet *ifp = sc->ifp;
6931 	const char *speed, *req_fec, *neg_fec, *autoneg, *flowcontrol;
6932 
6933 	speed = ice_aq_speed_to_str(hw->port_info);
6934 	req_fec = ice_requested_fec_mode(hw->port_info);
6935 	neg_fec = ice_negotiated_fec_mode(hw->port_info);
6936 	autoneg = ice_autoneg_mode(hw->port_info);
6937 	flowcontrol = ice_flowcontrol_mode(hw->port_info);
6938 
6939 	log(LOG_NOTICE, "%s: Link is up, %s Full Duplex, Requested FEC: %s, Negotiated FEC: %s, Autoneg: %s, Flow Control: %s\n",
6940 	    ifp->if_xname, speed, req_fec, neg_fec, autoneg, flowcontrol);
6941 }
6942 
6943 /**
6944  * ice_update_laa_mac - Update MAC address if Locally Administered
6945  * @sc: the device softc
6946  *
6947  * Update the device MAC address when a Locally Administered Address is
6948  * assigned.
6949  *
6950  * This function does *not* update the MAC filter list itself. Instead, it
6951  * should be called after ice_rm_pf_default_mac_filters, so that the previous
6952  * address filter will be removed, and before ice_cfg_pf_default_mac_filters,
6953  * so that the new address filter will be assigned.
6954  */
6955 int
6956 ice_update_laa_mac(struct ice_softc *sc)
6957 {
6958 	const u8 *lladdr = (const u8 *)IF_LLADDR(sc->ifp);
6959 	struct ice_hw *hw = &sc->hw;
6960 	enum ice_status status;
6961 
6962 	/* If the address is the same, then there is nothing to update */
6963 	if (!memcmp(lladdr, hw->port_info->mac.lan_addr, ETHER_ADDR_LEN))
6964 		return (0);
6965 
6966 	/* Reject Multicast addresses */
6967 	if (ETHER_IS_MULTICAST(lladdr))
6968 		return (EINVAL);
6969 
6970 	status = ice_aq_manage_mac_write(hw, lladdr, ICE_AQC_MAN_MAC_UPDATE_LAA_WOL, NULL);
6971 	if (status) {
6972 		device_printf(sc->dev, "Failed to write mac %6D to firmware, err %s aq_err %s\n",
6973 			      lladdr, ":", ice_status_str(status),
6974 			      ice_aq_str(hw->adminq.sq_last_status));
6975 		return (EFAULT);
6976 	}
6977 
6978 	/* Copy the address into place of the LAN address. */
6979 	bcopy(lladdr, hw->port_info->mac.lan_addr, ETHER_ADDR_LEN);
6980 
6981 	return (0);
6982 }
6983 
6984 /**
6985  * ice_get_and_print_bus_info - Save (PCI) bus info and print messages
6986  * @sc: device softc
6987  *
6988  * This will potentially print out a warning message if bus bandwidth
6989  * is insufficient for full-speed operation.
6990  *
6991  * This should only be called once, during the attach process, after
6992  * hw->port_info has been filled out with port link topology information
6993  * (from the Get PHY Capabilities Admin Queue command).
6994  */
6995 void
6996 ice_get_and_print_bus_info(struct ice_softc *sc)
6997 {
6998 	struct ice_hw *hw = &sc->hw;
6999 	device_t dev = sc->dev;
7000 	u16 pci_link_status;
7001 	int offset;
7002 
7003 	pci_find_cap(dev, PCIY_EXPRESS, &offset);
7004 	pci_link_status = pci_read_config(dev, offset + PCIER_LINK_STA, 2);
7005 
7006 	/* Fill out hw struct with PCIE link status info */
7007 	ice_set_pci_link_status_data(hw, pci_link_status);
7008 
7009 	/* Use info to print out bandwidth messages */
7010 	ice_print_bus_link_data(dev, hw);
7011 
7012 	if (ice_pcie_bandwidth_check(sc)) {
7013 		device_printf(dev,
7014 		    "PCI-Express bandwidth available for this device may be insufficient for optimal performance.\n");
7015 		device_printf(dev,
7016 		    "Please move the device to a different PCI-e link with more lanes and/or higher transfer rate.\n");
7017 	}
7018 }
7019 
7020 /**
7021  * ice_pcie_bus_speed_to_rate - Convert driver bus speed enum value to
7022  * a 64-bit baudrate.
7023  * @speed: enum value to convert
7024  *
7025  * This only goes up to PCIE Gen 4.
7026  */
7027 static uint64_t
7028 ice_pcie_bus_speed_to_rate(enum ice_pcie_bus_speed speed)
7029 {
7030 	/* If the PCI-E speed is Gen1 or Gen2, then report
7031 	 * only 80% of bus speed to account for encoding overhead.
7032 	 */
7033 	switch (speed) {
7034 	case ice_pcie_speed_2_5GT:
7035 		return IF_Gbps(2);
7036 	case ice_pcie_speed_5_0GT:
7037 		return IF_Gbps(4);
7038 	case ice_pcie_speed_8_0GT:
7039 		return IF_Gbps(8);
7040 	case ice_pcie_speed_16_0GT:
7041 		return IF_Gbps(16);
7042 	case ice_pcie_speed_unknown:
7043 	default:
7044 		return 0;
7045 	}
7046 }
7047 
7048 /**
7049  * ice_pcie_lnk_width_to_int - Convert driver pci-e width enum value to
7050  * a 32-bit number.
7051  * @width: enum value to convert
7052  */
7053 static int
7054 ice_pcie_lnk_width_to_int(enum ice_pcie_link_width width)
7055 {
7056 	switch (width) {
7057 	case ice_pcie_lnk_x1:
7058 		return (1);
7059 	case ice_pcie_lnk_x2:
7060 		return (2);
7061 	case ice_pcie_lnk_x4:
7062 		return (4);
7063 	case ice_pcie_lnk_x8:
7064 		return (8);
7065 	case ice_pcie_lnk_x12:
7066 		return (12);
7067 	case ice_pcie_lnk_x16:
7068 		return (16);
7069 	case ice_pcie_lnk_x32:
7070 		return (32);
7071 	case ice_pcie_lnk_width_resrv:
7072 	case ice_pcie_lnk_width_unknown:
7073 	default:
7074 		return (0);
7075 	}
7076 }
7077 
7078 /**
7079  * ice_pcie_bandwidth_check - Check if PCI-E bandwidth is sufficient for
7080  * full-speed device operation.
7081  * @sc: adapter softc
7082  *
7083  * Returns 0 if sufficient; 1 if not.
7084  */
7085 static uint8_t
7086 ice_pcie_bandwidth_check(struct ice_softc *sc)
7087 {
7088 	struct ice_hw *hw = &sc->hw;
7089 	int num_ports, pcie_width;
7090 	u64 pcie_speed, port_speed;
7091 
7092 	MPASS(hw->port_info);
7093 
7094 	num_ports = bitcount32(hw->func_caps.common_cap.valid_functions);
7095 	port_speed = ice_phy_types_to_max_rate(hw->port_info);
7096 	pcie_speed = ice_pcie_bus_speed_to_rate(hw->bus.speed);
7097 	pcie_width = ice_pcie_lnk_width_to_int(hw->bus.width);
7098 
7099 	/*
7100 	 * If 2x100, clamp ports to 1 -- 2nd port is intended for
7101 	 * failover.
7102 	 */
7103 	if (port_speed == IF_Gbps(100))
7104 		num_ports = 1;
7105 
7106 	return !!((num_ports * port_speed) > pcie_speed * pcie_width);
7107 }
7108 
7109 /**
7110  * ice_print_bus_link_data - Print PCI-E bandwidth information
7111  * @dev: device to print string for
7112  * @hw: hw struct with PCI-e link information
7113  */
7114 static void
7115 ice_print_bus_link_data(device_t dev, struct ice_hw *hw)
7116 {
7117         device_printf(dev, "PCI Express Bus: Speed %s %s\n",
7118             ((hw->bus.speed == ice_pcie_speed_16_0GT) ? "16.0GT/s" :
7119             (hw->bus.speed == ice_pcie_speed_8_0GT) ? "8.0GT/s" :
7120             (hw->bus.speed == ice_pcie_speed_5_0GT) ? "5.0GT/s" :
7121             (hw->bus.speed == ice_pcie_speed_2_5GT) ? "2.5GT/s" : "Unknown"),
7122             (hw->bus.width == ice_pcie_lnk_x32) ? "Width x32" :
7123             (hw->bus.width == ice_pcie_lnk_x16) ? "Width x16" :
7124             (hw->bus.width == ice_pcie_lnk_x12) ? "Width x12" :
7125             (hw->bus.width == ice_pcie_lnk_x8) ? "Width x8" :
7126             (hw->bus.width == ice_pcie_lnk_x4) ? "Width x4" :
7127             (hw->bus.width == ice_pcie_lnk_x2) ? "Width x2" :
7128             (hw->bus.width == ice_pcie_lnk_x1) ? "Width x1" : "Width Unknown");
7129 }
7130 
7131 /**
7132  * ice_set_pci_link_status_data - store PCI bus info
7133  * @hw: pointer to hardware structure
7134  * @link_status: the link status word from PCI config space
7135  *
7136  * Stores the PCI bus info (speed, width, type) within the ice_hw structure
7137  **/
7138 static void
7139 ice_set_pci_link_status_data(struct ice_hw *hw, u16 link_status)
7140 {
7141 	u16 reg;
7142 
7143 	hw->bus.type = ice_bus_pci_express;
7144 
7145 	reg = (link_status & PCIEM_LINK_STA_WIDTH) >> 4;
7146 
7147 	switch (reg) {
7148 	case ice_pcie_lnk_x1:
7149 	case ice_pcie_lnk_x2:
7150 	case ice_pcie_lnk_x4:
7151 	case ice_pcie_lnk_x8:
7152 	case ice_pcie_lnk_x12:
7153 	case ice_pcie_lnk_x16:
7154 	case ice_pcie_lnk_x32:
7155 		hw->bus.width = (enum ice_pcie_link_width)reg;
7156 		break;
7157 	default:
7158 		hw->bus.width = ice_pcie_lnk_width_unknown;
7159 		break;
7160 	}
7161 
7162 	reg = (link_status & PCIEM_LINK_STA_SPEED) + 0x13;
7163 
7164 	switch (reg) {
7165 	case ice_pcie_speed_2_5GT:
7166 	case ice_pcie_speed_5_0GT:
7167 	case ice_pcie_speed_8_0GT:
7168 	case ice_pcie_speed_16_0GT:
7169 		hw->bus.speed = (enum ice_pcie_bus_speed)reg;
7170 		break;
7171 	default:
7172 		hw->bus.speed = ice_pcie_speed_unknown;
7173 		break;
7174 	}
7175 }
7176 
7177 /**
7178  * ice_init_link_events - Initialize Link Status Events mask
7179  * @sc: the device softc
7180  *
7181  * Initialize the Link Status Events mask to disable notification of link
7182  * events we don't care about in software. Also request that link status
7183  * events be enabled.
7184  */
7185 int
7186 ice_init_link_events(struct ice_softc *sc)
7187 {
7188 	struct ice_hw *hw = &sc->hw;
7189 	enum ice_status status;
7190 	u16 wanted_events;
7191 
7192 	/* Set the bits for the events that we want to be notified by */
7193 	wanted_events = (ICE_AQ_LINK_EVENT_UPDOWN |
7194 			 ICE_AQ_LINK_EVENT_MEDIA_NA |
7195 			 ICE_AQ_LINK_EVENT_MODULE_QUAL_FAIL);
7196 
7197 	/* request that every event except the wanted events be masked */
7198 	status = ice_aq_set_event_mask(hw, hw->port_info->lport, ~wanted_events, NULL);
7199 	if (status) {
7200 		device_printf(sc->dev,
7201 			      "Failed to set link status event mask, err %s aq_err %s\n",
7202 			      ice_status_str(status), ice_aq_str(hw->adminq.sq_last_status));
7203 		return (EIO);
7204 	}
7205 
7206 	/* Request link info with the LSE bit set to enable link status events */
7207 	status = ice_aq_get_link_info(hw->port_info, true, NULL, NULL);
7208 	if (status) {
7209 		device_printf(sc->dev,
7210 			      "Failed to enable link status events, err %s aq_err %s\n",
7211 			      ice_status_str(status), ice_aq_str(hw->adminq.sq_last_status));
7212 		return (EIO);
7213 	}
7214 
7215 	return (0);
7216 }
7217 
7218 /**
7219  * ice_handle_mdd_event - Handle possibly malicious events
7220  * @sc: the device softc
7221  *
7222  * Called by the admin task if an MDD detection interrupt is triggered.
7223  * Identifies possibly malicious events coming from VFs. Also triggers for
7224  * similar incorrect behavior from the PF as well.
7225  */
7226 void
7227 ice_handle_mdd_event(struct ice_softc *sc)
7228 {
7229 	struct ice_hw *hw = &sc->hw;
7230 	bool mdd_detected = false, request_reinit = false;
7231 	device_t dev = sc->dev;
7232 	u32 reg;
7233 
7234 	if (!ice_testandclear_state(&sc->state, ICE_STATE_MDD_PENDING))
7235 		return;
7236 
7237 	reg = rd32(hw, GL_MDET_TX_TCLAN);
7238 	if (reg & GL_MDET_TX_TCLAN_VALID_M) {
7239 		u8 pf_num  = (reg & GL_MDET_TX_TCLAN_PF_NUM_M) >> GL_MDET_TX_TCLAN_PF_NUM_S;
7240 		u16 vf_num = (reg & GL_MDET_TX_TCLAN_VF_NUM_M) >> GL_MDET_TX_TCLAN_VF_NUM_S;
7241 		u8 event   = (reg & GL_MDET_TX_TCLAN_MAL_TYPE_M) >> GL_MDET_TX_TCLAN_MAL_TYPE_S;
7242 		u16 queue  = (reg & GL_MDET_TX_TCLAN_QNUM_M) >> GL_MDET_TX_TCLAN_QNUM_S;
7243 
7244 		device_printf(dev, "Malicious Driver Detection Tx Descriptor check event '%s' on Tx queue %u PF# %u VF# %u\n",
7245 			      ice_mdd_tx_tclan_str(event), queue, pf_num, vf_num);
7246 
7247 		/* Only clear this event if it matches this PF, that way other
7248 		 * PFs can read the event and determine VF and queue number.
7249 		 */
7250 		if (pf_num == hw->pf_id)
7251 			wr32(hw, GL_MDET_TX_TCLAN, 0xffffffff);
7252 
7253 		mdd_detected = true;
7254 	}
7255 
7256 	/* Determine what triggered the MDD event */
7257 	reg = rd32(hw, GL_MDET_TX_PQM);
7258 	if (reg & GL_MDET_TX_PQM_VALID_M) {
7259 		u8 pf_num  = (reg & GL_MDET_TX_PQM_PF_NUM_M) >> GL_MDET_TX_PQM_PF_NUM_S;
7260 		u16 vf_num = (reg & GL_MDET_TX_PQM_VF_NUM_M) >> GL_MDET_TX_PQM_VF_NUM_S;
7261 		u8 event   = (reg & GL_MDET_TX_PQM_MAL_TYPE_M) >> GL_MDET_TX_PQM_MAL_TYPE_S;
7262 		u16 queue  = (reg & GL_MDET_TX_PQM_QNUM_M) >> GL_MDET_TX_PQM_QNUM_S;
7263 
7264 		device_printf(dev, "Malicious Driver Detection Tx Quanta check event '%s' on Tx queue %u PF# %u VF# %u\n",
7265 			      ice_mdd_tx_pqm_str(event), queue, pf_num, vf_num);
7266 
7267 		/* Only clear this event if it matches this PF, that way other
7268 		 * PFs can read the event and determine VF and queue number.
7269 		 */
7270 		if (pf_num == hw->pf_id)
7271 			wr32(hw, GL_MDET_TX_PQM, 0xffffffff);
7272 
7273 		mdd_detected = true;
7274 	}
7275 
7276 	reg = rd32(hw, GL_MDET_RX);
7277 	if (reg & GL_MDET_RX_VALID_M) {
7278 		u8 pf_num  = (reg & GL_MDET_RX_PF_NUM_M) >> GL_MDET_RX_PF_NUM_S;
7279 		u16 vf_num = (reg & GL_MDET_RX_VF_NUM_M) >> GL_MDET_RX_VF_NUM_S;
7280 		u8 event   = (reg & GL_MDET_RX_MAL_TYPE_M) >> GL_MDET_RX_MAL_TYPE_S;
7281 		u16 queue  = (reg & GL_MDET_RX_QNUM_M) >> GL_MDET_RX_QNUM_S;
7282 
7283 		device_printf(dev, "Malicious Driver Detection Rx event '%s' on Rx queue %u PF# %u VF# %u\n",
7284 			      ice_mdd_rx_str(event), queue, pf_num, vf_num);
7285 
7286 		/* Only clear this event if it matches this PF, that way other
7287 		 * PFs can read the event and determine VF and queue number.
7288 		 */
7289 		if (pf_num == hw->pf_id)
7290 			wr32(hw, GL_MDET_RX, 0xffffffff);
7291 
7292 		mdd_detected = true;
7293 	}
7294 
7295 	/* Now, confirm that this event actually affects this PF, by checking
7296 	 * the PF registers.
7297 	 */
7298 	if (mdd_detected) {
7299 		reg = rd32(hw, PF_MDET_TX_TCLAN);
7300 		if (reg & PF_MDET_TX_TCLAN_VALID_M) {
7301 			wr32(hw, PF_MDET_TX_TCLAN, 0xffff);
7302 			sc->soft_stats.tx_mdd_count++;
7303 			request_reinit = true;
7304 		}
7305 
7306 		reg = rd32(hw, PF_MDET_TX_PQM);
7307 		if (reg & PF_MDET_TX_PQM_VALID_M) {
7308 			wr32(hw, PF_MDET_TX_PQM, 0xffff);
7309 			sc->soft_stats.tx_mdd_count++;
7310 			request_reinit = true;
7311 		}
7312 
7313 		reg = rd32(hw, PF_MDET_RX);
7314 		if (reg & PF_MDET_RX_VALID_M) {
7315 			wr32(hw, PF_MDET_RX, 0xffff);
7316 			sc->soft_stats.rx_mdd_count++;
7317 			request_reinit = true;
7318 		}
7319 	}
7320 
7321 	/* TODO: Implement logic to detect and handle events caused by VFs. */
7322 
7323 	/* request that the upper stack re-initialize the Tx/Rx queues */
7324 	if (request_reinit)
7325 		ice_request_stack_reinit(sc);
7326 
7327 	ice_flush(hw);
7328 }
7329 
7330 /**
7331  * ice_init_dcb_setup - Initialize DCB settings for HW
7332  * @sc: the device softc
7333  *
7334  * This needs to be called after the fw_lldp_agent sysctl is added, since that
7335  * can update the device's LLDP agent status if a tunable value is set.
7336  *
7337  * Get and store the initial state of DCB settings on driver load. Print out
7338  * informational messages as well.
7339  */
7340 void
7341 ice_init_dcb_setup(struct ice_softc *sc)
7342 {
7343 	struct ice_hw *hw = &sc->hw;
7344 	device_t dev = sc->dev;
7345 	bool dcbx_agent_status;
7346 	enum ice_status status;
7347 
7348 	/* Don't do anything if DCB isn't supported */
7349 	if (!hw->func_caps.common_cap.dcb) {
7350 		device_printf(dev, "%s: No DCB support\n",
7351 		    __func__);
7352 		return;
7353 	}
7354 
7355 	hw->port_info->qos_cfg.dcbx_status = ice_get_dcbx_status(hw);
7356 	if (hw->port_info->qos_cfg.dcbx_status != ICE_DCBX_STATUS_DONE &&
7357 	    hw->port_info->qos_cfg.dcbx_status != ICE_DCBX_STATUS_IN_PROGRESS) {
7358 		/*
7359 		 * Start DCBX agent, but not LLDP. The return value isn't
7360 		 * checked here because a more detailed dcbx agent status is
7361 		 * retrieved and checked in ice_init_dcb() and below.
7362 		 */
7363 		status = ice_aq_start_stop_dcbx(hw, true, &dcbx_agent_status, NULL);
7364 		if (status && hw->adminq.sq_last_status != ICE_AQ_RC_EPERM)
7365 			device_printf(dev,
7366 			    "start_stop_dcbx failed, err %s aq_err %s\n",
7367 			    ice_status_str(status),
7368 			    ice_aq_str(hw->adminq.sq_last_status));
7369 	}
7370 
7371 	/* This sets hw->port_info->qos_cfg.is_sw_lldp */
7372 	status = ice_init_dcb(hw, true);
7373 
7374 	/* If there is an error, then FW LLDP is not in a usable state */
7375 	if (status != 0 && status != ICE_ERR_NOT_READY) {
7376 		/* Don't print an error message if the return code from the AQ
7377 		 * cmd performed in ice_init_dcb() is is EPERM; that means the
7378 		 * FW LLDP engine is disabled, and that is a valid state.
7379 		 */
7380 		if (!(status == ICE_ERR_AQ_ERROR &&
7381 		      hw->adminq.sq_last_status == ICE_AQ_RC_EPERM)) {
7382 			device_printf(dev, "DCB init failed, err %s aq_err %s\n",
7383 				      ice_status_str(status),
7384 				      ice_aq_str(hw->adminq.sq_last_status));
7385 		}
7386 		hw->port_info->qos_cfg.dcbx_status = ICE_DCBX_STATUS_NOT_STARTED;
7387 	}
7388 
7389 	switch (hw->port_info->qos_cfg.dcbx_status) {
7390 	case ICE_DCBX_STATUS_DIS:
7391 		ice_debug(hw, ICE_DBG_DCB, "DCBX disabled\n");
7392 		break;
7393 	case ICE_DCBX_STATUS_NOT_STARTED:
7394 		ice_debug(hw, ICE_DBG_DCB, "DCBX not started\n");
7395 		break;
7396 	case ICE_DCBX_STATUS_MULTIPLE_PEERS:
7397 		ice_debug(hw, ICE_DBG_DCB, "DCBX detected multiple peers\n");
7398 		break;
7399 	default:
7400 		break;
7401 	}
7402 
7403 	/* LLDP disabled in FW */
7404 	if (hw->port_info->qos_cfg.is_sw_lldp) {
7405 		ice_add_rx_lldp_filter(sc);
7406 		device_printf(dev, "Firmware LLDP agent disabled\n");
7407 	}
7408 }
7409 
7410 /**
7411  * ice_dcb_get_tc_map - Scans config to get bitmap of enabled TCs
7412  * @dcbcfg: DCB configuration to examine
7413  *
7414  * Scans a TC mapping table inside dcbcfg to find traffic classes
7415  * enabled and @returns a bitmask of enabled TCs
7416  */
7417 static u8
7418 ice_dcb_get_tc_map(const struct ice_dcbx_cfg *dcbcfg)
7419 {
7420 	u8 tc_map = 0;
7421 	int i = 0;
7422 
7423 	switch (dcbcfg->pfc_mode) {
7424 	case ICE_QOS_MODE_VLAN:
7425 		/* XXX: "i" is actually "User Priority" here, not
7426 		 * Traffic Class, but the max for both is 8, so it works
7427 		 * out here.
7428 		 */
7429 		for (i = 0; i < ICE_MAX_TRAFFIC_CLASS; i++)
7430 			tc_map |= BIT(dcbcfg->etscfg.prio_table[i]);
7431 		break;
7432 	default:
7433 		/* Invalid Mode */
7434 		tc_map = ICE_DFLT_TRAFFIC_CLASS;
7435 		break;
7436 	}
7437 
7438 	return (tc_map);
7439 }
7440 
7441 /**
7442  * ice_dcb_num_tc - Count the number of TCs in a bitmap
7443  * @tc_map: bitmap of enabled traffic classes
7444  *
7445  * @return the number of traffic classes in
7446  * an 8-bit TC bitmap, or 0 if they are noncontiguous
7447  */
7448 static u8
7449 ice_dcb_num_tc(u8 tc_map)
7450 {
7451 	bool tc_unused = false;
7452 	u8 ret = 0;
7453 	int i = 0;
7454 
7455 	ice_for_each_traffic_class(i) {
7456 		if (tc_map & BIT(i)) {
7457 			if (!tc_unused) {
7458 				ret++;
7459 			} else {
7460 				/* Non-contiguous TCs detected */
7461 				return (0);
7462 			}
7463 		} else
7464 			tc_unused = true;
7465 	}
7466 
7467 	return (ret);
7468 }
7469 
7470 /**
7471  * ice_debug_print_mib_change_event - helper function to log LLDP MIB change events
7472  * @sc: the device private softc
7473  * @event: event received on a control queue
7474  *
7475  * Prints out the type and contents of an LLDP MIB change event in a DCB debug message.
7476  */
7477 static void
7478 ice_debug_print_mib_change_event(struct ice_softc *sc, struct ice_rq_event_info *event)
7479 {
7480 	struct ice_aqc_lldp_get_mib *params =
7481 	    (struct ice_aqc_lldp_get_mib *)&event->desc.params.lldp_get_mib;
7482 	u8 mib_type, bridge_type, tx_status;
7483 
7484 	static const char* mib_type_strings[] = {
7485 	    "Local MIB",
7486 	    "Remote MIB",
7487 	    "Reserved",
7488 	    "Reserved"
7489 	};
7490 	static const char* bridge_type_strings[] = {
7491 	    "Nearest Bridge",
7492 	    "Non-TPMR Bridge",
7493 	    "Reserved",
7494 	    "Reserved"
7495 	};
7496 	static const char* tx_status_strings[] = {
7497 	    "Port's TX active",
7498 	    "Port's TX suspended and drained",
7499 	    "Reserved",
7500 	    "Port's TX suspended and drained; blocked TC pipe flushed"
7501 	};
7502 
7503 	mib_type = (params->type & ICE_AQ_LLDP_MIB_TYPE_M) >>
7504 	    ICE_AQ_LLDP_MIB_TYPE_S;
7505 	bridge_type = (params->type & ICE_AQ_LLDP_BRID_TYPE_M) >>
7506 	    ICE_AQ_LLDP_BRID_TYPE_S;
7507 	tx_status = (params->type & ICE_AQ_LLDP_TX_M) >>
7508 	    ICE_AQ_LLDP_TX_S;
7509 
7510 	ice_debug(&sc->hw, ICE_DBG_DCB, "LLDP MIB Change Event (%s, %s, %s)\n",
7511 	    mib_type_strings[mib_type], bridge_type_strings[bridge_type],
7512 	    tx_status_strings[tx_status]);
7513 
7514 	/* Nothing else to report */
7515 	if (!event->msg_buf)
7516 		return;
7517 
7518 	ice_debug(&sc->hw, ICE_DBG_DCB, "- %s contents:\n", mib_type_strings[mib_type]);
7519 	ice_debug_array(&sc->hw, ICE_DBG_DCB, 16, 1, event->msg_buf,
7520 			event->msg_len);
7521 }
7522 
7523 /**
7524  * ice_dcb_needs_reconfig - Returns true if driver needs to reconfigure
7525  * @sc: the device private softc
7526  * @old_cfg: Old DCBX configuration to compare against
7527  * @new_cfg: New DCBX configuration to check
7528  *
7529  * @return true if something changed in new_cfg that requires the driver
7530  * to do some reconfiguration.
7531  */
7532 static bool
7533 ice_dcb_needs_reconfig(struct ice_softc *sc, struct ice_dcbx_cfg *old_cfg,
7534     struct ice_dcbx_cfg *new_cfg)
7535 {
7536 	struct ice_hw *hw = &sc->hw;
7537 	bool needs_reconfig = false;
7538 
7539 	/* Check if ETS config has changed */
7540 	if (memcmp(&new_cfg->etscfg, &old_cfg->etscfg,
7541 		   sizeof(new_cfg->etscfg))) {
7542 		/* If Priority Table has changed, then driver reconfig is needed */
7543 		if (memcmp(&new_cfg->etscfg.prio_table,
7544 			   &old_cfg->etscfg.prio_table,
7545 			   sizeof(new_cfg->etscfg.prio_table))) {
7546 			ice_debug(hw, ICE_DBG_DCB, "ETS UP2TC changed\n");
7547 			needs_reconfig = true;
7548 		}
7549 
7550 		/* These are just informational */
7551 		if (memcmp(&new_cfg->etscfg.tcbwtable,
7552 			   &old_cfg->etscfg.tcbwtable,
7553 			   sizeof(new_cfg->etscfg.tcbwtable)))
7554 			ice_debug(hw, ICE_DBG_DCB, "ETS TCBW table changed\n");
7555 
7556 		if (memcmp(&new_cfg->etscfg.tsatable,
7557 			   &old_cfg->etscfg.tsatable,
7558 			   sizeof(new_cfg->etscfg.tsatable)))
7559 			ice_debug(hw, ICE_DBG_DCB, "ETS TSA table changed\n");
7560 	}
7561 
7562 	/* Check if PFC config has changed */
7563 	if (memcmp(&new_cfg->pfc, &old_cfg->pfc, sizeof(new_cfg->pfc))) {
7564 		needs_reconfig = true;
7565 		ice_debug(hw, ICE_DBG_DCB, "PFC config changed\n");
7566 	}
7567 
7568 	ice_debug(hw, ICE_DBG_DCB, "%s result: %d\n", __func__, needs_reconfig);
7569 
7570 	return (needs_reconfig);
7571 }
7572 
7573 /**
7574  * ice_stop_pf_vsi - Stop queues for PF LAN VSI
7575  * @sc: the device private softc
7576  *
7577  * Flushes interrupts and stops the queues associated with the PF LAN VSI.
7578  */
7579 static void
7580 ice_stop_pf_vsi(struct ice_softc *sc)
7581 {
7582 	/* Dissociate the Tx and Rx queues from the interrupts */
7583 	ice_flush_txq_interrupts(&sc->pf_vsi);
7584 	ice_flush_rxq_interrupts(&sc->pf_vsi);
7585 
7586 	if (!ice_testandclear_state(&sc->state, ICE_STATE_DRIVER_INITIALIZED))
7587 		return;
7588 
7589 	/* Disable the Tx and Rx queues */
7590 	ice_vsi_disable_tx(&sc->pf_vsi);
7591 	ice_control_rx_queues(&sc->pf_vsi, false);
7592 }
7593 
7594 /**
7595  * ice_vsi_setup_q_map - Setup a VSI queue map
7596  * @vsi: the VSI being configured
7597  * @ctxt: VSI context structure
7598  */
7599 static void
7600 ice_vsi_setup_q_map(struct ice_vsi *vsi, struct ice_vsi_ctx *ctxt)
7601 {
7602 	u16 offset = 0, qmap = 0, pow = 0;
7603 	u16 num_txq_per_tc, num_rxq_per_tc, qcount_rx;
7604 	int i, j, k;
7605 
7606 	if (vsi->num_tcs == 0) {
7607 		/* at least TC0 should be enabled by default */
7608 		vsi->num_tcs = 1;
7609 		vsi->tc_map = 0x1;
7610 	}
7611 
7612 	qcount_rx = vsi->num_rx_queues;
7613 	num_rxq_per_tc = min(qcount_rx / vsi->num_tcs, ICE_MAX_RXQS_PER_TC);
7614 	if (!num_rxq_per_tc)
7615 		num_rxq_per_tc = 1;
7616 
7617 	/* Have TX queue count match RX queue count */
7618 	num_txq_per_tc = num_rxq_per_tc;
7619 
7620 	/* find the (rounded up) power-of-2 of qcount */
7621 	pow = flsl(num_rxq_per_tc - 1);
7622 
7623 	/* TC mapping is a function of the number of Rx queues assigned to the
7624 	 * VSI for each traffic class and the offset of these queues.
7625 	 * The first 10 bits are for queue offset for TC0, next 4 bits for no:of
7626 	 * queues allocated to TC0. No:of queues is a power-of-2.
7627 	 *
7628 	 * If TC is not enabled, the queue offset is set to 0, and allocate one
7629 	 * queue, this way, traffic for the given TC will be sent to the default
7630 	 * queue.
7631 	 *
7632 	 * Setup number and offset of Rx queues for all TCs for the VSI
7633 	 */
7634 	ice_for_each_traffic_class(i) {
7635 		if (!(vsi->tc_map & BIT(i))) {
7636 			/* TC is not enabled */
7637 			vsi->tc_info[i].qoffset = 0;
7638 			vsi->tc_info[i].qcount_rx = 1;
7639 			vsi->tc_info[i].qcount_tx = 1;
7640 
7641 			ctxt->info.tc_mapping[i] = 0;
7642 			continue;
7643 		}
7644 
7645 		/* TC is enabled */
7646 		vsi->tc_info[i].qoffset = offset;
7647 		vsi->tc_info[i].qcount_rx = num_rxq_per_tc;
7648 		vsi->tc_info[i].qcount_tx = num_txq_per_tc;
7649 
7650 		qmap = ((offset << ICE_AQ_VSI_TC_Q_OFFSET_S) &
7651 			ICE_AQ_VSI_TC_Q_OFFSET_M) |
7652 			((pow << ICE_AQ_VSI_TC_Q_NUM_S) &
7653 			 ICE_AQ_VSI_TC_Q_NUM_M);
7654 		ctxt->info.tc_mapping[i] = CPU_TO_LE16(qmap);
7655 
7656 		/* Store traffic class and handle data in queue structures */
7657 		for (j = offset, k = 0; j < offset + num_txq_per_tc; j++, k++) {
7658 			vsi->tx_queues[j].q_handle = k;
7659 			vsi->tx_queues[j].tc = i;
7660 		}
7661 		for (j = offset; j < offset + num_rxq_per_tc; j++)
7662 			vsi->rx_queues[j].tc = i;
7663 
7664 		offset += num_rxq_per_tc;
7665 	}
7666 
7667 	/* Rx queue mapping */
7668 	ctxt->info.mapping_flags |= CPU_TO_LE16(ICE_AQ_VSI_Q_MAP_CONTIG);
7669 	ctxt->info.q_mapping[0] = CPU_TO_LE16(vsi->rx_qmap[0]);
7670 	ctxt->info.q_mapping[1] = CPU_TO_LE16(vsi->num_rx_queues);
7671 }
7672 
7673 /**
7674  * ice_pf_vsi_cfg_tc - Configure PF VSI for a given TC map
7675  * @sc: the device private softc
7676  * @tc_map: traffic class bitmap
7677  *
7678  * @pre VSI queues are stopped
7679  *
7680  * @return 0 if configuration is successful
7681  * @return EIO if Update VSI AQ cmd fails
7682  * @return ENODEV if updating Tx Scheduler fails
7683  */
7684 static int
7685 ice_pf_vsi_cfg_tc(struct ice_softc *sc, u8 tc_map)
7686 {
7687 	u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 };
7688 	struct ice_vsi *vsi = &sc->pf_vsi;
7689 	struct ice_hw *hw = &sc->hw;
7690 	struct ice_vsi_ctx ctx = { 0 };
7691 	device_t dev = sc->dev;
7692 	enum ice_status status;
7693 	u8 num_tcs = 0;
7694 	int i = 0;
7695 
7696 	/* Count the number of enabled Traffic Classes */
7697 	ice_for_each_traffic_class(i)
7698 		if (tc_map & BIT(i))
7699 			num_tcs++;
7700 
7701 	vsi->tc_map = tc_map;
7702 	vsi->num_tcs = num_tcs;
7703 
7704 	/* Set default parameters for context */
7705 	ctx.vf_num = 0;
7706 	ctx.info = vsi->info;
7707 
7708 	/* Setup queue map */
7709 	ice_vsi_setup_q_map(vsi, &ctx);
7710 
7711 	/* Update VSI configuration in firmware (RX queues) */
7712 	ctx.info.valid_sections = CPU_TO_LE16(ICE_AQ_VSI_PROP_RXQ_MAP_VALID);
7713 	status = ice_update_vsi(hw, vsi->idx, &ctx, NULL);
7714 	if (status) {
7715 		device_printf(dev,
7716 		    "%s: Update VSI AQ call failed, err %s aq_err %s\n",
7717 		    __func__, ice_status_str(status),
7718 		    ice_aq_str(hw->adminq.sq_last_status));
7719 		return (EIO);
7720 	}
7721 	vsi->info = ctx.info;
7722 
7723 	/* Use values derived in ice_vsi_setup_q_map() */
7724 	for (i = 0; i < num_tcs; i++)
7725 		max_txqs[i] = vsi->tc_info[i].qcount_tx;
7726 
7727 	/* Update LAN Tx queue info in firmware */
7728 	status = ice_cfg_vsi_lan(hw->port_info, vsi->idx, vsi->tc_map,
7729 				 max_txqs);
7730 	if (status) {
7731 		device_printf(dev,
7732 		    "%s: Failed VSI lan queue config, err %s aq_err %s\n",
7733 		    __func__, ice_status_str(status),
7734 		    ice_aq_str(hw->adminq.sq_last_status));
7735 		return (ENODEV);
7736 	}
7737 
7738 	vsi->info.valid_sections = 0;
7739 
7740 	return (0);
7741 }
7742 
7743 /**
7744  * ice_dcb_recfg - Reconfigure VSI with new DCB settings
7745  * @sc: the device private softc
7746  *
7747  * @pre All VSIs have been disabled/stopped
7748  *
7749  * Reconfigures VSI settings based on local_dcbx_cfg.
7750  */
7751 static void
7752 ice_dcb_recfg(struct ice_softc *sc)
7753 {
7754 	struct ice_dcbx_cfg *dcbcfg =
7755 	    &sc->hw.port_info->qos_cfg.local_dcbx_cfg;
7756 	device_t dev = sc->dev;
7757 	u8 tc_map = 0;
7758 	int ret;
7759 
7760 	tc_map = ice_dcb_get_tc_map(dcbcfg);
7761 
7762 	/* If non-contiguous TCs are used, then configure
7763 	 * the default TC instead. There's no support for
7764 	 * non-contiguous TCs being used.
7765 	 */
7766 	if (ice_dcb_num_tc(tc_map) == 0) {
7767 		tc_map = ICE_DFLT_TRAFFIC_CLASS;
7768 		ice_set_default_local_lldp_mib(sc);
7769 	}
7770 
7771 	/* Reconfigure VSI queues to add/remove traffic classes */
7772 	ret = ice_pf_vsi_cfg_tc(sc, tc_map);
7773 	if (ret)
7774 		device_printf(dev,
7775 		    "Failed to configure TCs for PF VSI, err %s\n",
7776 		    ice_err_str(ret));
7777 
7778 }
7779 
7780 /**
7781  * ice_do_dcb_reconfig - notify RDMA and reconfigure PF LAN VSI
7782  * @sc: the device private softc
7783  *
7784  * @pre Determined that the DCB configuration requires a change
7785  *
7786  * Reconfigures the PF LAN VSI based on updated DCB configuration
7787  * found in the hw struct's/port_info's/ local dcbx configuration.
7788  */
7789 static void
7790 ice_do_dcb_reconfig(struct ice_softc *sc)
7791 {
7792 	struct ice_aqc_port_ets_elem port_ets = { 0 };
7793 	struct ice_dcbx_cfg *local_dcbx_cfg;
7794 	struct ice_hw *hw = &sc->hw;
7795 	struct ice_port_info *pi;
7796 	device_t dev = sc->dev;
7797 	enum ice_status status;
7798 	u8 tc_map;
7799 
7800 	pi = sc->hw.port_info;
7801 	local_dcbx_cfg = &pi->qos_cfg.local_dcbx_cfg;
7802 
7803 	/* Set state when there's more than one TC */
7804 	tc_map = ice_dcb_get_tc_map(local_dcbx_cfg);
7805 	if (ice_dcb_num_tc(tc_map) > 1) {
7806 		device_printf(dev, "Multiple traffic classes enabled\n");
7807 		ice_set_state(&sc->state, ICE_STATE_MULTIPLE_TCS);
7808 	} else {
7809 		device_printf(dev, "Multiple traffic classes disabled\n");
7810 		ice_clear_state(&sc->state, ICE_STATE_MULTIPLE_TCS);
7811 	}
7812 
7813 	/* Disable PF VSI since it's going to be reconfigured */
7814 	ice_stop_pf_vsi(sc);
7815 
7816 	/* Query ETS configuration and update SW Tx scheduler info */
7817 	status = ice_query_port_ets(pi, &port_ets, sizeof(port_ets), NULL);
7818 	if (status != ICE_SUCCESS) {
7819 		device_printf(dev,
7820 		    "Query Port ETS AQ call failed, err %s aq_err %s\n",
7821 		    ice_status_str(status),
7822 		    ice_aq_str(hw->adminq.sq_last_status));
7823 		/* This won't break traffic, but QoS will not work as expected */
7824 	}
7825 
7826 	/* Change PF VSI configuration */
7827 	ice_dcb_recfg(sc);
7828 
7829 	ice_request_stack_reinit(sc);
7830 }
7831 
7832 /**
7833  * ice_handle_mib_change_event - helper function to handle LLDP MIB change events
7834  * @sc: the device private softc
7835  * @event: event received on a control queue
7836  *
7837  * Checks the updated MIB it receives and possibly reconfigures the PF LAN
7838  * VSI depending on what has changed. This will also print out some debug
7839  * information about the MIB event if ICE_DBG_DCB is enabled in the debug_mask.
7840  */
7841 static void
7842 ice_handle_mib_change_event(struct ice_softc *sc, struct ice_rq_event_info *event)
7843 {
7844 	struct ice_aqc_lldp_get_mib *params =
7845 	    (struct ice_aqc_lldp_get_mib *)&event->desc.params.lldp_get_mib;
7846 	struct ice_dcbx_cfg tmp_dcbx_cfg, *local_dcbx_cfg;
7847 	struct ice_port_info *pi;
7848 	device_t dev = sc->dev;
7849 	struct ice_hw *hw = &sc->hw;
7850 	bool needs_reconfig;
7851 	enum ice_status status;
7852 	u8 mib_type, bridge_type;
7853 
7854 	ASSERT_CFG_LOCKED(sc);
7855 
7856 	ice_debug_print_mib_change_event(sc, event);
7857 
7858 	pi = sc->hw.port_info;
7859 
7860 	mib_type = (params->type & ICE_AQ_LLDP_MIB_TYPE_M) >>
7861 	    ICE_AQ_LLDP_MIB_TYPE_S;
7862 	bridge_type = (params->type & ICE_AQ_LLDP_BRID_TYPE_M) >>
7863 	    ICE_AQ_LLDP_BRID_TYPE_S;
7864 
7865 	/* Ignore if event is not for Nearest Bridge */
7866 	if (bridge_type != ICE_AQ_LLDP_BRID_TYPE_NEAREST_BRID)
7867 		return;
7868 
7869 	/* Check MIB Type and return if event for Remote MIB update */
7870 	if (mib_type == ICE_AQ_LLDP_MIB_REMOTE) {
7871 		/* Update the cached remote MIB and return */
7872 		status = ice_aq_get_dcb_cfg(pi->hw, ICE_AQ_LLDP_MIB_REMOTE,
7873 					 ICE_AQ_LLDP_BRID_TYPE_NEAREST_BRID,
7874 					 &pi->qos_cfg.remote_dcbx_cfg);
7875 		if (status)
7876 			device_printf(dev,
7877 			    "%s: Failed to get Remote DCB config; status %s, aq_err %s\n",
7878 			    __func__, ice_status_str(status),
7879 			    ice_aq_str(hw->adminq.sq_last_status));
7880 		/* Not fatal if this fails */
7881 		return;
7882 	}
7883 
7884 	/* Save line length by aliasing the local dcbx cfg */
7885 	local_dcbx_cfg = &pi->qos_cfg.local_dcbx_cfg;
7886 	/* Save off the old configuration and clear current config */
7887 	tmp_dcbx_cfg = *local_dcbx_cfg;
7888 	memset(local_dcbx_cfg, 0, sizeof(*local_dcbx_cfg));
7889 
7890 	/* Get updated DCBX data from firmware */
7891 	status = ice_get_dcb_cfg(pi);
7892 	if (status) {
7893 		device_printf(dev,
7894 		    "%s: Failed to get Local DCB config; status %s, aq_err %s\n",
7895 		    __func__, ice_status_str(status),
7896 		    ice_aq_str(hw->adminq.sq_last_status));
7897 		return;
7898 	}
7899 
7900 	/* No change detected in DCBX config */
7901 	if (!memcmp(&tmp_dcbx_cfg, local_dcbx_cfg,
7902 		    sizeof(tmp_dcbx_cfg))) {
7903 		ice_debug(hw, ICE_DBG_DCB, "No change detected in local DCBX configuration\n");
7904 		return;
7905 	}
7906 
7907 	/* Check to see if DCB needs reconfiguring */
7908 	needs_reconfig = ice_dcb_needs_reconfig(sc, &tmp_dcbx_cfg,
7909 	    local_dcbx_cfg);
7910 
7911 	if (!needs_reconfig)
7912 		return;
7913 
7914 	/* Reconfigure */
7915 	ice_do_dcb_reconfig(sc);
7916 }
7917 
7918 /**
7919  * ice_send_version - Send driver version to firmware
7920  * @sc: the device private softc
7921  *
7922  * Send the driver version to the firmware. This must be called as early as
7923  * possible after ice_init_hw().
7924  */
7925 int
7926 ice_send_version(struct ice_softc *sc)
7927 {
7928 	struct ice_driver_ver driver_version = {0};
7929 	struct ice_hw *hw = &sc->hw;
7930 	device_t dev = sc->dev;
7931 	enum ice_status status;
7932 
7933 	driver_version.major_ver = ice_major_version;
7934 	driver_version.minor_ver = ice_minor_version;
7935 	driver_version.build_ver = ice_patch_version;
7936 	driver_version.subbuild_ver = ice_rc_version;
7937 
7938 	strlcpy((char *)driver_version.driver_string, ice_driver_version,
7939 		sizeof(driver_version.driver_string));
7940 
7941 	status = ice_aq_send_driver_ver(hw, &driver_version, NULL);
7942 	if (status) {
7943 		device_printf(dev, "Unable to send driver version to firmware, err %s aq_err %s\n",
7944 			      ice_status_str(status), ice_aq_str(hw->adminq.sq_last_status));
7945 		return (EIO);
7946 	}
7947 
7948 	return (0);
7949 }
7950 
7951 /**
7952  * ice_handle_lan_overflow_event - helper function to log LAN overflow events
7953  * @sc: device softc
7954  * @event: event received on a control queue
7955  *
7956  * Prints out a message when a LAN overflow event is detected on a receive
7957  * queue.
7958  */
7959 static void
7960 ice_handle_lan_overflow_event(struct ice_softc *sc, struct ice_rq_event_info *event)
7961 {
7962 	struct ice_aqc_event_lan_overflow *params =
7963 	    (struct ice_aqc_event_lan_overflow *)&event->desc.params.lan_overflow;
7964 	struct ice_hw *hw = &sc->hw;
7965 
7966 	ice_debug(hw, ICE_DBG_DCB, "LAN overflow event detected, prtdcb_ruptq=0x%08x, qtx_ctl=0x%08x\n",
7967 		  LE32_TO_CPU(params->prtdcb_ruptq),
7968 		  LE32_TO_CPU(params->qtx_ctl));
7969 }
7970 
7971 /**
7972  * ice_add_ethertype_to_list - Add an Ethertype filter to a filter list
7973  * @vsi: the VSI to target packets to
7974  * @list: the list to add the filter to
7975  * @ethertype: the Ethertype to filter on
7976  * @direction: The direction of the filter (Tx or Rx)
7977  * @action: the action to take
7978  *
7979  * Add an Ethertype filter to a filter list. Used to forward a series of
7980  * filters to the firmware for configuring the switch.
7981  *
7982  * Returns 0 on success, and an error code on failure.
7983  */
7984 static int
7985 ice_add_ethertype_to_list(struct ice_vsi *vsi, struct ice_list_head *list,
7986 			  u16 ethertype, u16 direction,
7987 			  enum ice_sw_fwd_act_type action)
7988 {
7989 	struct ice_fltr_list_entry *entry;
7990 
7991 	MPASS((direction == ICE_FLTR_TX) || (direction == ICE_FLTR_RX));
7992 
7993 	entry = (__typeof(entry))malloc(sizeof(*entry), M_ICE, M_NOWAIT|M_ZERO);
7994 	if (!entry)
7995 		return (ENOMEM);
7996 
7997 	entry->fltr_info.flag = direction;
7998 	entry->fltr_info.src_id = ICE_SRC_ID_VSI;
7999 	entry->fltr_info.lkup_type = ICE_SW_LKUP_ETHERTYPE;
8000 	entry->fltr_info.fltr_act = action;
8001 	entry->fltr_info.vsi_handle = vsi->idx;
8002 	entry->fltr_info.l_data.ethertype_mac.ethertype = ethertype;
8003 
8004 	LIST_ADD(&entry->list_entry, list);
8005 
8006 	return 0;
8007 }
8008 
8009 #define ETHERTYPE_PAUSE_FRAMES 0x8808
8010 #define ETHERTYPE_LLDP_FRAMES 0x88cc
8011 
8012 /**
8013  * ice_cfg_pf_ethertype_filters - Configure switch to drop ethertypes
8014  * @sc: the device private softc
8015  *
8016  * Configure the switch to drop PAUSE frames and LLDP frames transmitted from
8017  * the host. This prevents malicious VFs from sending these frames and being
8018  * able to control or configure the network.
8019  */
8020 int
8021 ice_cfg_pf_ethertype_filters(struct ice_softc *sc)
8022 {
8023 	struct ice_list_head ethertype_list;
8024 	struct ice_vsi *vsi = &sc->pf_vsi;
8025 	struct ice_hw *hw = &sc->hw;
8026 	device_t dev = sc->dev;
8027 	enum ice_status status;
8028 	int err = 0;
8029 
8030 	INIT_LIST_HEAD(&ethertype_list);
8031 
8032 	/*
8033 	 * Note that the switch filters will ignore the VSI index for the drop
8034 	 * action, so we only need to program drop filters once for the main
8035 	 * VSI.
8036 	 */
8037 
8038 	/* Configure switch to drop all Tx pause frames coming from any VSI. */
8039 	if (sc->enable_tx_fc_filter) {
8040 		err = ice_add_ethertype_to_list(vsi, &ethertype_list,
8041 						ETHERTYPE_PAUSE_FRAMES,
8042 						ICE_FLTR_TX, ICE_DROP_PACKET);
8043 		if (err)
8044 			goto free_ethertype_list;
8045 	}
8046 
8047 	/* Configure switch to drop LLDP frames coming from any VSI */
8048 	if (sc->enable_tx_lldp_filter) {
8049 		err = ice_add_ethertype_to_list(vsi, &ethertype_list,
8050 						ETHERTYPE_LLDP_FRAMES,
8051 						ICE_FLTR_TX, ICE_DROP_PACKET);
8052 		if (err)
8053 			goto free_ethertype_list;
8054 	}
8055 
8056 	status = ice_add_eth_mac(hw, &ethertype_list);
8057 	if (status) {
8058 		device_printf(dev,
8059 			      "Failed to add Tx Ethertype filters, err %s aq_err %s\n",
8060 			      ice_status_str(status),
8061 			      ice_aq_str(hw->adminq.sq_last_status));
8062 		err = (EIO);
8063 	}
8064 
8065 free_ethertype_list:
8066 	ice_free_fltr_list(&ethertype_list);
8067 	return err;
8068 }
8069 
8070 /**
8071  * ice_add_rx_lldp_filter - add ethertype filter for Rx LLDP frames
8072  * @sc: the device private structure
8073  *
8074  * Add a switch ethertype filter which forwards the LLDP frames to the main PF
8075  * VSI. Called when the fw_lldp_agent is disabled, to allow the LLDP frames to
8076  * be forwarded to the stack.
8077  */
8078 static void
8079 ice_add_rx_lldp_filter(struct ice_softc *sc)
8080 {
8081 	struct ice_list_head ethertype_list;
8082 	struct ice_vsi *vsi = &sc->pf_vsi;
8083 	struct ice_hw *hw = &sc->hw;
8084 	device_t dev = sc->dev;
8085 	enum ice_status status;
8086 	int err;
8087 	u16 vsi_num;
8088 
8089 	/*
8090 	 * If FW is new enough, use a direct AQ command to perform the filter
8091 	 * addition.
8092 	 */
8093 	if (ice_fw_supports_lldp_fltr_ctrl(hw)) {
8094 		vsi_num = ice_get_hw_vsi_num(hw, vsi->idx);
8095 		status = ice_lldp_fltr_add_remove(hw, vsi_num, true);
8096 		if (status) {
8097 			device_printf(dev,
8098 			    "Failed to add Rx LLDP filter, err %s aq_err %s\n",
8099 			    ice_status_str(status),
8100 			    ice_aq_str(hw->adminq.sq_last_status));
8101 		} else
8102 			ice_set_state(&sc->state,
8103 			    ICE_STATE_LLDP_RX_FLTR_FROM_DRIVER);
8104 		return;
8105 	}
8106 
8107 	INIT_LIST_HEAD(&ethertype_list);
8108 
8109 	/* Forward Rx LLDP frames to the stack */
8110 	err = ice_add_ethertype_to_list(vsi, &ethertype_list,
8111 					ETHERTYPE_LLDP_FRAMES,
8112 					ICE_FLTR_RX, ICE_FWD_TO_VSI);
8113 	if (err) {
8114 		device_printf(dev,
8115 			      "Failed to add Rx LLDP filter, err %s\n",
8116 			      ice_err_str(err));
8117 		goto free_ethertype_list;
8118 	}
8119 
8120 	status = ice_add_eth_mac(hw, &ethertype_list);
8121 	if (status && status != ICE_ERR_ALREADY_EXISTS) {
8122 		device_printf(dev,
8123 			      "Failed to add Rx LLDP filter, err %s aq_err %s\n",
8124 			      ice_status_str(status),
8125 			      ice_aq_str(hw->adminq.sq_last_status));
8126 	} else {
8127 		/*
8128 		 * If status == ICE_ERR_ALREADY_EXISTS, we won't treat an
8129 		 * already existing filter as an error case.
8130 		 */
8131 		ice_set_state(&sc->state, ICE_STATE_LLDP_RX_FLTR_FROM_DRIVER);
8132 	}
8133 
8134 free_ethertype_list:
8135 	ice_free_fltr_list(&ethertype_list);
8136 }
8137 
8138 /**
8139  * ice_del_rx_lldp_filter - Remove ethertype filter for Rx LLDP frames
8140  * @sc: the device private structure
8141  *
8142  * Remove the switch filter forwarding LLDP frames to the main PF VSI, called
8143  * when the firmware LLDP agent is enabled, to stop routing LLDP frames to the
8144  * stack.
8145  */
8146 static void
8147 ice_del_rx_lldp_filter(struct ice_softc *sc)
8148 {
8149 	struct ice_list_head ethertype_list;
8150 	struct ice_vsi *vsi = &sc->pf_vsi;
8151 	struct ice_hw *hw = &sc->hw;
8152 	device_t dev = sc->dev;
8153 	enum ice_status status;
8154 	int err;
8155 	u16 vsi_num;
8156 
8157 	/*
8158 	 * Only in the scenario where the driver added the filter during
8159 	 * this session (while the driver was loaded) would we be able to
8160 	 * delete this filter.
8161 	 */
8162 	if (!ice_test_state(&sc->state, ICE_STATE_LLDP_RX_FLTR_FROM_DRIVER))
8163 		return;
8164 
8165 	/*
8166 	 * If FW is new enough, use a direct AQ command to perform the filter
8167 	 * removal.
8168 	 */
8169 	if (ice_fw_supports_lldp_fltr_ctrl(hw)) {
8170 		vsi_num = ice_get_hw_vsi_num(hw, vsi->idx);
8171 		status = ice_lldp_fltr_add_remove(hw, vsi_num, false);
8172 		if (status) {
8173 			device_printf(dev,
8174 			    "Failed to remove Rx LLDP filter, err %s aq_err %s\n",
8175 			    ice_status_str(status),
8176 			    ice_aq_str(hw->adminq.sq_last_status));
8177 		}
8178 		return;
8179 	}
8180 
8181 	INIT_LIST_HEAD(&ethertype_list);
8182 
8183 	/* Remove filter forwarding Rx LLDP frames to the stack */
8184 	err = ice_add_ethertype_to_list(vsi, &ethertype_list,
8185 					ETHERTYPE_LLDP_FRAMES,
8186 					ICE_FLTR_RX, ICE_FWD_TO_VSI);
8187 	if (err) {
8188 		device_printf(dev,
8189 			      "Failed to remove Rx LLDP filter, err %s\n",
8190 			      ice_err_str(err));
8191 		goto free_ethertype_list;
8192 	}
8193 
8194 	status = ice_remove_eth_mac(hw, &ethertype_list);
8195 	if (status == ICE_ERR_DOES_NOT_EXIST) {
8196 		; /* Don't complain if we try to remove a filter that doesn't exist */
8197 	} else if (status) {
8198 		device_printf(dev,
8199 			      "Failed to remove Rx LLDP filter, err %s aq_err %s\n",
8200 			      ice_status_str(status),
8201 			      ice_aq_str(hw->adminq.sq_last_status));
8202 	}
8203 
8204 free_ethertype_list:
8205 	ice_free_fltr_list(&ethertype_list);
8206 }
8207 
8208 /**
8209  * ice_init_link_configuration -- Setup link in different ways depending
8210  * on whether media is available or not.
8211  * @sc: device private structure
8212  *
8213  * Called at the end of the attach process to either set default link
8214  * parameters if there is media available, or force HW link down and
8215  * set a state bit if there is no media.
8216  */
8217 void
8218 ice_init_link_configuration(struct ice_softc *sc)
8219 {
8220 	struct ice_port_info *pi = sc->hw.port_info;
8221 	struct ice_hw *hw = &sc->hw;
8222 	device_t dev = sc->dev;
8223 	enum ice_status status;
8224 
8225 	pi->phy.get_link_info = true;
8226 	status = ice_get_link_status(pi, &sc->link_up);
8227 	if (status != ICE_SUCCESS) {
8228 		device_printf(dev,
8229 		    "%s: ice_get_link_status failed; status %s, aq_err %s\n",
8230 		    __func__, ice_status_str(status),
8231 		    ice_aq_str(hw->adminq.sq_last_status));
8232 		return;
8233 	}
8234 
8235 	if (pi->phy.link_info.link_info & ICE_AQ_MEDIA_AVAILABLE) {
8236 		ice_clear_state(&sc->state, ICE_STATE_NO_MEDIA);
8237 		/* Apply default link settings */
8238 		ice_apply_saved_phy_cfg(sc, ICE_APPLY_LS_FEC_FC);
8239 	} else {
8240 		 /* Set link down, and poll for media available in timer. This prevents the
8241 		  * driver from receiving spurious link-related events.
8242 		  */
8243 		ice_set_state(&sc->state, ICE_STATE_NO_MEDIA);
8244 		status = ice_aq_set_link_restart_an(pi, false, NULL);
8245 		if (status != ICE_SUCCESS)
8246 			device_printf(dev,
8247 			    "%s: ice_aq_set_link_restart_an: status %s, aq_err %s\n",
8248 			    __func__, ice_status_str(status),
8249 			    ice_aq_str(hw->adminq.sq_last_status));
8250 	}
8251 }
8252 
8253 /**
8254  * ice_apply_saved_phy_req_to_cfg -- Write saved user PHY settings to cfg data
8255  * @sc: device private structure
8256  * @cfg: new PHY config data to be modified
8257  *
8258  * Applies user settings for advertised speeds to the PHY type fields in the
8259  * supplied PHY config struct. It uses the data from pcaps to check if the
8260  * saved settings are invalid and uses the pcaps data instead if they are
8261  * invalid.
8262  */
8263 static int
8264 ice_apply_saved_phy_req_to_cfg(struct ice_softc *sc,
8265 			       struct ice_aqc_set_phy_cfg_data *cfg)
8266 {
8267 	struct ice_phy_data phy_data = { 0 };
8268 	struct ice_port_info *pi = sc->hw.port_info;
8269 	u64 phy_low = 0, phy_high = 0;
8270 	u16 link_speeds;
8271 	int ret;
8272 
8273 	link_speeds = pi->phy.curr_user_speed_req;
8274 
8275 	if (ice_is_bit_set(sc->feat_en, ICE_FEATURE_LINK_MGMT_VER_2)) {
8276 		memset(&phy_data, 0, sizeof(phy_data));
8277 		phy_data.report_mode = ICE_AQC_REPORT_DFLT_CFG;
8278 		phy_data.user_speeds_orig = link_speeds;
8279 		ret = ice_intersect_phy_types_and_speeds(sc, &phy_data);
8280 		if (ret != 0) {
8281 			/* Error message already printed within function */
8282 			return (ret);
8283 		}
8284 		phy_low = phy_data.phy_low_intr;
8285 		phy_high = phy_data.phy_high_intr;
8286 
8287 		if (link_speeds == 0 || phy_data.user_speeds_intr)
8288 			goto finalize_link_speed;
8289 		if (ice_is_bit_set(sc->feat_en, ICE_FEATURE_LENIENT_LINK_MODE)) {
8290 			memset(&phy_data, 0, sizeof(phy_data));
8291 			phy_data.report_mode = ICE_AQC_REPORT_TOPO_CAP_NO_MEDIA;
8292 			phy_data.user_speeds_orig = link_speeds;
8293 			ret = ice_intersect_phy_types_and_speeds(sc, &phy_data);
8294 			if (ret != 0) {
8295 				/* Error message already printed within function */
8296 				return (ret);
8297 			}
8298 			phy_low = phy_data.phy_low_intr;
8299 			phy_high = phy_data.phy_high_intr;
8300 
8301 			if (!phy_data.user_speeds_intr) {
8302 				phy_low = phy_data.phy_low_orig;
8303 				phy_high = phy_data.phy_high_orig;
8304 			}
8305 			goto finalize_link_speed;
8306 		}
8307 		/* If we're here, then it means the benefits of Version 2
8308 		 * link management aren't utilized.  We fall through to
8309 		 * handling Strict Link Mode the same as Version 1 link
8310 		 * management.
8311 		 */
8312 	}
8313 
8314 	memset(&phy_data, 0, sizeof(phy_data));
8315 	if ((link_speeds == 0) &&
8316 	    (sc->ldo_tlv.phy_type_low || sc->ldo_tlv.phy_type_high))
8317 		phy_data.report_mode = ICE_AQC_REPORT_TOPO_CAP_NO_MEDIA;
8318 	else
8319 		phy_data.report_mode = ICE_AQC_REPORT_TOPO_CAP_MEDIA;
8320 	phy_data.user_speeds_orig = link_speeds;
8321 	ret = ice_intersect_phy_types_and_speeds(sc, &phy_data);
8322 	if (ret != 0) {
8323 		/* Error message already printed within function */
8324 		return (ret);
8325 	}
8326 	phy_low = phy_data.phy_low_intr;
8327 	phy_high = phy_data.phy_high_intr;
8328 
8329 	if (!ice_is_bit_set(sc->feat_en, ICE_FEATURE_LENIENT_LINK_MODE)) {
8330 		if (phy_low == 0 && phy_high == 0) {
8331 			device_printf(sc->dev,
8332 			    "The selected speed is not supported by the current media. Please select a link speed that is supported by the current media.\n");
8333 			return (EINVAL);
8334 		}
8335 	} else {
8336 		if (link_speeds == 0) {
8337 			if (sc->ldo_tlv.phy_type_low & phy_low ||
8338 			    sc->ldo_tlv.phy_type_high & phy_high) {
8339 				phy_low &= sc->ldo_tlv.phy_type_low;
8340 				phy_high &= sc->ldo_tlv.phy_type_high;
8341 			}
8342 		} else if (phy_low == 0 && phy_high == 0) {
8343 			memset(&phy_data, 0, sizeof(phy_data));
8344 			phy_data.report_mode = ICE_AQC_REPORT_TOPO_CAP_NO_MEDIA;
8345 			phy_data.user_speeds_orig = link_speeds;
8346 			ret = ice_intersect_phy_types_and_speeds(sc, &phy_data);
8347 			if (ret != 0) {
8348 				/* Error message already printed within function */
8349 				return (ret);
8350 			}
8351 			phy_low = phy_data.phy_low_intr;
8352 			phy_high = phy_data.phy_high_intr;
8353 
8354 			if (!phy_data.user_speeds_intr) {
8355 				phy_low = phy_data.phy_low_orig;
8356 				phy_high = phy_data.phy_high_orig;
8357 			}
8358 		}
8359 	}
8360 
8361 finalize_link_speed:
8362 
8363 	/* Cache new user settings for speeds */
8364 	pi->phy.curr_user_speed_req = phy_data.user_speeds_intr;
8365 	cfg->phy_type_low = htole64(phy_low);
8366 	cfg->phy_type_high = htole64(phy_high);
8367 
8368 	return (ret);
8369 }
8370 
8371 /**
8372  * ice_apply_saved_fec_req_to_cfg -- Write saved user FEC mode to cfg data
8373  * @sc: device private structure
8374  * @cfg: new PHY config data to be modified
8375  *
8376  * Applies user setting for FEC mode to PHY config struct. It uses the data
8377  * from pcaps to check if the saved settings are invalid and uses the pcaps
8378  * data instead if they are invalid.
8379  */
8380 static int
8381 ice_apply_saved_fec_req_to_cfg(struct ice_softc *sc,
8382 			       struct ice_aqc_set_phy_cfg_data *cfg)
8383 {
8384 	struct ice_port_info *pi = sc->hw.port_info;
8385 	enum ice_status status;
8386 
8387 	cfg->caps &= ~ICE_AQC_PHY_EN_AUTO_FEC;
8388 	status = ice_cfg_phy_fec(pi, cfg, pi->phy.curr_user_fec_req);
8389 	if (status)
8390 		return (EIO);
8391 
8392 	return (0);
8393 }
8394 
8395 /**
8396  * ice_apply_saved_fc_req_to_cfg -- Write saved user flow control mode to cfg data
8397  * @pi: port info struct
8398  * @cfg: new PHY config data to be modified
8399  *
8400  * Applies user setting for flow control mode to PHY config struct. There are
8401  * no invalid flow control mode settings; if there are, then this function
8402  * treats them like "ICE_FC_NONE".
8403  */
8404 static void
8405 ice_apply_saved_fc_req_to_cfg(struct ice_port_info *pi,
8406 			      struct ice_aqc_set_phy_cfg_data *cfg)
8407 {
8408 	cfg->caps &= ~(ICE_AQ_PHY_ENA_TX_PAUSE_ABILITY |
8409 		       ICE_AQ_PHY_ENA_RX_PAUSE_ABILITY);
8410 
8411 	switch (pi->phy.curr_user_fc_req) {
8412 	case ICE_FC_FULL:
8413 		cfg->caps |= ICE_AQ_PHY_ENA_TX_PAUSE_ABILITY |
8414 			     ICE_AQ_PHY_ENA_RX_PAUSE_ABILITY;
8415 		break;
8416 	case ICE_FC_RX_PAUSE:
8417 		cfg->caps |= ICE_AQ_PHY_ENA_RX_PAUSE_ABILITY;
8418 		break;
8419 	case ICE_FC_TX_PAUSE:
8420 		cfg->caps |= ICE_AQ_PHY_ENA_TX_PAUSE_ABILITY;
8421 		break;
8422 	default:
8423 		/* ICE_FC_NONE */
8424 		break;
8425 	}
8426 }
8427 
8428 /**
8429  * ice_apply_saved_phy_cfg -- Re-apply user PHY config settings
8430  * @sc: device private structure
8431  * @settings: which settings to apply
8432  *
8433  * Applies user settings for advertised speeds, FEC mode, and flow
8434  * control mode to a PHY config struct; it uses the data from pcaps
8435  * to check if the saved settings are invalid and uses the pcaps
8436  * data instead if they are invalid.
8437  *
8438  * For things like sysctls where only one setting needs to be
8439  * updated, the bitmap allows the caller to specify which setting
8440  * to update.
8441  */
8442 int
8443 ice_apply_saved_phy_cfg(struct ice_softc *sc, u8 settings)
8444 {
8445 	struct ice_aqc_set_phy_cfg_data cfg = { 0 };
8446 	struct ice_port_info *pi = sc->hw.port_info;
8447 	struct ice_aqc_get_phy_caps_data pcaps = { 0 };
8448 	struct ice_hw *hw = &sc->hw;
8449 	device_t dev = sc->dev;
8450 	u64 phy_low, phy_high;
8451 	enum ice_status status;
8452 	enum ice_fec_mode dflt_fec_mode;
8453 	u16 dflt_user_speed;
8454 
8455 	if (!settings || settings > ICE_APPLY_LS_FEC_FC) {
8456 		ice_debug(hw, ICE_DBG_LINK, "Settings out-of-bounds: %u\n",
8457 		    settings);
8458 	}
8459 
8460 	status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_ACTIVE_CFG,
8461 				     &pcaps, NULL);
8462 	if (status != ICE_SUCCESS) {
8463 		device_printf(dev,
8464 		    "%s: ice_aq_get_phy_caps (ACTIVE) failed; status %s, aq_err %s\n",
8465 		    __func__, ice_status_str(status),
8466 		    ice_aq_str(hw->adminq.sq_last_status));
8467 		return (EIO);
8468 	}
8469 
8470 	phy_low = le64toh(pcaps.phy_type_low);
8471 	phy_high = le64toh(pcaps.phy_type_high);
8472 
8473 	/* Save off initial config parameters */
8474 	dflt_user_speed = ice_aq_phy_types_to_link_speeds(phy_low, phy_high);
8475 	dflt_fec_mode = ice_caps_to_fec_mode(pcaps.caps, pcaps.link_fec_options);
8476 
8477 	/* Setup new PHY config */
8478 	ice_copy_phy_caps_to_cfg(pi, &pcaps, &cfg);
8479 
8480 	/* On error, restore active configuration values */
8481 	if ((settings & ICE_APPLY_LS) &&
8482 	    ice_apply_saved_phy_req_to_cfg(sc, &cfg)) {
8483 		pi->phy.curr_user_speed_req = dflt_user_speed;
8484 		cfg.phy_type_low = pcaps.phy_type_low;
8485 		cfg.phy_type_high = pcaps.phy_type_high;
8486 	}
8487 	if ((settings & ICE_APPLY_FEC) &&
8488 	    ice_apply_saved_fec_req_to_cfg(sc, &cfg)) {
8489 		pi->phy.curr_user_fec_req = dflt_fec_mode;
8490 	}
8491 	if (settings & ICE_APPLY_FC) {
8492 		/* No real error indicators for this process,
8493 		 * so we'll just have to assume it works. */
8494 		ice_apply_saved_fc_req_to_cfg(pi, &cfg);
8495 	}
8496 
8497 	/* Enable link and re-negotiate it */
8498 	cfg.caps |= ICE_AQ_PHY_ENA_AUTO_LINK_UPDT | ICE_AQ_PHY_ENA_LINK;
8499 
8500 	status = ice_aq_set_phy_cfg(hw, pi, &cfg, NULL);
8501 	if (status != ICE_SUCCESS) {
8502 		/* Don't indicate failure if there's no media in the port.
8503 		 * The settings have been saved and will apply when media
8504 		 * is inserted.
8505 		 */
8506 		if ((status == ICE_ERR_AQ_ERROR) &&
8507 		    (hw->adminq.sq_last_status == ICE_AQ_RC_EBUSY)) {
8508 			device_printf(dev,
8509 			    "%s: Setting will be applied when media is inserted\n",
8510 			    __func__);
8511 			return (0);
8512 		} else {
8513 			device_printf(dev,
8514 			    "%s: ice_aq_set_phy_cfg failed; status %s, aq_err %s\n",
8515 			    __func__, ice_status_str(status),
8516 			    ice_aq_str(hw->adminq.sq_last_status));
8517 			return (EIO);
8518 		}
8519 	}
8520 
8521 	return (0);
8522 }
8523 
8524 /**
8525  * ice_print_ldo_tlv - Print out LDO TLV information
8526  * @sc: device private structure
8527  * @tlv: LDO TLV information from the adapter NVM
8528  *
8529  * Dump out the information in tlv to the kernel message buffer; intended for
8530  * debugging purposes.
8531  */
8532 static void
8533 ice_print_ldo_tlv(struct ice_softc *sc, struct ice_link_default_override_tlv *tlv)
8534 {
8535 	device_t dev = sc->dev;
8536 
8537 	device_printf(dev, "TLV: -options     0x%02x\n", tlv->options);
8538 	device_printf(dev, "     -phy_config  0x%02x\n", tlv->phy_config);
8539 	device_printf(dev, "     -fec_options 0x%02x\n", tlv->fec_options);
8540 	device_printf(dev, "     -phy_high    0x%016llx\n",
8541 	    (unsigned long long)tlv->phy_type_high);
8542 	device_printf(dev, "     -phy_low     0x%016llx\n",
8543 	    (unsigned long long)tlv->phy_type_low);
8544 }
8545 
8546 /**
8547  * ice_set_link_management_mode -- Strict or lenient link management
8548  * @sc: device private structure
8549  *
8550  * Some NVMs give the adapter the option to advertise a superset of link
8551  * configurations.  This checks to see if that option is enabled.
8552  * Further, the NVM could also provide a specific set of configurations
8553  * to try; these are cached in the driver's private structure if they
8554  * are available.
8555  */
8556 void
8557 ice_set_link_management_mode(struct ice_softc *sc)
8558 {
8559 	struct ice_port_info *pi = sc->hw.port_info;
8560 	device_t dev = sc->dev;
8561 	struct ice_link_default_override_tlv tlv = { 0 };
8562 	enum ice_status status;
8563 
8564 	/* Port must be in strict mode if FW version is below a certain
8565 	 * version. (i.e. Don't set lenient mode features)
8566 	 */
8567 	if (!(ice_fw_supports_link_override(&sc->hw)))
8568 		return;
8569 
8570 	status = ice_get_link_default_override(&tlv, pi);
8571 	if (status != ICE_SUCCESS) {
8572 		device_printf(dev,
8573 		    "%s: ice_get_link_default_override failed; status %s, aq_err %s\n",
8574 		    __func__, ice_status_str(status),
8575 		    ice_aq_str(sc->hw.adminq.sq_last_status));
8576 		return;
8577 	}
8578 
8579 	if (sc->hw.debug_mask & ICE_DBG_LINK)
8580 		ice_print_ldo_tlv(sc, &tlv);
8581 
8582 	/* Set lenient link mode */
8583 	if (ice_is_bit_set(sc->feat_cap, ICE_FEATURE_LENIENT_LINK_MODE) &&
8584 	    (!(tlv.options & ICE_LINK_OVERRIDE_STRICT_MODE)))
8585 		ice_set_bit(ICE_FEATURE_LENIENT_LINK_MODE, sc->feat_en);
8586 
8587 	/* FW supports reporting a default configuration */
8588 	if (ice_is_bit_set(sc->feat_cap, ICE_FEATURE_LINK_MGMT_VER_2) &&
8589 	    ice_fw_supports_report_dflt_cfg(&sc->hw)) {
8590 		ice_set_bit(ICE_FEATURE_LINK_MGMT_VER_2, sc->feat_en);
8591 		/* Knowing we're at a high enough firmware revision to
8592 		 * support this link management configuration, we don't
8593 		 * need to check/support earlier versions.
8594 		 */
8595 		return;
8596 	}
8597 
8598 	/* Default overrides only work if in lenient link mode */
8599 	if (ice_is_bit_set(sc->feat_cap, ICE_FEATURE_LINK_MGMT_VER_1) &&
8600 	    ice_is_bit_set(sc->feat_en, ICE_FEATURE_LENIENT_LINK_MODE) &&
8601 	    (tlv.options & ICE_LINK_OVERRIDE_EN))
8602 		ice_set_bit(ICE_FEATURE_LINK_MGMT_VER_1, sc->feat_en);
8603 
8604 	/* Cache the LDO TLV structure in the driver, since it
8605 	 * won't change during the driver's lifetime.
8606 	 */
8607 	sc->ldo_tlv = tlv;
8608 }
8609 
8610 /**
8611  * ice_init_saved_phy_cfg -- Set cached user PHY cfg settings with NVM defaults
8612  * @sc: device private structure
8613  *
8614  * This should be called before the tunables for these link settings
8615  * (e.g. advertise_speed) are added -- so that these defaults don't overwrite
8616  * the cached values that the sysctl handlers will write.
8617  *
8618  * This also needs to be called before ice_init_link_configuration, to ensure
8619  * that there are sane values that can be written if there is media available
8620  * in the port.
8621  */
8622 void
8623 ice_init_saved_phy_cfg(struct ice_softc *sc)
8624 {
8625 	struct ice_port_info *pi = sc->hw.port_info;
8626 	struct ice_aqc_get_phy_caps_data pcaps = { 0 };
8627 	struct ice_hw *hw = &sc->hw;
8628 	device_t dev = sc->dev;
8629 	enum ice_status status;
8630 	u64 phy_low, phy_high;
8631 	u8 report_mode = ICE_AQC_REPORT_TOPO_CAP_MEDIA;
8632 
8633 	if (ice_is_bit_set(sc->feat_en, ICE_FEATURE_LINK_MGMT_VER_2))
8634 		report_mode = ICE_AQC_REPORT_DFLT_CFG;
8635 	status = ice_aq_get_phy_caps(pi, false, report_mode, &pcaps, NULL);
8636 	if (status != ICE_SUCCESS) {
8637 		device_printf(dev,
8638 		    "%s: ice_aq_get_phy_caps (%s) failed; status %s, aq_err %s\n",
8639 		    __func__,
8640 		    report_mode == ICE_AQC_REPORT_DFLT_CFG ? "DFLT" : "w/MEDIA",
8641 		    ice_status_str(status),
8642 		    ice_aq_str(hw->adminq.sq_last_status));
8643 		return;
8644 	}
8645 
8646 	phy_low = le64toh(pcaps.phy_type_low);
8647 	phy_high = le64toh(pcaps.phy_type_high);
8648 
8649 	/* Save off initial config parameters */
8650 	pi->phy.curr_user_speed_req =
8651 	   ice_aq_phy_types_to_link_speeds(phy_low, phy_high);
8652 	pi->phy.curr_user_fec_req = ice_caps_to_fec_mode(pcaps.caps,
8653 	    pcaps.link_fec_options);
8654 	pi->phy.curr_user_fc_req = ice_caps_to_fc_mode(pcaps.caps);
8655 }
8656 
8657 /**
8658  * ice_module_init - Driver callback to handle module load
8659  *
8660  * Callback for handling module load events. This function should initialize
8661  * any data structures that are used for the life of the device driver.
8662  */
8663 static int
8664 ice_module_init(void)
8665 {
8666 	return (0);
8667 }
8668 
8669 /**
8670  * ice_module_exit - Driver callback to handle module exit
8671  *
8672  * Callback for handling module unload events. This function should release
8673  * any resources initialized during ice_module_init.
8674  *
8675  * If this function returns non-zero, the module will not be unloaded. It
8676  * should only return such a value if the module cannot be unloaded at all,
8677  * such as due to outstanding memory references that cannot be revoked.
8678  */
8679 static int
8680 ice_module_exit(void)
8681 {
8682 	return (0);
8683 }
8684 
8685 /**
8686  * ice_module_event_handler - Callback for module events
8687  * @mod: unused module_t parameter
8688  * @what: the event requested
8689  * @arg: unused event argument
8690  *
8691  * Callback used to handle module events from the stack. Used to allow the
8692  * driver to define custom behavior that should happen at module load and
8693  * unload.
8694  */
8695 int
8696 ice_module_event_handler(module_t __unused mod, int what, void __unused *arg)
8697 {
8698 	switch (what) {
8699 	case MOD_LOAD:
8700 		return ice_module_init();
8701 	case MOD_UNLOAD:
8702 		return ice_module_exit();
8703 	default:
8704 		/* TODO: do we need to handle MOD_QUIESCE and MOD_SHUTDOWN? */
8705 		return (EOPNOTSUPP);
8706 	}
8707 }
8708 
8709 /**
8710  * ice_handle_nvm_access_ioctl - Handle an NVM access ioctl request
8711  * @sc: the device private softc
8712  * @ifd: ifdrv ioctl request pointer
8713  */
8714 int
8715 ice_handle_nvm_access_ioctl(struct ice_softc *sc, struct ifdrv *ifd)
8716 {
8717 	union ice_nvm_access_data *data;
8718 	struct ice_nvm_access_cmd *cmd;
8719 	size_t ifd_len = ifd->ifd_len, malloc_len;
8720 	struct ice_hw *hw = &sc->hw;
8721 	device_t dev = sc->dev;
8722 	enum ice_status status;
8723 	u8 *nvm_buffer;
8724 	int err;
8725 
8726 	/*
8727 	 * ifioctl forwards SIOCxDRVSPEC to iflib without performing
8728 	 * a privilege check. In turn, iflib forwards the ioctl to the driver
8729 	 * without performing a privilege check. Perform one here to ensure
8730 	 * that non-privileged threads cannot access this interface.
8731 	 */
8732 	err = priv_check(curthread, PRIV_DRIVER);
8733 	if (err)
8734 		return (err);
8735 
8736 	if (ifd_len < sizeof(struct ice_nvm_access_cmd)) {
8737 		device_printf(dev, "%s: ifdrv length is too small. Got %zu, but expected %zu\n",
8738 			      __func__, ifd_len, sizeof(struct ice_nvm_access_cmd));
8739 		return (EINVAL);
8740 	}
8741 
8742 	if (ifd->ifd_data == NULL) {
8743 		device_printf(dev, "%s: ifd data buffer not present.\n",
8744 			      __func__);
8745 		return (EINVAL);
8746 	}
8747 
8748 	/*
8749 	 * If everything works correctly, ice_handle_nvm_access should not
8750 	 * modify data past the size of the ioctl length. However, it could
8751 	 * lead to memory corruption if it did. Make sure to allocate at least
8752 	 * enough space for the command and data regardless. This
8753 	 * ensures that any access to the data union will not access invalid
8754 	 * memory.
8755 	 */
8756 	malloc_len = max(ifd_len, sizeof(*data) + sizeof(*cmd));
8757 
8758 	nvm_buffer = (u8 *)malloc(malloc_len, M_ICE, M_ZERO | M_WAITOK);
8759 	if (!nvm_buffer)
8760 		return (ENOMEM);
8761 
8762 	/* Copy the NVM access command and data in from user space */
8763 	/* coverity[tainted_data_argument] */
8764 	err = copyin(ifd->ifd_data, nvm_buffer, ifd_len);
8765 	if (err) {
8766 		device_printf(dev, "%s: Copying request from user space failed, err %s\n",
8767 			      __func__, ice_err_str(err));
8768 		goto cleanup_free_nvm_buffer;
8769 	}
8770 
8771 	/*
8772 	 * The NVM command structure is immediately followed by data which
8773 	 * varies in size based on the command.
8774 	 */
8775 	cmd = (struct ice_nvm_access_cmd *)nvm_buffer;
8776 	data = (union ice_nvm_access_data *)(nvm_buffer + sizeof(struct ice_nvm_access_cmd));
8777 
8778 	/* Handle the NVM access request */
8779 	status = ice_handle_nvm_access(hw, cmd, data);
8780 	if (status)
8781 		ice_debug(hw, ICE_DBG_NVM,
8782 			  "NVM access request failed, err %s\n",
8783 			  ice_status_str(status));
8784 
8785 	/* Copy the possibly modified contents of the handled request out */
8786 	err = copyout(nvm_buffer, ifd->ifd_data, ifd_len);
8787 	if (err) {
8788 		device_printf(dev, "%s: Copying response back to user space failed, err %s\n",
8789 			      __func__, ice_err_str(err));
8790 		goto cleanup_free_nvm_buffer;
8791 	}
8792 
8793 	/* Convert private status to an error code for proper ioctl response */
8794 	switch (status) {
8795 	case ICE_SUCCESS:
8796 		err = (0);
8797 		break;
8798 	case ICE_ERR_NO_MEMORY:
8799 		err = (ENOMEM);
8800 		break;
8801 	case ICE_ERR_OUT_OF_RANGE:
8802 		err = (ENOTTY);
8803 		break;
8804 	case ICE_ERR_PARAM:
8805 	default:
8806 		err = (EINVAL);
8807 		break;
8808 	}
8809 
8810 cleanup_free_nvm_buffer:
8811 	free(nvm_buffer, M_ICE);
8812 	return err;
8813 }
8814 
8815 /**
8816  * ice_read_sff_eeprom - Read data from SFF eeprom
8817  * @sc: device softc
8818  * @dev_addr: I2C device address (typically 0xA0 or 0xA2)
8819  * @offset: offset into the eeprom
8820  * @data: pointer to data buffer to store read data in
8821  * @length: length to read; max length is 16
8822  *
8823  * Read from the SFF eeprom in the module for this PF's port. For more details
8824  * on the contents of an SFF eeprom, refer to SFF-8724 (SFP), SFF-8636 (QSFP),
8825  * and SFF-8024 (both).
8826  */
8827 int
8828 ice_read_sff_eeprom(struct ice_softc *sc, u16 dev_addr, u16 offset, u8* data, u16 length)
8829 {
8830 	struct ice_hw *hw = &sc->hw;
8831 	int ret = 0, retries = 0;
8832 	enum ice_status status;
8833 
8834 	if (length > 16)
8835 		return (EINVAL);
8836 
8837 	if (ice_test_state(&sc->state, ICE_STATE_RECOVERY_MODE))
8838 		return (ENOSYS);
8839 
8840 	if (ice_test_state(&sc->state, ICE_STATE_NO_MEDIA))
8841 		return (ENXIO);
8842 
8843 	do {
8844 		status = ice_aq_sff_eeprom(hw, 0, dev_addr,
8845 					   offset, 0, 0, data, length,
8846 					   false, NULL);
8847 		if (!status) {
8848 			ret = 0;
8849 			break;
8850 		}
8851 		if (status == ICE_ERR_AQ_ERROR &&
8852 		    hw->adminq.sq_last_status == ICE_AQ_RC_EBUSY) {
8853 			ret = EBUSY;
8854 			continue;
8855 		}
8856 		if (status == ICE_ERR_AQ_ERROR &&
8857 		    hw->adminq.sq_last_status == ICE_AQ_RC_EACCES) {
8858 			/* FW says I2C access isn't supported */
8859 			ret = EACCES;
8860 			break;
8861 		}
8862 		if (status == ICE_ERR_AQ_ERROR &&
8863 		    hw->adminq.sq_last_status == ICE_AQ_RC_EPERM) {
8864 			device_printf(sc->dev,
8865 				  "%s: Module pointer location specified in command does not permit the required operation.\n",
8866 				  __func__);
8867 			ret = EPERM;
8868 			break;
8869 		} else {
8870 			device_printf(sc->dev,
8871 				  "%s: Error reading I2C data: err %s aq_err %s\n",
8872 				  __func__, ice_status_str(status),
8873 				  ice_aq_str(hw->adminq.sq_last_status));
8874 			ret = EIO;
8875 			break;
8876 		}
8877 	} while (retries++ < ICE_I2C_MAX_RETRIES);
8878 
8879 	if (ret == EBUSY)
8880 		device_printf(sc->dev,
8881 			  "%s: Error reading I2C data after %d retries\n",
8882 			  __func__, ICE_I2C_MAX_RETRIES);
8883 
8884 	return (ret);
8885 }
8886 
8887 /**
8888  * ice_handle_i2c_req - Driver independent I2C request handler
8889  * @sc: device softc
8890  * @req: The I2C parameters to use
8891  *
8892  * Read from the port's I2C eeprom using the parameters from the ioctl.
8893  */
8894 int
8895 ice_handle_i2c_req(struct ice_softc *sc, struct ifi2creq *req)
8896 {
8897 	return ice_read_sff_eeprom(sc, req->dev_addr, req->offset, req->data, req->len);
8898 }
8899 
8900 /**
8901  * ice_sysctl_read_i2c_diag_data - Read some module diagnostic data via i2c
8902  * @oidp: sysctl oid structure
8903  * @arg1: pointer to private data structure
8904  * @arg2: unused
8905  * @req: sysctl request pointer
8906  *
8907  * Read 8 bytes of diagnostic data from the SFF eeprom in the (Q)SFP module
8908  * inserted into the port.
8909  *
8910  *             | SFP A2  | QSFP Lower Page
8911  * ------------|---------|----------------
8912  * Temperature | 96-97	 | 22-23
8913  * Vcc         | 98-99   | 26-27
8914  * TX power    | 102-103 | 34-35..40-41
8915  * RX power    | 104-105 | 50-51..56-57
8916  */
8917 static int
8918 ice_sysctl_read_i2c_diag_data(SYSCTL_HANDLER_ARGS)
8919 {
8920 	struct ice_softc *sc = (struct ice_softc *)arg1;
8921 	device_t dev = sc->dev;
8922 	struct sbuf *sbuf;
8923 	int ret;
8924 	u8 data[16];
8925 
8926 	UNREFERENCED_PARAMETER(arg2);
8927 	UNREFERENCED_PARAMETER(oidp);
8928 
8929 	if (ice_driver_is_detaching(sc))
8930 		return (ESHUTDOWN);
8931 
8932 	if (req->oldptr == NULL) {
8933 		ret = SYSCTL_OUT(req, 0, 128);
8934 		return (ret);
8935 	}
8936 
8937 	ret = ice_read_sff_eeprom(sc, 0xA0, 0, data, 1);
8938 	if (ret)
8939 		return (ret);
8940 
8941 	/* 0x3 for SFP; 0xD/0x11 for QSFP+/QSFP28 */
8942 	if (data[0] == 0x3) {
8943 		/*
8944 		 * Check for:
8945 		 * - Internally calibrated data
8946 		 * - Diagnostic monitoring is implemented
8947 		 */
8948 		ice_read_sff_eeprom(sc, 0xA0, 92, data, 1);
8949 		if (!(data[0] & 0x60)) {
8950 			device_printf(dev, "Module doesn't support diagnostics: 0xA0[92] = %02X\n", data[0]);
8951 			return (ENODEV);
8952 		}
8953 
8954 		sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
8955 
8956 		ice_read_sff_eeprom(sc, 0xA2, 96, data, 4);
8957 		for (int i = 0; i < 4; i++)
8958 			sbuf_printf(sbuf, "%02X ", data[i]);
8959 
8960 		ice_read_sff_eeprom(sc, 0xA2, 102, data, 4);
8961 		for (int i = 0; i < 4; i++)
8962 			sbuf_printf(sbuf, "%02X ", data[i]);
8963 	} else if (data[0] == 0xD || data[0] == 0x11) {
8964 		/*
8965 		 * QSFP+ modules are always internally calibrated, and must indicate
8966 		 * what types of diagnostic monitoring are implemented
8967 		 */
8968 		sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
8969 
8970 		ice_read_sff_eeprom(sc, 0xA0, 22, data, 2);
8971 		for (int i = 0; i < 2; i++)
8972 			sbuf_printf(sbuf, "%02X ", data[i]);
8973 
8974 		ice_read_sff_eeprom(sc, 0xA0, 26, data, 2);
8975 		for (int i = 0; i < 2; i++)
8976 			sbuf_printf(sbuf, "%02X ", data[i]);
8977 
8978 		ice_read_sff_eeprom(sc, 0xA0, 34, data, 2);
8979 		for (int i = 0; i < 2; i++)
8980 			sbuf_printf(sbuf, "%02X ", data[i]);
8981 
8982 		ice_read_sff_eeprom(sc, 0xA0, 50, data, 2);
8983 		for (int i = 0; i < 2; i++)
8984 			sbuf_printf(sbuf, "%02X ", data[i]);
8985 	} else {
8986 		device_printf(dev, "Module is not SFP/SFP+/SFP28/QSFP+ (%02X)\n", data[0]);
8987 		return (ENODEV);
8988 	}
8989 
8990 	sbuf_finish(sbuf);
8991 	sbuf_delete(sbuf);
8992 
8993 	return (0);
8994 }
8995 
8996 /**
8997  * ice_alloc_intr_tracking - Setup interrupt tracking structures
8998  * @sc: device softc structure
8999  *
9000  * Sets up the resource manager for keeping track of interrupt allocations,
9001  * and initializes the tracking maps for the PF's interrupt allocations.
9002  *
9003  * Unlike the scheme for queues, this is done in one step since both the
9004  * manager and the maps both have the same lifetime.
9005  *
9006  * @returns 0 on success, or an error code on failure.
9007  */
9008 int
9009 ice_alloc_intr_tracking(struct ice_softc *sc)
9010 {
9011 	struct ice_hw *hw = &sc->hw;
9012 	device_t dev = sc->dev;
9013 	int err;
9014 
9015 	/* Initialize the interrupt allocation manager */
9016 	err = ice_resmgr_init_contig_only(&sc->imgr,
9017 	    hw->func_caps.common_cap.num_msix_vectors);
9018 	if (err) {
9019 		device_printf(dev, "Unable to initialize PF interrupt manager: %s\n",
9020 			      ice_err_str(err));
9021 		return (err);
9022 	}
9023 
9024 	/* Allocate PF interrupt mapping storage */
9025 	if (!(sc->pf_imap =
9026 	      (u16 *)malloc(sizeof(u16) * hw->func_caps.common_cap.num_msix_vectors,
9027 	      M_ICE, M_NOWAIT))) {
9028 		device_printf(dev, "Unable to allocate PF imap memory\n");
9029 		err = ENOMEM;
9030 		goto free_imgr;
9031 	}
9032 	for (u32 i = 0; i < hw->func_caps.common_cap.num_msix_vectors; i++) {
9033 		sc->pf_imap[i] = ICE_INVALID_RES_IDX;
9034 	}
9035 
9036 	return (0);
9037 
9038 free_imgr:
9039 	ice_resmgr_destroy(&sc->imgr);
9040 	return (err);
9041 }
9042 
9043 /**
9044  * ice_free_intr_tracking - Free PF interrupt tracking structures
9045  * @sc: device softc structure
9046  *
9047  * Frees the interrupt resource allocation manager and the PF's owned maps.
9048  *
9049  * VF maps are released when the owning VF's are destroyed, which should always
9050  * happen before this function is called.
9051  */
9052 void
9053 ice_free_intr_tracking(struct ice_softc *sc)
9054 {
9055 	if (sc->pf_imap) {
9056 		ice_resmgr_release_map(&sc->imgr, sc->pf_imap,
9057 				       sc->lan_vectors);
9058 		free(sc->pf_imap, M_ICE);
9059 		sc->pf_imap = NULL;
9060 	}
9061 
9062 	ice_resmgr_destroy(&sc->imgr);
9063 }
9064 
9065 /**
9066  * ice_apply_supported_speed_filter - Mask off unsupported speeds
9067  * @report_speeds: bit-field for the desired link speeds
9068  * @mod_type: type of module/sgmii connection we have
9069  *
9070  * Given a bitmap of the desired lenient mode link speeds,
9071  * this function will mask off the speeds that are not currently
9072  * supported by the device.
9073  */
9074 static u16
9075 ice_apply_supported_speed_filter(u16 report_speeds, u8 mod_type)
9076 {
9077 	u16 speed_mask;
9078 	enum { IS_SGMII, IS_SFP, IS_QSFP } module;
9079 
9080 	/*
9081 	 * The SFF specification says 0 is unknown, so we'll
9082 	 * treat it like we're connected through SGMII for now.
9083 	 * This may need revisiting if a new type is supported
9084 	 * in the future.
9085 	 */
9086 	switch (mod_type) {
9087 	case 0:
9088 		module = IS_SGMII;
9089 		break;
9090 	case 3:
9091 		module = IS_SFP;
9092 		break;
9093 	default:
9094 		module = IS_QSFP;
9095 		break;
9096 	}
9097 
9098 	/* We won't offer anything lower than 100M for any part,
9099 	 * but we'll need to mask off other speeds based on the
9100 	 * device and module type.
9101 	 */
9102 	speed_mask = ~((u16)ICE_AQ_LINK_SPEED_100MB - 1);
9103 	if ((report_speeds & ICE_AQ_LINK_SPEED_10GB) && (module == IS_SFP))
9104 		speed_mask = ~((u16)ICE_AQ_LINK_SPEED_1000MB - 1);
9105 	if (report_speeds & ICE_AQ_LINK_SPEED_25GB)
9106 		speed_mask = ~((u16)ICE_AQ_LINK_SPEED_1000MB - 1);
9107 	if (report_speeds & ICE_AQ_LINK_SPEED_50GB) {
9108 		speed_mask = ~((u16)ICE_AQ_LINK_SPEED_1000MB - 1);
9109 		if (module == IS_QSFP)
9110 			speed_mask = ~((u16)ICE_AQ_LINK_SPEED_10GB - 1);
9111 	}
9112 	if (report_speeds & ICE_AQ_LINK_SPEED_100GB)
9113 		speed_mask = ~((u16)ICE_AQ_LINK_SPEED_25GB - 1);
9114 	return (report_speeds & speed_mask);
9115 }
9116 
9117 /**
9118  * ice_init_health_events - Enable FW health event reporting
9119  * @sc: device softc
9120  *
9121  * Will try to enable firmware health event reporting, but shouldn't
9122  * cause any grief (to the caller) if this fails.
9123  */
9124 void
9125 ice_init_health_events(struct ice_softc *sc)
9126 {
9127 	enum ice_status status;
9128 	u8 health_mask;
9129 
9130 	if ((!ice_is_bit_set(sc->feat_cap, ICE_FEATURE_HEALTH_STATUS)) ||
9131 	    (!sc->enable_health_events))
9132 		return;
9133 
9134 	health_mask = ICE_AQC_HEALTH_STATUS_SET_PF_SPECIFIC_MASK |
9135 		      ICE_AQC_HEALTH_STATUS_SET_GLOBAL_MASK;
9136 
9137 	status = ice_aq_set_health_status_config(&sc->hw, health_mask, NULL);
9138 	if (status)
9139 		device_printf(sc->dev,
9140 		    "Failed to enable firmware health events, err %s aq_err %s\n",
9141 		    ice_status_str(status),
9142 		    ice_aq_str(sc->hw.adminq.sq_last_status));
9143 	else
9144 		ice_set_bit(ICE_FEATURE_HEALTH_STATUS, sc->feat_en);
9145 }
9146 
9147 /**
9148  * ice_print_health_status_string - Print message for given FW health event
9149  * @dev: the PCIe device
9150  * @elem: health status element containing status code
9151  *
9152  * A rather large list of possible health status codes and their associated
9153  * messages.
9154  */
9155 static void
9156 ice_print_health_status_string(device_t dev,
9157 			       struct ice_aqc_health_status_elem *elem)
9158 {
9159 	u16 status_code = le16toh(elem->health_status_code);
9160 
9161 	switch (status_code) {
9162 	case ICE_AQC_HEALTH_STATUS_INFO_RECOVERY:
9163 		device_printf(dev, "The device is in firmware recovery mode.\n");
9164 		device_printf(dev, "Possible Solution: Update to the latest NVM image.\n");
9165 		break;
9166 	case ICE_AQC_HEALTH_STATUS_ERR_FLASH_ACCESS:
9167 		device_printf(dev, "The flash chip cannot be accessed.\n");
9168 		device_printf(dev, "Possible Solution: If issue persists, call customer support.\n");
9169 		break;
9170 	case ICE_AQC_HEALTH_STATUS_ERR_NVM_AUTH:
9171 		device_printf(dev, "NVM authentication failed.\n");
9172 		device_printf(dev, "Possible Solution: Update to the latest NVM image.\n");
9173 		break;
9174 	case ICE_AQC_HEALTH_STATUS_ERR_OROM_AUTH:
9175 		device_printf(dev, "Option ROM authentication failed.\n");
9176 		device_printf(dev, "Possible Solution: Update to the latest NVM image.\n");
9177 		break;
9178 	case ICE_AQC_HEALTH_STATUS_ERR_DDP_AUTH:
9179 		device_printf(dev, "DDP package failed.\n");
9180 		device_printf(dev, "Possible Solution: Update to latest base driver and DDP package.\n");
9181 		break;
9182 	case ICE_AQC_HEALTH_STATUS_ERR_NVM_COMPAT:
9183 		device_printf(dev, "NVM image is incompatible.\n");
9184 		device_printf(dev, "Possible Solution: Update to the latest NVM image.\n");
9185 		break;
9186 	case ICE_AQC_HEALTH_STATUS_ERR_OROM_COMPAT:
9187 		device_printf(dev, "Option ROM is incompatible.\n");
9188 		device_printf(dev, "Possible Solution: Update to the latest NVM image.\n");
9189 		break;
9190 	case ICE_AQC_HEALTH_STATUS_ERR_DCB_MIB:
9191 		device_printf(dev, "Supplied MIB file is invalid. DCB reverted to default configuration.\n");
9192 		device_printf(dev, "Possible Solution: Disable FW-LLDP and check DCBx system configuration.\n");
9193 		break;
9194 	case ICE_AQC_HEALTH_STATUS_ERR_UNKNOWN_MOD_STRICT:
9195 		device_printf(dev, "An unsupported module was detected.\n");
9196 		device_printf(dev, "Possible Solution 1: Check your cable connection.\n");
9197 		device_printf(dev, "Possible Solution 2: Change or replace the module or cable.\n");
9198 		break;
9199 	case ICE_AQC_HEALTH_STATUS_ERR_MOD_TYPE:
9200 		device_printf(dev, "Module type is not supported.\n");
9201 		device_printf(dev, "Possible Solution: Change or replace the module or cable.\n");
9202 		break;
9203 	case ICE_AQC_HEALTH_STATUS_ERR_MOD_QUAL:
9204 		device_printf(dev, "Module is not qualified.\n");
9205 		device_printf(dev, "Possible Solution 1: Check your cable connection.\n");
9206 		device_printf(dev, "Possible Solution 2: Change or replace the module or cable.\n");
9207 		device_printf(dev, "Possible Solution 3: Manually set speed and duplex.\n");
9208 		break;
9209 	case ICE_AQC_HEALTH_STATUS_ERR_MOD_COMM:
9210 		device_printf(dev, "Device cannot communicate with the module.\n");
9211 		device_printf(dev, "Possible Solution 1: Check your cable connection.\n");
9212 		device_printf(dev, "Possible Solution 2: Change or replace the module or cable.\n");
9213 		device_printf(dev, "Possible Solution 3: Manually set speed and duplex.\n");
9214 		break;
9215 	case ICE_AQC_HEALTH_STATUS_ERR_MOD_CONFLICT:
9216 		device_printf(dev, "Unresolved module conflict.\n");
9217 		device_printf(dev, "Possible Solution 1: Manually set speed/duplex or use Intel(R) Ethernet Port Configuration Tool to change the port option.\n");
9218 		device_printf(dev, "Possible Solution 2: If the problem persists, use a cable/module that is found in the supported modules and cables list for this device.\n");
9219 		break;
9220 	case ICE_AQC_HEALTH_STATUS_ERR_MOD_NOT_PRESENT:
9221 		device_printf(dev, "Module is not present.\n");
9222 		device_printf(dev, "Possible Solution 1: Check that the module is inserted correctly.\n");
9223 		device_printf(dev, "Possible Solution 2: If the problem persists, use a cable/module that is found in the supported modules and cables list for this device.\n");
9224 		break;
9225 	case ICE_AQC_HEALTH_STATUS_INFO_MOD_UNDERUTILIZED:
9226 		device_printf(dev, "Underutilized module.\n");
9227 		device_printf(dev, "Possible Solution 1: Change or replace the module or cable.\n");
9228 		device_printf(dev, "Possible Solution 2: Use Intel(R) Ethernet Port Configuration Tool to change the port option.\n");
9229 		break;
9230 	case ICE_AQC_HEALTH_STATUS_ERR_UNKNOWN_MOD_LENIENT:
9231 		device_printf(dev, "An unsupported module was detected.\n");
9232 		device_printf(dev, "Possible Solution 1: Check your cable connection.\n");
9233 		device_printf(dev, "Possible Solution 2: Change or replace the module or cable.\n");
9234 		device_printf(dev, "Possible Solution 3: Manually set speed and duplex.\n");
9235 		break;
9236 	case ICE_AQC_HEALTH_STATUS_ERR_INVALID_LINK_CFG:
9237 		device_printf(dev, "Invalid link configuration.\n");
9238 		break;
9239 	case ICE_AQC_HEALTH_STATUS_ERR_PORT_ACCESS:
9240 		device_printf(dev, "Port hardware access error.\n");
9241 		device_printf(dev, "Possible Solution: Update to the latest NVM image.\n");
9242 		break;
9243 	case ICE_AQC_HEALTH_STATUS_ERR_PORT_UNREACHABLE:
9244 		device_printf(dev, "A port is unreachable.\n");
9245 		device_printf(dev, "Possible Solution 1: Use Intel(R) Ethernet Port Configuration Tool to change the port option.\n");
9246 		device_printf(dev, "Possible Solution 2: Update to the latest NVM image.\n");
9247 		break;
9248 	case ICE_AQC_HEALTH_STATUS_INFO_PORT_SPEED_MOD_LIMITED:
9249 		device_printf(dev, "Port speed is limited due to module.\n");
9250 		device_printf(dev, "Possible Solution: Change the module or use Intel(R) Ethernet Port Configuration Tool to configure the port option to match the current module speed.\n");
9251 		break;
9252 	case ICE_AQC_HEALTH_STATUS_ERR_PARALLEL_FAULT:
9253 		device_printf(dev, "A parallel fault was detected.\n");
9254 		device_printf(dev, "Possible Solution: Check link partner connection and configuration.\n");
9255 		break;
9256 	case ICE_AQC_HEALTH_STATUS_INFO_PORT_SPEED_PHY_LIMITED:
9257 		device_printf(dev, "Port speed is limited by PHY capabilities.\n");
9258 		device_printf(dev, "Possible Solution 1: Change the module to align to port option.\n");
9259 		device_printf(dev, "Possible Solution 2: Use Intel(R) Ethernet Port Configuration Tool to change the port option.\n");
9260 		break;
9261 	case ICE_AQC_HEALTH_STATUS_ERR_NETLIST_TOPO:
9262 		device_printf(dev, "LOM topology netlist is corrupted.\n");
9263 		device_printf(dev, "Possible Solution: Update to the latest NVM image.\n");
9264 		break;
9265 	case ICE_AQC_HEALTH_STATUS_ERR_NETLIST:
9266 		device_printf(dev, "Unrecoverable netlist error.\n");
9267 		device_printf(dev, "Possible Solution: Update to the latest NVM image.\n");
9268 		break;
9269 	case ICE_AQC_HEALTH_STATUS_ERR_TOPO_CONFLICT:
9270 		device_printf(dev, "Port topology conflict.\n");
9271 		device_printf(dev, "Possible Solution 1: Use Intel(R) Ethernet Port Configuration Tool to change the port option.\n");
9272 		device_printf(dev, "Possible Solution 2: Update to the latest NVM image.\n");
9273 		break;
9274 	case ICE_AQC_HEALTH_STATUS_ERR_LINK_HW_ACCESS:
9275 		device_printf(dev, "Unrecoverable hardware access error.\n");
9276 		device_printf(dev, "Possible Solution: Update to the latest NVM image.\n");
9277 		break;
9278 	case ICE_AQC_HEALTH_STATUS_ERR_LINK_RUNTIME:
9279 		device_printf(dev, "Unrecoverable runtime error.\n");
9280 		device_printf(dev, "Possible Solution: Update to the latest NVM image.\n");
9281 		break;
9282 	case ICE_AQC_HEALTH_STATUS_ERR_DNL_INIT:
9283 		device_printf(dev, "Link management engine failed to initialize.\n");
9284 		device_printf(dev, "Possible Solution: Update to the latest NVM image.\n");
9285 		break;
9286 	default:
9287 		break;
9288 	}
9289 }
9290 
9291 /**
9292  * ice_handle_health_status_event - helper function to output health status
9293  * @sc: device softc structure
9294  * @event: event received on a control queue
9295  *
9296  * Prints out the appropriate string based on the given Health Status Event
9297  * code.
9298  */
9299 static void
9300 ice_handle_health_status_event(struct ice_softc *sc,
9301 			       struct ice_rq_event_info *event)
9302 {
9303 	struct ice_aqc_health_status_elem *health_info;
9304 	u16 status_count;
9305 	int i;
9306 
9307 	if (!ice_is_bit_set(sc->feat_en, ICE_FEATURE_HEALTH_STATUS))
9308 		return;
9309 
9310 	health_info = (struct ice_aqc_health_status_elem *)event->msg_buf;
9311 	status_count = le16toh(event->desc.params.get_health_status.health_status_count);
9312 
9313 	if (status_count > (event->buf_len / sizeof(*health_info))) {
9314 		device_printf(sc->dev, "Received a health status event with invalid event count\n");
9315 		return;
9316 	}
9317 
9318 	for (i = 0; i < status_count; i++) {
9319 		ice_print_health_status_string(sc->dev, health_info);
9320 		health_info++;
9321 	}
9322 }
9323 
9324 /**
9325  * ice_set_default_local_lldp_mib - Set Local LLDP MIB to default settings
9326  * @sc: device softc structure
9327  *
9328  * This function needs to be called after link up; it makes sure the FW
9329  * has certain PFC/DCB settings. This is intended to workaround a FW behavior
9330  * where these settings seem to be cleared on link up.
9331  */
9332 void
9333 ice_set_default_local_lldp_mib(struct ice_softc *sc)
9334 {
9335 	struct ice_dcbx_cfg *dcbcfg;
9336 	struct ice_hw *hw = &sc->hw;
9337 	struct ice_port_info *pi;
9338 	device_t dev = sc->dev;
9339 	enum ice_status status;
9340 	u8 maxtcs, maxtcs_ets;
9341 
9342 	pi = hw->port_info;
9343 
9344 	dcbcfg = &pi->qos_cfg.local_dcbx_cfg;
9345 
9346 	maxtcs = hw->func_caps.common_cap.maxtc;
9347 	/* This value is only 3 bits; 8 TCs maps to 0 */
9348 	maxtcs_ets = maxtcs & ICE_IEEE_ETS_MAXTC_M;
9349 
9350 	/**
9351 	 * Setup the default settings used by the driver for the Set Local
9352 	 * LLDP MIB Admin Queue command (0x0A08). (1TC w/ 100% BW, ETS, no
9353 	 * PFC).
9354 	 */
9355 	memset(dcbcfg, 0, sizeof(*dcbcfg));
9356 	dcbcfg->etscfg.willing = 1;
9357 	dcbcfg->etscfg.tcbwtable[0] = 100;
9358 	dcbcfg->etscfg.maxtcs = maxtcs_ets;
9359 	dcbcfg->etsrec = dcbcfg->etscfg;
9360 	dcbcfg->pfc.willing = 1;
9361 	dcbcfg->pfc.pfccap = maxtcs;
9362 
9363 	status = ice_set_dcb_cfg(pi);
9364 
9365 	if (status)
9366 		device_printf(dev,
9367 		    "Error setting Local LLDP MIB: %s aq_err %s\n",
9368 		    ice_status_str(status),
9369 		    ice_aq_str(hw->adminq.sq_last_status));
9370 }
9371 
9372 /**
9373  * ice_sbuf_print_ets_cfg - Helper function to print ETS cfg
9374  * @sbuf: string buffer to print to
9375  * @name: prefix string to use
9376  * @ets: structure to pull values from
9377  *
9378  * A helper function for ice_sysctl_dump_dcbx_cfg(), this
9379  * formats the ETS rec and cfg TLVs into text.
9380  */
9381 static void
9382 ice_sbuf_print_ets_cfg(struct sbuf *sbuf, const char *name, struct ice_dcb_ets_cfg *ets)
9383 {
9384 	sbuf_printf(sbuf, "%s.willing: %u\n", name, ets->willing);
9385 	sbuf_printf(sbuf, "%s.cbs: %u\n", name, ets->cbs);
9386 	sbuf_printf(sbuf, "%s.maxtcs: %u\n", name, ets->maxtcs);
9387 
9388 	sbuf_printf(sbuf, "%s.prio_table:", name);
9389 	for (int i = 0; i < ICE_MAX_TRAFFIC_CLASS; i++)
9390 		sbuf_printf(sbuf, " %d", ets->prio_table[i]);
9391 	sbuf_printf(sbuf, "\n");
9392 
9393 	sbuf_printf(sbuf, "%s.tcbwtable:", name);
9394 	for (int i = 0; i < ICE_MAX_TRAFFIC_CLASS; i++)
9395 		sbuf_printf(sbuf, " %d", ets->tcbwtable[i]);
9396 	sbuf_printf(sbuf, "\n");
9397 
9398 	sbuf_printf(sbuf, "%s.tsatable:", name);
9399 	for (int i = 0; i < ICE_MAX_TRAFFIC_CLASS; i++)
9400 		sbuf_printf(sbuf, " %d", ets->tsatable[i]);
9401 	sbuf_printf(sbuf, "\n");
9402 }
9403 
9404 /**
9405  * ice_sysctl_dump_dcbx_cfg - Print out DCBX/DCB config info
9406  * @oidp: sysctl oid structure
9407  * @arg1: pointer to private data structure
9408  * @arg2: AQ define for either Local or Remote MIB
9409  * @req: sysctl request pointer
9410  *
9411  * Prints out DCB/DCBX configuration, including the contents
9412  * of either the local or remote MIB, depending on the value
9413  * used in arg2.
9414  */
9415 static int
9416 ice_sysctl_dump_dcbx_cfg(SYSCTL_HANDLER_ARGS)
9417 {
9418 	struct ice_softc *sc = (struct ice_softc *)arg1;
9419 	struct ice_aqc_get_cee_dcb_cfg_resp cee_cfg = {};
9420 	struct ice_dcbx_cfg dcb_buf = {};
9421 	struct ice_dcbx_cfg *dcbcfg;
9422 	struct ice_hw *hw = &sc->hw;
9423 	device_t dev = sc->dev;
9424 	struct sbuf *sbuf;
9425 	enum ice_status status;
9426 	u8 maxtcs, dcbx_status, is_sw_lldp;
9427 
9428 	UNREFERENCED_PARAMETER(oidp);
9429 
9430 	if (ice_driver_is_detaching(sc))
9431 		return (ESHUTDOWN);
9432 
9433 	is_sw_lldp = hw->port_info->qos_cfg.is_sw_lldp;
9434 
9435 	/* The driver doesn't receive a Remote MIB via SW */
9436 	if (is_sw_lldp && arg2 == ICE_AQ_LLDP_MIB_REMOTE)
9437 		return (ENOENT);
9438 
9439 	dcbcfg = &hw->port_info->qos_cfg.local_dcbx_cfg;
9440 	if (!is_sw_lldp) {
9441 		/* Collect information from the FW in FW LLDP mode */
9442 		dcbcfg = &dcb_buf;
9443 		status = ice_aq_get_dcb_cfg(hw, (u8)arg2,
9444 		    ICE_AQ_LLDP_BRID_TYPE_NEAREST_BRID, dcbcfg);
9445 		if (status && arg2 == ICE_AQ_LLDP_MIB_REMOTE &&
9446 		    hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT) {
9447 			device_printf(dev,
9448 			    "Unable to query Remote MIB; port has not received one yet\n");
9449 			return (ENOENT);
9450 		}
9451 		if (status) {
9452 			device_printf(dev, "Unable to query LLDP MIB, err %s aq_err %s\n",
9453 			    ice_status_str(status),
9454 			    ice_aq_str(hw->adminq.sq_last_status));
9455 			return (EIO);
9456 		}
9457 	}
9458 
9459 	status = ice_aq_get_cee_dcb_cfg(hw, &cee_cfg, NULL);
9460 	if (status == ICE_SUCCESS)
9461 		dcbcfg->dcbx_mode = ICE_DCBX_MODE_CEE;
9462 	else if (hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT)
9463 		dcbcfg->dcbx_mode = ICE_DCBX_MODE_IEEE;
9464 
9465 	maxtcs = hw->func_caps.common_cap.maxtc;
9466 	dcbx_status = ice_get_dcbx_status(hw);
9467 
9468 	sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
9469 
9470 	/* Do the actual printing */
9471 	sbuf_printf(sbuf, "\n");
9472 	sbuf_printf(sbuf, "SW LLDP mode: %d\n", is_sw_lldp);
9473 	sbuf_printf(sbuf, "Function caps maxtcs: %d\n", maxtcs);
9474 	sbuf_printf(sbuf, "dcbx_status: %d\n", dcbx_status);
9475 
9476 	sbuf_printf(sbuf, "numapps: %u\n", dcbcfg->numapps);
9477 	sbuf_printf(sbuf, "CEE TLV status: %u\n", dcbcfg->tlv_status);
9478 	sbuf_printf(sbuf, "pfc_mode: %s\n", (dcbcfg->pfc_mode == ICE_QOS_MODE_DSCP) ?
9479 	    "DSCP" : "VLAN");
9480 	sbuf_printf(sbuf, "dcbx_mode: %s\n",
9481 	    (dcbcfg->dcbx_mode == ICE_DCBX_MODE_IEEE) ? "IEEE" :
9482 	    (dcbcfg->dcbx_mode == ICE_DCBX_MODE_CEE) ? "CEE" :
9483 	    "Unknown");
9484 
9485 	ice_sbuf_print_ets_cfg(sbuf, "etscfg", &dcbcfg->etscfg);
9486 	ice_sbuf_print_ets_cfg(sbuf, "etsrec", &dcbcfg->etsrec);
9487 
9488 	sbuf_printf(sbuf, "pfc.willing: %u\n", dcbcfg->pfc.willing);
9489 	sbuf_printf(sbuf, "pfc.mbc: %u\n", dcbcfg->pfc.mbc);
9490 	sbuf_printf(sbuf, "pfc.pfccap: 0x%0x\n", dcbcfg->pfc.pfccap);
9491 	sbuf_printf(sbuf, "pfc.pfcena: 0x%0x\n", dcbcfg->pfc.pfcena);
9492 
9493 	if (arg2 == ICE_AQ_LLDP_MIB_LOCAL) {
9494 		sbuf_printf(sbuf, "\nLocal registers:\n");
9495 		sbuf_printf(sbuf, "PRTDCB_GENC.NUMTC: %d\n",
9496 		    (rd32(hw, PRTDCB_GENC) & PRTDCB_GENC_NUMTC_M)
9497 		        >> PRTDCB_GENC_NUMTC_S);
9498 		sbuf_printf(sbuf, "PRTDCB_TUP2TC: 0x%0x\n",
9499 		    (rd32(hw, PRTDCB_TUP2TC)));
9500 		sbuf_printf(sbuf, "PRTDCB_RUP2TC: 0x%0x\n",
9501 		    (rd32(hw, PRTDCB_RUP2TC)));
9502 		sbuf_printf(sbuf, "GLDCB_TC2PFC: 0x%0x\n",
9503 		    (rd32(hw, GLDCB_TC2PFC)));
9504 	}
9505 
9506 	/* Finish */
9507 	sbuf_finish(sbuf);
9508 	sbuf_delete(sbuf);
9509 
9510 	return (0);
9511 }
9512 
9513 /**
9514  * ice_sysctl_dump_vsi_cfg - print PF LAN VSI configuration
9515  * @oidp: sysctl oid structure
9516  * @arg1: pointer to private data structure
9517  * @arg2: unused
9518  * @req: sysctl request pointer
9519  *
9520  * XXX: This could be extended to apply to arbitrary PF-owned VSIs,
9521  * but for simplicity, this only works on the PF's LAN VSI.
9522  */
9523 static int
9524 ice_sysctl_dump_vsi_cfg(SYSCTL_HANDLER_ARGS)
9525 {
9526 	struct ice_softc *sc = (struct ice_softc *)arg1;
9527 	struct ice_vsi_ctx ctx = { 0 };
9528 	struct ice_hw *hw = &sc->hw;
9529 	device_t dev = sc->dev;
9530 	struct sbuf *sbuf;
9531 	enum ice_status status;
9532 
9533 	UNREFERENCED_PARAMETER(oidp);
9534 	UNREFERENCED_PARAMETER(arg2);
9535 
9536 	if (ice_driver_is_detaching(sc))
9537 		return (ESHUTDOWN);
9538 
9539 	/* Get HW absolute index of a VSI */
9540 	ctx.vsi_num = ice_get_hw_vsi_num(hw, sc->pf_vsi.idx);
9541 
9542 	status = ice_aq_get_vsi_params(hw, &ctx, NULL);
9543 	if (status != ICE_SUCCESS) {
9544 		device_printf(dev,
9545 		    "Get VSI AQ call failed, err %s aq_err %s\n",
9546 		    ice_status_str(status),
9547 		    ice_aq_str(hw->adminq.sq_last_status));
9548 		return (EIO);
9549 	}
9550 
9551 	sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
9552 
9553 	/* Do the actual printing */
9554 	sbuf_printf(sbuf, "\n");
9555 
9556 	sbuf_printf(sbuf, "VSI NUM: %d\n", ctx.vsi_num);
9557 	sbuf_printf(sbuf, "VF  NUM: %d\n", ctx.vf_num);
9558 	sbuf_printf(sbuf, "VSIs allocated: %d\n", ctx.vsis_allocd);
9559 	sbuf_printf(sbuf, "VSIs unallocated: %d\n", ctx.vsis_unallocated);
9560 
9561 	sbuf_printf(sbuf, "Rx Queue Map method: %d\n",
9562 	    LE16_TO_CPU(ctx.info.mapping_flags));
9563 	/* The PF VSI is always contiguous, so there's no if-statement here */
9564 	sbuf_printf(sbuf, "Rx Queue base: %d\n",
9565 	    LE16_TO_CPU(ctx.info.q_mapping[0]));
9566 	sbuf_printf(sbuf, "Rx Queue count: %d\n",
9567 	    LE16_TO_CPU(ctx.info.q_mapping[1]));
9568 
9569 	sbuf_printf(sbuf, "TC qbases  :");
9570 	for (int i = 0; i < ICE_MAX_TRAFFIC_CLASS; i++) {
9571 		sbuf_printf(sbuf, " %4d",
9572 		    ctx.info.tc_mapping[i] & ICE_AQ_VSI_TC_Q_OFFSET_M);
9573 	}
9574 	sbuf_printf(sbuf, "\n");
9575 
9576 	sbuf_printf(sbuf, "TC qcounts :");
9577 	for (int i = 0; i < ICE_MAX_TRAFFIC_CLASS; i++) {
9578 		sbuf_printf(sbuf, " %4d",
9579 		    1 << (ctx.info.tc_mapping[i] >> ICE_AQ_VSI_TC_Q_NUM_S));
9580 	}
9581 
9582 	/* Finish */
9583 	sbuf_finish(sbuf);
9584 	sbuf_delete(sbuf);
9585 
9586 	return (0);
9587 }
9588 
9589 /**
9590  * ice_ets_str_to_tbl - Parse string into ETS table
9591  * @str: input string to parse
9592  * @table: output eight values used for ETS values
9593  * @limit: max valid value to accept for ETS values
9594  *
9595  * Parses a string and converts the eight values within
9596  * into a table that can be used in setting ETS settings
9597  * in a MIB.
9598  *
9599  * @return 0 on success, EINVAL if a parsed value is
9600  * not between 0 and limit.
9601  */
9602 static int
9603 ice_ets_str_to_tbl(const char *str, u8 *table, u8 limit)
9604 {
9605 	const char *str_start = str;
9606 	char *str_end;
9607 	long token;
9608 
9609 	for (int i = 0; i < ICE_MAX_TRAFFIC_CLASS; i++) {
9610 		token = strtol(str_start, &str_end, 0);
9611 		if (token < 0 || token > limit)
9612 			return (EINVAL);
9613 
9614 		table[i] = (u8)token;
9615 		str_start = (str_end + 1);
9616 	}
9617 
9618 	return (0);
9619 }
9620 
9621 /**
9622  * ice_check_ets_bw - Check if ETS bw vals are valid
9623  * @table: eight values used for ETS bandwidth
9624  *
9625  * @return true if the sum of all 8 values in table
9626  * equals 100.
9627  */
9628 static bool
9629 ice_check_ets_bw(u8 *table)
9630 {
9631 	int sum = 0;
9632 	for (int i = 0; i < ICE_MAX_TRAFFIC_CLASS; i++)
9633 		sum += (int)table[i];
9634 
9635 	return (sum == 100);
9636 }
9637 
9638 /**
9639  * ice_cfg_pba_num - Determine if PBA Number is retrievable
9640  * @sc: the device private softc structure
9641  *
9642  * Sets the feature flag for the existence of a PBA number
9643  * based on the success of the read command.  This does not
9644  * cache the result.
9645  */
9646 void
9647 ice_cfg_pba_num(struct ice_softc *sc)
9648 {
9649 	u8 pba_string[32] = "";
9650 
9651 	if ((ice_is_bit_set(sc->feat_cap, ICE_FEATURE_HAS_PBA)) &&
9652 	    (ice_read_pba_string(&sc->hw, pba_string, sizeof(pba_string)) == 0))
9653 		ice_set_bit(ICE_FEATURE_HAS_PBA, sc->feat_en);
9654 }
9655 
9656 /**
9657  * ice_sysctl_query_port_ets - print Port ETS Config from AQ
9658  * @oidp: sysctl oid structure
9659  * @arg1: pointer to private data structure
9660  * @arg2: unused
9661  * @req: sysctl request pointer
9662  */
9663 static int
9664 ice_sysctl_query_port_ets(SYSCTL_HANDLER_ARGS)
9665 {
9666 	struct ice_softc *sc = (struct ice_softc *)arg1;
9667 	struct ice_aqc_port_ets_elem port_ets = { 0 };
9668 	struct ice_hw *hw = &sc->hw;
9669 	struct ice_port_info *pi;
9670 	device_t dev = sc->dev;
9671 	struct sbuf *sbuf;
9672 	enum ice_status status;
9673 	int i = 0;
9674 
9675 	UNREFERENCED_PARAMETER(oidp);
9676 	UNREFERENCED_PARAMETER(arg2);
9677 
9678 	if (ice_driver_is_detaching(sc))
9679 		return (ESHUTDOWN);
9680 
9681 	pi = hw->port_info;
9682 
9683 	status = ice_aq_query_port_ets(pi, &port_ets, sizeof(port_ets), NULL);
9684 	if (status != ICE_SUCCESS) {
9685 		device_printf(dev,
9686 		    "Query Port ETS AQ call failed, err %s aq_err %s\n",
9687 		    ice_status_str(status),
9688 		    ice_aq_str(hw->adminq.sq_last_status));
9689 		return (EIO);
9690 	}
9691 
9692 	sbuf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
9693 
9694 	/* Do the actual printing */
9695 	sbuf_printf(sbuf, "\n");
9696 
9697 	sbuf_printf(sbuf, "Valid TC map: 0x%x\n", port_ets.tc_valid_bits);
9698 
9699 	sbuf_printf(sbuf, "TC BW %%:");
9700 	ice_for_each_traffic_class(i) {
9701 		sbuf_printf(sbuf, " %3d", port_ets.tc_bw_share[i]);
9702 	}
9703 	sbuf_printf(sbuf, "\n");
9704 
9705 	sbuf_printf(sbuf, "EIR profile ID: %d\n", port_ets.port_eir_prof_id);
9706 	sbuf_printf(sbuf, "CIR profile ID: %d\n", port_ets.port_cir_prof_id);
9707 	sbuf_printf(sbuf, "TC Node prio: 0x%x\n", port_ets.tc_node_prio);
9708 
9709 	sbuf_printf(sbuf, "TC Node TEIDs:\n");
9710 	ice_for_each_traffic_class(i) {
9711 		sbuf_printf(sbuf, "%d: %d\n", i, port_ets.tc_node_teid[i]);
9712 	}
9713 
9714 	/* Finish */
9715 	sbuf_finish(sbuf);
9716 	sbuf_delete(sbuf);
9717 
9718 	return (0);
9719 }
9720