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