efx_mac.c revision 299323
150472Speter/*- 238738Sbrian * Copyright (c) 2007-2015 Solarflare Communications Inc. 390807Sgshapiro * All rights reserved. 490807Sgshapiro * 590807Sgshapiro * Redistribution and use in source and binary forms, with or without 690807Sgshapiro * modification, are permitted provided that the following conditions are met: 790807Sgshapiro * 896210Sgshapiro * 1. Redistributions of source code must retain the above copyright notice, 990807Sgshapiro * this list of conditions and the following disclaimer. 1090807Sgshapiro * 2. Redistributions in binary form must reproduce the above copyright notice, 1190807Sgshapiro * this list of conditions and the following disclaimer in the documentation 1292857Sgshapiro * and/or other materials provided with the distribution. 1390807Sgshapiro * 1497131Sgshapiro * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 1597131Sgshapiro * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 1697131Sgshapiro * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1797131Sgshapiro * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 1897131Sgshapiro * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 1997131Sgshapiro * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2090807Sgshapiro * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 2194678Sgshapiro * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 2294678Sgshapiro * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 2394678Sgshapiro * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 2494678Sgshapiro * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2594678Sgshapiro * 2694678Sgshapiro * The views and conclusions contained in the software and documentation are 2790807Sgshapiro * those of the authors and should not be interpreted as representing official 2890807Sgshapiro * policies, either expressed or implied, of the FreeBSD Project. 2990807Sgshapiro */ 3090807Sgshapiro 3190807Sgshapiro#include <sys/cdefs.h> 3291379Sru__FBSDID("$FreeBSD: head/sys/dev/sfxge/common/efx_mac.c 299323 2016-05-10 07:07:49Z arybchik $"); 3390807Sgshapiro 3490807Sgshapiro#include "efx.h" 3590807Sgshapiro#include "efx_impl.h" 3690807Sgshapiro 3790807Sgshapiro#if EFSYS_OPT_SIENA 3890807Sgshapiro 3990807Sgshapirostatic __checkReturn efx_rc_t 4091379Srufalconsiena_mac_multicast_list_set( 4191379Sru __in efx_nic_t *enp); 4291379Sru 4390807Sgshapiro#endif /* EFSYS_OPT_SIENA */ 4490807Sgshapiro 4533835Sjmb#if EFSYS_OPT_SIENA 4630581Sjmbstatic efx_mac_ops_t __efx_siena_mac_ops = { 4768297Sgshapiro NULL, /* emo_reset */ 4866940Sgshapiro siena_mac_poll, /* emo_poll */ 4966940Sgshapiro siena_mac_up, /* emo_up */ 5066940Sgshapiro siena_mac_reconfigure, /* emo_addr_set */ 5166940Sgshapiro siena_mac_reconfigure, /* emo_pdu_set */ 5266940Sgshapiro siena_mac_reconfigure, /* emo_reconfigure */ 5366940Sgshapiro falconsiena_mac_multicast_list_set, /* emo_multicast_list_set */ 5430581Sjmb NULL, /* emo_filter_set_default_rxq */ 5566940Sgshapiro NULL, /* emo_filter_default_rxq_clear */ 5666940Sgshapiro#if EFSYS_OPT_LOOPBACK 5766940Sgshapiro siena_mac_loopback_set, /* emo_loopback_set */ 5866940Sgshapiro#endif /* EFSYS_OPT_LOOPBACK */ 59#if EFSYS_OPT_MAC_STATS 60 efx_mcdi_mac_stats_upload, /* emo_stats_upload */ 61 efx_mcdi_mac_stats_periodic, /* emo_stats_periodic */ 62 siena_mac_stats_update /* emo_stats_update */ 63#endif /* EFSYS_OPT_MAC_STATS */ 64}; 65#endif /* EFSYS_OPT_SIENA */ 66 67#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD 68static efx_mac_ops_t __efx_ef10_mac_ops = { 69 NULL, /* emo_reset */ 70 ef10_mac_poll, /* emo_poll */ 71 ef10_mac_up, /* emo_up */ 72 ef10_mac_addr_set, /* emo_addr_set */ 73 ef10_mac_pdu_set, /* emo_pdu_set */ 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 efx_mcdi_mac_stats_upload, /* emo_stats_upload */ 84 efx_mcdi_mac_stats_periodic, /* emo_stats_periodic */ 85 ef10_mac_stats_update /* emo_stats_update */ 86#endif /* EFSYS_OPT_MAC_STATS */ 87}; 88#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */ 89 90static efx_mac_ops_t *__efx_mac_ops[] = { 91 /* [EFX_MAC_INVALID] */ 92 NULL, 93 /* [EFX_MAC_FALCON_GMAC] */ 94 NULL, 95 /* [EFX_MAC_FALCON_XMAC] */ 96 NULL, 97 /* [EFX_MAC_SIENA] */ 98#if EFSYS_OPT_SIENA 99 &__efx_siena_mac_ops, 100#else 101 NULL, 102#endif 103 /* [EFX_MAC_HUNTINGTON] */ 104#if EFSYS_OPT_HUNTINGTON 105 &__efx_ef10_mac_ops, 106#else 107 NULL, 108#endif 109 /* [EFX_MAC_MEDFORD] */ 110#if EFSYS_OPT_MEDFORD 111 &__efx_ef10_mac_ops, 112#else 113 NULL, 114#endif 115}; 116 117 __checkReturn efx_rc_t 118efx_mac_pdu_set( 119 __in efx_nic_t *enp, 120 __in size_t pdu) 121{ 122 efx_port_t *epp = &(enp->en_port); 123 efx_mac_ops_t *emop = epp->ep_emop; 124 uint32_t old_pdu; 125 efx_rc_t rc; 126 127 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 128 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 129 EFSYS_ASSERT(emop != NULL); 130 131 if (pdu < EFX_MAC_PDU_MIN) { 132 rc = EINVAL; 133 goto fail1; 134 } 135 136 if (pdu > EFX_MAC_PDU_MAX) { 137 rc = EINVAL; 138 goto fail2; 139 } 140 141 old_pdu = epp->ep_mac_pdu; 142 epp->ep_mac_pdu = (uint32_t)pdu; 143 if ((rc = emop->emo_pdu_set(enp)) != 0) 144 goto fail3; 145 146 return (0); 147 148fail3: 149 EFSYS_PROBE(fail3); 150 151 epp->ep_mac_pdu = old_pdu; 152 153fail2: 154 EFSYS_PROBE(fail2); 155fail1: 156 EFSYS_PROBE1(fail1, efx_rc_t, rc); 157 158 return (rc); 159} 160 161 __checkReturn efx_rc_t 162efx_mac_addr_set( 163 __in efx_nic_t *enp, 164 __in uint8_t *addr) 165{ 166 efx_port_t *epp = &(enp->en_port); 167 efx_mac_ops_t *emop = epp->ep_emop; 168 uint8_t old_addr[6]; 169 uint32_t oui; 170 efx_rc_t rc; 171 172 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 173 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 174 175 if (EFX_MAC_ADDR_IS_MULTICAST(addr)) { 176 rc = EINVAL; 177 goto fail1; 178 } 179 180 oui = addr[0] << 16 | addr[1] << 8 | addr[2]; 181 if (oui == 0x000000) { 182 rc = EINVAL; 183 goto fail2; 184 } 185 186 EFX_MAC_ADDR_COPY(old_addr, epp->ep_mac_addr); 187 EFX_MAC_ADDR_COPY(epp->ep_mac_addr, addr); 188 if ((rc = emop->emo_addr_set(enp)) != 0) 189 goto fail3; 190 191 return (0); 192 193fail3: 194 EFSYS_PROBE(fail3); 195 196 EFX_MAC_ADDR_COPY(epp->ep_mac_addr, old_addr); 197 198fail2: 199 EFSYS_PROBE(fail2); 200fail1: 201 EFSYS_PROBE1(fail1, efx_rc_t, rc); 202 203 return (rc); 204} 205 206 __checkReturn efx_rc_t 207efx_mac_filter_set( 208 __in efx_nic_t *enp, 209 __in boolean_t all_unicst, 210 __in boolean_t mulcst, 211 __in boolean_t all_mulcst, 212 __in boolean_t brdcst) 213{ 214 efx_port_t *epp = &(enp->en_port); 215 efx_mac_ops_t *emop = epp->ep_emop; 216 boolean_t old_all_unicst; 217 boolean_t old_mulcst; 218 boolean_t old_all_mulcst; 219 boolean_t old_brdcst; 220 efx_rc_t rc; 221 222 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 223 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 224 225 old_all_unicst = epp->ep_all_unicst; 226 old_mulcst = epp->ep_mulcst; 227 old_all_mulcst = epp->ep_all_mulcst; 228 old_brdcst = epp->ep_brdcst; 229 230 epp->ep_all_unicst = all_unicst; 231 epp->ep_mulcst = mulcst; 232 epp->ep_all_mulcst = all_mulcst; 233 epp->ep_brdcst = brdcst; 234 235 if ((rc = emop->emo_reconfigure(enp)) != 0) 236 goto fail1; 237 238 return (0); 239 240fail1: 241 EFSYS_PROBE1(fail1, efx_rc_t, rc); 242 243 epp->ep_all_unicst = old_all_unicst; 244 epp->ep_mulcst = old_mulcst; 245 epp->ep_all_mulcst = old_all_mulcst; 246 epp->ep_brdcst = old_brdcst; 247 248 return (rc); 249} 250 251 __checkReturn efx_rc_t 252efx_mac_drain( 253 __in efx_nic_t *enp, 254 __in boolean_t enabled) 255{ 256 efx_port_t *epp = &(enp->en_port); 257 efx_mac_ops_t *emop = epp->ep_emop; 258 efx_rc_t rc; 259 260 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 261 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 262 EFSYS_ASSERT(emop != NULL); 263 264 if (epp->ep_mac_drain == enabled) 265 return (0); 266 267 epp->ep_mac_drain = enabled; 268 269 if (enabled && emop->emo_reset != NULL) { 270 if ((rc = emop->emo_reset(enp)) != 0) 271 goto fail1; 272 273 EFSYS_ASSERT(enp->en_reset_flags & EFX_RESET_MAC); 274 enp->en_reset_flags &= ~EFX_RESET_PHY; 275 } 276 277 if ((rc = emop->emo_reconfigure(enp)) != 0) 278 goto fail2; 279 280 return (0); 281 282fail2: 283 EFSYS_PROBE(fail2); 284fail1: 285 EFSYS_PROBE1(fail1, efx_rc_t, rc); 286 287 return (rc); 288} 289 290 __checkReturn efx_rc_t 291efx_mac_up( 292 __in efx_nic_t *enp, 293 __out boolean_t *mac_upp) 294{ 295 efx_port_t *epp = &(enp->en_port); 296 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 307fail1: 308 EFSYS_PROBE1(fail1, efx_rc_t, rc); 309 310 return (rc); 311} 312 313 __checkReturn efx_rc_t 314efx_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 efx_mac_ops_t *emop = epp->ep_emop; 321 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 372fail3: 373 EFSYS_PROBE(fail3); 374 375fail2: 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 382fail1: 383 EFSYS_PROBE1(fail1, efx_rc_t, rc); 384 385 return (rc); 386} 387 388 void 389efx_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 414efx_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 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 465fail3: 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 479fail2: 480 EFSYS_PROBE(fail2); 481 482fail1: 483 EFSYS_PROBE1(fail1, efx_rc_t, rc); 484 485 return (rc); 486 487} 488 489 __checkReturn efx_rc_t 490efx_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 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 510fail1: 511 EFSYS_PROBE1(fail1, efx_rc_t, rc); 512 513 return (rc); 514} 515 516 void 517efx_mac_filter_default_rxq_clear( 518 __in efx_nic_t *enp) 519{ 520 efx_port_t *epp = &(enp->en_port); 521 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 054d43a31d2d7a45 */ 536static const char *__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}; 619/* END MKCONFIG GENERATED EfxMacStatNamesBlock */ 620 621 __checkReturn const char * 622efx_mac_stat_name( 623 __in efx_nic_t *enp, 624 __in unsigned int id) 625{ 626 _NOTE(ARGUNUSED(enp)) 627 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 628 629 EFSYS_ASSERT3U(id, <, EFX_MAC_NSTATS); 630 return (__efx_mac_stat_name[id]); 631} 632 633#endif /* EFSYS_OPT_NAMES */ 634 635 __checkReturn efx_rc_t 636efx_mac_stats_upload( 637 __in efx_nic_t *enp, 638 __in efsys_mem_t *esmp) 639{ 640 efx_port_t *epp = &(enp->en_port); 641 efx_mac_ops_t *emop = epp->ep_emop; 642 efx_rc_t rc; 643 644 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 645 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 646 EFSYS_ASSERT(emop != NULL); 647 648 /* 649 * Don't assert !ep_mac_stats_pending, because the client might 650 * have failed to finalise statistics when previously stopping 651 * the port. 652 */ 653 if ((rc = emop->emo_stats_upload(enp, esmp)) != 0) 654 goto fail1; 655 656 epp->ep_mac_stats_pending = B_TRUE; 657 658 return (0); 659 660fail1: 661 EFSYS_PROBE1(fail1, efx_rc_t, rc); 662 663 return (rc); 664} 665 666 __checkReturn efx_rc_t 667efx_mac_stats_periodic( 668 __in efx_nic_t *enp, 669 __in efsys_mem_t *esmp, 670 __in uint16_t period_ms, 671 __in boolean_t events) 672{ 673 efx_port_t *epp = &(enp->en_port); 674 efx_mac_ops_t *emop = epp->ep_emop; 675 efx_rc_t rc; 676 677 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 678 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 679 680 EFSYS_ASSERT(emop != NULL); 681 682 if (emop->emo_stats_periodic == NULL) { 683 rc = EINVAL; 684 goto fail1; 685 } 686 687 if ((rc = emop->emo_stats_periodic(enp, esmp, period_ms, events)) != 0) 688 goto fail2; 689 690 return (0); 691 692fail2: 693 EFSYS_PROBE(fail2); 694fail1: 695 EFSYS_PROBE1(fail1, efx_rc_t, rc); 696 697 return (rc); 698} 699 700 701 __checkReturn efx_rc_t 702efx_mac_stats_update( 703 __in efx_nic_t *enp, 704 __in efsys_mem_t *esmp, 705 __inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *essp, 706 __inout_opt uint32_t *generationp) 707{ 708 efx_port_t *epp = &(enp->en_port); 709 efx_mac_ops_t *emop = epp->ep_emop; 710 efx_rc_t rc; 711 712 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 713 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 714 EFSYS_ASSERT(emop != NULL); 715 716 rc = emop->emo_stats_update(enp, esmp, essp, generationp); 717 if (rc == 0) 718 epp->ep_mac_stats_pending = B_FALSE; 719 720 return (rc); 721} 722 723#endif /* EFSYS_OPT_MAC_STATS */ 724 725 __checkReturn efx_rc_t 726efx_mac_select( 727 __in efx_nic_t *enp) 728{ 729 efx_port_t *epp = &(enp->en_port); 730 efx_mac_type_t type = EFX_MAC_INVALID; 731 efx_mac_ops_t *emop; 732 int rc = EINVAL; 733 734#if EFSYS_OPT_SIENA 735 if (enp->en_family == EFX_FAMILY_SIENA) { 736 type = EFX_MAC_SIENA; 737 goto chosen; 738 } 739#endif 740 741#if EFSYS_OPT_HUNTINGTON 742 if (enp->en_family == EFX_FAMILY_HUNTINGTON) { 743 type = EFX_MAC_HUNTINGTON; 744 goto chosen; 745 } 746#endif 747 748#if EFSYS_OPT_MEDFORD 749 if (enp->en_family == EFX_FAMILY_MEDFORD) { 750 type = EFX_MAC_MEDFORD; 751 goto chosen; 752 } 753#endif 754 755chosen: 756 EFSYS_ASSERT(type != EFX_MAC_INVALID); 757 EFSYS_ASSERT3U(type, <, EFX_MAC_NTYPES); 758 emop = epp->ep_emop = (efx_mac_ops_t *)__efx_mac_ops[type]; 759 EFSYS_ASSERT(emop != NULL); 760 761 epp->ep_mac_type = type; 762 763 if (emop->emo_reset != NULL) { 764 if ((rc = emop->emo_reset(enp)) != 0) 765 goto fail1; 766 767 EFSYS_ASSERT(enp->en_reset_flags & EFX_RESET_MAC); 768 enp->en_reset_flags &= ~EFX_RESET_MAC; 769 } 770 771 return (0); 772 773fail1: 774 EFSYS_PROBE1(fail1, efx_rc_t, rc); 775 776 return (rc); 777} 778 779 780#if EFSYS_OPT_SIENA 781 782#define EFX_MAC_HASH_BITS (1 << 8) 783 784/* Compute the multicast hash as used on Falcon and Siena. */ 785static void 786falconsiena_mac_multicast_hash_compute( 787 __in_ecount(6*count) uint8_t const *addrs, 788 __in int count, 789 __out efx_oword_t *hash_low, 790 __out efx_oword_t *hash_high) 791{ 792 uint32_t crc, index; 793 int i; 794 795 EFSYS_ASSERT(hash_low != NULL); 796 EFSYS_ASSERT(hash_high != NULL); 797 798 EFX_ZERO_OWORD(*hash_low); 799 EFX_ZERO_OWORD(*hash_high); 800 801 for (i = 0; i < count; i++) { 802 /* Calculate hash bucket (IEEE 802.3 CRC32 of the MAC addr) */ 803 crc = efx_crc32_calculate(0xffffffff, addrs, EFX_MAC_ADDR_LEN); 804 index = crc % EFX_MAC_HASH_BITS; 805 if (index < 128) { 806 EFX_SET_OWORD_BIT(*hash_low, index); 807 } else { 808 EFX_SET_OWORD_BIT(*hash_high, index - 128); 809 } 810 811 addrs += EFX_MAC_ADDR_LEN; 812 } 813} 814 815static __checkReturn efx_rc_t 816falconsiena_mac_multicast_list_set( 817 __in efx_nic_t *enp) 818{ 819 efx_port_t *epp = &(enp->en_port); 820 efx_mac_ops_t *emop = epp->ep_emop; 821 efx_oword_t old_hash[2]; 822 efx_rc_t rc; 823 824 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 825 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT); 826 827 memcpy(old_hash, epp->ep_multicst_hash, sizeof (old_hash)); 828 829 falconsiena_mac_multicast_hash_compute(epp->ep_mulcst_addr_list, 830 epp->ep_mulcst_addr_count, 831 &epp->ep_multicst_hash[0], 832 &epp->ep_multicst_hash[1]); 833 834 if ((rc = emop->emo_reconfigure(enp)) != 0) 835 goto fail1; 836 837 return (0); 838 839fail1: 840 EFSYS_PROBE1(fail1, efx_rc_t, rc); 841 842 memcpy(epp->ep_multicst_hash, old_hash, sizeof (old_hash)); 843 844 return (rc); 845} 846 847#endif /* EFSYS_OPT_SIENA */ 848