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