1 /*
   2  * Copyright 2009 Solarflare Communications Inc.  All rights reserved.
   3  *
   4  * Redistribution and use in source and binary forms, with or without
   5  * modification, are permitted provided that the following conditions
   6  * are met:
   7  * 1. Redistributions of source code must retain the above copyright
   8  *    notice, this list of conditions and the following disclaimer.
   9  * 2. Redistributions in binary form must reproduce the above copyright
  10  *    notice, this list of conditions and the following disclaimer in the
  11  *    documentation and/or other materials provided with the distribution.
  12  *
  13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND
  14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  23  * SUCH DAMAGE.
  24  */
  25 #include "efsys.h"
  26 #include "efx.h"
  27 #include "efx_impl.h"
  28 
  29 #if EFSYS_OPT_SIENA
  30 
  31         __checkReturn   int
  32 siena_mac_poll(
  33         __in            efx_nic_t *enp,
  34         __out           efx_link_mode_t *link_modep)
  35 {
  36         efx_port_t *epp = &(enp->en_port);
  37         siena_link_state_t sls;
  38         int rc;
  39 
  40         if ((rc = siena_phy_get_link(enp, &sls)) != 0)
  41                 goto fail1;
  42 
  43         epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
  44         epp->ep_fcntl = sls.sls_fcntl;
  45 
  46         *link_modep = sls.sls_link_mode;
  47 
  48         return (0);
  49 
  50 fail1:
  51         EFSYS_PROBE1(fail1, int, rc);
  52 
  53         *link_modep = EFX_LINK_UNKNOWN;
  54 
  55         return (rc);
  56 }
  57 
  58         __checkReturn   int
  59 siena_mac_up(
  60         __in            efx_nic_t *enp,
  61         __out           boolean_t *mac_upp)
  62 {
  63         siena_link_state_t sls;
  64         int rc;
  65 
  66         /*
  67          * Because Siena doesn't *require* polling, we can't rely on
  68          * siena_mac_poll() being executed to populate epp->ep_mac_up.
  69          */
  70         if ((rc = siena_phy_get_link(enp, &sls)) != 0)
  71                 goto fail1;
  72 
  73         *mac_upp = sls.sls_mac_up;
  74 
  75         return (0);
  76 
  77 fail1:
  78         EFSYS_PROBE1(fail1, int, rc);
  79 
  80         return (rc);
  81 }
  82 
  83         __checkReturn   int
  84 siena_mac_reconfigure(
  85         __in            efx_nic_t *enp)
  86 {
  87         efx_port_t *epp = &(enp->en_port);
  88         uint8_t payload[MAX(MC_CMD_SET_MAC_IN_LEN,
  89                             MC_CMD_SET_MCAST_HASH_IN_LEN)];
  90         efx_mcdi_req_t req;
  91         unsigned int fcntl;
  92         int rc;
  93 
  94         req.emr_cmd = MC_CMD_SET_MAC;
  95         req.emr_in_buf = payload;
  96         req.emr_in_length = MC_CMD_SET_MAC_IN_LEN;
  97         EFX_STATIC_ASSERT(MC_CMD_SET_MAC_OUT_LEN == 0);
  98         req.emr_out_buf = NULL;
  99         req.emr_out_length = 0;
 100 
 101         MCDI_IN_SET_DWORD(req, SET_MAC_IN_MTU, epp->ep_mac_pdu);
 102         MCDI_IN_SET_DWORD(req, SET_MAC_IN_DRAIN, epp->ep_mac_drain ? 1 : 0);
 103         EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, SET_MAC_IN_ADDR),
 104                             epp->ep_mac_addr);
 105         MCDI_IN_POPULATE_DWORD_2(req, SET_MAC_IN_REJECT,
 106                                     SET_MAC_IN_REJECT_UNCST, !epp->ep_unicst,
 107                                     SET_MAC_IN_REJECT_BRDCST, !epp->ep_brdcst);
 108 
 109         if (epp->ep_fcntl_autoneg)
 110                 /* efx_fcntl_set() has already set the phy capabilities */
 111                 fcntl = MC_CMD_FCNTL_AUTO;
 112         else if (epp->ep_fcntl & EFX_FCNTL_RESPOND)
 113                 fcntl = (epp->ep_fcntl & EFX_FCNTL_GENERATE)
 114                         ? MC_CMD_FCNTL_BIDIR
 115                         : MC_CMD_FCNTL_RESPOND;
 116         else
 117                 fcntl = MC_CMD_FCNTL_OFF;
 118 
 119         MCDI_IN_SET_DWORD(req, SET_MAC_IN_FCNTL, fcntl);
 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         /* Push multicast hash. Set the broadcast bit (0xff) appropriately */
 129         req.emr_cmd = MC_CMD_SET_MCAST_HASH;
 130         req.emr_in_buf = payload;
 131         req.emr_in_length = MC_CMD_SET_MCAST_HASH_IN_LEN;
 132         EFX_STATIC_ASSERT(MC_CMD_SET_MCAST_HASH_OUT_LEN == 0);
 133         req.emr_out_buf = NULL;
 134         req.emr_out_length = 0;
 135 
 136         memcpy(MCDI_IN2(req, uint8_t, SET_MCAST_HASH_IN_HASH0),
 137             epp->ep_multicst_hash, sizeof (epp->ep_multicst_hash));
 138         if (epp->ep_brdcst)
 139                 EFX_SET_OWORD_BIT(*MCDI_IN2(req, efx_oword_t,
 140                     SET_MCAST_HASH_IN_HASH1), 0x7f);
 141 
 142         efx_mcdi_execute(enp, &req);
 143 
 144         if (req.emr_rc != 0) {
 145                 rc = req.emr_rc;
 146                 goto fail2;
 147         }
 148 
 149         return (0);
 150 
 151 fail2:
 152         EFSYS_PROBE(fail2);
 153 fail1:
 154         EFSYS_PROBE1(fail1, int, rc);
 155 
 156         return (rc);
 157 }
 158 
 159 #if EFSYS_OPT_LOOPBACK
 160 
 161         __checkReturn   int
 162 siena_mac_loopback_set(
 163         __in            efx_nic_t *enp,
 164         __in            efx_link_mode_t link_mode,
 165         __in            efx_loopback_type_t loopback_type)
 166 {
 167         efx_port_t *epp = &(enp->en_port);
 168         efx_phy_ops_t *epop = epp->ep_epop;
 169         efx_loopback_type_t old_loopback_type;
 170         efx_link_mode_t old_loopback_link_mode;
 171         int rc;
 172 
 173         /* The PHY object handles this on Siena */
 174         old_loopback_type = epp->ep_loopback_type;
 175         old_loopback_link_mode = epp->ep_loopback_link_mode;
 176         epp->ep_loopback_type = loopback_type;
 177         epp->ep_loopback_link_mode = link_mode;
 178 
 179         if ((rc = epop->epo_reconfigure(enp)) != 0)
 180                 goto fail1;
 181 
 182         return (0);
 183 
 184 fail1:
 185         EFSYS_PROBE(fail2);
 186 
 187         epp->ep_loopback_type = old_loopback_type;
 188         epp->ep_loopback_link_mode = old_loopback_link_mode;
 189 
 190         return (rc);
 191 }
 192 
 193 #endif  /* EFSYS_OPT_LOOPBACK */
 194 
 195 #if EFSYS_OPT_MAC_STATS
 196 
 197         __checkReturn                   int
 198 siena_mac_stats_clear(
 199         __in                            efx_nic_t *enp)
 200 {
 201         uint8_t payload[MC_CMD_MAC_STATS_IN_LEN];
 202         efx_mcdi_req_t req;
 203         int rc;
 204 
 205         req.emr_cmd = MC_CMD_MAC_STATS;
 206         req.emr_in_buf = payload;
 207         req.emr_in_length = sizeof (payload);
 208         EFX_STATIC_ASSERT(MC_CMD_MAC_STATS_OUT_DMA_LEN == 0);
 209         req.emr_out_buf = NULL;
 210         req.emr_out_length = 0;
 211 
 212         MCDI_IN_POPULATE_DWORD_3(req, MAC_STATS_IN_CMD,
 213                                     MAC_STATS_IN_DMA, 0,
 214                                     MAC_STATS_IN_CLEAR, 1,
 215                                     MAC_STATS_IN_PERIODIC_CHANGE, 0);
 216 
 217         efx_mcdi_execute(enp, &req);
 218 
 219         if (req.emr_rc != 0) {
 220                 rc = req.emr_rc;
 221                 goto fail1;
 222         }
 223 
 224         return (0);
 225 
 226 fail1:
 227         EFSYS_PROBE1(fail1, int, rc);
 228 
 229         return (rc);
 230 }
 231 
 232         __checkReturn                   int
 233 siena_mac_stats_upload(
 234         __in                            efx_nic_t *enp,
 235         __in                            efsys_mem_t *esmp)
 236 {
 237         uint8_t payload[MC_CMD_MAC_STATS_IN_LEN];
 238         efx_mcdi_req_t req;
 239         size_t bytes;
 240         int rc;
 241 
 242         EFX_STATIC_ASSERT(MC_CMD_MAC_NSTATS * sizeof (uint64_t) <=
 243             EFX_MAC_STATS_SIZE);
 244 
 245         bytes = MC_CMD_MAC_NSTATS * sizeof (uint64_t);
 246 
 247         req.emr_cmd = MC_CMD_MAC_STATS;
 248         req.emr_in_buf = payload;
 249         req.emr_in_length = sizeof (payload);
 250         EFX_STATIC_ASSERT(MC_CMD_MAC_STATS_OUT_DMA_LEN == 0);
 251         req.emr_out_buf = NULL;
 252         req.emr_out_length = 0;
 253 
 254         MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_LO,
 255                             EFSYS_MEM_ADDR(esmp) & 0xffffffff);
 256         MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_HI,
 257                             EFSYS_MEM_ADDR(esmp) >> 32);
 258         MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_LEN, bytes);
 259 
 260         /*
 261          * The MC DMAs aggregate statistics for our convinience, so we can
 262          * avoid having to pull the statistics buffer into the cache to
 263          * maintain cumulative statistics.
 264          */
 265         MCDI_IN_POPULATE_DWORD_3(req, MAC_STATS_IN_CMD,
 266                                     MAC_STATS_IN_DMA, 1,
 267                                     MAC_STATS_IN_CLEAR, 0,
 268                                     MAC_STATS_IN_PERIODIC_CHANGE, 0);
 269 
 270         efx_mcdi_execute(enp, &req);
 271 
 272         if (req.emr_rc != 0) {
 273                 rc = req.emr_rc;
 274                 goto fail1;
 275         }
 276 
 277         return (0);
 278 
 279 fail1:
 280         EFSYS_PROBE1(fail1, int, rc);
 281 
 282         return (rc);
 283 }
 284 
 285         __checkReturn                   int
 286 siena_mac_stats_periodic(
 287         __in                            efx_nic_t *enp,
 288         __in                            efsys_mem_t *esmp,
 289         __in                            uint16_t period,
 290         __in                            boolean_t events)
 291 {
 292         uint8_t payload[MC_CMD_MAC_STATS_IN_LEN];
 293         efx_mcdi_req_t req;
 294         size_t bytes;
 295         int rc;
 296 
 297         bytes = MC_CMD_MAC_NSTATS * sizeof (uint64_t);
 298 
 299         req.emr_cmd = MC_CMD_MAC_STATS;
 300         req.emr_in_buf = payload;
 301         req.emr_in_length = sizeof (payload);
 302         EFX_STATIC_ASSERT(MC_CMD_MAC_STATS_OUT_DMA_LEN == 0);
 303         req.emr_out_buf = NULL;
 304         req.emr_out_length = 0;
 305 
 306         MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_LO,
 307                             EFSYS_MEM_ADDR(esmp) & 0xffffffff);
 308         MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_HI,
 309                             EFSYS_MEM_ADDR(esmp) >> 32);
 310         MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_LEN, bytes);
 311 
 312         /*
 313          * The MC DMAs aggregate statistics for our convinience, so we can
 314          * avoid having to pull the statistics buffer into the cache to
 315          * maintain cumulative statistics.
 316          */
 317         MCDI_IN_POPULATE_DWORD_6(req, MAC_STATS_IN_CMD,
 318                             MAC_STATS_IN_DMA, 0,
 319                             MAC_STATS_IN_CLEAR, 0,
 320                             MAC_STATS_IN_PERIODIC_CHANGE, 1,
 321                             MAC_STATS_IN_PERIODIC_ENABLE, period ? 1 : 0,
 322                             MAC_STATS_IN_PERIODIC_NOEVENT, events ? 0 : 1,
 323                             MAC_STATS_IN_PERIOD_MS, period);
 324 
 325         efx_mcdi_execute(enp, &req);
 326 
 327         if (req.emr_rc != 0) {
 328                 rc = req.emr_rc;
 329                 goto fail1;
 330         }
 331 
 332         return (0);
 333 
 334 fail1:
 335         EFSYS_PROBE1(fail1, int, rc);
 336 
 337         return (rc);
 338 }
 339 
 340 
 341 #define SIENA_MAC_STAT_READ(_esmp, _field, _eqp)                        \
 342         EFSYS_MEM_READQ((_esmp), (_field) * sizeof (efx_qword_t), _eqp)
 343 
 344         __checkReturn                   int
 345 siena_mac_stats_update(
 346         __in                            efx_nic_t *enp,
 347         __in                            efsys_mem_t *esmp,
 348         __out_ecount(EFX_MAC_NSTATS)    efsys_stat_t *stat,
 349         __out_opt                       uint32_t *generationp)
 350 {
 351         efx_qword_t rx_pkts;
 352         efx_qword_t value;
 353         efx_qword_t generation_start;
 354         efx_qword_t generation_end;
 355 
 356         _NOTE(ARGUNUSED(enp))
 357 
 358         /* Read END first so we don't race with the MC */
 359         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_END,
 360                             &generation_end);
 361         EFSYS_MEM_READ_BARRIER();
 362 
 363         /* TX */
 364         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PKTS, &value);
 365         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value);
 366         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_CONTROL_PKTS, &value);
 367         EFSYS_STAT_SUBR_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value);
 368 
 369         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PAUSE_PKTS, &value);
 370         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PAUSE_PKTS]), &value);
 371 
 372         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_UNICAST_PKTS, &value);
 373         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_UNICST_PKTS]), &value);
 374 
 375         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTICAST_PKTS, &value);
 376         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULTICST_PKTS]), &value);
 377 
 378         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BROADCAST_PKTS, &value);
 379         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_BRDCST_PKTS]), &value);
 380 
 381         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BYTES, &value);
 382         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_OCTETS]), &value);
 383 
 384         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LT64_PKTS, &value);
 385         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
 386         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_64_PKTS, &value);
 387         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
 388 
 389         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_65_TO_127_PKTS, &value);
 390         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_65_TO_127_PKTS]), &value);
 391 
 392         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_128_TO_255_PKTS, &value);
 393         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_128_TO_255_PKTS]), &value);
 394 
 395         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_256_TO_511_PKTS, &value);
 396         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_256_TO_511_PKTS]), &value);
 397 
 398         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_512_TO_1023_PKTS, &value);
 399         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_512_TO_1023_PKTS]), &value);
 400 
 401         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_1024_TO_15XX_PKTS, &value);
 402         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_1024_TO_15XX_PKTS]), &value);
 403 
 404         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS, &value);
 405         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value);
 406         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_GTJUMBO_PKTS, &value);
 407         EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value);
 408 
 409         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BAD_FCS_PKTS, &value);
 410         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_ERRORS]), &value);
 411 
 412         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS, &value);
 413         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_SGL_COL_PKTS]), &value);
 414 
 415         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS,
 416                             &value);
 417         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULT_COL_PKTS]), &value);
 418 
 419         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS,
 420                             &value);
 421         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_COL_PKTS]), &value);
 422 
 423         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LATE_COLLISION_PKTS, &value);
 424         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LATE_COL_PKTS]), &value);
 425 
 426         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_DEFERRED_PKTS, &value);
 427         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_DEF_PKTS]), &value);
 428 
 429         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS,
 430             &value);
 431         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_DEF_PKTS]), &value);
 432 
 433         /* RX */
 434         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BYTES, &rx_pkts);
 435         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_OCTETS]), &rx_pkts);
 436 
 437         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PKTS, &value);
 438         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PKTS]), &value);
 439 
 440         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNICAST_PKTS, &value);
 441         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_UNICST_PKTS]), &value);
 442 
 443         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MULTICAST_PKTS, &value);
 444         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MULTICST_PKTS]), &value);
 445 
 446         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BROADCAST_PKTS, &value);
 447         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_BRDCST_PKTS]), &value);
 448 
 449         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PAUSE_PKTS, &value);
 450         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PAUSE_PKTS]), &value);
 451 
 452         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNDERSIZE_PKTS, &value);
 453         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value);
 454         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_64_PKTS, &value);
 455         EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value);
 456 
 457         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_65_TO_127_PKTS, &value);
 458         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_65_TO_127_PKTS]), &value);
 459 
 460         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_128_TO_255_PKTS, &value);
 461         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_128_TO_255_PKTS]), &value);
 462 
 463         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_256_TO_511_PKTS, &value);
 464         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_256_TO_511_PKTS]), &value);
 465 
 466         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_512_TO_1023_PKTS, &value);
 467         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_512_TO_1023_PKTS]), &value);
 468 
 469         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_1024_TO_15XX_PKTS, &value);
 470         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_1024_TO_15XX_PKTS]), &value);
 471 
 472         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS, &value);
 473         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value);
 474         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_GTJUMBO_PKTS, &value);
 475         EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value);
 476 
 477         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BAD_FCS_PKTS, &value);
 478         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FCS_ERRORS]), &value);
 479 
 480         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_OVERFLOW_PKTS, &value);
 481         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_DROP_EVENTS]), &value);
 482 
 483         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_FALSE_CARRIER_PKTS, &value);
 484         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FALSE_CARRIER_ERRORS]), &value);
 485 
 486         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS, &value);
 487         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_SYMBOL_ERRORS]), &value);
 488 
 489         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_ALIGN_ERROR_PKTS, &value);
 490         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_ALIGN_ERRORS]), &value);
 491 
 492         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS, &value);
 493         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_INTERNAL_ERRORS]), &value);
 494 
 495         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_JABBER_PKTS, &value);
 496         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_JABBER_PKTS]), &value);
 497 
 498         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_CHAR_ERR, &value);
 499         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_CHAR_ERR]),
 500                             &(value.eq_dword[0]));
 501         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_CHAR_ERR]),
 502                             &(value.eq_dword[1]));
 503 
 504         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_CHAR_ERR, &value);
 505         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_CHAR_ERR]),
 506                             &(value.eq_dword[0]));
 507         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_CHAR_ERR]),
 508                             &(value.eq_dword[1]));
 509 
 510         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_DISP_ERR, &value);
 511         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_DISP_ERR]),
 512                             &(value.eq_dword[0]));
 513         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_DISP_ERR]),
 514                             &(value.eq_dword[1]));
 515 
 516         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_DISP_ERR, &value);
 517         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_DISP_ERR]),
 518                             &(value.eq_dword[0]));
 519         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_DISP_ERR]),
 520                             &(value.eq_dword[1]));
 521 
 522         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MATCH_FAULT, &value);
 523         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MATCH_FAULT]), &value);
 524 
 525         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_NODESC_DROPS, &value);
 526         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_NODESC_DROP_CNT]), &value);
 527 
 528         EFSYS_MEM_READ_BARRIER();
 529         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_START,
 530                             &generation_start);
 531 
 532         /* Check that we didn't read the stats in the middle of a DMA */
 533         /* Not a good enough check ? */
 534         if (memcmp(&generation_start, &generation_end,
 535             sizeof (generation_start)))
 536                 return (EAGAIN);
 537 
 538         if (generationp)
 539                 *generationp = EFX_QWORD_FIELD(generation_start, EFX_DWORD_0);
 540 
 541         return (0);
 542 }
 543 
 544 #endif  /* EFSYS_OPT_MAC_STATS */
 545 
 546 #endif  /* EFSYS_OPT_SIENA */