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