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