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