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