1/*- 2 * Copyright (c) 2012-2016 Solarflare Communications Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * The views and conclusions contained in the software and documentation are 27 * those of the authors and should not be interpreted as representing official 28 * policies, either expressed or implied, of the FreeBSD Project. 29 */ 30 31#include <sys/cdefs.h> 32__FBSDID("$FreeBSD: stable/10/sys/dev/sfxge/common/ef10_mac.c 342519 2018-12-26 10:26:58Z arybchik $"); 33 34#include "efx.h" 35#include "efx_impl.h" 36 37 38#if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD 39 40 __checkReturn efx_rc_t 41ef10_mac_poll( 42 __in efx_nic_t *enp, 43 __out efx_link_mode_t *link_modep) 44{ 45 efx_port_t *epp = &(enp->en_port); 46 ef10_link_state_t els; 47 efx_rc_t rc; 48 49 if ((rc = ef10_phy_get_link(enp, &els)) != 0) 50 goto fail1; 51 52 epp->ep_adv_cap_mask = els.els_adv_cap_mask; 53 epp->ep_fcntl = els.els_fcntl; 54 55 *link_modep = els.els_link_mode; 56 57 return (0); 58 59fail1: 60 EFSYS_PROBE1(fail1, efx_rc_t, rc); 61 62 *link_modep = EFX_LINK_UNKNOWN; 63 64 return (rc); 65} 66 67 __checkReturn efx_rc_t 68ef10_mac_up( 69 __in efx_nic_t *enp, 70 __out boolean_t *mac_upp) 71{ 72 ef10_link_state_t els; 73 efx_rc_t rc; 74 75 /* 76 * Because EF10 doesn't *require* polling, we can't rely on 77 * ef10_mac_poll() being executed to populate epp->ep_mac_up. 78 */ 79 if ((rc = ef10_phy_get_link(enp, &els)) != 0) 80 goto fail1; 81 82 *mac_upp = els.els_mac_up; 83 84 return (0); 85 86fail1: 87 EFSYS_PROBE1(fail1, efx_rc_t, rc); 88 89 return (rc); 90} 91 92/* 93 * EF10 adapters use MC_CMD_VADAPTOR_SET_MAC to set the 94 * MAC address; the address field in MC_CMD_SET_MAC has no 95 * effect. 96 * MC_CMD_VADAPTOR_SET_MAC requires mac-spoofing privilege and 97 * the port to have no filters or queues active. 98 */ 99static __checkReturn efx_rc_t 100efx_mcdi_vadapter_set_mac( 101 __in efx_nic_t *enp) 102{ 103 efx_port_t *epp = &(enp->en_port); 104 efx_mcdi_req_t req; 105 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VADAPTOR_SET_MAC_IN_LEN, 106 MC_CMD_VADAPTOR_SET_MAC_OUT_LEN); 107 efx_rc_t rc; 108 109 req.emr_cmd = MC_CMD_VADAPTOR_SET_MAC; 110 req.emr_in_buf = payload; 111 req.emr_in_length = MC_CMD_VADAPTOR_SET_MAC_IN_LEN; 112 req.emr_out_buf = payload; 113 req.emr_out_length = MC_CMD_VADAPTOR_SET_MAC_OUT_LEN; 114 115 MCDI_IN_SET_DWORD(req, VADAPTOR_SET_MAC_IN_UPSTREAM_PORT_ID, 116 enp->en_vport_id); 117 EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, VADAPTOR_SET_MAC_IN_MACADDR), 118 epp->ep_mac_addr); 119 120 efx_mcdi_execute(enp, &req); 121 122 if (req.emr_rc != 0) { 123 rc = req.emr_rc; 124 goto fail1; 125 } 126 127 return (0); 128 129fail1: 130 EFSYS_PROBE1(fail1, efx_rc_t, rc); 131 132 return (rc); 133} 134 135 __checkReturn efx_rc_t 136ef10_mac_addr_set( 137 __in efx_nic_t *enp) 138{ 139 efx_rc_t rc; 140 141 if ((rc = efx_mcdi_vadapter_set_mac(enp)) != 0) { 142 if (rc != ENOTSUP) 143 goto fail1; 144 145 /* 146 * Fallback for older Huntington firmware without Vadapter 147 * support. 148 */ 149 if ((rc = ef10_mac_reconfigure(enp)) != 0) 150 goto fail2; 151 } 152 153 return (0); 154 155fail2: 156 EFSYS_PROBE(fail2); 157 158fail1: 159 EFSYS_PROBE1(fail1, efx_rc_t, rc); 160 161 return (rc); 162} 163 164static __checkReturn efx_rc_t 165efx_mcdi_mtu_set( 166 __in efx_nic_t *enp, 167 __in uint32_t mtu) 168{ 169 efx_mcdi_req_t req; 170 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_MAC_EXT_IN_LEN, 171 MC_CMD_SET_MAC_OUT_LEN); 172 efx_rc_t rc; 173 174 req.emr_cmd = MC_CMD_SET_MAC; 175 req.emr_in_buf = payload; 176 req.emr_in_length = MC_CMD_SET_MAC_EXT_IN_LEN; 177 req.emr_out_buf = payload; 178 req.emr_out_length = MC_CMD_SET_MAC_OUT_LEN; 179 180 /* Only configure the MTU in this call to MC_CMD_SET_MAC */ 181 MCDI_IN_SET_DWORD(req, SET_MAC_EXT_IN_MTU, mtu); 182 MCDI_IN_POPULATE_DWORD_1(req, SET_MAC_EXT_IN_CONTROL, 183 SET_MAC_EXT_IN_CFG_MTU, 1); 184 185 efx_mcdi_execute(enp, &req); 186 187 if (req.emr_rc != 0) { 188 rc = req.emr_rc; 189 goto fail1; 190 } 191 192 return (0); 193 194fail1: 195 EFSYS_PROBE1(fail1, efx_rc_t, rc); 196 197 return (rc); 198} 199 200static __checkReturn efx_rc_t 201efx_mcdi_mtu_get( 202 __in efx_nic_t *enp, 203 __out size_t *mtu) 204{ 205 efx_mcdi_req_t req; 206 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_MAC_EXT_IN_LEN, 207 MC_CMD_SET_MAC_V2_OUT_LEN); 208 efx_rc_t rc; 209 210 req.emr_cmd = MC_CMD_SET_MAC; 211 req.emr_in_buf = payload; 212 req.emr_in_length = MC_CMD_SET_MAC_EXT_IN_LEN; 213 req.emr_out_buf = payload; 214 req.emr_out_length = MC_CMD_SET_MAC_V2_OUT_LEN; 215 216 /* 217 * With MC_CMD_SET_MAC_EXT_IN_CONTROL set to 0, this just queries the 218 * MTU. This should always be supported on Medford, but it is not 219 * supported on older Huntington firmware. 220 */ 221 MCDI_IN_SET_DWORD(req, SET_MAC_EXT_IN_CONTROL, 0); 222 223 efx_mcdi_execute(enp, &req); 224 225 if (req.emr_rc != 0) { 226 rc = req.emr_rc; 227 goto fail1; 228 } 229 if (req.emr_out_length_used < MC_CMD_SET_MAC_V2_OUT_MTU_OFST + 4) { 230 rc = EMSGSIZE; 231 goto fail2; 232 } 233 234 *mtu = MCDI_OUT_DWORD(req, SET_MAC_V2_OUT_MTU); 235 236 return (0); 237 238fail2: 239 EFSYS_PROBE(fail2); 240fail1: 241 EFSYS_PROBE1(fail1, efx_rc_t, rc); 242 243 return (rc); 244} 245 246 __checkReturn efx_rc_t 247ef10_mac_pdu_set( 248 __in efx_nic_t *enp) 249{ 250 efx_port_t *epp = &(enp->en_port); 251 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 252 efx_rc_t rc; 253 254 if (encp->enc_enhanced_set_mac_supported) { 255 if ((rc = efx_mcdi_mtu_set(enp, epp->ep_mac_pdu)) != 0) 256 goto fail1; 257 } else { 258 /* 259 * Fallback for older Huntington firmware, which always 260 * configure all of the parameters to MC_CMD_SET_MAC. This isn't 261 * suitable for setting the MTU on unpriviliged functions. 262 */ 263 if ((rc = ef10_mac_reconfigure(enp)) != 0) 264 goto fail2; 265 } 266 267 return (0); 268 269fail2: 270 EFSYS_PROBE(fail2); 271fail1: 272 EFSYS_PROBE1(fail1, efx_rc_t, rc); 273 274 return (rc); 275} 276 277 __checkReturn efx_rc_t 278ef10_mac_pdu_get( 279 __in efx_nic_t *enp, 280 __out size_t *pdu) 281{ 282 efx_rc_t rc; 283 284 if ((rc = efx_mcdi_mtu_get(enp, pdu)) != 0) 285 goto fail1; 286 287 return (0); 288 289fail1: 290 EFSYS_PROBE1(fail1, efx_rc_t, rc); 291 292 return (rc); 293} 294 295__checkReturn efx_rc_t 296ef10_mac_reconfigure( 297 __in efx_nic_t *enp) 298{ 299 efx_port_t *epp = &(enp->en_port); 300 efx_mcdi_req_t req; 301 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_MAC_IN_LEN, 302 MC_CMD_SET_MAC_OUT_LEN); 303 efx_rc_t rc; 304 305 req.emr_cmd = MC_CMD_SET_MAC; 306 req.emr_in_buf = payload; 307 req.emr_in_length = MC_CMD_SET_MAC_IN_LEN; 308 req.emr_out_buf = payload; 309 req.emr_out_length = MC_CMD_SET_MAC_OUT_LEN; 310 311 MCDI_IN_SET_DWORD(req, SET_MAC_IN_MTU, epp->ep_mac_pdu); 312 MCDI_IN_SET_DWORD(req, SET_MAC_IN_DRAIN, epp->ep_mac_drain ? 1 : 0); 313 EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, SET_MAC_IN_ADDR), 314 epp->ep_mac_addr); 315 316 /* 317 * Note: The Huntington MAC does not support REJECT_BRDCST. 318 * The REJECT_UNCST flag will also prevent multicast traffic 319 * from reaching the filters. As Huntington filters drop any 320 * traffic that does not match a filter it is ok to leave the 321 * MAC running in promiscuous mode. See bug41141. 322 * 323 * FIXME: Does REJECT_UNCST behave the same way on Medford? 324 */ 325 MCDI_IN_POPULATE_DWORD_2(req, SET_MAC_IN_REJECT, 326 SET_MAC_IN_REJECT_UNCST, 0, 327 SET_MAC_IN_REJECT_BRDCST, 0); 328 329 /* 330 * Flow control, whether it is auto-negotiated or not, 331 * is set via the PHY advertised capabilities. When set to 332 * automatic the MAC will use the PHY settings to determine 333 * the flow control settings. 334 */ 335 MCDI_IN_SET_DWORD(req, SET_MAC_IN_FCNTL, MC_CMD_FCNTL_AUTO); 336 337 /* Do not include the Ethernet frame checksum in RX packets */ 338 MCDI_IN_POPULATE_DWORD_1(req, SET_MAC_IN_FLAGS, 339 SET_MAC_IN_FLAG_INCLUDE_FCS, 0); 340 341 efx_mcdi_execute_quiet(enp, &req); 342 343 if (req.emr_rc != 0) { 344 /* 345 * Unprivileged functions cannot control link state, 346 * but still need to configure filters. 347 */ 348 if (req.emr_rc != EACCES) { 349 rc = req.emr_rc; 350 goto fail1; 351 } 352 } 353 354 /* 355 * Apply the filters for the MAC configuration. 356 * If the NIC isn't ready to accept filters this may 357 * return success without setting anything. 358 */ 359 rc = efx_filter_reconfigure(enp, epp->ep_mac_addr, 360 epp->ep_all_unicst, epp->ep_mulcst, 361 epp->ep_all_mulcst, epp->ep_brdcst, 362 epp->ep_mulcst_addr_list, 363 epp->ep_mulcst_addr_count); 364 365 return (0); 366 367fail1: 368 EFSYS_PROBE1(fail1, efx_rc_t, rc); 369 370 return (rc); 371} 372 373 __checkReturn efx_rc_t 374ef10_mac_multicast_list_set( 375 __in efx_nic_t *enp) 376{ 377 efx_port_t *epp = &(enp->en_port); 378 const efx_mac_ops_t *emop = epp->ep_emop; 379 efx_rc_t rc; 380 381 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 382 enp->en_family == EFX_FAMILY_MEDFORD); 383 384 if ((rc = emop->emo_reconfigure(enp)) != 0) 385 goto fail1; 386 387 return (0); 388 389fail1: 390 EFSYS_PROBE1(fail1, efx_rc_t, rc); 391 392 return (rc); 393} 394 395 __checkReturn efx_rc_t 396ef10_mac_filter_default_rxq_set( 397 __in efx_nic_t *enp, 398 __in efx_rxq_t *erp, 399 __in boolean_t using_rss) 400{ 401 efx_port_t *epp = &(enp->en_port); 402 efx_rxq_t *old_rxq; 403 boolean_t old_using_rss; 404 efx_rc_t rc; 405 406 ef10_filter_get_default_rxq(enp, &old_rxq, &old_using_rss); 407 408 ef10_filter_default_rxq_set(enp, erp, using_rss); 409 410 rc = efx_filter_reconfigure(enp, epp->ep_mac_addr, 411 epp->ep_all_unicst, epp->ep_mulcst, 412 epp->ep_all_mulcst, epp->ep_brdcst, 413 epp->ep_mulcst_addr_list, 414 epp->ep_mulcst_addr_count); 415 416 if (rc != 0) 417 goto fail1; 418 419 return (0); 420 421fail1: 422 EFSYS_PROBE1(fail1, efx_rc_t, rc); 423 424 ef10_filter_default_rxq_set(enp, old_rxq, old_using_rss); 425 426 return (rc); 427} 428 429 void 430ef10_mac_filter_default_rxq_clear( 431 __in efx_nic_t *enp) 432{ 433 efx_port_t *epp = &(enp->en_port); 434 435 ef10_filter_default_rxq_clear(enp); 436 437 (void) efx_filter_reconfigure(enp, epp->ep_mac_addr, 438 epp->ep_all_unicst, epp->ep_mulcst, 439 epp->ep_all_mulcst, epp->ep_brdcst, 440 epp->ep_mulcst_addr_list, 441 epp->ep_mulcst_addr_count); 442} 443 444 445#if EFSYS_OPT_LOOPBACK 446 447 __checkReturn efx_rc_t 448ef10_mac_loopback_set( 449 __in efx_nic_t *enp, 450 __in efx_link_mode_t link_mode, 451 __in efx_loopback_type_t loopback_type) 452{ 453 efx_port_t *epp = &(enp->en_port); 454 const efx_phy_ops_t *epop = epp->ep_epop; 455 efx_loopback_type_t old_loopback_type; 456 efx_link_mode_t old_loopback_link_mode; 457 efx_rc_t rc; 458 459 /* The PHY object handles this on EF10 */ 460 old_loopback_type = epp->ep_loopback_type; 461 old_loopback_link_mode = epp->ep_loopback_link_mode; 462 epp->ep_loopback_type = loopback_type; 463 epp->ep_loopback_link_mode = link_mode; 464 465 if ((rc = epop->epo_reconfigure(enp)) != 0) 466 goto fail1; 467 468 return (0); 469 470fail1: 471 EFSYS_PROBE1(fail1, efx_rc_t, rc); 472 473 epp->ep_loopback_type = old_loopback_type; 474 epp->ep_loopback_link_mode = old_loopback_link_mode; 475 476 return (rc); 477} 478 479#endif /* EFSYS_OPT_LOOPBACK */ 480 481#if EFSYS_OPT_MAC_STATS 482 483 __checkReturn efx_rc_t 484ef10_mac_stats_get_mask( 485 __in efx_nic_t *enp, 486 __inout_bcount(mask_size) uint32_t *maskp, 487 __in size_t mask_size) 488{ 489 const struct efx_mac_stats_range ef10_common[] = { 490 { EFX_MAC_RX_OCTETS, EFX_MAC_RX_GE_15XX_PKTS }, 491 { EFX_MAC_RX_FCS_ERRORS, EFX_MAC_RX_DROP_EVENTS }, 492 { EFX_MAC_RX_JABBER_PKTS, EFX_MAC_RX_JABBER_PKTS }, 493 { EFX_MAC_RX_NODESC_DROP_CNT, EFX_MAC_TX_PAUSE_PKTS }, 494 }; 495 const struct efx_mac_stats_range ef10_tx_size_bins[] = { 496 { EFX_MAC_TX_LE_64_PKTS, EFX_MAC_TX_GE_15XX_PKTS }, 497 }; 498 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 499 efx_port_t *epp = &(enp->en_port); 500 efx_rc_t rc; 501 502 if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size, 503 ef10_common, EFX_ARRAY_SIZE(ef10_common))) != 0) 504 goto fail1; 505 506 if (epp->ep_phy_cap_mask & (1 << MC_CMD_PHY_CAP_40000FDX_LBN)) { 507 const struct efx_mac_stats_range ef10_40g_extra[] = { 508 { EFX_MAC_RX_ALIGN_ERRORS, EFX_MAC_RX_ALIGN_ERRORS }, 509 }; 510 511 if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size, 512 ef10_40g_extra, EFX_ARRAY_SIZE(ef10_40g_extra))) != 0) 513 goto fail2; 514 515 if (encp->enc_mac_stats_40g_tx_size_bins) { 516 if ((rc = efx_mac_stats_mask_add_ranges(maskp, 517 mask_size, ef10_tx_size_bins, 518 EFX_ARRAY_SIZE(ef10_tx_size_bins))) != 0) 519 goto fail3; 520 } 521 } else { 522 if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size, 523 ef10_tx_size_bins, EFX_ARRAY_SIZE(ef10_tx_size_bins))) != 0) 524 goto fail4; 525 } 526 527 if (encp->enc_pm_and_rxdp_counters) { 528 const struct efx_mac_stats_range ef10_pm_and_rxdp[] = { 529 { EFX_MAC_PM_TRUNC_BB_OVERFLOW, EFX_MAC_RXDP_HLB_WAIT }, 530 }; 531 532 if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size, 533 ef10_pm_and_rxdp, EFX_ARRAY_SIZE(ef10_pm_and_rxdp))) != 0) 534 goto fail5; 535 } 536 537 if (encp->enc_datapath_cap_evb) { 538 const struct efx_mac_stats_range ef10_vadaptor[] = { 539 { EFX_MAC_VADAPTER_RX_UNICAST_PACKETS, 540 EFX_MAC_VADAPTER_TX_OVERFLOW }, 541 }; 542 543 if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size, 544 ef10_vadaptor, EFX_ARRAY_SIZE(ef10_vadaptor))) != 0) 545 goto fail6; 546 } 547 548 return (0); 549 550fail6: 551 EFSYS_PROBE(fail6); 552fail5: 553 EFSYS_PROBE(fail5); 554fail4: 555 EFSYS_PROBE(fail4); 556fail3: 557 EFSYS_PROBE(fail3); 558fail2: 559 EFSYS_PROBE(fail2); 560fail1: 561 EFSYS_PROBE1(fail1, efx_rc_t, rc); 562 563 return (rc); 564} 565 566#define EF10_MAC_STAT_READ(_esmp, _field, _eqp) \ 567 EFSYS_MEM_READQ((_esmp), (_field) * sizeof (efx_qword_t), _eqp) 568 569 570 __checkReturn efx_rc_t 571ef10_mac_stats_update( 572 __in efx_nic_t *enp, 573 __in efsys_mem_t *esmp, 574 __inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat, 575 __inout_opt uint32_t *generationp) 576{ 577 efx_qword_t value; 578 efx_qword_t generation_start; 579 efx_qword_t generation_end; 580 581 _NOTE(ARGUNUSED(enp)) 582 583 /* Read END first so we don't race with the MC */ 584 EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFX_MAC_STATS_SIZE); 585 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_END, 586 &generation_end); 587 EFSYS_MEM_READ_BARRIER(); 588 589 /* TX */ 590 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PKTS, &value); 591 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value); 592 593 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_CONTROL_PKTS, &value); 594 EFSYS_STAT_SUBR_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value); 595 596 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PAUSE_PKTS, &value); 597 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PAUSE_PKTS]), &value); 598 599 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_UNICAST_PKTS, &value); 600 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_UNICST_PKTS]), &value); 601 602 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTICAST_PKTS, &value); 603 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULTICST_PKTS]), &value); 604 605 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BROADCAST_PKTS, &value); 606 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_BRDCST_PKTS]), &value); 607 608 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BYTES, &value); 609 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_OCTETS]), &value); 610 611 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LT64_PKTS, &value); 612 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value); 613 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_64_PKTS, &value); 614 EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value); 615 616 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_65_TO_127_PKTS, &value); 617 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_65_TO_127_PKTS]), &value); 618 619 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_128_TO_255_PKTS, &value); 620 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_128_TO_255_PKTS]), &value); 621 622 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_256_TO_511_PKTS, &value); 623 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_256_TO_511_PKTS]), &value); 624 625 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_512_TO_1023_PKTS, &value); 626 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_512_TO_1023_PKTS]), &value); 627 628 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_1024_TO_15XX_PKTS, &value); 629 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_1024_TO_15XX_PKTS]), &value); 630 631 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS, &value); 632 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value); 633 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_GTJUMBO_PKTS, &value); 634 EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value); 635 636 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BAD_FCS_PKTS, &value); 637 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_ERRORS]), &value); 638 639 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS, &value); 640 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_SGL_COL_PKTS]), &value); 641 642 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS, 643 &value); 644 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULT_COL_PKTS]), &value); 645 646 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS, 647 &value); 648 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_COL_PKTS]), &value); 649 650 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LATE_COLLISION_PKTS, &value); 651 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LATE_COL_PKTS]), &value); 652 653 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_DEFERRED_PKTS, &value); 654 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_DEF_PKTS]), &value); 655 656 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS, 657 &value); 658 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_DEF_PKTS]), &value); 659 660 /* RX */ 661 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BYTES, &value); 662 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_OCTETS]), &value); 663 664 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PKTS, &value); 665 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PKTS]), &value); 666 667 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNICAST_PKTS, &value); 668 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_UNICST_PKTS]), &value); 669 670 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MULTICAST_PKTS, &value); 671 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MULTICST_PKTS]), &value); 672 673 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BROADCAST_PKTS, &value); 674 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_BRDCST_PKTS]), &value); 675 676 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PAUSE_PKTS, &value); 677 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PAUSE_PKTS]), &value); 678 679 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNDERSIZE_PKTS, &value); 680 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value); 681 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_64_PKTS, &value); 682 EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value); 683 684 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_65_TO_127_PKTS, &value); 685 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_65_TO_127_PKTS]), &value); 686 687 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_128_TO_255_PKTS, &value); 688 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_128_TO_255_PKTS]), &value); 689 690 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_256_TO_511_PKTS, &value); 691 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_256_TO_511_PKTS]), &value); 692 693 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_512_TO_1023_PKTS, &value); 694 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_512_TO_1023_PKTS]), &value); 695 696 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_1024_TO_15XX_PKTS, &value); 697 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_1024_TO_15XX_PKTS]), &value); 698 699 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS, &value); 700 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value); 701 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_GTJUMBO_PKTS, &value); 702 EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value); 703 704 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BAD_FCS_PKTS, &value); 705 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FCS_ERRORS]), &value); 706 707 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_OVERFLOW_PKTS, &value); 708 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_DROP_EVENTS]), &value); 709 710 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_FALSE_CARRIER_PKTS, &value); 711 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FALSE_CARRIER_ERRORS]), &value); 712 713 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS, &value); 714 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_SYMBOL_ERRORS]), &value); 715 716 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_ALIGN_ERROR_PKTS, &value); 717 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_ALIGN_ERRORS]), &value); 718 719 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS, &value); 720 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_INTERNAL_ERRORS]), &value); 721 722 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_JABBER_PKTS, &value); 723 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_JABBER_PKTS]), &value); 724 725 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_CHAR_ERR, &value); 726 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_CHAR_ERR]), 727 &(value.eq_dword[0])); 728 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_CHAR_ERR]), 729 &(value.eq_dword[1])); 730 731 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_CHAR_ERR, &value); 732 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_CHAR_ERR]), 733 &(value.eq_dword[0])); 734 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_CHAR_ERR]), 735 &(value.eq_dword[1])); 736 737 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_DISP_ERR, &value); 738 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_DISP_ERR]), 739 &(value.eq_dword[0])); 740 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_DISP_ERR]), 741 &(value.eq_dword[1])); 742 743 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_DISP_ERR, &value); 744 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_DISP_ERR]), 745 &(value.eq_dword[0])); 746 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_DISP_ERR]), 747 &(value.eq_dword[1])); 748 749 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MATCH_FAULT, &value); 750 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MATCH_FAULT]), &value); 751 752 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_NODESC_DROPS, &value); 753 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_NODESC_DROP_CNT]), &value); 754 755 /* Packet memory (EF10 only) */ 756 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_TRUNC_BB_OVERFLOW, &value); 757 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_TRUNC_BB_OVERFLOW]), &value); 758 759 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_BB_OVERFLOW, &value); 760 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_BB_OVERFLOW]), &value); 761 762 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_TRUNC_VFIFO_FULL, &value); 763 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_TRUNC_VFIFO_FULL]), &value); 764 765 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_VFIFO_FULL, &value); 766 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_VFIFO_FULL]), &value); 767 768 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_TRUNC_QBB, &value); 769 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_TRUNC_QBB]), &value); 770 771 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_QBB, &value); 772 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_QBB]), &value); 773 774 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_MAPPING, &value); 775 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_MAPPING]), &value); 776 777 /* RX datapath */ 778 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_Q_DISABLED_PKTS, &value); 779 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_Q_DISABLED_PKTS]), &value); 780 781 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_DI_DROPPED_PKTS, &value); 782 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_DI_DROPPED_PKTS]), &value); 783 784 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_STREAMING_PKTS, &value); 785 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_STREAMING_PKTS]), &value); 786 787 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_HLB_FETCH_CONDITIONS, &value); 788 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_HLB_FETCH]), &value); 789 790 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_HLB_WAIT_CONDITIONS, &value); 791 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_HLB_WAIT]), &value); 792 793 794 /* VADAPTER RX */ 795 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_UNICAST_PACKETS, 796 &value); 797 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_UNICAST_PACKETS]), 798 &value); 799 800 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_UNICAST_BYTES, 801 &value); 802 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_UNICAST_BYTES]), 803 &value); 804 805 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_MULTICAST_PACKETS, 806 &value); 807 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_MULTICAST_PACKETS]), 808 &value); 809 810 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_MULTICAST_BYTES, 811 &value); 812 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_MULTICAST_BYTES]), 813 &value); 814 815 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BROADCAST_PACKETS, 816 &value); 817 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BROADCAST_PACKETS]), 818 &value); 819 820 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BROADCAST_BYTES, 821 &value); 822 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BROADCAST_BYTES]), 823 &value); 824 825 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BAD_PACKETS, 826 &value); 827 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BAD_PACKETS]), 828 &value); 829 830 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BAD_BYTES, &value); 831 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BAD_BYTES]), &value); 832 833 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_OVERFLOW, &value); 834 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_OVERFLOW]), &value); 835 836 /* VADAPTER TX */ 837 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_UNICAST_PACKETS, 838 &value); 839 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_UNICAST_PACKETS]), 840 &value); 841 842 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_UNICAST_BYTES, 843 &value); 844 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_UNICAST_BYTES]), 845 &value); 846 847 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_MULTICAST_PACKETS, 848 &value); 849 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_MULTICAST_PACKETS]), 850 &value); 851 852 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_MULTICAST_BYTES, 853 &value); 854 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_MULTICAST_BYTES]), 855 &value); 856 857 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BROADCAST_PACKETS, 858 &value); 859 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BROADCAST_PACKETS]), 860 &value); 861 862 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BROADCAST_BYTES, 863 &value); 864 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BROADCAST_BYTES]), 865 &value); 866 867 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BAD_PACKETS, &value); 868 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BAD_PACKETS]), &value); 869 870 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BAD_BYTES, &value); 871 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BAD_BYTES]), &value); 872 873 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_OVERFLOW, &value); 874 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_OVERFLOW]), &value); 875 876 877 EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFX_MAC_STATS_SIZE); 878 EFSYS_MEM_READ_BARRIER(); 879 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_START, 880 &generation_start); 881 882 /* Check that we didn't read the stats in the middle of a DMA */ 883 /* Not a good enough check ? */ 884 if (memcmp(&generation_start, &generation_end, 885 sizeof (generation_start))) 886 return (EAGAIN); 887 888 if (generationp) 889 *generationp = EFX_QWORD_FIELD(generation_start, EFX_DWORD_0); 890 891 return (0); 892} 893 894#endif /* EFSYS_OPT_MAC_STATS */ 895 896#endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD */ 897