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 #if EFSYS_OPT_MAC_STATS 520 521 #if EFSYS_OPT_NAMES 522 523 /* START MKCONFIG GENERATED EfxMacStatNamesBlock 1a45a82fcfb30c1b */ 524 static const char * const __efx_mac_stat_name[] = { 525 "rx_octets", 526 "rx_pkts", 527 "rx_unicst_pkts", 528 "rx_multicst_pkts", 529 "rx_brdcst_pkts", 530 "rx_pause_pkts", 531 "rx_le_64_pkts", 532 "rx_65_to_127_pkts", 533 "rx_128_to_255_pkts", 534 "rx_256_to_511_pkts", 535 "rx_512_to_1023_pkts", 536 "rx_1024_to_15xx_pkts", 537 "rx_ge_15xx_pkts", 538 "rx_errors", 539 "rx_fcs_errors", 540 "rx_drop_events", 541 "rx_false_carrier_errors", 542 "rx_symbol_errors", 543 "rx_align_errors", 544 "rx_internal_errors", 545 "rx_jabber_pkts", 546 "rx_lane0_char_err", 547 "rx_lane1_char_err", 548 "rx_lane2_char_err", 549 "rx_lane3_char_err", 550 "rx_lane0_disp_err", 551 "rx_lane1_disp_err", 552 "rx_lane2_disp_err", 553 "rx_lane3_disp_err", 554 "rx_match_fault", 555 "rx_nodesc_drop_cnt", 556 "tx_octets", 557 "tx_pkts", 558 "tx_unicst_pkts", 559 "tx_multicst_pkts", 560 "tx_brdcst_pkts", 561 "tx_pause_pkts", 562 "tx_le_64_pkts", 563 "tx_65_to_127_pkts", 564 "tx_128_to_255_pkts", 565 "tx_256_to_511_pkts", 566 "tx_512_to_1023_pkts", 567 "tx_1024_to_15xx_pkts", 568 "tx_ge_15xx_pkts", 569 "tx_errors", 570 "tx_sgl_col_pkts", 571 "tx_mult_col_pkts", 572 "tx_ex_col_pkts", 573 "tx_late_col_pkts", 574 "tx_def_pkts", 575 "tx_ex_def_pkts", 576 "pm_trunc_bb_overflow", 577 "pm_discard_bb_overflow", 578 "pm_trunc_vfifo_full", 579 "pm_discard_vfifo_full", 580 "pm_trunc_qbb", 581 "pm_discard_qbb", 582 "pm_discard_mapping", 583 "rxdp_q_disabled_pkts", 584 "rxdp_di_dropped_pkts", 585 "rxdp_streaming_pkts", 586 "rxdp_hlb_fetch", 587 "rxdp_hlb_wait", 588 "vadapter_rx_unicast_packets", 589 "vadapter_rx_unicast_bytes", 590 "vadapter_rx_multicast_packets", 591 "vadapter_rx_multicast_bytes", 592 "vadapter_rx_broadcast_packets", 593 "vadapter_rx_broadcast_bytes", 594 "vadapter_rx_bad_packets", 595 "vadapter_rx_bad_bytes", 596 "vadapter_rx_overflow", 597 "vadapter_tx_unicast_packets", 598 "vadapter_tx_unicast_bytes", 599 "vadapter_tx_multicast_packets", 600 "vadapter_tx_multicast_bytes", 601 "vadapter_tx_broadcast_packets", 602 "vadapter_tx_broadcast_bytes", 603 "vadapter_tx_bad_packets", 604 "vadapter_tx_bad_bytes", 605 "vadapter_tx_overflow", 606 "fec_uncorrected_errors", 607 "fec_corrected_errors", 608 "fec_corrected_symbols_lane0", 609 "fec_corrected_symbols_lane1", 610 "fec_corrected_symbols_lane2", 611 "fec_corrected_symbols_lane3", 612 "ctpio_vi_busy_fallback", 613 "ctpio_long_write_success", 614 "ctpio_missing_dbell_fail", 615 "ctpio_overflow_fail", 616 "ctpio_underflow_fail", 617 "ctpio_timeout_fail", 618 "ctpio_noncontig_wr_fail", 619 "ctpio_frm_clobber_fail", 620 "ctpio_invalid_wr_fail", 621 "ctpio_vi_clobber_fallback", 622 "ctpio_unqualified_fallback", 623 "ctpio_runt_fallback", 624 "ctpio_success", 625 "ctpio_fallback", 626 "ctpio_poison", 627 "ctpio_erase", 628 "rxdp_scatter_disabled_trunc", 629 "rxdp_hlb_idle", 630 "rxdp_hlb_timeout", 631 }; 632 /* END MKCONFIG GENERATED EfxMacStatNamesBlock */ 633 634 __checkReturn const char * 635 efx_mac_stat_name( 636 __in efx_nic_t *enp, 637 __in unsigned int id) 638 { 639 _NOTE(ARGUNUSED(enp)) 640 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 641 642 EFSYS_ASSERT3U(id, <, EFX_MAC_NSTATS); 643 return (__efx_mac_stat_name[id]); 644 } 645 646 #endif /* EFSYS_OPT_NAMES */ 647 648 static efx_rc_t 649 efx_mac_stats_mask_add_range( 650 __inout_bcount(mask_size) uint32_t *maskp, 651 __in size_t mask_size, 652 __in const struct efx_mac_stats_range *rngp) 653 { 654 unsigned int mask_npages = mask_size / sizeof (*maskp); 655 unsigned int el; 656 unsigned int el_min; 657 unsigned int el_max; 658 unsigned int low; 659 unsigned int high; 660 unsigned int width; 661 efx_rc_t rc; 662 663 if ((mask_npages * EFX_MAC_STATS_MASK_BITS_PER_PAGE) <= 664 (unsigned int)rngp->last) { 665 rc = EINVAL; 666 goto fail1; 667 } 668 669 EFSYS_ASSERT3U(rngp->first, <=, rngp->last); 670 EFSYS_ASSERT3U(rngp->last, <, EFX_MAC_NSTATS); 671 672 for (el = 0; el < mask_npages; ++el) { 673 el_min = el * EFX_MAC_STATS_MASK_BITS_PER_PAGE; 674 el_max = 675 el_min + (EFX_MAC_STATS_MASK_BITS_PER_PAGE - 1); 676 if ((unsigned int)rngp->first > el_max || 677 (unsigned int)rngp->last < el_min) 678 continue; 679 low = MAX((unsigned int)rngp->first, el_min); 680 high = MIN((unsigned int)rngp->last, el_max); 681 width = high - low + 1; 682 maskp[el] |= 683 (width == EFX_MAC_STATS_MASK_BITS_PER_PAGE) ? 684 (~0ULL) : (((1ULL << width) - 1) << (low - el_min)); 685 } 686 687 return (0); 688 689 fail1: 690 EFSYS_PROBE1(fail1, efx_rc_t, rc); 691 692 return (rc); 693 } 694 695 efx_rc_t 696 efx_mac_stats_mask_add_ranges( 697 __inout_bcount(mask_size) uint32_t *maskp, 698 __in size_t mask_size, 699 __in_ecount(rng_count) const struct efx_mac_stats_range *rngp, 700 __in unsigned int rng_count) 701 { 702 unsigned int i; 703 efx_rc_t rc; 704 705 for (i = 0; i < rng_count; ++i) { 706 if ((rc = efx_mac_stats_mask_add_range(maskp, mask_size, 707 &rngp[i])) != 0) 708 goto fail1; 709 } 710 711 return (0); 712 713 fail1: 714 EFSYS_PROBE1(fail1, efx_rc_t, rc); 715 716 return (rc); 717 } 718 719 __checkReturn efx_rc_t 720 efx_mac_stats_get_mask( 721 __in efx_nic_t *enp, 722 __out_bcount(mask_size) uint32_t *maskp, 723 __in size_t mask_size) 724 { 725 efx_port_t *epp = &(enp->en_port); 726 const efx_mac_ops_t *emop = epp->ep_emop; 727 efx_rc_t rc; 728 729 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 730 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 731 EFSYS_ASSERT(maskp != NULL); 732 EFSYS_ASSERT(mask_size % sizeof (maskp[0]) == 0); 733 734 (void) memset(maskp, 0, mask_size); 735 736 if ((rc = emop->emo_stats_get_mask(enp, maskp, mask_size)) != 0) 737 goto fail1; 738 739 return (0); 740 741 fail1: 742 EFSYS_PROBE1(fail1, efx_rc_t, rc); 743 744 return (rc); 745 } 746 747 __checkReturn efx_rc_t 748 efx_mac_stats_clear( 749 __in efx_nic_t *enp) 750 { 751 efx_port_t *epp = &(enp->en_port); 752 const efx_mac_ops_t *emop = epp->ep_emop; 753 efx_rc_t rc; 754 755 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 756 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 757 EFSYS_ASSERT(emop != NULL); 758 759 if ((rc = emop->emo_stats_clear(enp)) != 0) 760 goto fail1; 761 762 return (0); 763 764 fail1: 765 EFSYS_PROBE1(fail1, efx_rc_t, rc); 766 767 return (rc); 768 } 769 770 __checkReturn efx_rc_t 771 efx_mac_stats_upload( 772 __in efx_nic_t *enp, 773 __in efsys_mem_t *esmp) 774 { 775 efx_port_t *epp = &(enp->en_port); 776 const efx_mac_ops_t *emop = epp->ep_emop; 777 efx_rc_t rc; 778 779 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 780 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 781 EFSYS_ASSERT(emop != NULL); 782 783 if ((rc = emop->emo_stats_upload(enp, esmp)) != 0) 784 goto fail1; 785 786 return (0); 787 788 fail1: 789 EFSYS_PROBE1(fail1, efx_rc_t, rc); 790 791 return (rc); 792 } 793 794 __checkReturn efx_rc_t 795 efx_mac_stats_periodic( 796 __in efx_nic_t *enp, 797 __in efsys_mem_t *esmp, 798 __in uint16_t period_ms, 799 __in boolean_t events) 800 { 801 efx_port_t *epp = &(enp->en_port); 802 const efx_mac_ops_t *emop = epp->ep_emop; 803 efx_rc_t rc; 804 805 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 806 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 807 808 EFSYS_ASSERT(emop != NULL); 809 810 if (emop->emo_stats_periodic == NULL) { 811 rc = EINVAL; 812 goto fail1; 813 } 814 815 if ((rc = emop->emo_stats_periodic(enp, esmp, period_ms, events)) != 0) 816 goto fail2; 817 818 return (0); 819 820 fail2: 821 EFSYS_PROBE(fail2); 822 fail1: 823 EFSYS_PROBE1(fail1, efx_rc_t, rc); 824 825 return (rc); 826 } 827 828 __checkReturn efx_rc_t 829 efx_mac_stats_update( 830 __in efx_nic_t *enp, 831 __in efsys_mem_t *esmp, 832 __inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *essp, 833 __inout_opt uint32_t *generationp) 834 { 835 efx_port_t *epp = &(enp->en_port); 836 const efx_mac_ops_t *emop = epp->ep_emop; 837 efx_rc_t rc; 838 839 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 840 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 841 EFSYS_ASSERT(emop != NULL); 842 843 rc = emop->emo_stats_update(enp, esmp, essp, generationp); 844 845 return (rc); 846 } 847 848 #endif /* EFSYS_OPT_MAC_STATS */ 849 850 __checkReturn efx_rc_t 851 efx_mac_select( 852 __in efx_nic_t *enp) 853 { 854 efx_port_t *epp = &(enp->en_port); 855 efx_mac_type_t type = EFX_MAC_INVALID; 856 const efx_mac_ops_t *emop; 857 int rc = EINVAL; 858 859 switch (enp->en_family) { 860 #if EFSYS_OPT_SIENA 861 case EFX_FAMILY_SIENA: 862 emop = &__efx_mac_siena_ops; 863 type = EFX_MAC_SIENA; 864 break; 865 #endif /* EFSYS_OPT_SIENA */ 866 867 #if EFSYS_OPT_HUNTINGTON 868 case EFX_FAMILY_HUNTINGTON: 869 emop = &__efx_mac_ef10_ops; 870 type = EFX_MAC_HUNTINGTON; 871 break; 872 #endif /* EFSYS_OPT_HUNTINGTON */ 873 874 #if EFSYS_OPT_MEDFORD 875 case EFX_FAMILY_MEDFORD: 876 emop = &__efx_mac_ef10_ops; 877 type = EFX_MAC_MEDFORD; 878 break; 879 #endif /* EFSYS_OPT_MEDFORD */ 880 881 #if EFSYS_OPT_MEDFORD2 882 case EFX_FAMILY_MEDFORD2: 883 emop = &__efx_mac_ef10_ops; 884 type = EFX_MAC_MEDFORD2; 885 break; 886 #endif /* EFSYS_OPT_MEDFORD2 */ 887 888 default: 889 rc = EINVAL; 890 goto fail1; 891 } 892 893 EFSYS_ASSERT(type != EFX_MAC_INVALID); 894 EFSYS_ASSERT3U(type, <, EFX_MAC_NTYPES); 895 EFSYS_ASSERT(emop != NULL); 896 897 epp->ep_emop = emop; 898 epp->ep_mac_type = type; 899 900 return (0); 901 902 fail1: 903 EFSYS_PROBE1(fail1, efx_rc_t, rc); 904 905 return (rc); 906 } 907 908 #if EFSYS_OPT_SIENA 909 910 #define EFX_MAC_HASH_BITS (1 << 8) 911 912 /* Compute the multicast hash as used on Falcon and Siena. */ 913 static void 914 siena_mac_multicast_hash_compute( 915 __in_ecount(6*count) uint8_t const *addrs, 916 __in int count, 917 __out efx_oword_t *hash_low, 918 __out efx_oword_t *hash_high) 919 { 920 uint32_t crc, index; 921 int i; 922 923 EFSYS_ASSERT(hash_low != NULL); 924 EFSYS_ASSERT(hash_high != NULL); 925 926 EFX_ZERO_OWORD(*hash_low); 927 EFX_ZERO_OWORD(*hash_high); 928 929 for (i = 0; i < count; i++) { 930 /* Calculate hash bucket (IEEE 802.3 CRC32 of the MAC addr) */ 931 crc = efx_crc32_calculate(0xffffffff, addrs, EFX_MAC_ADDR_LEN); 932 index = crc % EFX_MAC_HASH_BITS; 933 if (index < 128) { 934 EFX_SET_OWORD_BIT(*hash_low, index); 935 } else { 936 EFX_SET_OWORD_BIT(*hash_high, index - 128); 937 } 938 939 addrs += EFX_MAC_ADDR_LEN; 940 } 941 } 942 943 static __checkReturn efx_rc_t 944 siena_mac_multicast_list_set( 945 __in efx_nic_t *enp) 946 { 947 efx_port_t *epp = &(enp->en_port); 948 const efx_mac_ops_t *emop = epp->ep_emop; 949 efx_oword_t old_hash[2]; 950 efx_rc_t rc; 951 952 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 953 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 954 955 memcpy(old_hash, epp->ep_multicst_hash, sizeof (old_hash)); 956 957 siena_mac_multicast_hash_compute( 958 epp->ep_mulcst_addr_list, 959 epp->ep_mulcst_addr_count, 960 &epp->ep_multicst_hash[0], 961 &epp->ep_multicst_hash[1]); 962 963 if ((rc = emop->emo_reconfigure(enp)) != 0) 964 goto fail1; 965 966 return (0); 967 968 fail1: 969 EFSYS_PROBE1(fail1, efx_rc_t, rc); 970 971 memcpy(epp->ep_multicst_hash, old_hash, sizeof (old_hash)); 972 973 return (rc); 974 } 975 976 #endif /* EFSYS_OPT_SIENA */ 977