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