1/*- 2 * Copyright 2007-2009 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 40static 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 57static 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 74static 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 90static 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 110efx_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 140fail3: 141 EFSYS_PROBE(fail3); 142 143 epp->ep_mac_pdu = old_pdu; 144 145fail2: 146 EFSYS_PROBE(fail2); 147fail1: 148 EFSYS_PROBE1(fail1, int, rc); 149 150 return (rc); 151} 152 153 __checkReturn int 154efx_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 185fail3: 186 EFSYS_PROBE(fail3); 187 188 EFX_MAC_ADDR_COPY(epp->ep_mac_addr, old_addr); 189 190fail2: 191 EFSYS_PROBE(fail2); 192fail1: 193 EFSYS_PROBE1(fail1, int, rc); 194 195 return (rc); 196} 197 198 __checkReturn int 199efx_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 224fail1: 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 234efx_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 264fail2: 265 EFSYS_PROBE(fail2); 266fail1: 267 EFSYS_PROBE1(fail1, int, rc); 268 269 return (rc); 270} 271 272 __checkReturn int 273efx_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 289fail1: 290 EFSYS_PROBE1(fail1, int, rc); 291 292 return (rc); 293} 294 295 __checkReturn int 296efx_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 357fail2: 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 364fail1: 365 EFSYS_PROBE1(fail1, int, rc); 366 367 return (rc); 368} 369 370 void 371efx_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 401efx_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 idx; 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 (idx = 0; idx < 128; idx++) { 419 if (bucket[idx] != 0) 420#pragma GCC diagnostic push 421#pragma GCC diagnostic ignored "-Wtype-limits" 422 EFX_SET_OWORD_BIT(epp->ep_multicst_hash[0], idx); 423#pragma GCC diagnostic pop 424 } 425 426 /* Set the upper 128 bits of the hash */ 427 EFX_ZERO_OWORD(epp->ep_multicst_hash[1]); 428 for (idx = 0; idx < 128; idx++) { 429 if (bucket[idx + 128] != 0) 430#pragma GCC diagnostic push 431#pragma GCC diagnostic ignored "-Wtype-limits" 432 EFX_SET_OWORD_BIT(epp->ep_multicst_hash[1], idx); 433#pragma GCC diagnostic pop 434 } 435 436 if ((rc = emop->emo_reconfigure(enp)) != 0) 437 goto fail1; 438 439 return (0); 440 441fail1: 442 EFSYS_PROBE1(fail1, int, rc); 443 444 memcpy(epp->ep_multicst_hash, old_hash, sizeof (old_hash)); 445 446 return (rc); 447} 448 449#if EFSYS_OPT_MAC_STATS 450 451#if EFSYS_OPT_NAMES 452 453/* START MKCONFIG GENERATED EfxMacStatNamesBlock adf707adba80813e */ 454static const char __cs * __cs __efx_mac_stat_name[] = { 455 "rx_octets", 456 "rx_pkts", 457 "rx_unicst_pkts", 458 "rx_multicst_pkts", 459 "rx_brdcst_pkts", 460 "rx_pause_pkts", 461 "rx_le_64_pkts", 462 "rx_65_to_127_pkts", 463 "rx_128_to_255_pkts", 464 "rx_256_to_511_pkts", 465 "rx_512_to_1023_pkts", 466 "rx_1024_to_15xx_pkts", 467 "rx_ge_15xx_pkts", 468 "rx_errors", 469 "rx_fcs_errors", 470 "rx_drop_events", 471 "rx_false_carrier_errors", 472 "rx_symbol_errors", 473 "rx_align_errors", 474 "rx_internal_errors", 475 "rx_jabber_pkts", 476 "rx_lane0_char_err", 477 "rx_lane1_char_err", 478 "rx_lane2_char_err", 479 "rx_lane3_char_err", 480 "rx_lane0_disp_err", 481 "rx_lane1_disp_err", 482 "rx_lane2_disp_err", 483 "rx_lane3_disp_err", 484 "rx_match_fault", 485 "rx_nodesc_drop_cnt", 486 "tx_octets", 487 "tx_pkts", 488 "tx_unicst_pkts", 489 "tx_multicst_pkts", 490 "tx_brdcst_pkts", 491 "tx_pause_pkts", 492 "tx_le_64_pkts", 493 "tx_65_to_127_pkts", 494 "tx_128_to_255_pkts", 495 "tx_256_to_511_pkts", 496 "tx_512_to_1023_pkts", 497 "tx_1024_to_15xx_pkts", 498 "tx_ge_15xx_pkts", 499 "tx_errors", 500 "tx_sgl_col_pkts", 501 "tx_mult_col_pkts", 502 "tx_ex_col_pkts", 503 "tx_late_col_pkts", 504 "tx_def_pkts", 505 "tx_ex_def_pkts", 506}; 507/* END MKCONFIG GENERATED EfxMacStatNamesBlock */ 508 509 __checkReturn const char __cs * 510efx_mac_stat_name( 511 __in efx_nic_t *enp, 512 __in unsigned int id) 513{ 514 _NOTE(ARGUNUSED(enp)) 515 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 516 517 EFSYS_ASSERT3U(id, <, EFX_MAC_NSTATS); 518 return (__efx_mac_stat_name[id]); 519} 520 521#endif /* EFSYS_OPT_STAT_NAME */ 522 523 __checkReturn int 524efx_mac_stats_upload( 525 __in efx_nic_t *enp, 526 __in efsys_mem_t *esmp) 527{ 528 efx_port_t *epp = &(enp->en_port); 529 efx_mac_ops_t *emop = epp->ep_emop; 530 int rc; 531 532 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 533 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 534 EFSYS_ASSERT(emop != NULL); 535 536 /* 537 * Don't assert !ep_mac_stats_pending, because the client might 538 * have failed to finalise statistics when previously stopping 539 * the port. 540 */ 541 if ((rc = emop->emo_stats_upload(enp, esmp)) != 0) 542 goto fail1; 543 544 epp->ep_mac_stats_pending = B_TRUE; 545 546 return (0); 547 548fail1: 549 EFSYS_PROBE1(fail1, int, rc); 550 551 return (rc); 552} 553 554 __checkReturn int 555efx_mac_stats_periodic( 556 __in efx_nic_t *enp, 557 __in efsys_mem_t *esmp, 558 __in uint16_t period_ms, 559 __in boolean_t events) 560{ 561 efx_port_t *epp = &(enp->en_port); 562 efx_mac_ops_t *emop = epp->ep_emop; 563 int rc; 564 565 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 566 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 567 568 EFSYS_ASSERT(emop != NULL); 569 570 if (emop->emo_stats_periodic == NULL) { 571 rc = EINVAL; 572 goto fail1; 573 } 574 575 if ((rc = emop->emo_stats_periodic(enp, esmp, period_ms, events)) != 0) 576 goto fail2; 577 578 return (0); 579 580fail2: 581 EFSYS_PROBE(fail2); 582fail1: 583 EFSYS_PROBE1(fail1, int, rc); 584 585 return (rc); 586} 587 588 589 __checkReturn int 590efx_mac_stats_update( 591 __in efx_nic_t *enp, 592 __in efsys_mem_t *esmp, 593 __inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *essp, 594 __in uint32_t *generationp) 595{ 596 efx_port_t *epp = &(enp->en_port); 597 efx_mac_ops_t *emop = epp->ep_emop; 598 int rc; 599 600 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 601 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 602 EFSYS_ASSERT(emop != NULL); 603 604 rc = emop->emo_stats_update(enp, esmp, essp, generationp); 605 if (rc == 0) 606 epp->ep_mac_stats_pending = B_FALSE; 607 608 return (rc); 609} 610 611#endif /* EFSYS_OPT_MAC_STATS */ 612 613 __checkReturn int 614efx_mac_select( 615 __in efx_nic_t *enp) 616{ 617 efx_port_t *epp = &(enp->en_port); 618 efx_mac_type_t type = EFX_MAC_INVALID; 619 efx_mac_ops_t *emop; 620 int rc = EINVAL; 621 622#if EFSYS_OPT_SIENA 623 if (enp->en_family == EFX_FAMILY_SIENA) { 624 type = EFX_MAC_SIENA; 625 goto chosen; 626 } 627#endif 628 629#if EFSYS_OPT_FALCON 630 switch (epp->ep_link_mode) { 631#if EFSYS_OPT_MAC_FALCON_GMAC 632 case EFX_LINK_100HDX: 633 case EFX_LINK_100FDX: 634 case EFX_LINK_1000HDX: 635 case EFX_LINK_1000FDX: 636 type = EFX_MAC_FALCON_GMAC; 637 goto chosen; 638#endif /* EFSYS_OPT_FALCON_GMAC */ 639 640#if EFSYS_OPT_MAC_FALCON_XMAC 641 case EFX_LINK_10000FDX: 642 type = EFX_MAC_FALCON_XMAC; 643 goto chosen; 644#endif /* EFSYS_OPT_FALCON_XMAC */ 645 646 default: 647#if EFSYS_OPT_MAC_FALCON_GMAC && EFSYS_OPT_MAC_FALCON_XMAC 648 /* Only initialise a MAC supported by the PHY */ 649 if (epp->ep_phy_cap_mask & 650 ((1 << EFX_PHY_CAP_1000FDX) | 651 (1 << EFX_PHY_CAP_1000HDX) | 652 (1 << EFX_PHY_CAP_100FDX) | 653 (1 << EFX_PHY_CAP_100HDX) | 654 (1 << EFX_PHY_CAP_10FDX) | 655 (1 << EFX_PHY_CAP_10FDX))) 656 type = EFX_MAC_FALCON_GMAC; 657 else 658 type = EFX_MAC_FALCON_XMAC; 659#elif EFSYS_OPT_MAC_FALCON_GMAC 660 type = EFX_MAC_FALCON_GMAC; 661#else 662 type = EFX_MAC_FALCON_XMAC; 663#endif 664 goto chosen; 665 } 666#endif /* EFSYS_OPT_FALCON */ 667 668chosen: 669 EFSYS_ASSERT(type != EFX_MAC_INVALID); 670 EFSYS_ASSERT3U(type, <, EFX_MAC_NTYPES); 671 emop = epp->ep_emop = (efx_mac_ops_t *)__efx_mac_ops[type]; 672 EFSYS_ASSERT(emop != NULL); 673 674 epp->ep_mac_type = type; 675 676 if (emop->emo_reset != NULL) { 677 if ((rc = emop->emo_reset(enp)) != 0) 678 goto fail1; 679 680 EFSYS_ASSERT(enp->en_reset_flags & EFX_RESET_MAC); 681 enp->en_reset_flags &= ~EFX_RESET_MAC; 682 } 683 684 return (0); 685 686fail1: 687 EFSYS_PROBE1(fail1, int, rc); 688 689 return (rc); 690} 691