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/sfxge/common/efx_mac.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 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2007-2016 Solarflare Communications Inc.
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions are met:
    9  *
   10  * 1. Redistributions of source code must retain the above copyright notice,
   11  *    this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright notice,
   13  *    this list of conditions and the following disclaimer in the documentation
   14  *    and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   18  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
   20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   21  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   23  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   25  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
   26  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27  *
   28  * The views and conclusions contained in the software and documentation are
   29  * those of the authors and should not be interpreted as representing official
   30  * policies, either expressed or implied, of the FreeBSD Project.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __FBSDID("$FreeBSD$");
   35 
   36 #include "efx.h"
   37 #include "efx_impl.h"
   38 
   39 #if EFSYS_OPT_SIENA
   40 
   41 static  __checkReturn   efx_rc_t
   42 siena_mac_multicast_list_set(
   43         __in            efx_nic_t *enp);
   44 
   45 #endif /* EFSYS_OPT_SIENA */
   46 
   47 #if EFSYS_OPT_SIENA
   48 static const efx_mac_ops_t      __efx_mac_siena_ops = {
   49         siena_mac_poll,                         /* emo_poll */
   50         siena_mac_up,                           /* emo_up */
   51         siena_mac_reconfigure,                  /* emo_addr_set */
   52         siena_mac_reconfigure,                  /* emo_pdu_set */
   53         siena_mac_pdu_get,                      /* emo_pdu_get */
   54         siena_mac_reconfigure,                  /* emo_reconfigure */
   55         siena_mac_multicast_list_set,           /* emo_multicast_list_set */
   56         NULL,                                   /* emo_filter_set_default_rxq */
   57         NULL,                           /* emo_filter_default_rxq_clear */
   58 #if EFSYS_OPT_LOOPBACK
   59         siena_mac_loopback_set,                 /* emo_loopback_set */
   60 #endif  /* EFSYS_OPT_LOOPBACK */
   61 #if EFSYS_OPT_MAC_STATS
   62         siena_mac_stats_get_mask,               /* emo_stats_get_mask */
   63         efx_mcdi_mac_stats_clear,               /* emo_stats_clear */
   64         efx_mcdi_mac_stats_upload,              /* emo_stats_upload */
   65         efx_mcdi_mac_stats_periodic,            /* emo_stats_periodic */
   66         siena_mac_stats_update                  /* emo_stats_update */
   67 #endif  /* EFSYS_OPT_MAC_STATS */
   68 };
   69 #endif  /* EFSYS_OPT_SIENA */
   70 
   71 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2
   72 static const efx_mac_ops_t      __efx_mac_ef10_ops = {
   73         ef10_mac_poll,                          /* emo_poll */
   74         ef10_mac_up,                            /* emo_up */
   75         ef10_mac_addr_set,                      /* emo_addr_set */
   76         ef10_mac_pdu_set,                       /* emo_pdu_set */
   77         ef10_mac_pdu_get,                       /* emo_pdu_get */
   78         ef10_mac_reconfigure,                   /* emo_reconfigure */
   79         ef10_mac_multicast_list_set,            /* emo_multicast_list_set */
   80         ef10_mac_filter_default_rxq_set,        /* emo_filter_default_rxq_set */
   81         ef10_mac_filter_default_rxq_clear,
   82                                         /* emo_filter_default_rxq_clear */
   83 #if EFSYS_OPT_LOOPBACK
   84         ef10_mac_loopback_set,                  /* emo_loopback_set */
   85 #endif  /* EFSYS_OPT_LOOPBACK */
   86 #if EFSYS_OPT_MAC_STATS
   87         ef10_mac_stats_get_mask,                /* emo_stats_get_mask */
   88         efx_mcdi_mac_stats_clear,               /* emo_stats_clear */
   89         efx_mcdi_mac_stats_upload,              /* emo_stats_upload */
   90         efx_mcdi_mac_stats_periodic,            /* emo_stats_periodic */
   91         ef10_mac_stats_update                   /* emo_stats_update */
   92 #endif  /* EFSYS_OPT_MAC_STATS */
   93 };
   94 #endif  /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */
   95 
   96         __checkReturn                   efx_rc_t
   97 efx_mac_pdu_set(
   98         __in                            efx_nic_t *enp,
   99         __in                            size_t pdu)
  100 {
  101         efx_port_t *epp = &(enp->en_port);
  102         const efx_mac_ops_t *emop = epp->ep_emop;
  103         uint32_t old_pdu;
  104         efx_rc_t rc;
  105 
  106         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
  107         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
  108         EFSYS_ASSERT(emop != NULL);
  109 
  110         if (pdu < EFX_MAC_PDU_MIN) {
  111                 rc = EINVAL;
  112                 goto fail1;
  113         }
  114 
  115         if (pdu > EFX_MAC_PDU_MAX) {
  116                 rc = EINVAL;
  117                 goto fail2;
  118         }
  119 
  120         old_pdu = epp->ep_mac_pdu;
  121         epp->ep_mac_pdu = (uint32_t)pdu;
  122         if ((rc = emop->emo_pdu_set(enp)) != 0)
  123                 goto fail3;
  124 
  125         return (0);
  126 
  127 fail3:
  128         EFSYS_PROBE(fail3);
  129 
  130         epp->ep_mac_pdu = old_pdu;
  131 
  132 fail2:
  133         EFSYS_PROBE(fail2);
  134 fail1:
  135         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  136 
  137         return (rc);
  138 }
  139 
  140         __checkReturn   efx_rc_t
  141 efx_mac_pdu_get(
  142         __in            efx_nic_t *enp,
  143         __out           size_t *pdu)
  144 {
  145         efx_port_t *epp = &(enp->en_port);
  146         const efx_mac_ops_t *emop = epp->ep_emop;
  147         efx_rc_t rc;
  148 
  149         if ((rc = emop->emo_pdu_get(enp, pdu)) != 0)
  150                 goto fail1;
  151 
  152         return (0);
  153 
  154 fail1:
  155         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  156 
  157         return (rc);
  158 }
  159 
  160         __checkReturn                   efx_rc_t
  161 efx_mac_addr_set(
  162         __in                            efx_nic_t *enp,
  163         __in                            uint8_t *addr)
  164 {
  165         efx_port_t *epp = &(enp->en_port);
  166         const efx_mac_ops_t *emop = epp->ep_emop;
  167         uint8_t old_addr[6];
  168         uint32_t oui;
  169         efx_rc_t rc;
  170 
  171         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
  172         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
  173 
  174         if (EFX_MAC_ADDR_IS_MULTICAST(addr)) {
  175                 rc = EINVAL;
  176                 goto fail1;
  177         }
  178 
  179         oui = addr[0] << 16 | addr[1] << 8 | addr[2];
  180         if (oui == 0x000000) {
  181                 rc = EINVAL;
  182                 goto fail2;
  183         }
  184 
  185         EFX_MAC_ADDR_COPY(old_addr, epp->ep_mac_addr);
  186         EFX_MAC_ADDR_COPY(epp->ep_mac_addr, addr);
  187         if ((rc = emop->emo_addr_set(enp)) != 0)
  188                 goto fail3;
  189 
  190         return (0);
  191 
  192 fail3:
  193         EFSYS_PROBE(fail3);
  194 
  195         EFX_MAC_ADDR_COPY(epp->ep_mac_addr, old_addr);
  196 
  197 fail2:
  198         EFSYS_PROBE(fail2);
  199 fail1:
  200         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  201 
  202         return (rc);
  203 }
  204 
  205         __checkReturn                   efx_rc_t
  206 efx_mac_filter_set(
  207         __in                            efx_nic_t *enp,
  208         __in                            boolean_t all_unicst,
  209         __in                            boolean_t mulcst,
  210         __in                            boolean_t all_mulcst,
  211         __in                            boolean_t brdcst)
  212 {
  213         efx_port_t *epp = &(enp->en_port);
  214         const efx_mac_ops_t *emop = epp->ep_emop;
  215         boolean_t old_all_unicst;
  216         boolean_t old_mulcst;
  217         boolean_t old_all_mulcst;
  218         boolean_t old_brdcst;
  219         efx_rc_t rc;
  220 
  221         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
  222         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
  223 
  224         old_all_unicst = epp->ep_all_unicst;
  225         old_mulcst = epp->ep_mulcst;
  226         old_all_mulcst = epp->ep_all_mulcst;
  227         old_brdcst = epp->ep_brdcst;
  228 
  229         epp->ep_all_unicst = all_unicst;
  230         epp->ep_mulcst = mulcst;
  231         epp->ep_all_mulcst = all_mulcst;
  232         epp->ep_brdcst = brdcst;
  233 
  234         if ((rc = emop->emo_reconfigure(enp)) != 0)
  235                 goto fail1;
  236 
  237         return (0);
  238 
  239 fail1:
  240         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  241 
  242         epp->ep_all_unicst = old_all_unicst;
  243         epp->ep_mulcst = old_mulcst;
  244         epp->ep_all_mulcst = old_all_mulcst;
  245         epp->ep_brdcst = old_brdcst;
  246 
  247         return (rc);
  248 }
  249 
  250         __checkReturn                   efx_rc_t
  251 efx_mac_drain(
  252         __in                            efx_nic_t *enp,
  253         __in                            boolean_t enabled)
  254 {
  255         efx_port_t *epp = &(enp->en_port);
  256         const efx_mac_ops_t *emop = epp->ep_emop;
  257         efx_rc_t rc;
  258 
  259         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
  260         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
  261         EFSYS_ASSERT(emop != NULL);
  262 
  263         if (epp->ep_mac_drain == enabled)
  264                 return (0);
  265 
  266         epp->ep_mac_drain = enabled;
  267 
  268         if ((rc = emop->emo_reconfigure(enp)) != 0)
  269                 goto fail1;
  270 
  271         return (0);
  272 
  273 fail1:
  274         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  275 
  276         return (rc);
  277 }
  278 
  279         __checkReturn   efx_rc_t
  280 efx_mac_up(
  281         __in            efx_nic_t *enp,
  282         __out           boolean_t *mac_upp)
  283 {
  284         efx_port_t *epp = &(enp->en_port);
  285         const efx_mac_ops_t *emop = epp->ep_emop;
  286         efx_rc_t rc;
  287 
  288         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
  289         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
  290 
  291         if ((rc = emop->emo_up(enp, mac_upp)) != 0)
  292                 goto fail1;
  293 
  294         return (0);
  295 
  296 fail1:
  297         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  298 
  299         return (rc);
  300 }
  301 
  302         __checkReturn                   efx_rc_t
  303 efx_mac_fcntl_set(
  304         __in                            efx_nic_t *enp,
  305         __in                            unsigned int fcntl,
  306         __in                            boolean_t autoneg)
  307 {
  308         efx_port_t *epp = &(enp->en_port);
  309         const efx_mac_ops_t *emop = epp->ep_emop;
  310         const efx_phy_ops_t *epop = epp->ep_epop;
  311         unsigned int old_fcntl;
  312         boolean_t old_autoneg;
  313         unsigned int old_adv_cap;
  314         efx_rc_t rc;
  315 
  316         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
  317         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
  318 
  319         if ((fcntl & ~(EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE)) != 0) {
  320                 rc = EINVAL;
  321                 goto fail1;
  322         }
  323 
  324         /*
  325          * Ignore a request to set flow control auto-negotiation
  326          * if the PHY doesn't support it.
  327          */
  328         if (~epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN))
  329                 autoneg = B_FALSE;
  330 
  331         old_fcntl = epp->ep_fcntl;
  332         old_autoneg = epp->ep_fcntl_autoneg;
  333         old_adv_cap = epp->ep_adv_cap_mask;
  334 
  335         epp->ep_fcntl = fcntl;
  336         epp->ep_fcntl_autoneg = autoneg;
  337 
  338         /*
  339          * Always encode the flow control settings in the advertised
  340          * capabilities even if we are not trying to auto-negotiate
  341          * them and reconfigure both the PHY and the MAC.
  342          */
  343         if (fcntl & EFX_FCNTL_RESPOND)
  344                 epp->ep_adv_cap_mask |=    (1 << EFX_PHY_CAP_PAUSE |
  345                                             1 << EFX_PHY_CAP_ASYM);
  346         else
  347                 epp->ep_adv_cap_mask &=   ~(1 << EFX_PHY_CAP_PAUSE |
  348                                             1 << EFX_PHY_CAP_ASYM);
  349 
  350         if (fcntl & EFX_FCNTL_GENERATE)
  351                 epp->ep_adv_cap_mask ^= (1 << EFX_PHY_CAP_ASYM);
  352 
  353         if ((rc = epop->epo_reconfigure(enp)) != 0)
  354                 goto fail2;
  355 
  356         if ((rc = emop->emo_reconfigure(enp)) != 0)
  357                 goto fail3;
  358 
  359         return (0);
  360 
  361 fail3:
  362         EFSYS_PROBE(fail3);
  363 
  364 fail2:
  365         EFSYS_PROBE(fail2);
  366 
  367         epp->ep_fcntl = old_fcntl;
  368         epp->ep_fcntl_autoneg = old_autoneg;
  369         epp->ep_adv_cap_mask = old_adv_cap;
  370 
  371 fail1:
  372         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  373 
  374         return (rc);
  375 }
  376 
  377                         void
  378 efx_mac_fcntl_get(
  379         __in            efx_nic_t *enp,
  380         __out           unsigned int *fcntl_wantedp,
  381         __out           unsigned int *fcntl_linkp)
  382 {
  383         efx_port_t *epp = &(enp->en_port);
  384         unsigned int wanted = 0;
  385 
  386         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
  387         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
  388 
  389         /*
  390          * Decode the requested flow control settings from the PHY
  391          * advertised capabilities.
  392          */
  393         if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE))
  394                 wanted = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
  395         if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_ASYM))
  396                 wanted ^= EFX_FCNTL_GENERATE;
  397 
  398         *fcntl_linkp = epp->ep_fcntl;
  399         *fcntl_wantedp = wanted;
  400 }
  401 
  402         __checkReturn   efx_rc_t
  403 efx_mac_multicast_list_set(
  404         __in                            efx_nic_t *enp,
  405         __in_ecount(6*count)            uint8_t const *addrs,
  406         __in                            int count)
  407 {
  408         efx_port_t *epp = &(enp->en_port);
  409         const efx_mac_ops_t *emop = epp->ep_emop;
  410         uint8_t *old_mulcst_addr_list = NULL;
  411         uint32_t old_mulcst_addr_count;
  412         efx_rc_t rc;
  413 
  414         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
  415         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
  416 
  417         if (count > EFX_MAC_MULTICAST_LIST_MAX) {
  418                 rc = EINVAL;
  419                 goto fail1;
  420         }
  421 
  422         old_mulcst_addr_count = epp->ep_mulcst_addr_count;
  423         if (old_mulcst_addr_count > 0) {
  424                 /* Allocate memory to store old list (instead of using stack) */
  425                 EFSYS_KMEM_ALLOC(enp->en_esip,
  426                                 old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
  427                                 old_mulcst_addr_list);
  428                 if (old_mulcst_addr_list == NULL) {
  429                         rc = ENOMEM;
  430                         goto fail2;
  431                 }
  432 
  433                 /* Save the old list in case we need to rollback */
  434                 memcpy(old_mulcst_addr_list, epp->ep_mulcst_addr_list,
  435                         old_mulcst_addr_count * EFX_MAC_ADDR_LEN);
  436         }
  437 
  438         /* Store the new list */
  439         memcpy(epp->ep_mulcst_addr_list, addrs,
  440                 count * EFX_MAC_ADDR_LEN);
  441         epp->ep_mulcst_addr_count = count;
  442 
  443         if ((rc = emop->emo_multicast_list_set(enp)) != 0)
  444                 goto fail3;
  445 
  446         if (old_mulcst_addr_count > 0) {
  447                 EFSYS_KMEM_FREE(enp->en_esip,
  448                                 old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
  449                                 old_mulcst_addr_list);
  450         }
  451 
  452         return (0);
  453 
  454 fail3:
  455         EFSYS_PROBE(fail3);
  456 
  457         /* Restore original list on failure */
  458         epp->ep_mulcst_addr_count = old_mulcst_addr_count;
  459         if (old_mulcst_addr_count > 0) {
  460                 memcpy(epp->ep_mulcst_addr_list, old_mulcst_addr_list,
  461                         old_mulcst_addr_count * EFX_MAC_ADDR_LEN);
  462 
  463                 EFSYS_KMEM_FREE(enp->en_esip,
  464                                 old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
  465                                 old_mulcst_addr_list);
  466         }
  467 
  468 fail2:
  469         EFSYS_PROBE(fail2);
  470 
  471 fail1:
  472         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  473 
  474         return (rc);
  475 
  476 }
  477 
  478         __checkReturn   efx_rc_t
  479 efx_mac_filter_default_rxq_set(
  480         __in            efx_nic_t *enp,
  481         __in            efx_rxq_t *erp,
  482         __in            boolean_t using_rss)
  483 {
  484         efx_port_t *epp = &(enp->en_port);
  485         const efx_mac_ops_t *emop = epp->ep_emop;
  486         efx_rc_t rc;
  487 
  488         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
  489         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
  490 
  491         if (emop->emo_filter_default_rxq_set != NULL) {
  492                 rc = emop->emo_filter_default_rxq_set(enp, erp, using_rss);
  493                 if (rc != 0)
  494                         goto fail1;
  495         }
  496 
  497         return (0);
  498 
  499 fail1:
  500         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  501 
  502         return (rc);
  503 }
  504 
  505                         void
  506 efx_mac_filter_default_rxq_clear(
  507         __in            efx_nic_t *enp)
  508 {
  509         efx_port_t *epp = &(enp->en_port);
  510         const efx_mac_ops_t *emop = epp->ep_emop;
  511 
  512         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
  513         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
  514 
  515         if (emop->emo_filter_default_rxq_clear != NULL)
  516                 emop->emo_filter_default_rxq_clear(enp);
  517 }
  518 
  519 #if EFSYS_OPT_MAC_STATS
  520 
  521 #if EFSYS_OPT_NAMES
  522 
  523 /* START MKCONFIG GENERATED EfxMacStatNamesBlock 1a45a82fcfb30c1b */
  524 static const char * const __efx_mac_stat_name[] = {
  525         "rx_octets",
  526         "rx_pkts",
  527         "rx_unicst_pkts",
  528         "rx_multicst_pkts",
  529         "rx_brdcst_pkts",
  530         "rx_pause_pkts",
  531         "rx_le_64_pkts",
  532         "rx_65_to_127_pkts",
  533         "rx_128_to_255_pkts",
  534         "rx_256_to_511_pkts",
  535         "rx_512_to_1023_pkts",
  536         "rx_1024_to_15xx_pkts",
  537         "rx_ge_15xx_pkts",
  538         "rx_errors",
  539         "rx_fcs_errors",
  540         "rx_drop_events",
  541         "rx_false_carrier_errors",
  542         "rx_symbol_errors",
  543         "rx_align_errors",
  544         "rx_internal_errors",
  545         "rx_jabber_pkts",
  546         "rx_lane0_char_err",
  547         "rx_lane1_char_err",
  548         "rx_lane2_char_err",
  549         "rx_lane3_char_err",
  550         "rx_lane0_disp_err",
  551         "rx_lane1_disp_err",
  552         "rx_lane2_disp_err",
  553         "rx_lane3_disp_err",
  554         "rx_match_fault",
  555         "rx_nodesc_drop_cnt",
  556         "tx_octets",
  557         "tx_pkts",
  558         "tx_unicst_pkts",
  559         "tx_multicst_pkts",
  560         "tx_brdcst_pkts",
  561         "tx_pause_pkts",
  562         "tx_le_64_pkts",
  563         "tx_65_to_127_pkts",
  564         "tx_128_to_255_pkts",
  565         "tx_256_to_511_pkts",
  566         "tx_512_to_1023_pkts",
  567         "tx_1024_to_15xx_pkts",
  568         "tx_ge_15xx_pkts",
  569         "tx_errors",
  570         "tx_sgl_col_pkts",
  571         "tx_mult_col_pkts",
  572         "tx_ex_col_pkts",
  573         "tx_late_col_pkts",
  574         "tx_def_pkts",
  575         "tx_ex_def_pkts",
  576         "pm_trunc_bb_overflow",
  577         "pm_discard_bb_overflow",
  578         "pm_trunc_vfifo_full",
  579         "pm_discard_vfifo_full",
  580         "pm_trunc_qbb",
  581         "pm_discard_qbb",
  582         "pm_discard_mapping",
  583         "rxdp_q_disabled_pkts",
  584         "rxdp_di_dropped_pkts",
  585         "rxdp_streaming_pkts",
  586         "rxdp_hlb_fetch",
  587         "rxdp_hlb_wait",
  588         "vadapter_rx_unicast_packets",
  589         "vadapter_rx_unicast_bytes",
  590         "vadapter_rx_multicast_packets",
  591         "vadapter_rx_multicast_bytes",
  592         "vadapter_rx_broadcast_packets",
  593         "vadapter_rx_broadcast_bytes",
  594         "vadapter_rx_bad_packets",
  595         "vadapter_rx_bad_bytes",
  596         "vadapter_rx_overflow",
  597         "vadapter_tx_unicast_packets",
  598         "vadapter_tx_unicast_bytes",
  599         "vadapter_tx_multicast_packets",
  600         "vadapter_tx_multicast_bytes",
  601         "vadapter_tx_broadcast_packets",
  602         "vadapter_tx_broadcast_bytes",
  603         "vadapter_tx_bad_packets",
  604         "vadapter_tx_bad_bytes",
  605         "vadapter_tx_overflow",
  606         "fec_uncorrected_errors",
  607         "fec_corrected_errors",
  608         "fec_corrected_symbols_lane0",
  609         "fec_corrected_symbols_lane1",
  610         "fec_corrected_symbols_lane2",
  611         "fec_corrected_symbols_lane3",
  612         "ctpio_vi_busy_fallback",
  613         "ctpio_long_write_success",
  614         "ctpio_missing_dbell_fail",
  615         "ctpio_overflow_fail",
  616         "ctpio_underflow_fail",
  617         "ctpio_timeout_fail",
  618         "ctpio_noncontig_wr_fail",
  619         "ctpio_frm_clobber_fail",
  620         "ctpio_invalid_wr_fail",
  621         "ctpio_vi_clobber_fallback",
  622         "ctpio_unqualified_fallback",
  623         "ctpio_runt_fallback",
  624         "ctpio_success",
  625         "ctpio_fallback",
  626         "ctpio_poison",
  627         "ctpio_erase",
  628         "rxdp_scatter_disabled_trunc",
  629         "rxdp_hlb_idle",
  630         "rxdp_hlb_timeout",
  631 };
  632 /* END MKCONFIG GENERATED EfxMacStatNamesBlock */
  633 
  634         __checkReturn                   const char *
  635 efx_mac_stat_name(
  636         __in                            efx_nic_t *enp,
  637         __in                            unsigned int id)
  638 {
  639         _NOTE(ARGUNUSED(enp))
  640         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
  641 
  642         EFSYS_ASSERT3U(id, <, EFX_MAC_NSTATS);
  643         return (__efx_mac_stat_name[id]);
  644 }
  645 
  646 #endif  /* EFSYS_OPT_NAMES */
  647 
  648 static                                  efx_rc_t
  649 efx_mac_stats_mask_add_range(
  650         __inout_bcount(mask_size)       uint32_t *maskp,
  651         __in                            size_t mask_size,
  652         __in                            const struct efx_mac_stats_range *rngp)
  653 {
  654         unsigned int mask_npages = mask_size / sizeof (*maskp);
  655         unsigned int el;
  656         unsigned int el_min;
  657         unsigned int el_max;
  658         unsigned int low;
  659         unsigned int high;
  660         unsigned int width;
  661         efx_rc_t rc;
  662 
  663         if ((mask_npages * EFX_MAC_STATS_MASK_BITS_PER_PAGE) <=
  664             (unsigned int)rngp->last) {
  665                 rc = EINVAL;
  666                 goto fail1;
  667         }
  668 
  669         EFSYS_ASSERT3U(rngp->first, <=, rngp->last);
  670         EFSYS_ASSERT3U(rngp->last, <, EFX_MAC_NSTATS);
  671 
  672         for (el = 0; el < mask_npages; ++el) {
  673                 el_min = el * EFX_MAC_STATS_MASK_BITS_PER_PAGE;
  674                 el_max =
  675                     el_min + (EFX_MAC_STATS_MASK_BITS_PER_PAGE - 1);
  676                 if ((unsigned int)rngp->first > el_max ||
  677                     (unsigned int)rngp->last < el_min)
  678                         continue;
  679                 low = MAX((unsigned int)rngp->first, el_min);
  680                 high = MIN((unsigned int)rngp->last, el_max);
  681                 width = high - low + 1;
  682                 maskp[el] |=
  683                     (width == EFX_MAC_STATS_MASK_BITS_PER_PAGE) ?
  684                     (~0ULL) : (((1ULL << width) - 1) << (low - el_min));
  685         }
  686 
  687         return (0);
  688 
  689 fail1:
  690         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  691 
  692         return (rc);
  693 }
  694 
  695                                         efx_rc_t
  696 efx_mac_stats_mask_add_ranges(
  697         __inout_bcount(mask_size)       uint32_t *maskp,
  698         __in                            size_t mask_size,
  699         __in_ecount(rng_count)          const struct efx_mac_stats_range *rngp,
  700         __in                            unsigned int rng_count)
  701 {
  702         unsigned int i;
  703         efx_rc_t rc;
  704 
  705         for (i = 0; i < rng_count; ++i) {
  706                 if ((rc = efx_mac_stats_mask_add_range(maskp, mask_size,
  707                     &rngp[i])) != 0)
  708                         goto fail1;
  709         }
  710 
  711         return (0);
  712 
  713 fail1:
  714         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  715 
  716         return (rc);
  717 }
  718 
  719         __checkReturn                   efx_rc_t
  720 efx_mac_stats_get_mask(
  721         __in                            efx_nic_t *enp,
  722         __out_bcount(mask_size)         uint32_t *maskp,
  723         __in                            size_t mask_size)
  724 {
  725         efx_port_t *epp = &(enp->en_port);
  726         const efx_mac_ops_t *emop = epp->ep_emop;
  727         efx_rc_t rc;
  728 
  729         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
  730         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
  731         EFSYS_ASSERT(maskp != NULL);
  732         EFSYS_ASSERT(mask_size % sizeof (maskp[0]) == 0);
  733 
  734         (void) memset(maskp, 0, mask_size);
  735 
  736         if ((rc = emop->emo_stats_get_mask(enp, maskp, mask_size)) != 0)
  737                 goto fail1;
  738 
  739         return (0);
  740 
  741 fail1:
  742         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  743 
  744         return (rc);
  745 }
  746 
  747         __checkReturn                   efx_rc_t
  748 efx_mac_stats_clear(
  749         __in                            efx_nic_t *enp)
  750 {
  751         efx_port_t *epp = &(enp->en_port);
  752         const efx_mac_ops_t *emop = epp->ep_emop;
  753         efx_rc_t rc;
  754 
  755         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
  756         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
  757         EFSYS_ASSERT(emop != NULL);
  758 
  759         if ((rc = emop->emo_stats_clear(enp)) != 0)
  760                 goto fail1;
  761 
  762         return (0);
  763 
  764 fail1:
  765         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  766 
  767         return (rc);
  768 }
  769 
  770         __checkReturn                   efx_rc_t
  771 efx_mac_stats_upload(
  772         __in                            efx_nic_t *enp,
  773         __in                            efsys_mem_t *esmp)
  774 {
  775         efx_port_t *epp = &(enp->en_port);
  776         const efx_mac_ops_t *emop = epp->ep_emop;
  777         efx_rc_t rc;
  778 
  779         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
  780         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
  781         EFSYS_ASSERT(emop != NULL);
  782 
  783         if ((rc = emop->emo_stats_upload(enp, esmp)) != 0)
  784                 goto fail1;
  785 
  786         return (0);
  787 
  788 fail1:
  789         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  790 
  791         return (rc);
  792 }
  793 
  794         __checkReturn                   efx_rc_t
  795 efx_mac_stats_periodic(
  796         __in                            efx_nic_t *enp,
  797         __in                            efsys_mem_t *esmp,
  798         __in                            uint16_t period_ms,
  799         __in                            boolean_t events)
  800 {
  801         efx_port_t *epp = &(enp->en_port);
  802         const efx_mac_ops_t *emop = epp->ep_emop;
  803         efx_rc_t rc;
  804 
  805         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
  806         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
  807 
  808         EFSYS_ASSERT(emop != NULL);
  809 
  810         if (emop->emo_stats_periodic == NULL) {
  811                 rc = EINVAL;
  812                 goto fail1;
  813         }
  814 
  815         if ((rc = emop->emo_stats_periodic(enp, esmp, period_ms, events)) != 0)
  816                 goto fail2;
  817 
  818         return (0);
  819 
  820 fail2:
  821         EFSYS_PROBE(fail2);
  822 fail1:
  823         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  824 
  825         return (rc);
  826 }
  827 
  828         __checkReturn                   efx_rc_t
  829 efx_mac_stats_update(
  830         __in                            efx_nic_t *enp,
  831         __in                            efsys_mem_t *esmp,
  832         __inout_ecount(EFX_MAC_NSTATS)  efsys_stat_t *essp,
  833         __inout_opt                     uint32_t *generationp)
  834 {
  835         efx_port_t *epp = &(enp->en_port);
  836         const efx_mac_ops_t *emop = epp->ep_emop;
  837         efx_rc_t rc;
  838 
  839         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
  840         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
  841         EFSYS_ASSERT(emop != NULL);
  842 
  843         rc = emop->emo_stats_update(enp, esmp, essp, generationp);
  844 
  845         return (rc);
  846 }
  847 
  848 #endif  /* EFSYS_OPT_MAC_STATS */
  849 
  850         __checkReturn                   efx_rc_t
  851 efx_mac_select(
  852         __in                            efx_nic_t *enp)
  853 {
  854         efx_port_t *epp = &(enp->en_port);
  855         efx_mac_type_t type = EFX_MAC_INVALID;
  856         const efx_mac_ops_t *emop;
  857         int rc = EINVAL;
  858 
  859         switch (enp->en_family) {
  860 #if EFSYS_OPT_SIENA
  861         case EFX_FAMILY_SIENA:
  862                 emop = &__efx_mac_siena_ops;
  863                 type = EFX_MAC_SIENA;
  864                 break;
  865 #endif /* EFSYS_OPT_SIENA */
  866 
  867 #if EFSYS_OPT_HUNTINGTON
  868         case EFX_FAMILY_HUNTINGTON:
  869                 emop = &__efx_mac_ef10_ops;
  870                 type = EFX_MAC_HUNTINGTON;
  871                 break;
  872 #endif /* EFSYS_OPT_HUNTINGTON */
  873 
  874 #if EFSYS_OPT_MEDFORD
  875         case EFX_FAMILY_MEDFORD:
  876                 emop = &__efx_mac_ef10_ops;
  877                 type = EFX_MAC_MEDFORD;
  878                 break;
  879 #endif /* EFSYS_OPT_MEDFORD */
  880 
  881 #if EFSYS_OPT_MEDFORD2
  882         case EFX_FAMILY_MEDFORD2:
  883                 emop = &__efx_mac_ef10_ops;
  884                 type = EFX_MAC_MEDFORD2;
  885                 break;
  886 #endif /* EFSYS_OPT_MEDFORD2 */
  887 
  888         default:
  889                 rc = EINVAL;
  890                 goto fail1;
  891         }
  892 
  893         EFSYS_ASSERT(type != EFX_MAC_INVALID);
  894         EFSYS_ASSERT3U(type, <, EFX_MAC_NTYPES);
  895         EFSYS_ASSERT(emop != NULL);
  896 
  897         epp->ep_emop = emop;
  898         epp->ep_mac_type = type;
  899 
  900         return (0);
  901 
  902 fail1:
  903         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  904 
  905         return (rc);
  906 }
  907 
  908 #if EFSYS_OPT_SIENA
  909 
  910 #define EFX_MAC_HASH_BITS       (1 << 8)
  911 
  912 /* Compute the multicast hash as used on Falcon and Siena. */
  913 static  void
  914 siena_mac_multicast_hash_compute(
  915         __in_ecount(6*count)            uint8_t const *addrs,
  916         __in                            int count,
  917         __out                           efx_oword_t *hash_low,
  918         __out                           efx_oword_t *hash_high)
  919 {
  920         uint32_t crc, index;
  921         int i;
  922 
  923         EFSYS_ASSERT(hash_low != NULL);
  924         EFSYS_ASSERT(hash_high != NULL);
  925 
  926         EFX_ZERO_OWORD(*hash_low);
  927         EFX_ZERO_OWORD(*hash_high);
  928 
  929         for (i = 0; i < count; i++) {
  930                 /* Calculate hash bucket (IEEE 802.3 CRC32 of the MAC addr) */
  931                 crc = efx_crc32_calculate(0xffffffff, addrs, EFX_MAC_ADDR_LEN);
  932                 index = crc % EFX_MAC_HASH_BITS;
  933                 if (index < 128) {
  934                         EFX_SET_OWORD_BIT(*hash_low, index);
  935                 } else {
  936                         EFX_SET_OWORD_BIT(*hash_high, index - 128);
  937                 }
  938 
  939                 addrs += EFX_MAC_ADDR_LEN;
  940         }
  941 }
  942 
  943 static  __checkReturn   efx_rc_t
  944 siena_mac_multicast_list_set(
  945         __in            efx_nic_t *enp)
  946 {
  947         efx_port_t *epp = &(enp->en_port);
  948         const efx_mac_ops_t *emop = epp->ep_emop;
  949         efx_oword_t old_hash[2];
  950         efx_rc_t rc;
  951 
  952         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
  953         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
  954 
  955         memcpy(old_hash, epp->ep_multicst_hash, sizeof (old_hash));
  956 
  957         siena_mac_multicast_hash_compute(
  958             epp->ep_mulcst_addr_list,
  959             epp->ep_mulcst_addr_count,
  960             &epp->ep_multicst_hash[0],
  961             &epp->ep_multicst_hash[1]);
  962 
  963         if ((rc = emop->emo_reconfigure(enp)) != 0)
  964                 goto fail1;
  965 
  966         return (0);
  967 
  968 fail1:
  969         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  970 
  971         memcpy(epp->ep_multicst_hash, old_hash, sizeof (old_hash));
  972 
  973         return (rc);
  974 }
  975 
  976 #endif /* EFSYS_OPT_SIENA */

Cache object: c95d4bbe74bbb8c959acef57c7aa4eeb


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