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 #include "efx.h" 33 #include "efx_impl.h" 34 35 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 36 37 __checkReturn efx_rc_t 38 ef10_mac_poll( 39 __in efx_nic_t *enp, 40 __out efx_link_mode_t *link_modep) 41 { 42 efx_port_t *epp = &(enp->en_port); 43 ef10_link_state_t els; 44 efx_rc_t rc; 45 46 if ((rc = ef10_phy_get_link(enp, &els)) != 0) 47 goto fail1; 48 49 epp->ep_adv_cap_mask = els.epls.epls_adv_cap_mask; 50 epp->ep_fcntl = els.epls.epls_fcntl; 51 52 *link_modep = els.epls.epls_link_mode; 53 54 return (0); 55 56 fail1: 57 EFSYS_PROBE1(fail1, efx_rc_t, rc); 58 59 *link_modep = EFX_LINK_UNKNOWN; 60 61 return (rc); 62 } 63 64 __checkReturn efx_rc_t 65 ef10_mac_up( 66 __in efx_nic_t *enp, 67 __out boolean_t *mac_upp) 68 { 69 ef10_link_state_t els; 70 efx_rc_t rc; 71 72 /* 73 * Because EF10 doesn't *require* polling, we can't rely on 74 * ef10_mac_poll() being executed to populate epp->ep_mac_up. 75 */ 76 if ((rc = ef10_phy_get_link(enp, &els)) != 0) 77 goto fail1; 78 79 *mac_upp = els.els_mac_up; 80 81 return (0); 82 83 fail1: 84 EFSYS_PROBE1(fail1, efx_rc_t, rc); 85 86 return (rc); 87 } 88 89 /* 90 * EF10 adapters use MC_CMD_VADAPTOR_SET_MAC to set the 91 * MAC address; the address field in MC_CMD_SET_MAC has no 92 * effect. 93 * MC_CMD_VADAPTOR_SET_MAC requires mac-spoofing privilege and 94 * the port to have no filters or queues active. 95 */ 96 static __checkReturn efx_rc_t 97 efx_mcdi_vadapter_set_mac( 98 __in efx_nic_t *enp) 99 { 100 efx_port_t *epp = &(enp->en_port); 101 efx_mcdi_req_t req; 102 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_VADAPTOR_SET_MAC_IN_LEN, 103 MC_CMD_VADAPTOR_SET_MAC_OUT_LEN); 104 efx_rc_t rc; 105 106 req.emr_cmd = MC_CMD_VADAPTOR_SET_MAC; 107 req.emr_in_buf = payload; 108 req.emr_in_length = MC_CMD_VADAPTOR_SET_MAC_IN_LEN; 109 req.emr_out_buf = payload; 110 req.emr_out_length = MC_CMD_VADAPTOR_SET_MAC_OUT_LEN; 111 112 MCDI_IN_SET_DWORD(req, VADAPTOR_SET_MAC_IN_UPSTREAM_PORT_ID, 113 enp->en_vport_id); 114 EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, VADAPTOR_SET_MAC_IN_MACADDR), 115 epp->ep_mac_addr); 116 117 efx_mcdi_execute(enp, &req); 118 119 if (req.emr_rc != 0) { 120 rc = req.emr_rc; 121 goto fail1; 122 } 123 124 return (0); 125 126 fail1: 127 EFSYS_PROBE1(fail1, efx_rc_t, rc); 128 129 return (rc); 130 } 131 132 __checkReturn efx_rc_t 133 ef10_mac_addr_set( 134 __in efx_nic_t *enp) 135 { 136 efx_rc_t rc; 137 138 if ((rc = efx_mcdi_vadapter_set_mac(enp)) != 0) { 139 if (rc != ENOTSUP) 140 goto fail1; 141 142 /* 143 * Fallback for older Huntington firmware without Vadapter 144 * support. 145 */ 146 if ((rc = ef10_mac_reconfigure(enp)) != 0) 147 goto fail2; 148 } 149 150 return (0); 151 152 fail2: 153 EFSYS_PROBE(fail2); 154 155 fail1: 156 EFSYS_PROBE1(fail1, efx_rc_t, rc); 157 158 return (rc); 159 } 160 161 static __checkReturn efx_rc_t 162 efx_mcdi_mtu_set( 163 __in efx_nic_t *enp, 164 __in uint32_t mtu) 165 { 166 efx_mcdi_req_t req; 167 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_MAC_EXT_IN_LEN, 168 MC_CMD_SET_MAC_OUT_LEN); 169 efx_rc_t rc; 170 171 req.emr_cmd = MC_CMD_SET_MAC; 172 req.emr_in_buf = payload; 173 req.emr_in_length = MC_CMD_SET_MAC_EXT_IN_LEN; 174 req.emr_out_buf = payload; 175 req.emr_out_length = MC_CMD_SET_MAC_OUT_LEN; 176 177 /* Only configure the MTU in this call to MC_CMD_SET_MAC */ 178 MCDI_IN_SET_DWORD(req, SET_MAC_EXT_IN_MTU, mtu); 179 MCDI_IN_POPULATE_DWORD_1(req, SET_MAC_EXT_IN_CONTROL, 180 SET_MAC_EXT_IN_CFG_MTU, 1); 181 182 efx_mcdi_execute(enp, &req); 183 184 if (req.emr_rc != 0) { 185 rc = req.emr_rc; 186 goto fail1; 187 } 188 189 return (0); 190 191 fail1: 192 EFSYS_PROBE1(fail1, efx_rc_t, rc); 193 194 return (rc); 195 } 196 197 static __checkReturn efx_rc_t 198 efx_mcdi_mtu_get( 199 __in efx_nic_t *enp, 200 __out size_t *mtu) 201 { 202 efx_mcdi_req_t req; 203 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_MAC_EXT_IN_LEN, 204 MC_CMD_SET_MAC_V2_OUT_LEN); 205 efx_rc_t rc; 206 207 req.emr_cmd = MC_CMD_SET_MAC; 208 req.emr_in_buf = payload; 209 req.emr_in_length = MC_CMD_SET_MAC_EXT_IN_LEN; 210 req.emr_out_buf = payload; 211 req.emr_out_length = MC_CMD_SET_MAC_V2_OUT_LEN; 212 213 /* 214 * With MC_CMD_SET_MAC_EXT_IN_CONTROL set to 0, this just queries the 215 * MTU. This should always be supported on Medford, but it is not 216 * supported on older Huntington firmware. 217 */ 218 MCDI_IN_SET_DWORD(req, SET_MAC_EXT_IN_CONTROL, 0); 219 220 efx_mcdi_execute(enp, &req); 221 222 if (req.emr_rc != 0) { 223 rc = req.emr_rc; 224 goto fail1; 225 } 226 if (req.emr_out_length_used < MC_CMD_SET_MAC_V2_OUT_MTU_OFST + 4) { 227 rc = EMSGSIZE; 228 goto fail2; 229 } 230 231 *mtu = MCDI_OUT_DWORD(req, SET_MAC_V2_OUT_MTU); 232 233 return (0); 234 235 fail2: 236 EFSYS_PROBE(fail2); 237 fail1: 238 EFSYS_PROBE1(fail1, efx_rc_t, rc); 239 240 return (rc); 241 } 242 243 __checkReturn efx_rc_t 244 ef10_mac_pdu_set( 245 __in efx_nic_t *enp) 246 { 247 efx_port_t *epp = &(enp->en_port); 248 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 249 efx_rc_t rc; 250 251 if (encp->enc_enhanced_set_mac_supported) { 252 if ((rc = efx_mcdi_mtu_set(enp, epp->ep_mac_pdu)) != 0) 253 goto fail1; 254 } else { 255 /* 256 * Fallback for older Huntington firmware, which always 257 * configure all of the parameters to MC_CMD_SET_MAC. This isn't 258 * suitable for setting the MTU on unpriviliged functions. 259 */ 260 if ((rc = ef10_mac_reconfigure(enp)) != 0) 261 goto fail2; 262 } 263 264 return (0); 265 266 fail2: 267 EFSYS_PROBE(fail2); 268 fail1: 269 EFSYS_PROBE1(fail1, efx_rc_t, rc); 270 271 return (rc); 272 } 273 274 __checkReturn efx_rc_t 275 ef10_mac_pdu_get( 276 __in efx_nic_t *enp, 277 __out size_t *pdu) 278 { 279 efx_rc_t rc; 280 281 if ((rc = efx_mcdi_mtu_get(enp, pdu)) != 0) 282 goto fail1; 283 284 return (0); 285 286 fail1: 287 EFSYS_PROBE1(fail1, efx_rc_t, rc); 288 289 return (rc); 290 } 291 292 __checkReturn efx_rc_t 293 ef10_mac_reconfigure( 294 __in efx_nic_t *enp) 295 { 296 efx_port_t *epp = &(enp->en_port); 297 efx_mcdi_req_t req; 298 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_SET_MAC_IN_LEN, 299 MC_CMD_SET_MAC_OUT_LEN); 300 efx_rc_t rc; 301 302 req.emr_cmd = MC_CMD_SET_MAC; 303 req.emr_in_buf = payload; 304 req.emr_in_length = MC_CMD_SET_MAC_IN_LEN; 305 req.emr_out_buf = payload; 306 req.emr_out_length = MC_CMD_SET_MAC_OUT_LEN; 307 308 MCDI_IN_SET_DWORD(req, SET_MAC_IN_MTU, epp->ep_mac_pdu); 309 MCDI_IN_SET_DWORD(req, SET_MAC_IN_DRAIN, epp->ep_mac_drain ? 1 : 0); 310 EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, SET_MAC_IN_ADDR), 311 epp->ep_mac_addr); 312 313 /* 314 * Note: The Huntington MAC does not support REJECT_BRDCST. 315 * The REJECT_UNCST flag will also prevent multicast traffic 316 * from reaching the filters. As Huntington filters drop any 317 * traffic that does not match a filter it is ok to leave the 318 * MAC running in promiscuous mode. See bug41141. 319 * 320 * FIXME: Does REJECT_UNCST behave the same way on Medford? 321 */ 322 MCDI_IN_POPULATE_DWORD_2(req, SET_MAC_IN_REJECT, 323 SET_MAC_IN_REJECT_UNCST, 0, 324 SET_MAC_IN_REJECT_BRDCST, 0); 325 326 /* 327 * Flow control, whether it is auto-negotiated or not, 328 * is set via the PHY advertised capabilities. When set to 329 * automatic the MAC will use the PHY settings to determine 330 * the flow control settings. 331 */ 332 MCDI_IN_SET_DWORD(req, SET_MAC_IN_FCNTL, MC_CMD_FCNTL_AUTO); 333 334 /* Do not include the Ethernet frame checksum in RX packets */ 335 MCDI_IN_POPULATE_DWORD_1(req, SET_MAC_IN_FLAGS, 336 SET_MAC_IN_FLAG_INCLUDE_FCS, 0); 337 338 efx_mcdi_execute_quiet(enp, &req); 339 340 if (req.emr_rc != 0) { 341 /* 342 * Unprivileged functions cannot control link state, 343 * but still need to configure filters. 344 */ 345 if (req.emr_rc != EACCES) { 346 rc = req.emr_rc; 347 goto fail1; 348 } 349 } 350 351 /* 352 * Apply the filters for the MAC configuration. 353 * If the NIC isn't ready to accept filters this may 354 * return success without setting anything. 355 */ 356 rc = efx_filter_reconfigure(enp, epp->ep_mac_addr, 357 epp->ep_all_unicst, epp->ep_mulcst, 358 epp->ep_all_mulcst, epp->ep_brdcst, 359 epp->ep_mulcst_addr_list, 360 epp->ep_mulcst_addr_count); 361 362 return (0); 363 364 fail1: 365 EFSYS_PROBE1(fail1, efx_rc_t, rc); 366 367 return (rc); 368 } 369 370 __checkReturn efx_rc_t 371 ef10_mac_multicast_list_set( 372 __in efx_nic_t *enp) 373 { 374 efx_port_t *epp = &(enp->en_port); 375 const efx_mac_ops_t *emop = epp->ep_emop; 376 efx_rc_t rc; 377 378 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON || 379 enp->en_family == EFX_FAMILY_MEDFORD || 380 enp->en_family == EFX_FAMILY_MEDFORD2); 381 382 if ((rc = emop->emo_reconfigure(enp)) != 0) 383 goto fail1; 384 385 return (0); 386 387 fail1: 388 EFSYS_PROBE1(fail1, efx_rc_t, rc); 389 390 return (rc); 391 } 392 393 __checkReturn efx_rc_t 394 ef10_mac_filter_default_rxq_set( 395 __in efx_nic_t *enp, 396 __in efx_rxq_t *erp, 397 __in boolean_t using_rss) 398 { 399 efx_port_t *epp = &(enp->en_port); 400 efx_rxq_t *old_rxq; 401 boolean_t old_using_rss; 402 efx_rc_t rc; 403 404 ef10_filter_get_default_rxq(enp, &old_rxq, &old_using_rss); 405 406 ef10_filter_default_rxq_set(enp, erp, using_rss); 407 408 rc = efx_filter_reconfigure(enp, epp->ep_mac_addr, 409 epp->ep_all_unicst, epp->ep_mulcst, 410 epp->ep_all_mulcst, epp->ep_brdcst, 411 epp->ep_mulcst_addr_list, 412 epp->ep_mulcst_addr_count); 413 414 if (rc != 0) 415 goto fail1; 416 417 return (0); 418 419 fail1: 420 EFSYS_PROBE1(fail1, efx_rc_t, rc); 421 422 ef10_filter_default_rxq_set(enp, old_rxq, old_using_rss); 423 424 return (rc); 425 } 426 427 void 428 ef10_mac_filter_default_rxq_clear( 429 __in efx_nic_t *enp) 430 { 431 efx_port_t *epp = &(enp->en_port); 432 433 ef10_filter_default_rxq_clear(enp); 434 435 (void) efx_filter_reconfigure(enp, epp->ep_mac_addr, 436 epp->ep_all_unicst, epp->ep_mulcst, 437 epp->ep_all_mulcst, epp->ep_brdcst, 438 epp->ep_mulcst_addr_list, 439 epp->ep_mulcst_addr_count); 440 } 441 442 #if EFSYS_OPT_LOOPBACK 443 444 __checkReturn efx_rc_t 445 ef10_mac_loopback_set( 446 __in efx_nic_t *enp, 447 __in efx_link_mode_t link_mode, 448 __in efx_loopback_type_t loopback_type) 449 { 450 efx_port_t *epp = &(enp->en_port); 451 const efx_phy_ops_t *epop = epp->ep_epop; 452 efx_loopback_type_t old_loopback_type; 453 efx_link_mode_t old_loopback_link_mode; 454 efx_rc_t rc; 455 456 /* The PHY object handles this on EF10 */ 457 old_loopback_type = epp->ep_loopback_type; 458 old_loopback_link_mode = epp->ep_loopback_link_mode; 459 epp->ep_loopback_type = loopback_type; 460 epp->ep_loopback_link_mode = link_mode; 461 462 if ((rc = epop->epo_reconfigure(enp)) != 0) 463 goto fail1; 464 465 return (0); 466 467 fail1: 468 EFSYS_PROBE1(fail1, efx_rc_t, rc); 469 470 epp->ep_loopback_type = old_loopback_type; 471 epp->ep_loopback_link_mode = old_loopback_link_mode; 472 473 return (rc); 474 } 475 476 #endif /* EFSYS_OPT_LOOPBACK */ 477 478 #if EFSYS_OPT_MAC_STATS 479 480 __checkReturn efx_rc_t 481 ef10_mac_stats_get_mask( 482 __in efx_nic_t *enp, 483 __inout_bcount(mask_size) uint32_t *maskp, 484 __in size_t mask_size) 485 { 486 const struct efx_mac_stats_range ef10_common[] = { 487 { EFX_MAC_RX_OCTETS, EFX_MAC_RX_GE_15XX_PKTS }, 488 { EFX_MAC_RX_FCS_ERRORS, EFX_MAC_RX_DROP_EVENTS }, 489 { EFX_MAC_RX_JABBER_PKTS, EFX_MAC_RX_JABBER_PKTS }, 490 { EFX_MAC_RX_NODESC_DROP_CNT, EFX_MAC_TX_PAUSE_PKTS }, 491 }; 492 const struct efx_mac_stats_range ef10_tx_size_bins[] = { 493 { EFX_MAC_TX_LE_64_PKTS, EFX_MAC_TX_GE_15XX_PKTS }, 494 }; 495 efx_nic_cfg_t *encp = &(enp->en_nic_cfg); 496 efx_port_t *epp = &(enp->en_port); 497 efx_rc_t rc; 498 499 if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size, 500 ef10_common, EFX_ARRAY_SIZE(ef10_common))) != 0) 501 goto fail1; 502 503 if (epp->ep_phy_cap_mask & (1 << MC_CMD_PHY_CAP_40000FDX_LBN)) { 504 const struct efx_mac_stats_range ef10_40g_extra[] = { 505 { EFX_MAC_RX_ALIGN_ERRORS, EFX_MAC_RX_ALIGN_ERRORS }, 506 }; 507 508 if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size, 509 ef10_40g_extra, EFX_ARRAY_SIZE(ef10_40g_extra))) != 0) 510 goto fail2; 511 512 if (encp->enc_mac_stats_40g_tx_size_bins) { 513 if ((rc = efx_mac_stats_mask_add_ranges(maskp, 514 mask_size, ef10_tx_size_bins, 515 EFX_ARRAY_SIZE(ef10_tx_size_bins))) != 0) 516 goto fail3; 517 } 518 } else { 519 if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size, 520 ef10_tx_size_bins, EFX_ARRAY_SIZE(ef10_tx_size_bins))) != 0) 521 goto fail4; 522 } 523 524 if (encp->enc_pm_and_rxdp_counters) { 525 const struct efx_mac_stats_range ef10_pm_and_rxdp[] = { 526 { EFX_MAC_PM_TRUNC_BB_OVERFLOW, EFX_MAC_RXDP_HLB_WAIT }, 527 }; 528 529 if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size, 530 ef10_pm_and_rxdp, EFX_ARRAY_SIZE(ef10_pm_and_rxdp))) != 0) 531 goto fail5; 532 } 533 534 if (encp->enc_datapath_cap_evb) { 535 const struct efx_mac_stats_range ef10_vadaptor[] = { 536 { EFX_MAC_VADAPTER_RX_UNICAST_PACKETS, 537 EFX_MAC_VADAPTER_TX_OVERFLOW }, 538 }; 539 540 if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size, 541 ef10_vadaptor, EFX_ARRAY_SIZE(ef10_vadaptor))) != 0) 542 goto fail6; 543 } 544 545 if (encp->enc_fec_counters) { 546 const struct efx_mac_stats_range ef10_fec[] = { 547 { EFX_MAC_FEC_UNCORRECTED_ERRORS, 548 EFX_MAC_FEC_CORRECTED_SYMBOLS_LANE3 }, 549 }; 550 if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size, 551 ef10_fec, EFX_ARRAY_SIZE(ef10_fec))) != 0) 552 goto fail7; 553 } 554 555 if (encp->enc_mac_stats_nstats >= MC_CMD_MAC_NSTATS_V4) { 556 const struct efx_mac_stats_range ef10_rxdp_sdt[] = { 557 { EFX_MAC_RXDP_SCATTER_DISABLED_TRUNC, 558 EFX_MAC_RXDP_SCATTER_DISABLED_TRUNC }, 559 }; 560 561 if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size, 562 ef10_rxdp_sdt, EFX_ARRAY_SIZE(ef10_rxdp_sdt))) != 0) 563 goto fail8; 564 } 565 566 if (encp->enc_hlb_counters) { 567 const struct efx_mac_stats_range ef10_hlb[] = { 568 { EFX_MAC_RXDP_HLB_IDLE, EFX_MAC_RXDP_HLB_TIMEOUT }, 569 }; 570 if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size, 571 ef10_hlb, EFX_ARRAY_SIZE(ef10_hlb))) != 0) 572 goto fail9; 573 } 574 575 return (0); 576 577 fail9: 578 EFSYS_PROBE(fail9); 579 fail8: 580 EFSYS_PROBE(fail8); 581 fail7: 582 EFSYS_PROBE(fail7); 583 fail6: 584 EFSYS_PROBE(fail6); 585 fail5: 586 EFSYS_PROBE(fail5); 587 fail4: 588 EFSYS_PROBE(fail4); 589 fail3: 590 EFSYS_PROBE(fail3); 591 fail2: 592 EFSYS_PROBE(fail2); 593 fail1: 594 EFSYS_PROBE1(fail1, efx_rc_t, rc); 595 596 return (rc); 597 } 598 599 #define EF10_MAC_STAT_READ(_esmp, _field, _eqp) \ 600 EFSYS_MEM_READQ((_esmp), (_field) * sizeof (efx_qword_t), _eqp) 601 602 __checkReturn efx_rc_t 603 ef10_mac_stats_update( 604 __in efx_nic_t *enp, 605 __in efsys_mem_t *esmp, 606 __inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat, 607 __inout_opt uint32_t *generationp) 608 { 609 const efx_nic_cfg_t *encp = &enp->en_nic_cfg; 610 efx_qword_t generation_start; 611 efx_qword_t generation_end; 612 efx_qword_t value; 613 efx_rc_t rc; 614 615 /* 616 * The MAC_STATS contain start and end generation counters used to 617 * detect when the DMA buffer has been updated during stats decode. 618 * All stats counters are 64bit unsigned values. 619 * 620 * Siena-compatible MAC stats contain MC_CMD_MAC_NSTATS 64bit counters. 621 * The generation end counter is at index MC_CMD_MAC_GENERATION_END 622 * (same as MC_CMD_MAC_NSTATS-1). 623 * 624 * Medford2 and later use a larger DMA buffer: MAC_STATS_NUM_STATS from 625 * MC_CMD_GET_CAPABILITIES_V4_OUT reports the number of 64bit counters. 626 * 627 * Firmware writes the generation end counter as the last counter in the 628 * DMA buffer. Do not use MC_CMD_MAC_GENERATION_END, as that is only 629 * correct for legacy Siena-compatible MAC stats. 630 */ 631 632 if (encp->enc_mac_stats_nstats < MC_CMD_MAC_NSTATS) { 633 /* MAC stats count too small for legacy MAC stats */ 634 rc = ENOSPC; 635 goto fail1; 636 } 637 if (EFSYS_MEM_SIZE(esmp) < 638 (encp->enc_mac_stats_nstats * sizeof (efx_qword_t))) { 639 /* DMA buffer too small */ 640 rc = ENOSPC; 641 goto fail2; 642 } 643 644 /* Read END first so we don't race with the MC */ 645 EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFSYS_MEM_SIZE(esmp)); 646 EF10_MAC_STAT_READ(esmp, (encp->enc_mac_stats_nstats - 1), 647 &generation_end); 648 EFSYS_MEM_READ_BARRIER(); 649 650 /* TX */ 651 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PKTS, &value); 652 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value); 653 654 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_CONTROL_PKTS, &value); 655 EFSYS_STAT_SUBR_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value); 656 657 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PAUSE_PKTS, &value); 658 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PAUSE_PKTS]), &value); 659 660 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_UNICAST_PKTS, &value); 661 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_UNICST_PKTS]), &value); 662 663 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTICAST_PKTS, &value); 664 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULTICST_PKTS]), &value); 665 666 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BROADCAST_PKTS, &value); 667 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_BRDCST_PKTS]), &value); 668 669 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BYTES, &value); 670 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_OCTETS]), &value); 671 672 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LT64_PKTS, &value); 673 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value); 674 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_64_PKTS, &value); 675 EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value); 676 677 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_65_TO_127_PKTS, &value); 678 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_65_TO_127_PKTS]), &value); 679 680 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_128_TO_255_PKTS, &value); 681 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_128_TO_255_PKTS]), &value); 682 683 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_256_TO_511_PKTS, &value); 684 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_256_TO_511_PKTS]), &value); 685 686 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_512_TO_1023_PKTS, &value); 687 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_512_TO_1023_PKTS]), &value); 688 689 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_1024_TO_15XX_PKTS, &value); 690 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_1024_TO_15XX_PKTS]), &value); 691 692 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS, &value); 693 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value); 694 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_GTJUMBO_PKTS, &value); 695 EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value); 696 697 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BAD_FCS_PKTS, &value); 698 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_ERRORS]), &value); 699 700 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS, &value); 701 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_SGL_COL_PKTS]), &value); 702 703 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS, 704 &value); 705 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULT_COL_PKTS]), &value); 706 707 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS, 708 &value); 709 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_COL_PKTS]), &value); 710 711 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LATE_COLLISION_PKTS, &value); 712 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LATE_COL_PKTS]), &value); 713 714 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_DEFERRED_PKTS, &value); 715 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_DEF_PKTS]), &value); 716 717 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS, 718 &value); 719 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_DEF_PKTS]), &value); 720 721 /* RX */ 722 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BYTES, &value); 723 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_OCTETS]), &value); 724 725 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PKTS, &value); 726 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PKTS]), &value); 727 728 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNICAST_PKTS, &value); 729 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_UNICST_PKTS]), &value); 730 731 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MULTICAST_PKTS, &value); 732 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MULTICST_PKTS]), &value); 733 734 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BROADCAST_PKTS, &value); 735 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_BRDCST_PKTS]), &value); 736 737 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PAUSE_PKTS, &value); 738 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PAUSE_PKTS]), &value); 739 740 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNDERSIZE_PKTS, &value); 741 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value); 742 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_64_PKTS, &value); 743 EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value); 744 745 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_65_TO_127_PKTS, &value); 746 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_65_TO_127_PKTS]), &value); 747 748 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_128_TO_255_PKTS, &value); 749 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_128_TO_255_PKTS]), &value); 750 751 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_256_TO_511_PKTS, &value); 752 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_256_TO_511_PKTS]), &value); 753 754 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_512_TO_1023_PKTS, &value); 755 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_512_TO_1023_PKTS]), &value); 756 757 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_1024_TO_15XX_PKTS, &value); 758 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_1024_TO_15XX_PKTS]), &value); 759 760 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS, &value); 761 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value); 762 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_GTJUMBO_PKTS, &value); 763 EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value); 764 765 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BAD_FCS_PKTS, &value); 766 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FCS_ERRORS]), &value); 767 768 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_OVERFLOW_PKTS, &value); 769 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_DROP_EVENTS]), &value); 770 771 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_FALSE_CARRIER_PKTS, &value); 772 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FALSE_CARRIER_ERRORS]), &value); 773 774 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS, &value); 775 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_SYMBOL_ERRORS]), &value); 776 777 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_ALIGN_ERROR_PKTS, &value); 778 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_ALIGN_ERRORS]), &value); 779 780 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS, &value); 781 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_INTERNAL_ERRORS]), &value); 782 783 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_JABBER_PKTS, &value); 784 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_JABBER_PKTS]), &value); 785 786 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_CHAR_ERR, &value); 787 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_CHAR_ERR]), 788 &(value.eq_dword[0])); 789 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_CHAR_ERR]), 790 &(value.eq_dword[1])); 791 792 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_CHAR_ERR, &value); 793 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_CHAR_ERR]), 794 &(value.eq_dword[0])); 795 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_CHAR_ERR]), 796 &(value.eq_dword[1])); 797 798 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_DISP_ERR, &value); 799 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_DISP_ERR]), 800 &(value.eq_dword[0])); 801 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_DISP_ERR]), 802 &(value.eq_dword[1])); 803 804 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_DISP_ERR, &value); 805 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_DISP_ERR]), 806 &(value.eq_dword[0])); 807 EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_DISP_ERR]), 808 &(value.eq_dword[1])); 809 810 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MATCH_FAULT, &value); 811 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MATCH_FAULT]), &value); 812 813 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_NODESC_DROPS, &value); 814 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_NODESC_DROP_CNT]), &value); 815 816 /* Packet memory (EF10 only) */ 817 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_TRUNC_BB_OVERFLOW, &value); 818 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_TRUNC_BB_OVERFLOW]), &value); 819 820 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_BB_OVERFLOW, &value); 821 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_BB_OVERFLOW]), &value); 822 823 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_TRUNC_VFIFO_FULL, &value); 824 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_TRUNC_VFIFO_FULL]), &value); 825 826 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_VFIFO_FULL, &value); 827 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_VFIFO_FULL]), &value); 828 829 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_TRUNC_QBB, &value); 830 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_TRUNC_QBB]), &value); 831 832 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_QBB, &value); 833 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_QBB]), &value); 834 835 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_MAPPING, &value); 836 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_MAPPING]), &value); 837 838 /* RX datapath */ 839 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_Q_DISABLED_PKTS, &value); 840 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_Q_DISABLED_PKTS]), &value); 841 842 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_DI_DROPPED_PKTS, &value); 843 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_DI_DROPPED_PKTS]), &value); 844 845 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_STREAMING_PKTS, &value); 846 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_STREAMING_PKTS]), &value); 847 848 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_HLB_FETCH_CONDITIONS, &value); 849 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_HLB_FETCH]), &value); 850 851 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_HLB_WAIT_CONDITIONS, &value); 852 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_HLB_WAIT]), &value); 853 854 /* VADAPTER RX */ 855 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_UNICAST_PACKETS, 856 &value); 857 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_UNICAST_PACKETS]), 858 &value); 859 860 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_UNICAST_BYTES, 861 &value); 862 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_UNICAST_BYTES]), 863 &value); 864 865 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_MULTICAST_PACKETS, 866 &value); 867 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_MULTICAST_PACKETS]), 868 &value); 869 870 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_MULTICAST_BYTES, 871 &value); 872 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_MULTICAST_BYTES]), 873 &value); 874 875 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BROADCAST_PACKETS, 876 &value); 877 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BROADCAST_PACKETS]), 878 &value); 879 880 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BROADCAST_BYTES, 881 &value); 882 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BROADCAST_BYTES]), 883 &value); 884 885 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BAD_PACKETS, 886 &value); 887 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BAD_PACKETS]), 888 &value); 889 890 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BAD_BYTES, &value); 891 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BAD_BYTES]), &value); 892 893 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_OVERFLOW, &value); 894 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_OVERFLOW]), &value); 895 896 /* VADAPTER TX */ 897 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_UNICAST_PACKETS, 898 &value); 899 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_UNICAST_PACKETS]), 900 &value); 901 902 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_UNICAST_BYTES, 903 &value); 904 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_UNICAST_BYTES]), 905 &value); 906 907 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_MULTICAST_PACKETS, 908 &value); 909 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_MULTICAST_PACKETS]), 910 &value); 911 912 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_MULTICAST_BYTES, 913 &value); 914 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_MULTICAST_BYTES]), 915 &value); 916 917 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BROADCAST_PACKETS, 918 &value); 919 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BROADCAST_PACKETS]), 920 &value); 921 922 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BROADCAST_BYTES, 923 &value); 924 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BROADCAST_BYTES]), 925 &value); 926 927 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BAD_PACKETS, &value); 928 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BAD_PACKETS]), &value); 929 930 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BAD_BYTES, &value); 931 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BAD_BYTES]), &value); 932 933 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_OVERFLOW, &value); 934 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_OVERFLOW]), &value); 935 936 if (encp->enc_mac_stats_nstats < MC_CMD_MAC_NSTATS_V2) 937 goto done; 938 939 /* FEC */ 940 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_FEC_UNCORRECTED_ERRORS, &value); 941 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_FEC_UNCORRECTED_ERRORS]), &value); 942 943 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_FEC_CORRECTED_ERRORS, &value); 944 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_FEC_CORRECTED_ERRORS]), &value); 945 946 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_FEC_CORRECTED_SYMBOLS_LANE0, 947 &value); 948 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_FEC_CORRECTED_SYMBOLS_LANE0]), 949 &value); 950 951 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_FEC_CORRECTED_SYMBOLS_LANE1, 952 &value); 953 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_FEC_CORRECTED_SYMBOLS_LANE1]), 954 &value); 955 956 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_FEC_CORRECTED_SYMBOLS_LANE2, 957 &value); 958 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_FEC_CORRECTED_SYMBOLS_LANE2]), 959 &value); 960 961 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_FEC_CORRECTED_SYMBOLS_LANE3, 962 &value); 963 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_FEC_CORRECTED_SYMBOLS_LANE3]), 964 &value); 965 966 if (encp->enc_mac_stats_nstats < MC_CMD_MAC_NSTATS_V3) 967 goto done; 968 969 /* CTPIO exceptions */ 970 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_CTPIO_VI_BUSY_FALLBACK, &value); 971 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_CTPIO_VI_BUSY_FALLBACK]), &value); 972 973 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_CTPIO_LONG_WRITE_SUCCESS, &value); 974 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_CTPIO_LONG_WRITE_SUCCESS]), &value); 975 976 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_CTPIO_MISSING_DBELL_FAIL, &value); 977 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_CTPIO_MISSING_DBELL_FAIL]), &value); 978 979 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_CTPIO_OVERFLOW_FAIL, &value); 980 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_CTPIO_OVERFLOW_FAIL]), &value); 981 982 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_CTPIO_UNDERFLOW_FAIL, &value); 983 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_CTPIO_UNDERFLOW_FAIL]), &value); 984 985 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_CTPIO_TIMEOUT_FAIL, &value); 986 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_CTPIO_TIMEOUT_FAIL]), &value); 987 988 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_CTPIO_NONCONTIG_WR_FAIL, &value); 989 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_CTPIO_NONCONTIG_WR_FAIL]), &value); 990 991 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_CTPIO_FRM_CLOBBER_FAIL, &value); 992 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_CTPIO_FRM_CLOBBER_FAIL]), &value); 993 994 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_CTPIO_INVALID_WR_FAIL, &value); 995 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_CTPIO_INVALID_WR_FAIL]), &value); 996 997 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_CTPIO_VI_CLOBBER_FALLBACK, &value); 998 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_CTPIO_VI_CLOBBER_FALLBACK]), 999 &value); 1000 1001 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_CTPIO_UNQUALIFIED_FALLBACK, &value); 1002 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_CTPIO_UNQUALIFIED_FALLBACK]), 1003 &value); 1004 1005 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_CTPIO_RUNT_FALLBACK, &value); 1006 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_CTPIO_RUNT_FALLBACK]), &value); 1007 1008 /* CTPIO per-port stats */ 1009 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_CTPIO_SUCCESS, &value); 1010 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_CTPIO_SUCCESS]), &value); 1011 1012 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_CTPIO_FALLBACK, &value); 1013 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_CTPIO_FALLBACK]), &value); 1014 1015 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_CTPIO_POISON, &value); 1016 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_CTPIO_POISON]), &value); 1017 1018 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_CTPIO_ERASE, &value); 1019 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_CTPIO_ERASE]), &value); 1020 1021 if (encp->enc_mac_stats_nstats < MC_CMD_MAC_NSTATS_V4) 1022 goto done; 1023 1024 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_SCATTER_DISABLED_TRUNC, 1025 &value); 1026 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_SCATTER_DISABLED_TRUNC]), 1027 &value); 1028 1029 /* Head-of-line blocking */ 1030 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_HLB_IDLE, &value); 1031 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_HLB_IDLE]), &value); 1032 1033 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_HLB_TIMEOUT, &value); 1034 EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_HLB_TIMEOUT]), &value); 1035 1036 done: 1037 /* Read START generation counter */ 1038 EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFSYS_MEM_SIZE(esmp)); 1039 EFSYS_MEM_READ_BARRIER(); 1040 EF10_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_START, 1041 &generation_start); 1042 1043 /* Check that we didn't read the stats in the middle of a DMA */ 1044 /* Not a good enough check ? */ 1045 if (memcmp(&generation_start, &generation_end, 1046 sizeof (generation_start))) 1047 return (EAGAIN); 1048 1049 if (generationp) 1050 *generationp = EFX_QWORD_FIELD(generation_start, EFX_DWORD_0); 1051 1052 return (0); 1053 1054 fail2: 1055 EFSYS_PROBE(fail2); 1056 fail1: 1057 EFSYS_PROBE1(fail1, efx_rc_t, rc); 1058 1059 return (rc); 1060 } 1061 1062 #endif /* EFSYS_OPT_MAC_STATS */ 1063 1064 #endif /* EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD || EFSYS_OPT_MEDFORD2 */ 1065