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