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