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