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