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