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