1227569Sphilip/*- 2227569Sphilip * Copyright 2009 Solarflare Communications Inc. All rights reserved. 3227569Sphilip * 4227569Sphilip * Redistribution and use in source and binary forms, with or without 5227569Sphilip * modification, are permitted provided that the following conditions 6227569Sphilip * are met: 7227569Sphilip * 1. Redistributions of source code must retain the above copyright 8227569Sphilip * notice, this list of conditions and the following disclaimer. 9227569Sphilip * 2. Redistributions in binary form must reproduce the above copyright 10227569Sphilip * notice, this list of conditions and the following disclaimer in the 11227569Sphilip * documentation and/or other materials provided with the distribution. 12227569Sphilip * 13227569Sphilip * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND 14227569Sphilip * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15227569Sphilip * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16227569Sphilip * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17227569Sphilip * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18227569Sphilip * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19227569Sphilip * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20227569Sphilip * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21227569Sphilip * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22227569Sphilip * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23227569Sphilip * SUCH DAMAGE. 24227569Sphilip */ 25228078Sphilip 26228078Sphilip#include <sys/cdefs.h> 27228078Sphilip__FBSDID("$FreeBSD$"); 28228078Sphilip 29227569Sphilip#include "efsys.h" 30227569Sphilip#include "efx.h" 31227569Sphilip#include "efx_impl.h" 32227569Sphilip 33227569Sphilip#if EFSYS_OPT_SIENA 34227569Sphilip 35227569Sphilip __checkReturn int 36227569Sphilipsiena_mac_poll( 37227569Sphilip __in efx_nic_t *enp, 38227569Sphilip __out efx_link_mode_t *link_modep) 39227569Sphilip{ 40227569Sphilip efx_port_t *epp = &(enp->en_port); 41227569Sphilip siena_link_state_t sls; 42227569Sphilip int rc; 43227569Sphilip 44227569Sphilip if ((rc = siena_phy_get_link(enp, &sls)) != 0) 45227569Sphilip goto fail1; 46227569Sphilip 47227569Sphilip epp->ep_adv_cap_mask = sls.sls_adv_cap_mask; 48227569Sphilip epp->ep_fcntl = sls.sls_fcntl; 49227569Sphilip 50227569Sphilip *link_modep = sls.sls_link_mode; 51227569Sphilip 52227569Sphilip return (0); 53227569Sphilip 54227569Sphilipfail1: 55227569Sphilip EFSYS_PROBE1(fail1, int, rc); 56227569Sphilip 57227569Sphilip *link_modep = EFX_LINK_UNKNOWN; 58227569Sphilip 59227569Sphilip return (rc); 60227569Sphilip} 61227569Sphilip 62227569Sphilip __checkReturn int 63227569Sphilipsiena_mac_up( 64227569Sphilip __in efx_nic_t *enp, 65227569Sphilip __out boolean_t *mac_upp) 66227569Sphilip{ 67227569Sphilip siena_link_state_t sls; 68227569Sphilip int rc; 69227569Sphilip 70227569Sphilip /* 71227569Sphilip * Because Siena doesn't *require* polling, we can't rely on 72227569Sphilip * siena_mac_poll() being executed to populate epp->ep_mac_up. 73227569Sphilip */ 74227569Sphilip if ((rc = siena_phy_get_link(enp, &sls)) != 0) 75227569Sphilip goto fail1; 76227569Sphilip 77227569Sphilip *mac_upp = sls.sls_mac_up; 78227569Sphilip 79227569Sphilip return (0); 80227569Sphilip 81227569Sphilipfail1: 82227569Sphilip EFSYS_PROBE1(fail1, int, rc); 83227569Sphilip 84227569Sphilip return (rc); 85227569Sphilip} 86227569Sphilip 87227569Sphilip __checkReturn int 88227569Sphilipsiena_mac_reconfigure( 89227569Sphilip __in efx_nic_t *enp) 90227569Sphilip{ 91227569Sphilip efx_port_t *epp = &(enp->en_port); 92227569Sphilip uint8_t payload[MAX(MC_CMD_SET_MAC_IN_LEN, 93227569Sphilip MC_CMD_SET_MCAST_HASH_IN_LEN)]; 94227569Sphilip efx_mcdi_req_t req; 95227569Sphilip unsigned int fcntl; 96227569Sphilip int rc; 97227569Sphilip 98227569Sphilip req.emr_cmd = MC_CMD_SET_MAC; 99227569Sphilip req.emr_in_buf = payload; 100227569Sphilip req.emr_in_length = MC_CMD_SET_MAC_IN_LEN; 101227569Sphilip EFX_STATIC_ASSERT(MC_CMD_SET_MAC_OUT_LEN == 0); 102227569Sphilip req.emr_out_buf = NULL; 103227569Sphilip req.emr_out_length = 0; 104227569Sphilip 105227569Sphilip MCDI_IN_SET_DWORD(req, SET_MAC_IN_MTU, epp->ep_mac_pdu); 106227569Sphilip MCDI_IN_SET_DWORD(req, SET_MAC_IN_DRAIN, epp->ep_mac_drain ? 1 : 0); 107227569Sphilip EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, SET_MAC_IN_ADDR), 108227569Sphilip epp->ep_mac_addr); 109227569Sphilip MCDI_IN_POPULATE_DWORD_2(req, SET_MAC_IN_REJECT, 110227569Sphilip SET_MAC_IN_REJECT_UNCST, !epp->ep_unicst, 111227569Sphilip SET_MAC_IN_REJECT_BRDCST, !epp->ep_brdcst); 112227569Sphilip 113227569Sphilip if (epp->ep_fcntl_autoneg) 114227569Sphilip /* efx_fcntl_set() has already set the phy capabilities */ 115227569Sphilip fcntl = MC_CMD_FCNTL_AUTO; 116227569Sphilip else if (epp->ep_fcntl & EFX_FCNTL_RESPOND) 117227569Sphilip fcntl = (epp->ep_fcntl & EFX_FCNTL_GENERATE) 118227569Sphilip ? MC_CMD_FCNTL_BIDIR 119227569Sphilip : MC_CMD_FCNTL_RESPOND; 120227569Sphilip else 121227569Sphilip fcntl = MC_CMD_FCNTL_OFF; 122227569Sphilip 123227569Sphilip MCDI_IN_SET_DWORD(req, SET_MAC_IN_FCNTL, fcntl); 124227569Sphilip 125227569Sphilip efx_mcdi_execute(enp, &req); 126227569Sphilip 127227569Sphilip if (req.emr_rc != 0) { 128227569Sphilip rc = req.emr_rc; 129227569Sphilip goto fail1; 130227569Sphilip } 131227569Sphilip 132227569Sphilip /* Push multicast hash. Set the broadcast bit (0xff) appropriately */ 133227569Sphilip req.emr_cmd = MC_CMD_SET_MCAST_HASH; 134227569Sphilip req.emr_in_buf = payload; 135227569Sphilip req.emr_in_length = MC_CMD_SET_MCAST_HASH_IN_LEN; 136227569Sphilip EFX_STATIC_ASSERT(MC_CMD_SET_MCAST_HASH_OUT_LEN == 0); 137227569Sphilip req.emr_out_buf = NULL; 138227569Sphilip req.emr_out_length = 0; 139227569Sphilip 140227569Sphilip memcpy(MCDI_IN2(req, uint8_t, SET_MCAST_HASH_IN_HASH0), 141227569Sphilip epp->ep_multicst_hash, sizeof (epp->ep_multicst_hash)); 142227569Sphilip if (epp->ep_brdcst) 143227569Sphilip EFX_SET_OWORD_BIT(*MCDI_IN2(req, efx_oword_t, 144227569Sphilip SET_MCAST_HASH_IN_HASH1), 0x7f); 145227569Sphilip 146227569Sphilip efx_mcdi_execute(enp, &req); 147227569Sphilip 148227569Sphilip if (req.emr_rc != 0) { 149227569Sphilip rc = req.emr_rc; 150227569Sphilip goto fail2; 151227569Sphilip } 152227569Sphilip 153227569Sphilip return (0); 154227569Sphilip 155227569Sphilipfail2: 156227569Sphilip EFSYS_PROBE(fail2); 157227569Sphilipfail1: 158227569Sphilip EFSYS_PROBE1(fail1, int, rc); 159227569Sphilip 160227569Sphilip return (rc); 161227569Sphilip} 162227569Sphilip 163227569Sphilip#if EFSYS_OPT_LOOPBACK 164227569Sphilip 165227569Sphilip __checkReturn int 166227569Sphilipsiena_mac_loopback_set( 167227569Sphilip __in efx_nic_t *enp, 168227569Sphilip __in efx_link_mode_t link_mode, 169227569Sphilip __in efx_loopback_type_t loopback_type) 170227569Sphilip{ 171227569Sphilip efx_port_t *epp = &(enp->en_port); 172227569Sphilip efx_phy_ops_t *epop = epp->ep_epop; 173227569Sphilip efx_loopback_type_t old_loopback_type; 174227569Sphilip efx_link_mode_t old_loopback_link_mode; 175227569Sphilip int rc; 176227569Sphilip 177227569Sphilip /* The PHY object handles this on Siena */ 178227569Sphilip old_loopback_type = epp->ep_loopback_type; 179227569Sphilip old_loopback_link_mode = epp->ep_loopback_link_mode; 180227569Sphilip epp->ep_loopback_type = loopback_type; 181227569Sphilip epp->ep_loopback_link_mode = link_mode; 182227569Sphilip 183227569Sphilip if ((rc = epop->epo_reconfigure(enp)) != 0) 184227569Sphilip goto fail1; 185227569Sphilip 186227569Sphilip return (0); 187227569Sphilip 188227569Sphilipfail1: 189227569Sphilip EFSYS_PROBE(fail2); 190227569Sphilip 191227569Sphilip epp->ep_loopback_type = old_loopback_type; 192227569Sphilip epp->ep_loopback_link_mode = old_loopback_link_mode; 193227569Sphilip 194227569Sphilip return (rc); 195227569Sphilip} 196227569Sphilip 197227569Sphilip#endif /* EFSYS_OPT_LOOPBACK */ 198227569Sphilip 199227569Sphilip#if EFSYS_OPT_MAC_STATS 200227569Sphilip 201227569Sphilip __checkReturn int 202227569Sphilipsiena_mac_stats_clear( 203227569Sphilip __in efx_nic_t *enp) 204227569Sphilip{ 205227569Sphilip uint8_t payload[MC_CMD_MAC_STATS_IN_LEN]; 206227569Sphilip efx_mcdi_req_t req; 207227569Sphilip int rc; 208227569Sphilip 209227569Sphilip req.emr_cmd = MC_CMD_MAC_STATS; 210227569Sphilip req.emr_in_buf = payload; 211227569Sphilip req.emr_in_length = sizeof (payload); 212227569Sphilip EFX_STATIC_ASSERT(MC_CMD_MAC_STATS_OUT_DMA_LEN == 0); 213227569Sphilip req.emr_out_buf = NULL; 214227569Sphilip req.emr_out_length = 0; 215227569Sphilip 216227569Sphilip MCDI_IN_POPULATE_DWORD_3(req, MAC_STATS_IN_CMD, 217227569Sphilip MAC_STATS_IN_DMA, 0, 218227569Sphilip MAC_STATS_IN_CLEAR, 1, 219227569Sphilip MAC_STATS_IN_PERIODIC_CHANGE, 0); 220227569Sphilip 221227569Sphilip efx_mcdi_execute(enp, &req); 222227569Sphilip 223227569Sphilip if (req.emr_rc != 0) { 224227569Sphilip rc = req.emr_rc; 225227569Sphilip goto fail1; 226227569Sphilip } 227227569Sphilip 228227569Sphilip return (0); 229227569Sphilip 230227569Sphilipfail1: 231227569Sphilip EFSYS_PROBE1(fail1, int, rc); 232227569Sphilip 233227569Sphilip return (rc); 234227569Sphilip} 235227569Sphilip 236227569Sphilip __checkReturn int 237227569Sphilipsiena_mac_stats_upload( 238227569Sphilip __in efx_nic_t *enp, 239227569Sphilip __in efsys_mem_t *esmp) 240227569Sphilip{ 241227569Sphilip uint8_t payload[MC_CMD_MAC_STATS_IN_LEN]; 242227569Sphilip efx_mcdi_req_t req; 243227569Sphilip size_t bytes; 244227569Sphilip int rc; 245227569Sphilip 246227569Sphilip EFX_STATIC_ASSERT(MC_CMD_MAC_NSTATS * sizeof (uint64_t) <= 247227569Sphilip EFX_MAC_STATS_SIZE); 248227569Sphilip 249227569Sphilip bytes = MC_CMD_MAC_NSTATS * sizeof (uint64_t); 250227569Sphilip 251227569Sphilip req.emr_cmd = MC_CMD_MAC_STATS; 252227569Sphilip req.emr_in_buf = payload; 253227569Sphilip req.emr_in_length = sizeof (payload); 254227569Sphilip EFX_STATIC_ASSERT(MC_CMD_MAC_STATS_OUT_DMA_LEN == 0); 255227569Sphilip req.emr_out_buf = NULL; 256227569Sphilip req.emr_out_length = 0; 257227569Sphilip 258227569Sphilip MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_LO, 259227569Sphilip EFSYS_MEM_ADDR(esmp) & 0xffffffff); 260227569Sphilip MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_HI, 261227569Sphilip EFSYS_MEM_ADDR(esmp) >> 32); 262227569Sphilip MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_LEN, bytes); 263227569Sphilip 264227569Sphilip /* 265227569Sphilip * The MC DMAs aggregate statistics for our convinience, so we can 266227569Sphilip * avoid having to pull the statistics buffer into the cache to 267227569Sphilip * maintain cumulative statistics. 268227569Sphilip */ 269227569Sphilip MCDI_IN_POPULATE_DWORD_3(req, MAC_STATS_IN_CMD, 270227569Sphilip MAC_STATS_IN_DMA, 1, 271227569Sphilip MAC_STATS_IN_CLEAR, 0, 272227569Sphilip MAC_STATS_IN_PERIODIC_CHANGE, 0); 273227569Sphilip 274227569Sphilip efx_mcdi_execute(enp, &req); 275227569Sphilip 276227569Sphilip if (req.emr_rc != 0) { 277227569Sphilip rc = req.emr_rc; 278227569Sphilip goto fail1; 279227569Sphilip } 280227569Sphilip 281227569Sphilip return (0); 282227569Sphilip 283227569Sphilipfail1: 284227569Sphilip EFSYS_PROBE1(fail1, int, rc); 285227569Sphilip 286227569Sphilip return (rc); 287227569Sphilip} 288227569Sphilip 289227569Sphilip __checkReturn int 290227569Sphilipsiena_mac_stats_periodic( 291227569Sphilip __in efx_nic_t *enp, 292227569Sphilip __in efsys_mem_t *esmp, 293227569Sphilip __in uint16_t period, 294227569Sphilip __in boolean_t events) 295227569Sphilip{ 296227569Sphilip uint8_t payload[MC_CMD_MAC_STATS_IN_LEN]; 297227569Sphilip efx_mcdi_req_t req; 298227569Sphilip size_t bytes; 299227569Sphilip int rc; 300227569Sphilip 301227569Sphilip bytes = MC_CMD_MAC_NSTATS * sizeof (uint64_t); 302227569Sphilip 303227569Sphilip req.emr_cmd = MC_CMD_MAC_STATS; 304227569Sphilip req.emr_in_buf = payload; 305227569Sphilip req.emr_in_length = sizeof (payload); 306227569Sphilip EFX_STATIC_ASSERT(MC_CMD_MAC_STATS_OUT_DMA_LEN == 0); 307227569Sphilip req.emr_out_buf = NULL; 308227569Sphilip req.emr_out_length = 0; 309227569Sphilip 310227569Sphilip MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_LO, 311227569Sphilip EFSYS_MEM_ADDR(esmp) & 0xffffffff); 312227569Sphilip MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_HI, 313227569Sphilip EFSYS_MEM_ADDR(esmp) >> 32); 314227569Sphilip MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_LEN, bytes); 315227569Sphilip 316227569Sphilip /* 317227569Sphilip * The MC DMAs aggregate statistics for our convinience, so we can 318227569Sphilip * avoid having to pull the statistics buffer into the cache to 319227569Sphilip * maintain cumulative statistics. 320227569Sphilip */ 321227569Sphilip MCDI_IN_POPULATE_DWORD_6(req, MAC_STATS_IN_CMD, 322227569Sphilip MAC_STATS_IN_DMA, 0, 323227569Sphilip MAC_STATS_IN_CLEAR, 0, 324227569Sphilip MAC_STATS_IN_PERIODIC_CHANGE, 1, 325227569Sphilip MAC_STATS_IN_PERIODIC_ENABLE, period ? 1 : 0, 326227569Sphilip MAC_STATS_IN_PERIODIC_NOEVENT, events ? 0 : 1, 327227569Sphilip MAC_STATS_IN_PERIOD_MS, period); 328227569Sphilip 329227569Sphilip efx_mcdi_execute(enp, &req); 330227569Sphilip 331227569Sphilip if (req.emr_rc != 0) { 332227569Sphilip rc = req.emr_rc; 333227569Sphilip goto fail1; 334227569Sphilip } 335227569Sphilip 336227569Sphilip return (0); 337227569Sphilip 338227569Sphilipfail1: 339227569Sphilip EFSYS_PROBE1(fail1, int, rc); 340227569Sphilip 341227569Sphilip return (rc); 342227569Sphilip} 343227569Sphilip 344227569Sphilip 345227569Sphilip#define SIENA_MAC_STAT_READ(_esmp, _field, _eqp) \ 346227569Sphilip EFSYS_MEM_READQ((_esmp), (_field) * sizeof (efx_qword_t), _eqp) 347227569Sphilip 348227569Sphilip __checkReturn int 349227569Sphilipsiena_mac_stats_update( 350227569Sphilip __in efx_nic_t *enp, 351227569Sphilip __in efsys_mem_t *esmp, 352227569Sphilip __out_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat, 353227569Sphilip __out_opt uint32_t *generationp) 354227569Sphilip{ 355227569Sphilip efx_qword_t rx_pkts; 356227569Sphilip efx_qword_t value; 357227569Sphilip efx_qword_t generation_start; 358227569Sphilip efx_qword_t generation_end; 359227569Sphilip 360227569Sphilip _NOTE(ARGUNUSED(enp)) 361227569Sphilip 362227569Sphilip /* Read END first so we don't race with the MC */ 363227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_END, 364227569Sphilip &generation_end); 365227569Sphilip EFSYS_MEM_READ_BARRIER(); 366227569Sphilip 367227569Sphilip /* TX */ 368227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PKTS, &value); 369227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value); 370227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_CONTROL_PKTS, &value); 371227569Sphilip EFSYS_STAT_SUBR_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value); 372227569Sphilip 373227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PAUSE_PKTS, &value); 374227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PAUSE_PKTS]), &value); 375227569Sphilip 376227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_UNICAST_PKTS, &value); 377227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_UNICST_PKTS]), &value); 378227569Sphilip 379227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTICAST_PKTS, &value); 380227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULTICST_PKTS]), &value); 381227569Sphilip 382227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BROADCAST_PKTS, &value); 383227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_BRDCST_PKTS]), &value); 384227569Sphilip 385227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BYTES, &value); 386227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_OCTETS]), &value); 387227569Sphilip 388227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LT64_PKTS, &value); 389227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value); 390227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_64_PKTS, &value); 391227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value); 392227569Sphilip 393227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_65_TO_127_PKTS, &value); 394227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_65_TO_127_PKTS]), &value); 395227569Sphilip 396227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_128_TO_255_PKTS, &value); 397227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_128_TO_255_PKTS]), &value); 398227569Sphilip 399227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_256_TO_511_PKTS, &value); 400227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_256_TO_511_PKTS]), &value); 401227569Sphilip 402227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_512_TO_1023_PKTS, &value); 403227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_512_TO_1023_PKTS]), &value); 404227569Sphilip 405227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_1024_TO_15XX_PKTS, &value); 406227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_1024_TO_15XX_PKTS]), &value); 407227569Sphilip 408227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS, &value); 409227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value); 410227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_GTJUMBO_PKTS, &value); 411227569Sphilip EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value); 412227569Sphilip 413227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BAD_FCS_PKTS, &value); 414227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_ERRORS]), &value); 415227569Sphilip 416227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS, &value); 417227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_SGL_COL_PKTS]), &value); 418227569Sphilip 419227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS, 420227569Sphilip &value); 421227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULT_COL_PKTS]), &value); 422227569Sphilip 423227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS, 424227569Sphilip &value); 425227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_COL_PKTS]), &value); 426227569Sphilip 427227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LATE_COLLISION_PKTS, &value); 428227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LATE_COL_PKTS]), &value); 429227569Sphilip 430227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_DEFERRED_PKTS, &value); 431227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_DEF_PKTS]), &value); 432227569Sphilip 433227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS, 434227569Sphilip &value); 435227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_DEF_PKTS]), &value); 436227569Sphilip 437227569Sphilip /* RX */ 438227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BYTES, &rx_pkts); 439227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_OCTETS]), &rx_pkts); 440227569Sphilip 441227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PKTS, &value); 442227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PKTS]), &value); 443227569Sphilip 444227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNICAST_PKTS, &value); 445227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_UNICST_PKTS]), &value); 446227569Sphilip 447227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MULTICAST_PKTS, &value); 448227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MULTICST_PKTS]), &value); 449227569Sphilip 450227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BROADCAST_PKTS, &value); 451227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_BRDCST_PKTS]), &value); 452227569Sphilip 453227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PAUSE_PKTS, &value); 454227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PAUSE_PKTS]), &value); 455227569Sphilip 456227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNDERSIZE_PKTS, &value); 457227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value); 458227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_64_PKTS, &value); 459227569Sphilip EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value); 460227569Sphilip 461227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_65_TO_127_PKTS, &value); 462227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_65_TO_127_PKTS]), &value); 463227569Sphilip 464227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_128_TO_255_PKTS, &value); 465227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_128_TO_255_PKTS]), &value); 466227569Sphilip 467227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_256_TO_511_PKTS, &value); 468227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_256_TO_511_PKTS]), &value); 469227569Sphilip 470227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_512_TO_1023_PKTS, &value); 471227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_512_TO_1023_PKTS]), &value); 472227569Sphilip 473227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_1024_TO_15XX_PKTS, &value); 474227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_1024_TO_15XX_PKTS]), &value); 475227569Sphilip 476227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS, &value); 477227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value); 478227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_GTJUMBO_PKTS, &value); 479227569Sphilip EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value); 480227569Sphilip 481227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BAD_FCS_PKTS, &value); 482227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FCS_ERRORS]), &value); 483227569Sphilip 484227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_OVERFLOW_PKTS, &value); 485227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_DROP_EVENTS]), &value); 486227569Sphilip 487227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_FALSE_CARRIER_PKTS, &value); 488227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FALSE_CARRIER_ERRORS]), &value); 489227569Sphilip 490227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS, &value); 491227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_SYMBOL_ERRORS]), &value); 492227569Sphilip 493227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_ALIGN_ERROR_PKTS, &value); 494227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_ALIGN_ERRORS]), &value); 495227569Sphilip 496227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS, &value); 497227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_INTERNAL_ERRORS]), &value); 498227569Sphilip 499227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_JABBER_PKTS, &value); 500227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_JABBER_PKTS]), &value); 501227569Sphilip 502227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_CHAR_ERR, &value); 503227569Sphilip EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_CHAR_ERR]), 504227569Sphilip &(value.eq_dword[0])); 505227569Sphilip EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_CHAR_ERR]), 506227569Sphilip &(value.eq_dword[1])); 507227569Sphilip 508227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_CHAR_ERR, &value); 509227569Sphilip EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_CHAR_ERR]), 510227569Sphilip &(value.eq_dword[0])); 511227569Sphilip EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_CHAR_ERR]), 512227569Sphilip &(value.eq_dword[1])); 513227569Sphilip 514227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_DISP_ERR, &value); 515227569Sphilip EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_DISP_ERR]), 516227569Sphilip &(value.eq_dword[0])); 517227569Sphilip EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_DISP_ERR]), 518227569Sphilip &(value.eq_dword[1])); 519227569Sphilip 520227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_DISP_ERR, &value); 521227569Sphilip EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_DISP_ERR]), 522227569Sphilip &(value.eq_dword[0])); 523227569Sphilip EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_DISP_ERR]), 524227569Sphilip &(value.eq_dword[1])); 525227569Sphilip 526227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MATCH_FAULT, &value); 527227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MATCH_FAULT]), &value); 528227569Sphilip 529227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_NODESC_DROPS, &value); 530227569Sphilip EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_NODESC_DROP_CNT]), &value); 531227569Sphilip 532227569Sphilip EFSYS_MEM_READ_BARRIER(); 533227569Sphilip SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_START, 534227569Sphilip &generation_start); 535227569Sphilip 536227569Sphilip /* Check that we didn't read the stats in the middle of a DMA */ 537227569Sphilip if (memcmp(&generation_start, &generation_end, 538227569Sphilip sizeof (generation_start))) 539227569Sphilip return (EAGAIN); 540227569Sphilip 541227569Sphilip if (generationp) 542227569Sphilip *generationp = EFX_QWORD_FIELD(generation_start, EFX_DWORD_0); 543227569Sphilip 544227569Sphilip return (0); 545227569Sphilip} 546227569Sphilip 547227569Sphilip#endif /* EFSYS_OPT_MAC_STATS */ 548227569Sphilip 549227569Sphilip#endif /* EFSYS_OPT_SIENA */ 550