The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ice/ice_lib.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: cf3fa7816c4aaafc752552d69fc720cf


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.