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/iavf/iavf_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 iavf_lib.c
   35  * @brief library code common to both legacy and iflib
   36  *
   37  * Contains functions common to the iflib and legacy drivers. Includes
   38  * hardware initialization and control functions, as well as sysctl handlers
   39  * for the sysctls which are shared between the legacy and iflib drivers.
   40  */
   41 #include "iavf_iflib.h"
   42 #include "iavf_vc_common.h"
   43 
   44 static void iavf_init_hw(struct iavf_hw *hw, device_t dev);
   45 static u_int iavf_mc_filter_apply(void *arg, struct sockaddr_dl *sdl, u_int cnt);
   46 
   47 /**
   48  * iavf_msec_pause - Pause for at least the specified number of milliseconds
   49  * @msecs: number of milliseconds to pause for
   50  *
   51  * Pause execution of the current thread for a specified number of
   52  * milliseconds. Used to enforce minimum delay times when waiting for various
   53  * hardware events.
   54  */
   55 void
   56 iavf_msec_pause(int msecs)
   57 {
   58         pause("iavf_msec_pause", MSEC_2_TICKS(msecs));
   59 }
   60 
   61 /**
   62  * iavf_get_default_rss_key - Get the default RSS key for this driver
   63  * @key: output parameter to store the key in
   64  *
   65  * Copies the driver's default RSS key into the provided key variable.
   66  *
   67  * @pre assumes that key is not NULL and has at least IAVF_RSS_KEY_SIZE
   68  * storage space.
   69  */
   70 void
   71 iavf_get_default_rss_key(u32 *key)
   72 {
   73         MPASS(key != NULL);
   74 
   75         u32 rss_seed[IAVF_RSS_KEY_SIZE_REG] = {0x41b01687,
   76             0x183cfd8c, 0xce880440, 0x580cbc3c,
   77             0x35897377, 0x328b25e1, 0x4fa98922,
   78             0xb7d90c14, 0xd5bad70d, 0xcd15a2c1,
   79             0x0, 0x0, 0x0};
   80 
   81         bcopy(rss_seed, key, IAVF_RSS_KEY_SIZE);
   82 }
   83 
   84 /**
   85  * iavf_allocate_pci_resources_common - Allocate PCI resources
   86  * @sc: the private device softc pointer
   87  *
   88  * @pre sc->dev is set
   89  *
   90  * Allocates the common PCI resources used by the driver.
   91  *
   92  * @returns zero on success, or an error code on failure.
   93  */
   94 int
   95 iavf_allocate_pci_resources_common(struct iavf_sc *sc)
   96 {
   97         struct iavf_hw *hw = &sc->hw;
   98         device_t dev = sc->dev;
   99         int rid;
  100 
  101         /* Map PCI BAR0 */
  102         rid = PCIR_BAR(0);
  103         sc->pci_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
  104             &rid, RF_ACTIVE);
  105 
  106         if (!(sc->pci_mem)) {
  107                 device_printf(dev, "Unable to allocate bus resource: PCI memory\n");
  108                 return (ENXIO);
  109         }
  110 
  111         iavf_init_hw(hw, dev);
  112 
  113         /* Save off register access information */
  114         sc->osdep.mem_bus_space_tag =
  115                 rman_get_bustag(sc->pci_mem);
  116         sc->osdep.mem_bus_space_handle =
  117                 rman_get_bushandle(sc->pci_mem);
  118         sc->osdep.mem_bus_space_size = rman_get_size(sc->pci_mem);
  119         sc->osdep.flush_reg = IAVF_VFGEN_RSTAT;
  120         sc->osdep.dev = dev;
  121 
  122         sc->hw.hw_addr = (u8 *)&sc->osdep.mem_bus_space_handle;
  123         sc->hw.back = &sc->osdep;
  124 
  125         return (0);
  126 }
  127 
  128 /**
  129  * iavf_init_hw - Initialize the device HW
  130  * @hw: device hardware structure
  131  * @dev: the stack device_t pointer
  132  *
  133  * Attach helper function. Gathers information about the (virtual) hardware
  134  * for use elsewhere in the driver.
  135  */
  136 static void
  137 iavf_init_hw(struct iavf_hw *hw, device_t dev)
  138 {
  139         /* Save off the information about this board */
  140         hw->vendor_id = pci_get_vendor(dev);
  141         hw->device_id = pci_get_device(dev);
  142         hw->revision_id = pci_read_config(dev, PCIR_REVID, 1);
  143         hw->subsystem_vendor_id =
  144             pci_read_config(dev, PCIR_SUBVEND_0, 2);
  145         hw->subsystem_device_id =
  146             pci_read_config(dev, PCIR_SUBDEV_0, 2);
  147 
  148         hw->bus.device = pci_get_slot(dev);
  149         hw->bus.func = pci_get_function(dev);
  150 }
  151 
  152 /**
  153  * iavf_sysctl_current_speed - Sysctl to display the current device speed
  154  * @oidp: syctl oid pointer
  155  * @arg1: pointer to the device softc typecasted to void *
  156  * @arg2: unused sysctl argument
  157  * @req: sysctl request structure
  158  *
  159  * Reads the current speed reported from the physical device into a string for
  160  * display by the current_speed sysctl.
  161  *
  162  * @returns zero or an error code on failure.
  163  */
  164 int
  165 iavf_sysctl_current_speed(SYSCTL_HANDLER_ARGS)
  166 {
  167         struct iavf_sc *sc = (struct iavf_sc *)arg1;
  168         int error = 0;
  169 
  170         UNREFERENCED_PARAMETER(arg2);
  171 
  172         if (iavf_driver_is_detaching(sc))
  173                 return (ESHUTDOWN);
  174 
  175         if (IAVF_CAP_ADV_LINK_SPEED(sc))
  176                 error = sysctl_handle_string(oidp,
  177                   __DECONST(char *, iavf_ext_speed_to_str(iavf_adv_speed_to_ext_speed(sc->link_speed_adv))),
  178                   8, req);
  179         else
  180                 error = sysctl_handle_string(oidp,
  181                   __DECONST(char *, iavf_vc_speed_to_string(sc->link_speed)),
  182                   8, req);
  183 
  184         return (error);
  185 }
  186 
  187 /**
  188  * iavf_reset_complete - Wait for a device reset to complete
  189  * @hw: pointer to the hardware structure
  190  *
  191  * Reads the reset registers and waits until they indicate that a device reset
  192  * is complete.
  193  *
  194  * @pre this function may call pause() and must not be called from a context
  195  * that cannot sleep.
  196  *
  197  * @returns zero on success, or EBUSY if it times out waiting for reset.
  198  */
  199 int
  200 iavf_reset_complete(struct iavf_hw *hw)
  201 {
  202         u32 reg;
  203 
  204         /* Wait up to ~10 seconds */
  205         for (int i = 0; i < 100; i++) {
  206                 reg = rd32(hw, IAVF_VFGEN_RSTAT) &
  207                     IAVF_VFGEN_RSTAT_VFR_STATE_MASK;
  208 
  209                 if ((reg == VIRTCHNL_VFR_VFACTIVE) ||
  210                     (reg == VIRTCHNL_VFR_COMPLETED))
  211                         return (0);
  212                 iavf_msec_pause(100);
  213         }
  214 
  215         return (EBUSY);
  216 }
  217 
  218 /**
  219  * iavf_setup_vc - Setup virtchnl communication
  220  * @sc: device private softc
  221  *
  222  * iavf_attach() helper function. Initializes the admin queue and attempts to
  223  * establish contact with the PF by retrying the initial "API version" message
  224  * several times or until the PF responds.
  225  *
  226  * @returns zero on success, or an error code on failure.
  227  */
  228 int
  229 iavf_setup_vc(struct iavf_sc *sc)
  230 {
  231         struct iavf_hw *hw = &sc->hw;
  232         device_t dev = sc->dev;
  233         int error = 0, ret_error = 0, asq_retries = 0;
  234         bool send_api_ver_retried = 0;
  235 
  236         /* Need to set these AQ parameters before initializing AQ */
  237         hw->aq.num_arq_entries = IAVF_AQ_LEN;
  238         hw->aq.num_asq_entries = IAVF_AQ_LEN;
  239         hw->aq.arq_buf_size = IAVF_AQ_BUF_SZ;
  240         hw->aq.asq_buf_size = IAVF_AQ_BUF_SZ;
  241 
  242         for (int i = 0; i < IAVF_AQ_MAX_ERR; i++) {
  243                 /* Initialize admin queue */
  244                 error = iavf_init_adminq(hw);
  245                 if (error) {
  246                         device_printf(dev, "%s: init_adminq failed: %d\n",
  247                             __func__, error);
  248                         ret_error = 1;
  249                         continue;
  250                 }
  251 
  252                 iavf_dbg_init(sc, "Initialized Admin Queue; starting"
  253                     " send_api_ver attempt %d", i+1);
  254 
  255 retry_send:
  256                 /* Send VF's API version */
  257                 error = iavf_send_api_ver(sc);
  258                 if (error) {
  259                         iavf_shutdown_adminq(hw);
  260                         ret_error = 2;
  261                         device_printf(dev, "%s: unable to send api"
  262                             " version to PF on attempt %d, error %d\n",
  263                             __func__, i+1, error);
  264                 }
  265 
  266                 asq_retries = 0;
  267                 while (!iavf_asq_done(hw)) {
  268                         if (++asq_retries > IAVF_AQ_MAX_ERR) {
  269                                 iavf_shutdown_adminq(hw);
  270                                 device_printf(dev, "Admin Queue timeout "
  271                                     "(waiting for send_api_ver), %d more tries...\n",
  272                                     IAVF_AQ_MAX_ERR - (i + 1));
  273                                 ret_error = 3;
  274                                 break;
  275                         }
  276                         iavf_msec_pause(10);
  277                 }
  278                 if (asq_retries > IAVF_AQ_MAX_ERR)
  279                         continue;
  280 
  281                 iavf_dbg_init(sc, "Sent API version message to PF");
  282 
  283                 /* Verify that the VF accepts the PF's API version */
  284                 error = iavf_verify_api_ver(sc);
  285                 if (error == ETIMEDOUT) {
  286                         if (!send_api_ver_retried) {
  287                                 /* Resend message, one more time */
  288                                 send_api_ver_retried = true;
  289                                 device_printf(dev,
  290                                     "%s: Timeout while verifying API version on first"
  291                                     " try!\n", __func__);
  292                                 goto retry_send;
  293                         } else {
  294                                 device_printf(dev,
  295                                     "%s: Timeout while verifying API version on second"
  296                                     " try!\n", __func__);
  297                                 ret_error = 4;
  298                                 break;
  299                         }
  300                 }
  301                 if (error) {
  302                         device_printf(dev,
  303                             "%s: Unable to verify API version,"
  304                             " error %d\n", __func__, error);
  305                         ret_error = 5;
  306                 }
  307                 break;
  308         }
  309 
  310         if (ret_error >= 4)
  311                 iavf_shutdown_adminq(hw);
  312         return (ret_error);
  313 }
  314 
  315 /**
  316  * iavf_reset - Requests a VF reset from the PF.
  317  * @sc: device private softc
  318  *
  319  * @pre Requires the VF's Admin Queue to be initialized.
  320  * @returns zero on success, or an error code on failure.
  321  */
  322 int
  323 iavf_reset(struct iavf_sc *sc)
  324 {
  325         struct iavf_hw  *hw = &sc->hw;
  326         device_t        dev = sc->dev;
  327         int             error = 0;
  328 
  329         /* Ask the PF to reset us if we are initiating */
  330         if (!iavf_test_state(&sc->state, IAVF_STATE_RESET_PENDING))
  331                 iavf_request_reset(sc);
  332 
  333         iavf_msec_pause(100);
  334         error = iavf_reset_complete(hw);
  335         if (error) {
  336                 device_printf(dev, "%s: VF reset failed\n",
  337                     __func__);
  338                 return (error);
  339         }
  340         pci_enable_busmaster(dev);
  341 
  342         error = iavf_shutdown_adminq(hw);
  343         if (error) {
  344                 device_printf(dev, "%s: shutdown_adminq failed: %d\n",
  345                     __func__, error);
  346                 return (error);
  347         }
  348 
  349         error = iavf_init_adminq(hw);
  350         if (error) {
  351                 device_printf(dev, "%s: init_adminq failed: %d\n",
  352                     __func__, error);
  353                 return (error);
  354         }
  355 
  356         /* IFLIB: This is called only in the iflib driver */
  357         iavf_enable_adminq_irq(hw);
  358         return (0);
  359 }
  360 
  361 /**
  362  * iavf_enable_admin_irq - Enable the administrative interrupt
  363  * @hw: pointer to the hardware structure
  364  *
  365  * Writes to registers to enable the administrative interrupt cause, in order
  366  * to handle non-queue related interrupt events.
  367  */
  368 void
  369 iavf_enable_adminq_irq(struct iavf_hw *hw)
  370 {
  371         wr32(hw, IAVF_VFINT_DYN_CTL01,
  372             IAVF_VFINT_DYN_CTL01_INTENA_MASK |
  373             IAVF_VFINT_DYN_CTL01_CLEARPBA_MASK |
  374             IAVF_VFINT_DYN_CTL01_ITR_INDX_MASK);
  375         wr32(hw, IAVF_VFINT_ICR0_ENA1, IAVF_VFINT_ICR0_ENA1_ADMINQ_MASK);
  376         /* flush */
  377         rd32(hw, IAVF_VFGEN_RSTAT);
  378 }
  379 
  380 /**
  381  * iavf_disable_admin_irq - Disable the administrative interrupt cause
  382  * @hw: pointer to the hardware structure
  383  *
  384  * Writes to registers to disable the administrative interrupt cause.
  385  */
  386 void
  387 iavf_disable_adminq_irq(struct iavf_hw *hw)
  388 {
  389         wr32(hw, IAVF_VFINT_DYN_CTL01, 0);
  390         wr32(hw, IAVF_VFINT_ICR0_ENA1, 0);
  391         iavf_flush(hw);
  392 }
  393 
  394 /**
  395  * iavf_vf_config - Configure this VF over the virtchnl
  396  * @sc: device private softc
  397  *
  398  * iavf_attach() helper function. Asks the PF for this VF's configuration, and
  399  * saves the information if it receives it.
  400  *
  401  * @returns zero on success, or an error code on failure.
  402  */
  403 int
  404 iavf_vf_config(struct iavf_sc *sc)
  405 {
  406         struct iavf_hw *hw = &sc->hw;
  407         device_t dev = sc->dev;
  408         int bufsz, error = 0, ret_error = 0;
  409         int asq_retries, retried = 0;
  410 
  411 retry_config:
  412         error = iavf_send_vf_config_msg(sc);
  413         if (error) {
  414                 device_printf(dev,
  415                     "%s: Unable to send VF config request, attempt %d,"
  416                     " error %d\n", __func__, retried + 1, error);
  417                 ret_error = 2;
  418         }
  419 
  420         asq_retries = 0;
  421         while (!iavf_asq_done(hw)) {
  422                 if (++asq_retries > IAVF_AQ_MAX_ERR) {
  423                         device_printf(dev, "%s: Admin Queue timeout "
  424                             "(waiting for send_vf_config_msg), attempt %d\n",
  425                             __func__, retried + 1);
  426                         ret_error = 3;
  427                         goto fail;
  428                 }
  429                 iavf_msec_pause(10);
  430         }
  431 
  432         iavf_dbg_init(sc, "Sent VF config message to PF, attempt %d\n",
  433             retried + 1);
  434 
  435         if (!sc->vf_res) {
  436                 bufsz = sizeof(struct virtchnl_vf_resource) +
  437                     (IAVF_MAX_VF_VSI * sizeof(struct virtchnl_vsi_resource));
  438                 sc->vf_res = (struct virtchnl_vf_resource *)malloc(bufsz, M_IAVF, M_NOWAIT);
  439                 if (!sc->vf_res) {
  440                         device_printf(dev,
  441                             "%s: Unable to allocate memory for VF configuration"
  442                             " message from PF on attempt %d\n", __func__, retried + 1);
  443                         ret_error = 1;
  444                         goto fail;
  445                 }
  446         }
  447 
  448         /* Check for VF config response */
  449         error = iavf_get_vf_config(sc);
  450         if (error == ETIMEDOUT) {
  451                 /* The 1st time we timeout, send the configuration message again */
  452                 if (!retried) {
  453                         retried++;
  454                         goto retry_config;
  455                 }
  456                 device_printf(dev,
  457                     "%s: iavf_get_vf_config() timed out waiting for a response\n",
  458                     __func__);
  459         }
  460         if (error) {
  461                 device_printf(dev,
  462                     "%s: Unable to get VF configuration from PF after %d tries!\n",
  463                     __func__, retried + 1);
  464                 ret_error = 4;
  465         }
  466         goto done;
  467 
  468 fail:
  469         free(sc->vf_res, M_IAVF);
  470 done:
  471         return (ret_error);
  472 }
  473 
  474 /**
  475  * iavf_print_device_info - Print some device parameters at attach
  476  * @sc: device private softc
  477  *
  478  * Log a message about this virtual device's capabilities at attach time.
  479  */
  480 void
  481 iavf_print_device_info(struct iavf_sc *sc)
  482 {
  483         device_t dev = sc->dev;
  484 
  485         device_printf(dev,
  486             "VSIs %d, QPs %d, MSI-X %d, RSS sizes: key %d lut %d\n",
  487             sc->vf_res->num_vsis,
  488             sc->vf_res->num_queue_pairs,
  489             sc->vf_res->max_vectors,
  490             sc->vf_res->rss_key_size,
  491             sc->vf_res->rss_lut_size);
  492         iavf_dbg_info(sc, "Capabilities=%b\n",
  493             sc->vf_res->vf_cap_flags, IAVF_PRINTF_VF_OFFLOAD_FLAGS);
  494 }
  495 
  496 /**
  497  * iavf_get_vsi_res_from_vf_res - Get VSI parameters and info for this VF
  498  * @sc: device private softc
  499  *
  500  * Get the VSI parameters and information from the general VF resource info
  501  * received by the physical device.
  502  *
  503  * @returns zero on success, or an error code on failure.
  504  */
  505 int
  506 iavf_get_vsi_res_from_vf_res(struct iavf_sc *sc)
  507 {
  508         struct iavf_vsi *vsi = &sc->vsi;
  509         device_t dev = sc->dev;
  510 
  511         sc->vsi_res = NULL;
  512 
  513         for (int i = 0; i < sc->vf_res->num_vsis; i++) {
  514                 /* XXX: We only use the first VSI we find */
  515                 if (sc->vf_res->vsi_res[i].vsi_type == IAVF_VSI_SRIOV)
  516                         sc->vsi_res = &sc->vf_res->vsi_res[i];
  517         }
  518         if (!sc->vsi_res) {
  519                 device_printf(dev, "%s: no LAN VSI found\n", __func__);
  520                 return (EIO);
  521         }
  522 
  523         vsi->id = sc->vsi_res->vsi_id;
  524         return (0);
  525 }
  526 
  527 /**
  528  * iavf_set_mac_addresses - Set the MAC address for this interface
  529  * @sc: device private softc
  530  *
  531  * Set the permanent MAC address field in the HW structure. If a MAC address
  532  * has not yet been set for this device by the physical function, generate one
  533  * randomly.
  534  */
  535 void
  536 iavf_set_mac_addresses(struct iavf_sc *sc)
  537 {
  538         struct iavf_hw *hw = &sc->hw;
  539         device_t dev = sc->dev;
  540         u8 addr[ETHER_ADDR_LEN];
  541 
  542         /* If no mac address was assigned just make a random one */
  543         if (ETHER_IS_ZERO(hw->mac.addr)) {
  544                 arc4rand(&addr, sizeof(addr), 0);
  545                 addr[0] &= 0xFE;
  546                 addr[0] |= 0x02;
  547                 memcpy(hw->mac.addr, addr, sizeof(addr));
  548                 device_printf(dev, "Generated random MAC address\n");
  549         }
  550         memcpy(hw->mac.perm_addr, hw->mac.addr, ETHER_ADDR_LEN);
  551 }
  552 
  553 /**
  554  * iavf_init_filters - Initialize filter structures
  555  * @sc: device private softc
  556  *
  557  * Initialize the MAC and VLAN filter list heads.
  558  *
  559  * @remark this is intended to be called only once during the device attach
  560  * process.
  561  *
  562  * @pre Because it uses M_WAITOK, this function should only be called in
  563  * a context that is safe to sleep.
  564  */
  565 void
  566 iavf_init_filters(struct iavf_sc *sc)
  567 {
  568         sc->mac_filters = (struct mac_list *)malloc(sizeof(struct iavf_mac_filter),
  569             M_IAVF, M_WAITOK | M_ZERO);
  570         SLIST_INIT(sc->mac_filters);
  571         sc->vlan_filters = (struct vlan_list *)malloc(sizeof(struct iavf_vlan_filter),
  572             M_IAVF, M_WAITOK | M_ZERO);
  573         SLIST_INIT(sc->vlan_filters);
  574 }
  575 
  576 /**
  577  * iavf_free_filters - Release filter lists
  578  * @sc: device private softc
  579  *
  580  * Free the MAC and VLAN filter lists.
  581  *
  582  * @remark this is intended to be called only once during the device detach
  583  * process.
  584  */
  585 void
  586 iavf_free_filters(struct iavf_sc *sc)
  587 {
  588         struct iavf_mac_filter *f;
  589         struct iavf_vlan_filter *v;
  590 
  591         while (!SLIST_EMPTY(sc->mac_filters)) {
  592                 f = SLIST_FIRST(sc->mac_filters);
  593                 SLIST_REMOVE_HEAD(sc->mac_filters, next);
  594                 free(f, M_IAVF);
  595         }
  596         free(sc->mac_filters, M_IAVF);
  597         while (!SLIST_EMPTY(sc->vlan_filters)) {
  598                 v = SLIST_FIRST(sc->vlan_filters);
  599                 SLIST_REMOVE_HEAD(sc->vlan_filters, next);
  600                 free(v, M_IAVF);
  601         }
  602         free(sc->vlan_filters, M_IAVF);
  603 }
  604 
  605 /**
  606  * iavf_add_device_sysctls_common - Initialize common device sysctls
  607  * @sc: device private softc
  608  *
  609  * Setup sysctls common to both the iflib and legacy drivers.
  610  */
  611 void
  612 iavf_add_device_sysctls_common(struct iavf_sc *sc)
  613 {
  614         device_t dev = sc->dev;
  615         struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
  616         struct sysctl_oid_list *ctx_list =
  617             SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
  618 
  619         SYSCTL_ADD_PROC(ctx, ctx_list,
  620             OID_AUTO, "current_speed", CTLTYPE_STRING | CTLFLAG_RD,
  621             sc, 0, iavf_sysctl_current_speed, "A", "Current Port Speed");
  622 
  623         SYSCTL_ADD_PROC(ctx, ctx_list,
  624             OID_AUTO, "tx_itr", CTLTYPE_INT | CTLFLAG_RW,
  625             sc, 0, iavf_sysctl_tx_itr, "I",
  626             "Immediately set TX ITR value for all queues");
  627 
  628         SYSCTL_ADD_PROC(ctx, ctx_list,
  629             OID_AUTO, "rx_itr", CTLTYPE_INT | CTLFLAG_RW,
  630             sc, 0, iavf_sysctl_rx_itr, "I",
  631             "Immediately set RX ITR value for all queues");
  632 
  633         SYSCTL_ADD_UQUAD(ctx, ctx_list,
  634             OID_AUTO, "admin_irq", CTLFLAG_RD,
  635             &sc->admin_irq, "Admin Queue IRQ Handled");
  636 }
  637 
  638 /**
  639  * iavf_add_debug_sysctls_common - Initialize common debug sysctls
  640  * @sc: device private softc
  641  * @debug_list: pionter to debug sysctl node
  642  *
  643  * Setup sysctls used for debugging the device driver into the debug sysctl
  644  * node.
  645  */
  646 void
  647 iavf_add_debug_sysctls_common(struct iavf_sc *sc, struct sysctl_oid_list *debug_list)
  648 {
  649         device_t dev = sc->dev;
  650         struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
  651 
  652         SYSCTL_ADD_UINT(ctx, debug_list,
  653             OID_AUTO, "shared_debug_mask", CTLFLAG_RW,
  654             &sc->hw.debug_mask, 0, "Shared code debug message level");
  655 
  656         SYSCTL_ADD_UINT(ctx, debug_list,
  657             OID_AUTO, "core_debug_mask", CTLFLAG_RW,
  658             (unsigned int *)&sc->dbg_mask, 0, "Non-shared code debug message level");
  659 
  660         SYSCTL_ADD_PROC(ctx, debug_list,
  661             OID_AUTO, "filter_list", CTLTYPE_STRING | CTLFLAG_RD,
  662             sc, 0, iavf_sysctl_sw_filter_list, "A", "SW Filter List");
  663 }
  664 
  665 /**
  666  * iavf_sysctl_tx_itr - Sysctl to set the Tx ITR value
  667  * @oidp: sysctl oid pointer
  668  * @arg1: pointer to the device softc
  669  * @arg2: unused sysctl argument
  670  * @req: sysctl req pointer
  671  *
  672  * On read, returns the Tx ITR value for all of the VF queues. On write,
  673  * update the Tx ITR registers with the new Tx ITR value.
  674  *
  675  * @returns zero on success, or an error code on failure.
  676  */
  677 int
  678 iavf_sysctl_tx_itr(SYSCTL_HANDLER_ARGS)
  679 {
  680         struct iavf_sc *sc = (struct iavf_sc *)arg1;
  681         device_t dev = sc->dev;
  682         int requested_tx_itr;
  683         int error = 0;
  684 
  685         UNREFERENCED_PARAMETER(arg2);
  686 
  687         if (iavf_driver_is_detaching(sc))
  688                 return (ESHUTDOWN);
  689 
  690         requested_tx_itr = sc->tx_itr;
  691         error = sysctl_handle_int(oidp, &requested_tx_itr, 0, req);
  692         if ((error) || (req->newptr == NULL))
  693                 return (error);
  694         if (requested_tx_itr < 0 || requested_tx_itr > IAVF_MAX_ITR) {
  695                 device_printf(dev,
  696                     "Invalid TX itr value; value must be between 0 and %d\n",
  697                         IAVF_MAX_ITR);
  698                 return (EINVAL);
  699         }
  700 
  701         sc->tx_itr = requested_tx_itr;
  702         iavf_configure_tx_itr(sc);
  703 
  704         return (error);
  705 }
  706 
  707 /**
  708  * iavf_sysctl_rx_itr - Sysctl to set the Rx ITR value
  709  * @oidp: sysctl oid pointer
  710  * @arg1: pointer to the device softc
  711  * @arg2: unused sysctl argument
  712  * @req: sysctl req pointer
  713  *
  714  * On read, returns the Rx ITR value for all of the VF queues. On write,
  715  * update the ITR registers with the new Rx ITR value.
  716  *
  717  * @returns zero on success, or an error code on failure.
  718  */
  719 int
  720 iavf_sysctl_rx_itr(SYSCTL_HANDLER_ARGS)
  721 {
  722         struct iavf_sc *sc = (struct iavf_sc *)arg1;
  723         device_t dev = sc->dev;
  724         int requested_rx_itr;
  725         int error = 0;
  726 
  727         UNREFERENCED_PARAMETER(arg2);
  728 
  729         if (iavf_driver_is_detaching(sc))
  730                 return (ESHUTDOWN);
  731 
  732         requested_rx_itr = sc->rx_itr;
  733         error = sysctl_handle_int(oidp, &requested_rx_itr, 0, req);
  734         if ((error) || (req->newptr == NULL))
  735                 return (error);
  736         if (requested_rx_itr < 0 || requested_rx_itr > IAVF_MAX_ITR) {
  737                 device_printf(dev,
  738                     "Invalid RX itr value; value must be between 0 and %d\n",
  739                         IAVF_MAX_ITR);
  740                 return (EINVAL);
  741         }
  742 
  743         sc->rx_itr = requested_rx_itr;
  744         iavf_configure_rx_itr(sc);
  745 
  746         return (error);
  747 }
  748 
  749 /**
  750  * iavf_configure_tx_itr - Configure the Tx ITR
  751  * @sc: device private softc
  752  *
  753  * Updates the ITR registers with a new Tx ITR setting.
  754  */
  755 void
  756 iavf_configure_tx_itr(struct iavf_sc *sc)
  757 {
  758         struct iavf_hw          *hw = &sc->hw;
  759         struct iavf_vsi         *vsi = &sc->vsi;
  760         struct iavf_tx_queue    *que = vsi->tx_queues;
  761 
  762         vsi->tx_itr_setting = sc->tx_itr;
  763 
  764         for (int i = 0; i < IAVF_NTXQS(vsi); i++, que++) {
  765                 struct tx_ring  *txr = &que->txr;
  766 
  767                 wr32(hw, IAVF_VFINT_ITRN1(IAVF_TX_ITR, i),
  768                     vsi->tx_itr_setting);
  769                 txr->itr = vsi->tx_itr_setting;
  770                 txr->latency = IAVF_AVE_LATENCY;
  771         }
  772 }
  773 
  774 /**
  775  * iavf_configure_rx_itr - Configure the Rx ITR
  776  * @sc: device private softc
  777  *
  778  * Updates the ITR registers with a new Rx ITR setting.
  779  */
  780 void
  781 iavf_configure_rx_itr(struct iavf_sc *sc)
  782 {
  783         struct iavf_hw          *hw = &sc->hw;
  784         struct iavf_vsi         *vsi = &sc->vsi;
  785         struct iavf_rx_queue    *que = vsi->rx_queues;
  786 
  787         vsi->rx_itr_setting = sc->rx_itr;
  788 
  789         for (int i = 0; i < IAVF_NRXQS(vsi); i++, que++) {
  790                 struct rx_ring  *rxr = &que->rxr;
  791 
  792                 wr32(hw, IAVF_VFINT_ITRN1(IAVF_RX_ITR, i),
  793                     vsi->rx_itr_setting);
  794                 rxr->itr = vsi->rx_itr_setting;
  795                 rxr->latency = IAVF_AVE_LATENCY;
  796         }
  797 }
  798 
  799 /**
  800  * iavf_create_debug_sysctl_tree - Create a debug sysctl node
  801  * @sc: device private softc
  802  *
  803  * Create a sysctl node meant to hold sysctls used to print debug information.
  804  * Mark it as CTLFLAG_SKIP so that these sysctls do not show up in the
  805  * "sysctl -a" output.
  806  *
  807  * @returns a pointer to the created sysctl node.
  808  */
  809 struct sysctl_oid_list *
  810 iavf_create_debug_sysctl_tree(struct iavf_sc *sc)
  811 {
  812         device_t dev = sc->dev;
  813         struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(dev);
  814         struct sysctl_oid_list *ctx_list =
  815             SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
  816         struct sysctl_oid *debug_node;
  817 
  818         debug_node = SYSCTL_ADD_NODE(ctx, ctx_list,
  819             OID_AUTO, "debug", CTLFLAG_RD | CTLFLAG_SKIP, NULL, "Debug Sysctls");
  820 
  821         return (SYSCTL_CHILDREN(debug_node));
  822 }
  823 
  824 /**
  825  * iavf_add_vsi_sysctls - Add sysctls for a given VSI
  826  * @dev: device pointer
  827  * @vsi: pointer to the VSI
  828  * @ctx: sysctl context to add to
  829  * @sysctl_name: name of the sysctl node (containing the VSI number)
  830  *
  831  * Adds a new sysctl node for holding specific sysctls for the given VSI.
  832  */
  833 void
  834 iavf_add_vsi_sysctls(device_t dev, struct iavf_vsi *vsi,
  835     struct sysctl_ctx_list *ctx, const char *sysctl_name)
  836 {
  837         struct sysctl_oid *tree;
  838         struct sysctl_oid_list *child;
  839         struct sysctl_oid_list *vsi_list;
  840 
  841         tree = device_get_sysctl_tree(dev);
  842         child = SYSCTL_CHILDREN(tree);
  843         vsi->vsi_node = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, sysctl_name,
  844                                    CTLFLAG_RD, NULL, "VSI Number");
  845         vsi_list = SYSCTL_CHILDREN(vsi->vsi_node);
  846 
  847         iavf_add_sysctls_eth_stats(ctx, vsi_list, &vsi->eth_stats);
  848 }
  849 
  850 /**
  851  * iavf_sysctl_sw_filter_list - Dump software filters
  852  * @oidp: sysctl oid pointer
  853  * @arg1: pointer to the device softc
  854  * @arg2: unused sysctl argument
  855  * @req: sysctl req pointer
  856  *
  857  * On read, generates a string which lists the MAC and VLAN filters added to
  858  * this virtual device. Useful for debugging to see whether or not the
  859  * expected filters have been configured by software.
  860  *
  861  * @returns zero on success, or an error code on failure.
  862  */
  863 int
  864 iavf_sysctl_sw_filter_list(SYSCTL_HANDLER_ARGS)
  865 {
  866         struct iavf_sc *sc = (struct iavf_sc *)arg1;
  867         struct iavf_mac_filter *f;
  868         struct iavf_vlan_filter *v;
  869         device_t dev = sc->dev;
  870         int ftl_len, ftl_counter = 0, error = 0;
  871         struct sbuf *buf;
  872 
  873         UNREFERENCED_2PARAMETER(arg2, oidp);
  874 
  875         if (iavf_driver_is_detaching(sc))
  876                 return (ESHUTDOWN);
  877 
  878         buf = sbuf_new_for_sysctl(NULL, NULL, 128, req);
  879         if (!buf) {
  880                 device_printf(dev, "Could not allocate sbuf for output.\n");
  881                 return (ENOMEM);
  882         }
  883 
  884         sbuf_printf(buf, "\n");
  885 
  886         /* Print MAC filters */
  887         sbuf_printf(buf, "MAC Filters:\n");
  888         ftl_len = 0;
  889         SLIST_FOREACH(f, sc->mac_filters, next)
  890                 ftl_len++;
  891         if (ftl_len < 1)
  892                 sbuf_printf(buf, "(none)\n");
  893         else {
  894                 SLIST_FOREACH(f, sc->mac_filters, next) {
  895                         sbuf_printf(buf,
  896                             MAC_FORMAT ", flags %#06x\n",
  897                             MAC_FORMAT_ARGS(f->macaddr), f->flags);
  898                 }
  899         }
  900 
  901         /* Print VLAN filters */
  902         sbuf_printf(buf, "VLAN Filters:\n");
  903         ftl_len = 0;
  904         SLIST_FOREACH(v, sc->vlan_filters, next)
  905                 ftl_len++;
  906         if (ftl_len < 1)
  907                 sbuf_printf(buf, "(none)");
  908         else {
  909                 SLIST_FOREACH(v, sc->vlan_filters, next) {
  910                         sbuf_printf(buf,
  911                             "%d, flags %#06x",
  912                             v->vlan, v->flags);
  913                         /* don't print '\n' for last entry */
  914                         if (++ftl_counter != ftl_len)
  915                                 sbuf_printf(buf, "\n");
  916                 }
  917         }
  918 
  919         error = sbuf_finish(buf);
  920         if (error)
  921                 device_printf(dev, "Error finishing sbuf: %d\n", error);
  922 
  923         sbuf_delete(buf);
  924         return (error);
  925 }
  926 
  927 /**
  928  * iavf_media_status_common - Get media status for this device
  929  * @sc: device softc pointer
  930  * @ifmr: ifmedia request structure
  931  *
  932  * Report the media status for this device into the given ifmr structure.
  933  */
  934 void
  935 iavf_media_status_common(struct iavf_sc *sc, struct ifmediareq *ifmr)
  936 {
  937         enum iavf_ext_link_speed ext_speed;
  938 
  939         iavf_update_link_status(sc);
  940 
  941         ifmr->ifm_status = IFM_AVALID;
  942         ifmr->ifm_active = IFM_ETHER;
  943 
  944         if (!sc->link_up)
  945                 return;
  946 
  947         ifmr->ifm_status |= IFM_ACTIVE;
  948         /* Hardware is always full-duplex */
  949         ifmr->ifm_active |= IFM_FDX;
  950 
  951         /* Based on the link speed reported by the PF over the AdminQ, choose a
  952          * PHY type to report. This isn't 100% correct since we don't really
  953          * know the underlying PHY type of the PF, but at least we can report
  954          * a valid link speed...
  955          */
  956         if (IAVF_CAP_ADV_LINK_SPEED(sc))
  957                 ext_speed = iavf_adv_speed_to_ext_speed(sc->link_speed_adv);
  958         else
  959                 ext_speed = iavf_vc_speed_to_ext_speed(sc->link_speed);
  960 
  961         ifmr->ifm_active |= iavf_ext_speed_to_ifmedia(ext_speed);
  962 }
  963 
  964 /**
  965  * iavf_media_change_common - Change the media type for this device
  966  * @ifp: ifnet structure
  967  *
  968  * @returns ENODEV because changing the media and speed is not supported.
  969  */
  970 int
  971 iavf_media_change_common(if_t ifp)
  972 {
  973         if_printf(ifp, "Changing speed is not supported\n");
  974 
  975         return (ENODEV);
  976 }
  977 
  978 /**
  979  * iavf_set_initial_baudrate - Set the initial device baudrate
  980  * @ifp: ifnet structure
  981  *
  982  * Set the baudrate for this ifnet structure to the expected initial value of
  983  * 40Gbps. This maybe updated to a lower baudrate after the physical function
  984  * reports speed to us over the virtchnl interface.
  985  */
  986 void
  987 iavf_set_initial_baudrate(if_t ifp)
  988 {
  989 #if __FreeBSD_version >= 1100000
  990         if_setbaudrate(ifp, IF_Gbps(40));
  991 #else
  992         if_initbaudrate(ifp, IF_Gbps(40));
  993 #endif
  994 }
  995 
  996 /**
  997  * iavf_add_sysctls_eth_stats - Add ethernet statistics sysctls
  998  * @ctx: the sysctl ctx to add to
  999  * @child: the node to add the sysctls to
 1000  * @eth_stats: ethernet stats structure
 1001  *
 1002  * Creates sysctls that report the values of the provided ethernet stats
 1003  * structure.
 1004  */
 1005 void
 1006 iavf_add_sysctls_eth_stats(struct sysctl_ctx_list *ctx,
 1007         struct sysctl_oid_list *child,
 1008         struct iavf_eth_stats *eth_stats)
 1009 {
 1010         struct iavf_sysctl_info ctls[] =
 1011         {
 1012                 {&eth_stats->rx_bytes, "good_octets_rcvd", "Good Octets Received"},
 1013                 {&eth_stats->rx_unicast, "ucast_pkts_rcvd",
 1014                         "Unicast Packets Received"},
 1015                 {&eth_stats->rx_multicast, "mcast_pkts_rcvd",
 1016                         "Multicast Packets Received"},
 1017                 {&eth_stats->rx_broadcast, "bcast_pkts_rcvd",
 1018                         "Broadcast Packets Received"},
 1019                 {&eth_stats->rx_discards, "rx_discards", "Discarded RX packets"},
 1020                 {&eth_stats->rx_unknown_protocol, "rx_unknown_proto",
 1021                         "RX unknown protocol packets"},
 1022                 {&eth_stats->tx_bytes, "good_octets_txd", "Good Octets Transmitted"},
 1023                 {&eth_stats->tx_unicast, "ucast_pkts_txd", "Unicast Packets Transmitted"},
 1024                 {&eth_stats->tx_multicast, "mcast_pkts_txd",
 1025                         "Multicast Packets Transmitted"},
 1026                 {&eth_stats->tx_broadcast, "bcast_pkts_txd",
 1027                         "Broadcast Packets Transmitted"},
 1028                 {&eth_stats->tx_errors, "tx_errors", "TX packet errors"},
 1029                 // end
 1030                 {0,0,0}
 1031         };
 1032 
 1033         struct iavf_sysctl_info *entry = ctls;
 1034 
 1035         while (entry->stat != 0)
 1036         {
 1037                 SYSCTL_ADD_UQUAD(ctx, child, OID_AUTO, entry->name,
 1038                                 CTLFLAG_RD, entry->stat,
 1039                                 entry->description);
 1040                 entry++;
 1041         }
 1042 }
 1043 
 1044 /**
 1045  * iavf_max_vc_speed_to_value - Convert link speed to IF speed value
 1046  * @link_speeds: bitmap of supported link speeds
 1047  *
 1048  * @returns the link speed value for the highest speed reported in the
 1049  * link_speeds bitmap.
 1050  */
 1051 u64
 1052 iavf_max_vc_speed_to_value(u8 link_speeds)
 1053 {
 1054         if (link_speeds & VIRTCHNL_LINK_SPEED_40GB)
 1055                 return IF_Gbps(40);
 1056         if (link_speeds & VIRTCHNL_LINK_SPEED_25GB)
 1057                 return IF_Gbps(25);
 1058         if (link_speeds & VIRTCHNL_LINK_SPEED_20GB)
 1059                 return IF_Gbps(20);
 1060         if (link_speeds & VIRTCHNL_LINK_SPEED_10GB)
 1061                 return IF_Gbps(10);
 1062         if (link_speeds & VIRTCHNL_LINK_SPEED_1GB)
 1063                 return IF_Gbps(1);
 1064         if (link_speeds & VIRTCHNL_LINK_SPEED_100MB)
 1065                 return IF_Mbps(100);
 1066         else
 1067                 /* Minimum supported link speed */
 1068                 return IF_Mbps(100);
 1069 }
 1070 
 1071 /**
 1072  * iavf_config_rss_reg - Configure RSS using registers
 1073  * @sc: device private softc
 1074  *
 1075  * Configures RSS for this function using the device registers. Called if the
 1076  * PF does not support configuring RSS over the virtchnl interface.
 1077  */
 1078 void
 1079 iavf_config_rss_reg(struct iavf_sc *sc)
 1080 {
 1081         struct iavf_hw  *hw = &sc->hw;
 1082         struct iavf_vsi *vsi = &sc->vsi;
 1083         u32             lut = 0;
 1084         u64             set_hena = 0, hena;
 1085         int             i, j, que_id;
 1086         u32             rss_seed[IAVF_RSS_KEY_SIZE_REG];
 1087 #ifdef RSS
 1088         u32             rss_hash_config;
 1089 #endif
 1090 
 1091         /* Don't set up RSS if using a single queue */
 1092         if (IAVF_NRXQS(vsi) == 1) {
 1093                 wr32(hw, IAVF_VFQF_HENA(0), 0);
 1094                 wr32(hw, IAVF_VFQF_HENA(1), 0);
 1095                 iavf_flush(hw);
 1096                 return;
 1097         }
 1098 
 1099 #ifdef RSS
 1100         /* Fetch the configured RSS key */
 1101         rss_getkey((uint8_t *) &rss_seed);
 1102 #else
 1103         iavf_get_default_rss_key(rss_seed);
 1104 #endif
 1105 
 1106         /* Fill out hash function seed */
 1107         for (i = 0; i < IAVF_RSS_KEY_SIZE_REG; i++)
 1108                 wr32(hw, IAVF_VFQF_HKEY(i), rss_seed[i]);
 1109 
 1110         /* Enable PCTYPES for RSS: */
 1111 #ifdef RSS
 1112         rss_hash_config = rss_gethashconfig();
 1113         if (rss_hash_config & RSS_HASHTYPE_RSS_IPV4)
 1114                 set_hena |= ((u64)1 << IAVF_FILTER_PCTYPE_NONF_IPV4_OTHER);
 1115         if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV4)
 1116                 set_hena |= ((u64)1 << IAVF_FILTER_PCTYPE_NONF_IPV4_TCP);
 1117         if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV4)
 1118                 set_hena |= ((u64)1 << IAVF_FILTER_PCTYPE_NONF_IPV4_UDP);
 1119         if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6)
 1120                 set_hena |= ((u64)1 << IAVF_FILTER_PCTYPE_NONF_IPV6_OTHER);
 1121         if (rss_hash_config & RSS_HASHTYPE_RSS_IPV6_EX)
 1122                 set_hena |= ((u64)1 << IAVF_FILTER_PCTYPE_FRAG_IPV6);
 1123         if (rss_hash_config & RSS_HASHTYPE_RSS_TCP_IPV6)
 1124                 set_hena |= ((u64)1 << IAVF_FILTER_PCTYPE_NONF_IPV6_TCP);
 1125         if (rss_hash_config & RSS_HASHTYPE_RSS_UDP_IPV6)
 1126                 set_hena |= ((u64)1 << IAVF_FILTER_PCTYPE_NONF_IPV6_UDP);
 1127 #else
 1128         set_hena = IAVF_DEFAULT_RSS_HENA_XL710;
 1129 #endif
 1130         hena = (u64)rd32(hw, IAVF_VFQF_HENA(0)) |
 1131             ((u64)rd32(hw, IAVF_VFQF_HENA(1)) << 32);
 1132         hena |= set_hena;
 1133         wr32(hw, IAVF_VFQF_HENA(0), (u32)hena);
 1134         wr32(hw, IAVF_VFQF_HENA(1), (u32)(hena >> 32));
 1135 
 1136         /* Populate the LUT with max no. of queues in round robin fashion */
 1137         for (i = 0, j = 0; i < IAVF_RSS_VSI_LUT_SIZE; i++, j++) {
 1138                 if (j == IAVF_NRXQS(vsi))
 1139                         j = 0;
 1140 #ifdef RSS
 1141                 /*
 1142                  * Fetch the RSS bucket id for the given indirection entry.
 1143                  * Cap it at the number of configured buckets (which is
 1144                  * num_rx_queues.)
 1145                  */
 1146                 que_id = rss_get_indirection_to_bucket(i);
 1147                 que_id = que_id % IAVF_NRXQS(vsi);
 1148 #else
 1149                 que_id = j;
 1150 #endif
 1151                 /* lut = 4-byte sliding window of 4 lut entries */
 1152                 lut = (lut << 8) | (que_id & IAVF_RSS_VF_LUT_ENTRY_MASK);
 1153                 /* On i = 3, we have 4 entries in lut; write to the register */
 1154                 if ((i & 3) == 3) {
 1155                         wr32(hw, IAVF_VFQF_HLUT(i >> 2), lut);
 1156                         iavf_dbg_rss(sc, "%s: HLUT(%2d): %#010x", __func__,
 1157                             i, lut);
 1158                 }
 1159         }
 1160         iavf_flush(hw);
 1161 }
 1162 
 1163 /**
 1164  * iavf_config_rss_pf - Configure RSS using PF virtchnl messages
 1165  * @sc: device private softc
 1166  *
 1167  * Configure RSS by sending virtchnl messages to the PF.
 1168  */
 1169 void
 1170 iavf_config_rss_pf(struct iavf_sc *sc)
 1171 {
 1172         iavf_send_vc_msg(sc, IAVF_FLAG_AQ_CONFIG_RSS_KEY);
 1173 
 1174         iavf_send_vc_msg(sc, IAVF_FLAG_AQ_SET_RSS_HENA);
 1175 
 1176         iavf_send_vc_msg(sc, IAVF_FLAG_AQ_CONFIG_RSS_LUT);
 1177 }
 1178 
 1179 /**
 1180  * iavf_config_rss - setup RSS
 1181  * @sc: device private softc
 1182  *
 1183  * Configures RSS using the method determined by capability flags in the VF
 1184  * resources structure sent from the PF over the virtchnl interface.
 1185  *
 1186  * @remark RSS keys and table are cleared on VF reset.
 1187  */
 1188 void
 1189 iavf_config_rss(struct iavf_sc *sc)
 1190 {
 1191         if (sc->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_REG) {
 1192                 iavf_dbg_info(sc, "Setting up RSS using VF registers...\n");
 1193                 iavf_config_rss_reg(sc);
 1194         } else if (sc->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF) {
 1195                 iavf_dbg_info(sc, "Setting up RSS using messages to PF...\n");
 1196                 iavf_config_rss_pf(sc);
 1197         } else
 1198                 device_printf(sc->dev, "VF does not support RSS capability sent by PF.\n");
 1199 }
 1200 
 1201 /**
 1202  * iavf_config_promisc - setup promiscuous mode
 1203  * @sc: device private softc
 1204  * @flags: promiscuous flags to configure
 1205  *
 1206  * Request that promiscuous modes be enabled from the PF
 1207  *
 1208  * @returns zero on success, or an error code on failure.
 1209  */
 1210 int
 1211 iavf_config_promisc(struct iavf_sc *sc, int flags)
 1212 {
 1213         if_t ifp = sc->vsi.ifp;
 1214 
 1215         sc->promisc_flags = 0;
 1216 
 1217         if (flags & IFF_ALLMULTI ||
 1218                 if_llmaddr_count(ifp) == MAX_MULTICAST_ADDR)
 1219                 sc->promisc_flags |= FLAG_VF_MULTICAST_PROMISC;
 1220         if (flags & IFF_PROMISC)
 1221                 sc->promisc_flags |= FLAG_VF_UNICAST_PROMISC;
 1222 
 1223         iavf_send_vc_msg(sc, IAVF_FLAG_AQ_CONFIGURE_PROMISC);
 1224 
 1225         return (0);
 1226 }
 1227 
 1228 /**
 1229  * iavf_mc_filter_apply - Program a MAC filter for this VF
 1230  * @arg: pointer to the device softc
 1231  * @sdl: MAC multicast address
 1232  * @cnt: unused parameter
 1233  *
 1234  * Program a MAC address multicast filter for this device. Intended
 1235  * to be used with the map-like function if_foreach_llmaddr().
 1236  *
 1237  * @returns 1 on success, or 0 on failure
 1238  */
 1239 static u_int
 1240 iavf_mc_filter_apply(void *arg, struct sockaddr_dl *sdl, u_int cnt __unused)
 1241 {
 1242         struct iavf_sc *sc = (struct iavf_sc *)arg;
 1243         int error;
 1244 
 1245         error = iavf_add_mac_filter(sc, (u8*)LLADDR(sdl), IAVF_FILTER_MC);
 1246 
 1247         return (!error);
 1248 }
 1249 
 1250 /**
 1251  * iavf_init_multi - Initialize multicast address filters
 1252  * @sc: device private softc
 1253  *
 1254  * Called during initialization to reset multicast address filters to a known
 1255  * fresh state by deleting all currently active filters.
 1256  */
 1257 void
 1258 iavf_init_multi(struct iavf_sc *sc)
 1259 {
 1260         struct iavf_mac_filter *f;
 1261         int mcnt = 0;
 1262 
 1263         /* First clear any multicast filters */
 1264         SLIST_FOREACH(f, sc->mac_filters, next) {
 1265                 if ((f->flags & IAVF_FILTER_USED)
 1266                     && (f->flags & IAVF_FILTER_MC)) {
 1267                         f->flags |= IAVF_FILTER_DEL;
 1268                         mcnt++;
 1269                 }
 1270         }
 1271         if (mcnt > 0)
 1272                 iavf_send_vc_msg(sc, IAVF_FLAG_AQ_DEL_MAC_FILTER);
 1273 }
 1274 
 1275 /**
 1276  * iavf_multi_set - Set multicast filters
 1277  * @sc: device private softc
 1278  *
 1279  * Set multicast MAC filters for this device. If there are too many filters,
 1280  * this will request the device to go into multicast promiscuous mode instead.
 1281  */
 1282 void
 1283 iavf_multi_set(struct iavf_sc *sc)
 1284 {
 1285         if_t ifp = sc->vsi.ifp;
 1286         int mcnt = 0;
 1287 
 1288         IOCTL_DEBUGOUT("iavf_multi_set: begin");
 1289 
 1290         mcnt = if_llmaddr_count(ifp);
 1291         if (__predict_false(mcnt == MAX_MULTICAST_ADDR)) {
 1292                 /* Delete MC filters and enable mulitcast promisc instead */
 1293                 iavf_init_multi(sc);
 1294                 sc->promisc_flags |= FLAG_VF_MULTICAST_PROMISC;
 1295                 iavf_send_vc_msg(sc, IAVF_FLAG_AQ_CONFIGURE_PROMISC);
 1296                 return;
 1297         }
 1298 
 1299         /* If there aren't too many filters, delete existing MC filters */
 1300         iavf_init_multi(sc);
 1301 
 1302         /* And (re-)install filters for all mcast addresses */
 1303         mcnt = if_foreach_llmaddr(ifp, iavf_mc_filter_apply, sc);
 1304 
 1305         if (mcnt > 0)
 1306                 iavf_send_vc_msg(sc, IAVF_FLAG_AQ_ADD_MAC_FILTER);
 1307 }
 1308 
 1309 /**
 1310  * iavf_add_mac_filter - Add a MAC filter to the sc MAC list
 1311  * @sc: device private softc
 1312  * @macaddr: MAC address to add
 1313  * @flags: filter flags
 1314  *
 1315  * Add a new MAC filter to the softc MAC filter list. These will later be sent
 1316  * to the physical function (and ultimately hardware) via the virtchnl
 1317  * interface.
 1318  *
 1319  * @returns zero on success, EEXIST if the filter already exists, and ENOMEM
 1320  * if we ran out of memory allocating the filter structure.
 1321  */
 1322 int
 1323 iavf_add_mac_filter(struct iavf_sc *sc, u8 *macaddr, u16 flags)
 1324 {
 1325         struct iavf_mac_filter  *f;
 1326 
 1327         /* Does one already exist? */
 1328         f = iavf_find_mac_filter(sc, macaddr);
 1329         if (f != NULL) {
 1330                 iavf_dbg_filter(sc, "exists: " MAC_FORMAT "\n",
 1331                     MAC_FORMAT_ARGS(macaddr));
 1332                 return (EEXIST);
 1333         }
 1334 
 1335         /* If not, get a new empty filter */
 1336         f = iavf_get_mac_filter(sc);
 1337         if (f == NULL) {
 1338                 device_printf(sc->dev, "%s: no filters available!!\n",
 1339                     __func__);
 1340                 return (ENOMEM);
 1341         }
 1342 
 1343         iavf_dbg_filter(sc, "marked: " MAC_FORMAT "\n",
 1344             MAC_FORMAT_ARGS(macaddr));
 1345 
 1346         bcopy(macaddr, f->macaddr, ETHER_ADDR_LEN);
 1347         f->flags |= (IAVF_FILTER_ADD | IAVF_FILTER_USED);
 1348         f->flags |= flags;
 1349         return (0);
 1350 }
 1351 
 1352 /**
 1353  * iavf_find_mac_filter - Find a MAC filter with the given address
 1354  * @sc: device private softc
 1355  * @macaddr: the MAC address to find
 1356  *
 1357  * Finds the filter structure in the MAC filter list with the corresponding
 1358  * MAC address.
 1359  *
 1360  * @returns a pointer to the filter structure, or NULL if no such filter
 1361  * exists in the list yet.
 1362  */
 1363 struct iavf_mac_filter *
 1364 iavf_find_mac_filter(struct iavf_sc *sc, u8 *macaddr)
 1365 {
 1366         struct iavf_mac_filter  *f;
 1367         bool match = FALSE;
 1368 
 1369         SLIST_FOREACH(f, sc->mac_filters, next) {
 1370                 if (cmp_etheraddr(f->macaddr, macaddr)) {
 1371                         match = TRUE;
 1372                         break;
 1373                 }
 1374         }
 1375 
 1376         if (!match)
 1377                 f = NULL;
 1378         return (f);
 1379 }
 1380 
 1381 /**
 1382  * iavf_get_mac_filter - Get a new MAC address filter
 1383  * @sc: device private softc
 1384  *
 1385  * Allocates a new filter structure and inserts it into the MAC filter list.
 1386  *
 1387  * @post the caller must fill in the structure details after calling this
 1388  * function, but does not need to insert it into the linked list.
 1389  *
 1390  * @returns a pointer to the new filter structure, or NULL of we failed to
 1391  * allocate it.
 1392  */
 1393 struct iavf_mac_filter *
 1394 iavf_get_mac_filter(struct iavf_sc *sc)
 1395 {
 1396         struct iavf_mac_filter *f;
 1397 
 1398         f = (struct iavf_mac_filter *)malloc(sizeof(struct iavf_mac_filter),
 1399             M_IAVF, M_NOWAIT | M_ZERO);
 1400         if (f)
 1401                 SLIST_INSERT_HEAD(sc->mac_filters, f, next);
 1402 
 1403         return (f);
 1404 }
 1405 
 1406 /**
 1407  * iavf_baudrate_from_link_speed - Convert link speed to baudrate
 1408  * @sc: device private softc
 1409  *
 1410  * @post The link_speed_adv field is in Mbps, so it is multipled by
 1411  * 1,000,000 before it's returned.
 1412  *
 1413  * @returns the adapter link speed in bits/sec
 1414  */
 1415 u64
 1416 iavf_baudrate_from_link_speed(struct iavf_sc *sc)
 1417 {
 1418         if (sc->vf_res->vf_cap_flags & VIRTCHNL_VF_CAP_ADV_LINK_SPEED)
 1419                 return (sc->link_speed_adv * IAVF_ADV_LINK_SPEED_SCALE);
 1420         else
 1421                 return iavf_max_vc_speed_to_value(sc->link_speed);
 1422 }
 1423 
 1424 /**
 1425  * iavf_add_vlan_filter - Add a VLAN filter to the softc VLAN list
 1426  * @sc: device private softc
 1427  * @vtag: the VLAN id to filter
 1428  *
 1429  * Allocate a new VLAN filter structure and insert it into the VLAN list.
 1430  */
 1431 void
 1432 iavf_add_vlan_filter(struct iavf_sc *sc, u16 vtag)
 1433 {
 1434         struct iavf_vlan_filter *v;
 1435 
 1436         v = (struct iavf_vlan_filter *)malloc(sizeof(struct iavf_vlan_filter),
 1437             M_IAVF, M_WAITOK | M_ZERO);
 1438         SLIST_INSERT_HEAD(sc->vlan_filters, v, next);
 1439         v->vlan = vtag;
 1440         v->flags = IAVF_FILTER_ADD;
 1441 }
 1442 
 1443 /**
 1444  * iavf_mark_del_vlan_filter - Mark a given VLAN id for deletion
 1445  * @sc: device private softc
 1446  * @vtag: the VLAN id to delete
 1447  *
 1448  * Marks all VLAN filters matching the given vtag for deletion.
 1449  *
 1450  * @returns the number of filters marked for deletion.
 1451  *
 1452  * @remark the filters are not removed immediately, but will be removed from
 1453  * the list by another function that synchronizes over the virtchnl interface.
 1454  */
 1455 int
 1456 iavf_mark_del_vlan_filter(struct iavf_sc *sc, u16 vtag)
 1457 {
 1458         struct iavf_vlan_filter *v;
 1459         int i = 0;
 1460 
 1461         SLIST_FOREACH(v, sc->vlan_filters, next) {
 1462                 if (v->vlan == vtag) {
 1463                         v->flags = IAVF_FILTER_DEL;
 1464                         ++i;
 1465                 }
 1466         }
 1467 
 1468         return (i);
 1469 }
 1470 
 1471 /**
 1472  * iavf_update_msix_devinfo - Fix MSIX values for pci_msix_count()
 1473  * @dev: pointer to kernel device
 1474  *
 1475  * Fix cached MSI-X control register information. This is a workaround
 1476  * for an issue where VFs spawned in non-passthrough mode on FreeBSD
 1477  * will have their PCI information cached before the PF driver
 1478  * finishes updating their PCI information.
 1479  *
 1480  * @pre Must be called before pci_msix_count()
 1481  */
 1482 void
 1483 iavf_update_msix_devinfo(device_t dev)
 1484 {
 1485         struct pci_devinfo *dinfo;
 1486         u32 msix_ctrl;
 1487 
 1488         dinfo = (struct pci_devinfo *)device_get_ivars(dev);
 1489         /* We can hardcode this offset since we know the device */
 1490         msix_ctrl = pci_read_config(dev, 0x70 + PCIR_MSIX_CTRL, 2);
 1491         dinfo->cfg.msix.msix_ctrl = msix_ctrl;
 1492         dinfo->cfg.msix.msix_msgnum = (msix_ctrl & PCIM_MSIXCTRL_TABLE_SIZE) + 1;
 1493 }
 1494 
 1495 /**
 1496  * iavf_disable_queues_with_retries - Send PF multiple DISABLE_QUEUES messages
 1497  * @sc: device softc
 1498  *
 1499  * Send a virtual channel message to the PF to DISABLE_QUEUES, but resend it up
 1500  * to IAVF_MAX_DIS_Q_RETRY times if the response says that it wasn't
 1501  * successful. This is intended to workaround a bug that can appear on the PF.
 1502  */
 1503 void
 1504 iavf_disable_queues_with_retries(struct iavf_sc *sc)
 1505 {
 1506         bool in_detach = iavf_driver_is_detaching(sc);
 1507         int max_attempts = IAVF_MAX_DIS_Q_RETRY;
 1508         int msg_count = 0;
 1509 
 1510         /* While the driver is detaching, it doesn't care if the queue
 1511          * disable finishes successfully or not. Just send one message
 1512          * to just notify the PF driver.
 1513          */
 1514         if (in_detach)
 1515                 max_attempts = 1;
 1516 
 1517         while ((msg_count < max_attempts) &&
 1518             atomic_load_acq_32(&sc->queues_enabled)) {
 1519                 msg_count++;
 1520                 iavf_send_vc_msg_sleep(sc, IAVF_FLAG_AQ_DISABLE_QUEUES);
 1521         }
 1522 
 1523         /* Possibly print messages about retry attempts and issues */
 1524         if (msg_count > 1)
 1525                 iavf_dbg_vc(sc, "DISABLE_QUEUES messages sent: %d\n",
 1526                     msg_count);
 1527 
 1528         if (!in_detach && msg_count >= max_attempts)
 1529                 device_printf(sc->dev, "%s: DISABLE_QUEUES may have failed\n",
 1530                     __func__);
 1531 }

Cache object: e5fb5fabfd699a2c6de08979ff69221f


[ 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.