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