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