1 /*
   2  * Copyright 2007-2013 Solarflare Communications Inc.  All rights reserved.
   3  *
   4  * Redistribution and use in source and binary forms, with or without
   5  * modification, are permitted provided that the following conditions
   6  * are met:
   7  * 1. Redistributions of source code must retain the above copyright
   8  *    notice, this list of conditions and the following disclaimer.
   9  * 2. Redistributions in binary form must reproduce the above copyright
  10  *    notice, this list of conditions and the following disclaimer in the
  11  *    documentation and/or other materials provided with the distribution.
  12  *
  13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND
  14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  23  * SUCH DAMAGE.
  24  */
  25 
  26 #include "efsys.h"
  27 #include "efx.h"
  28 #include "efx_types.h"
  29 #include "efx_impl.h"
  30 
  31 #if EFSYS_OPT_MAC_FALCON_GMAC
  32 #include "falcon_gmac.h"
  33 #endif
  34 
  35 #if EFSYS_OPT_MAC_FALCON_XMAC
  36 #include "falcon_xmac.h"
  37 #endif
  38 
  39 #if EFSYS_OPT_MAC_FALCON_GMAC
  40 static efx_mac_ops_t    __cs __efx_falcon_gmac_ops = {
  41         falcon_gmac_reset,              /* emo_reset */
  42         falcon_mac_poll,                /* emo_poll */
  43         falcon_mac_up,                  /* emo_up */
  44         falcon_gmac_reconfigure,        /* emo_reconfigure */
  45 #if EFSYS_OPT_LOOPBACK
  46         falcon_mac_loopback_set,        /* emo_loopback_set */
  47 #endif  /* EFSYS_OPT_LOOPBACK */
  48 #if EFSYS_OPT_MAC_STATS
  49         falcon_mac_stats_upload,        /* emo_stats_upload */
  50         NULL,                           /* emo_stats_periodic */
  51         falcon_gmac_stats_update        /* emo_stats_update */
  52 #endif  /* EFSYS_OPT_MAC_STATS */
  53 };
  54 #endif  /* EFSYS_OPT_MAC_FALCON_GMAC */
  55 
  56 #if EFSYS_OPT_MAC_FALCON_XMAC
  57 static efx_mac_ops_t    __cs __efx_falcon_xmac_ops = {
  58         falcon_xmac_reset,              /* emo_reset */
  59         falcon_mac_poll,                /* emo_poll */
  60         falcon_mac_up,                  /* emo_up */
  61         falcon_xmac_reconfigure,        /* emo_reconfigure */
  62 #if EFSYS_OPT_LOOPBACK
  63         falcon_mac_loopback_set,        /* emo_loopback_set */
  64 #endif  /* EFSYS_OPT_LOOPBACK */
  65 #if EFSYS_OPT_MAC_STATS
  66         falcon_mac_stats_upload,        /* emo_stats_upload */
  67         NULL,                           /* emo_stats_periodic */
  68         falcon_xmac_stats_update        /* emo_stats_update */
  69 #endif  /* EFSYS_OPT_MAC_STATS */
  70 };
  71 #endif  /* EFSYS_OPT_MAC_FALCON_XMAC */
  72 
  73 #if EFSYS_OPT_SIENA
  74 static efx_mac_ops_t    __cs __efx_siena_mac_ops = {
  75         NULL,                           /* emo_reset */
  76         siena_mac_poll,                 /* emo_poll */
  77         siena_mac_up,                   /* emo_up */
  78         siena_mac_reconfigure,          /* emo_reconfigure */
  79 #if EFSYS_OPT_LOOPBACK
  80         siena_mac_loopback_set,         /* emo_loopback_set */
  81 #endif  /* EFSYS_OPT_LOOPBACK */
  82 #if EFSYS_OPT_MAC_STATS
  83         siena_mac_stats_upload,         /* emo_stats_upload */
  84         siena_mac_stats_periodic,       /* emo_stats_periodic */
  85         siena_mac_stats_update          /* emo_stats_update */
  86 #endif  /* EFSYS_OPT_MAC_STATS */
  87 };
  88 #endif  /* EFSYS_OPT_SIENA */
  89 
  90 static efx_mac_ops_t    __cs * __cs __efx_mac_ops[] = {
  91         NULL,
  92 #if EFSYS_OPT_MAC_FALCON_GMAC
  93         &__efx_falcon_gmac_ops,
  94 #else
  95         NULL,
  96 #endif  /* EFSYS_OPT_MAC_FALCON_GMAC */
  97 #if EFSYS_OPT_MAC_FALCON_XMAC
  98         &__efx_falcon_xmac_ops,
  99 #else
 100         NULL,
 101 #endif  /* EFSYS_OPT_MAC_FALCON_XMAC */
 102 #if EFSYS_OPT_SIENA
 103         &__efx_siena_mac_ops,
 104 #else
 105         NULL,
 106 #endif  /* EFSYS_OPT_SIENA */
 107 };
 108 
 109         __checkReturn                   int
 110 efx_mac_pdu_set(
 111         __in                            efx_nic_t *enp,
 112         __in                            size_t pdu)
 113 {
 114         efx_port_t *epp = &(enp->en_port);
 115         efx_mac_ops_t *emop = epp->ep_emop;
 116         uint32_t old_pdu;
 117         int rc;
 118 
 119         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 120         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
 121         EFSYS_ASSERT(emop != NULL);
 122 
 123         if (pdu < EFX_MAC_PDU_MIN) {
 124                 rc = EINVAL;
 125                 goto fail1;
 126         }
 127 
 128         if (pdu > EFX_MAC_PDU_MAX) {
 129                 rc = EINVAL;
 130                 goto fail2;
 131         }
 132 
 133         old_pdu = epp->ep_mac_pdu;
 134         epp->ep_mac_pdu = (uint32_t)pdu;
 135         if ((rc = emop->emo_reconfigure(enp)) != 0)
 136                 goto fail3;
 137 
 138         return (0);
 139 
 140 fail3:
 141         EFSYS_PROBE(fail3);
 142 
 143         epp->ep_mac_pdu = old_pdu;
 144 
 145 fail2:
 146         EFSYS_PROBE(fail2);
 147 fail1:
 148         EFSYS_PROBE1(fail1, int, rc);
 149 
 150         return (rc);
 151 }
 152 
 153         __checkReturn                   int
 154 efx_mac_addr_set(
 155         __in                            efx_nic_t *enp,
 156         __in                            uint8_t *addr)
 157 {
 158         efx_port_t *epp = &(enp->en_port);
 159         efx_mac_ops_t *emop = epp->ep_emop;
 160         uint8_t old_addr[6];
 161         uint32_t oui;
 162         int rc;
 163 
 164         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 165         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
 166 
 167         if (addr[0] & 0x01) {
 168                 rc = EINVAL;
 169                 goto fail1;
 170         }
 171 
 172         oui = addr[0] << 16 | addr[1] << 8 | addr[2];
 173         if (oui == 0x000000) {
 174                 rc = EINVAL;
 175                 goto fail2;
 176         }
 177 
 178         EFX_MAC_ADDR_COPY(old_addr, epp->ep_mac_addr);
 179         EFX_MAC_ADDR_COPY(epp->ep_mac_addr, addr);
 180         if ((rc = emop->emo_reconfigure(enp)) != 0)
 181                 goto fail3;
 182 
 183         return (0);
 184 
 185 fail3:
 186         EFSYS_PROBE(fail3);
 187 
 188         EFX_MAC_ADDR_COPY(epp->ep_mac_addr, old_addr);
 189 
 190 fail2:
 191         EFSYS_PROBE(fail2);
 192 fail1:
 193         EFSYS_PROBE1(fail1, int, rc);
 194 
 195         return (rc);
 196 }
 197 
 198         __checkReturn                   int
 199 efx_mac_filter_set(
 200         __in                            efx_nic_t *enp,
 201         __in                            boolean_t unicst,
 202         __in                            boolean_t brdcst)
 203 {
 204         efx_port_t *epp = &(enp->en_port);
 205         efx_mac_ops_t *emop = epp->ep_emop;
 206         boolean_t old_unicst;
 207         boolean_t old_brdcst;
 208         int rc;
 209 
 210         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 211         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
 212 
 213         old_unicst = unicst;
 214         old_brdcst = brdcst;
 215 
 216         epp->ep_unicst = unicst;
 217         epp->ep_brdcst = brdcst;
 218 
 219         if ((rc = emop->emo_reconfigure(enp)) != 0)
 220                 goto fail1;
 221 
 222         return (0);
 223 
 224 fail1:
 225         EFSYS_PROBE1(fail1, int, rc);
 226 
 227         epp->ep_unicst = old_unicst;
 228         epp->ep_brdcst = old_brdcst;
 229 
 230         return (rc);
 231 }
 232 
 233         __checkReturn                   int
 234 efx_mac_drain(
 235         __in                            efx_nic_t *enp,
 236         __in                            boolean_t enabled)
 237 {
 238         efx_port_t *epp = &(enp->en_port);
 239         efx_mac_ops_t *emop = epp->ep_emop;
 240         int rc;
 241 
 242         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 243         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
 244         EFSYS_ASSERT(emop != NULL);
 245 
 246         if (epp->ep_mac_drain == enabled)
 247                 return (0);
 248 
 249         epp->ep_mac_drain = enabled;
 250 
 251         if (enabled && emop->emo_reset != NULL) {
 252                 if ((rc = emop->emo_reset(enp)) != 0)
 253                         goto fail1;
 254 
 255                 EFSYS_ASSERT(enp->en_reset_flags & EFX_RESET_MAC);
 256                 enp->en_reset_flags &= ~EFX_RESET_PHY;
 257         }
 258 
 259         if ((rc = emop->emo_reconfigure(enp)) != 0)
 260                 goto fail2;
 261 
 262         return (0);
 263 
 264 fail2:
 265         EFSYS_PROBE(fail2);
 266 fail1:
 267         EFSYS_PROBE1(fail1, int, rc);
 268 
 269         return (rc);
 270 }
 271 
 272         __checkReturn   int
 273 efx_mac_up(
 274         __in            efx_nic_t *enp,
 275         __out           boolean_t *mac_upp)
 276 {
 277         efx_port_t *epp = &(enp->en_port);
 278         efx_mac_ops_t *emop = epp->ep_emop;
 279         int rc;
 280 
 281         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 282         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
 283 
 284         if ((rc = emop->emo_up(enp, mac_upp)) != 0)
 285                 goto fail1;
 286 
 287         return (0);
 288 
 289 fail1:
 290         EFSYS_PROBE1(fail1, int, rc);
 291 
 292         return (rc);
 293 }
 294 
 295         __checkReturn                   int
 296 efx_mac_fcntl_set(
 297         __in                            efx_nic_t *enp,
 298         __in                            unsigned int fcntl,
 299         __in                            boolean_t autoneg)
 300 {
 301         efx_port_t *epp = &(enp->en_port);
 302         efx_mac_ops_t *emop = epp->ep_emop;
 303         efx_phy_ops_t *epop = epp->ep_epop;
 304         unsigned int old_fcntl;
 305         boolean_t old_autoneg;
 306         unsigned int old_adv_cap;
 307         int rc;
 308 
 309         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 310         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
 311 
 312         if ((fcntl & ~(EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE)) != 0) {
 313                 rc = EINVAL;
 314                 goto fail1;
 315         }
 316 
 317         /*
 318          * Ignore a request to set flow control autonegotiation
 319          * if the PHY doesn't support it.
 320          */
 321         if (~epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN))
 322                 autoneg = B_FALSE;
 323 
 324         old_fcntl = epp->ep_fcntl;
 325         old_autoneg = autoneg;
 326         old_adv_cap = epp->ep_adv_cap_mask;
 327 
 328         epp->ep_fcntl = fcntl;
 329         epp->ep_fcntl_autoneg = autoneg;
 330 
 331         /*
 332          * If the PHY supports autonegotiation, then encode the flow control
 333          * settings in the advertised capabilities, and restart AN. Otherwise,
 334          * just push the new settings directly to the MAC.
 335          */
 336         if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN)) {
 337                 if (fcntl & EFX_FCNTL_RESPOND)
 338                         epp->ep_adv_cap_mask |=    (1 << EFX_PHY_CAP_PAUSE |
 339                                                     1 << EFX_PHY_CAP_ASYM);
 340                 else
 341                         epp->ep_adv_cap_mask &=   ~(1 << EFX_PHY_CAP_PAUSE |
 342                                                     1 << EFX_PHY_CAP_ASYM);
 343 
 344                 if (fcntl & EFX_FCNTL_GENERATE)
 345                         epp->ep_adv_cap_mask ^= (1 << EFX_PHY_CAP_ASYM);
 346 
 347                 if ((rc = epop->epo_reconfigure(enp)) != 0)
 348                         goto fail2;
 349 
 350         } else {
 351                 if ((rc = emop->emo_reconfigure(enp)) != 0)
 352                         goto fail2;
 353         }
 354 
 355         return (0);
 356 
 357 fail2:
 358         EFSYS_PROBE(fail2);
 359 
 360         epp->ep_fcntl = old_fcntl;
 361         epp->ep_fcntl_autoneg = old_autoneg;
 362         epp->ep_adv_cap_mask = old_adv_cap;
 363 
 364 fail1:
 365         EFSYS_PROBE1(fail1, int, rc);
 366 
 367         return (rc);
 368 }
 369 
 370                         void
 371 efx_mac_fcntl_get(
 372         __in            efx_nic_t *enp,
 373         __out           unsigned int *fcntl_wantedp,
 374         __out           unsigned int *fcntl_linkp)
 375 {
 376         efx_port_t *epp = &(enp->en_port);
 377         unsigned int wanted;
 378 
 379         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 380         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
 381 
 382         /*
 383          * If the PHY supports auto negotiation, then the requested flow
 384          * control settings are encoded in the advertised capabilities.
 385          */
 386         if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN)) {
 387                 wanted = 0;
 388 
 389                 if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE))
 390                         wanted = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
 391                 if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_ASYM))
 392                         wanted ^= EFX_FCNTL_GENERATE;
 393         } else
 394                 wanted = epp->ep_fcntl;
 395 
 396         *fcntl_linkp = epp->ep_fcntl;
 397         *fcntl_wantedp = wanted;
 398 }
 399 
 400         __checkReturn                   int
 401 efx_mac_hash_set(
 402         __in                            efx_nic_t *enp,
 403         __in_ecount(EFX_MAC_HASH_BITS)  unsigned int const *bucket)
 404 {
 405         efx_port_t *epp = &(enp->en_port);
 406         efx_mac_ops_t *emop = epp->ep_emop;
 407         efx_oword_t old_hash[2];
 408         unsigned int index;
 409         int rc;
 410 
 411         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 412         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
 413 
 414         memcpy(old_hash, epp->ep_multicst_hash, sizeof (old_hash));
 415 
 416         /* Set the lower 128 bits of the hash */
 417         EFX_ZERO_OWORD(epp->ep_multicst_hash[0]);
 418         for (index = 0; index < 128; index++) {
 419                 if (bucket[index] != 0)
 420                         EFX_SET_OWORD_BIT(epp->ep_multicst_hash[0], index);
 421         }
 422 
 423         /* Set the upper 128 bits of the hash */
 424         EFX_ZERO_OWORD(epp->ep_multicst_hash[1]);
 425         for (index = 0; index < 128; index++) {
 426                 if (bucket[index + 128] != 0)
 427                         EFX_SET_OWORD_BIT(epp->ep_multicst_hash[1], index);
 428         }
 429 
 430         if ((rc = emop->emo_reconfigure(enp)) != 0)
 431                 goto fail1;
 432 
 433         return (0);
 434 
 435 fail1:
 436         EFSYS_PROBE1(fail1, int, rc);
 437 
 438         memcpy(epp->ep_multicst_hash, old_hash, sizeof (old_hash));
 439 
 440         return (rc);
 441 }
 442 
 443 #if EFSYS_OPT_MAC_STATS
 444 
 445 #if EFSYS_OPT_NAMES
 446 
 447 /* START MKCONFIG GENERATED EfxMacStatNamesBlock adf707adba80813e */
 448 static const char       __cs * __cs __efx_mac_stat_name[] = {
 449         "rx_octets",
 450         "rx_pkts",
 451         "rx_unicst_pkts",
 452         "rx_multicst_pkts",
 453         "rx_brdcst_pkts",
 454         "rx_pause_pkts",
 455         "rx_le_64_pkts",
 456         "rx_65_to_127_pkts",
 457         "rx_128_to_255_pkts",
 458         "rx_256_to_511_pkts",
 459         "rx_512_to_1023_pkts",
 460         "rx_1024_to_15xx_pkts",
 461         "rx_ge_15xx_pkts",
 462         "rx_errors",
 463         "rx_fcs_errors",
 464         "rx_drop_events",
 465         "rx_false_carrier_errors",
 466         "rx_symbol_errors",
 467         "rx_align_errors",
 468         "rx_internal_errors",
 469         "rx_jabber_pkts",
 470         "rx_lane0_char_err",
 471         "rx_lane1_char_err",
 472         "rx_lane2_char_err",
 473         "rx_lane3_char_err",
 474         "rx_lane0_disp_err",
 475         "rx_lane1_disp_err",
 476         "rx_lane2_disp_err",
 477         "rx_lane3_disp_err",
 478         "rx_match_fault",
 479         "rx_nodesc_drop_cnt",
 480         "tx_octets",
 481         "tx_pkts",
 482         "tx_unicst_pkts",
 483         "tx_multicst_pkts",
 484         "tx_brdcst_pkts",
 485         "tx_pause_pkts",
 486         "tx_le_64_pkts",
 487         "tx_65_to_127_pkts",
 488         "tx_128_to_255_pkts",
 489         "tx_256_to_511_pkts",
 490         "tx_512_to_1023_pkts",
 491         "tx_1024_to_15xx_pkts",
 492         "tx_ge_15xx_pkts",
 493         "tx_errors",
 494         "tx_sgl_col_pkts",
 495         "tx_mult_col_pkts",
 496         "tx_ex_col_pkts",
 497         "tx_late_col_pkts",
 498         "tx_def_pkts",
 499         "tx_ex_def_pkts",
 500 };
 501 /* END MKCONFIG GENERATED EfxMacStatNamesBlock */
 502 
 503         __checkReturn                   const char __cs *
 504 efx_mac_stat_name(
 505         __in                            efx_nic_t *enp,
 506         __in                            unsigned int id)
 507 {
 508         _NOTE(ARGUNUSED(enp))
 509         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 510 
 511         EFSYS_ASSERT3U(id, <, EFX_MAC_NSTATS);
 512         return (__efx_mac_stat_name[id]);
 513 }
 514 
 515 #endif  /* EFSYS_OPT_STAT_NAME */
 516 
 517         __checkReturn                   int
 518 efx_mac_stats_upload(
 519         __in                            efx_nic_t *enp,
 520         __in                            efsys_mem_t *esmp)
 521 {
 522         efx_port_t *epp = &(enp->en_port);
 523         efx_mac_ops_t *emop = epp->ep_emop;
 524         int rc;
 525 
 526         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 527         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
 528         EFSYS_ASSERT(emop != NULL);
 529 
 530         /*
 531          * Don't assert !ep_mac_stats_pending, because the client might
 532          * have failed to finalise statistics when previously stopping
 533          * the port.
 534          */
 535         if ((rc = emop->emo_stats_upload(enp, esmp)) != 0)
 536                 goto fail1;
 537 
 538         epp->ep_mac_stats_pending = B_TRUE;
 539 
 540         return (0);
 541 
 542 fail1:
 543         EFSYS_PROBE1(fail1, int, rc);
 544 
 545         return (rc);
 546 }
 547 
 548         __checkReturn                   int
 549 efx_mac_stats_periodic(
 550         __in                            efx_nic_t *enp,
 551         __in                            efsys_mem_t *esmp,
 552         __in                            uint16_t period_ms,
 553         __in                            boolean_t events)
 554 {
 555         efx_port_t *epp = &(enp->en_port);
 556         efx_mac_ops_t *emop = epp->ep_emop;
 557         int rc;
 558 
 559         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 560         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
 561 
 562         EFSYS_ASSERT(emop != NULL);
 563 
 564         if (emop->emo_stats_periodic == NULL) {
 565                 rc = EINVAL;
 566                 goto fail1;
 567         }
 568 
 569         if ((rc = emop->emo_stats_periodic(enp, esmp, period_ms, events)) != 0)
 570                 goto fail2;
 571 
 572         return (0);
 573 
 574 fail2:
 575         EFSYS_PROBE(fail2);
 576 fail1:
 577         EFSYS_PROBE1(fail1, int, rc);
 578 
 579         return (rc);
 580 }
 581 
 582 
 583         __checkReturn                   int
 584 efx_mac_stats_update(
 585         __in                            efx_nic_t *enp,
 586         __in                            efsys_mem_t *esmp,
 587         __inout_ecount(EFX_MAC_NSTATS)  efsys_stat_t *essp,
 588         __in                            uint32_t *generationp)
 589 {
 590         efx_port_t *epp = &(enp->en_port);
 591         efx_mac_ops_t *emop = epp->ep_emop;
 592         int rc;
 593 
 594         EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
 595         EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
 596         EFSYS_ASSERT(emop != NULL);
 597 
 598         rc = emop->emo_stats_update(enp, esmp, essp, generationp);
 599         if (rc == 0)
 600                 epp->ep_mac_stats_pending = B_FALSE;
 601 
 602         return (rc);
 603 }
 604 
 605 #endif  /* EFSYS_OPT_MAC_STATS */
 606 
 607         __checkReturn                   int
 608 efx_mac_select(
 609         __in                            efx_nic_t *enp)
 610 {
 611         efx_port_t *epp = &(enp->en_port);
 612         efx_mac_type_t type = EFX_MAC_INVALID;
 613         efx_mac_ops_t *emop;
 614         int rc = EINVAL;
 615 
 616 #if EFSYS_OPT_SIENA
 617         if (enp->en_family == EFX_FAMILY_SIENA) {
 618                 type = EFX_MAC_SIENA;
 619                 goto chosen;
 620         }
 621 #endif
 622 
 623 #if EFSYS_OPT_FALCON
 624         switch (epp->ep_link_mode) {
 625 #if EFSYS_OPT_MAC_FALCON_GMAC
 626         case EFX_LINK_100HDX:
 627         case EFX_LINK_100FDX:
 628         case EFX_LINK_1000HDX:
 629         case EFX_LINK_1000FDX:
 630                 type = EFX_MAC_FALCON_GMAC;
 631                 goto chosen;
 632 #endif  /* EFSYS_OPT_FALCON_GMAC */
 633 
 634 #if EFSYS_OPT_MAC_FALCON_XMAC
 635         case EFX_LINK_10000FDX:
 636                 type = EFX_MAC_FALCON_XMAC;
 637                 goto chosen;
 638 #endif  /* EFSYS_OPT_FALCON_XMAC */
 639 
 640         default:
 641 #if EFSYS_OPT_MAC_FALCON_GMAC && EFSYS_OPT_MAC_FALCON_XMAC
 642                 /* Only initialise a MAC supported by the PHY */
 643                 if (epp->ep_phy_cap_mask &
 644                     ((1 << EFX_PHY_CAP_1000FDX) |
 645                     (1 << EFX_PHY_CAP_1000HDX) |
 646                     (1 << EFX_PHY_CAP_100FDX) |
 647                     (1 << EFX_PHY_CAP_100HDX) |
 648                     (1 << EFX_PHY_CAP_10FDX) |
 649                     (1 << EFX_PHY_CAP_10FDX)))
 650                         type = EFX_MAC_FALCON_GMAC;
 651                 else
 652                         type = EFX_MAC_FALCON_XMAC;
 653 #elif EFSYS_OPT_MAC_FALCON_GMAC
 654                 type = EFX_MAC_FALCON_GMAC;
 655 #else
 656                 type = EFX_MAC_FALCON_XMAC;
 657 #endif
 658                 goto chosen;
 659         }
 660 #endif  /* EFSYS_OPT_FALCON */
 661 
 662 chosen:
 663         EFSYS_ASSERT(type != EFX_MAC_INVALID);
 664         EFSYS_ASSERT3U(type, <, EFX_MAC_NTYPES);
 665         emop = epp->ep_emop = (efx_mac_ops_t *)__efx_mac_ops[type];
 666         EFSYS_ASSERT(emop != NULL);
 667 
 668         epp->ep_mac_type = type;
 669 
 670         if (emop->emo_reset != NULL) {
 671                 if ((rc = emop->emo_reset(enp)) != 0)
 672                         goto fail1;
 673 
 674                 EFSYS_ASSERT(enp->en_reset_flags & EFX_RESET_MAC);
 675                 enp->en_reset_flags &= ~EFX_RESET_MAC;
 676         }
 677 
 678         return (0);
 679 
 680 fail1:
 681         EFSYS_PROBE1(fail1, int, rc);
 682 
 683         return (rc);
 684 }