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