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