1 /*
   2  * Copyright (c) 2009-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 #if EFSYS_OPT_SIENA
  35 
  36         __checkReturn   efx_rc_t
  37 siena_mac_poll(
  38         __in            efx_nic_t *enp,
  39         __out           efx_link_mode_t *link_modep)
  40 {
  41         efx_port_t *epp = &(enp->en_port);
  42         siena_link_state_t sls;
  43         efx_rc_t rc;
  44 
  45         if ((rc = siena_phy_get_link(enp, &sls)) != 0)
  46                 goto fail1;
  47 
  48         epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
  49         epp->ep_fcntl = sls.sls_fcntl;
  50 
  51         *link_modep = sls.sls_link_mode;
  52 
  53         return (0);
  54 
  55 fail1:
  56         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  57 
  58         *link_modep = EFX_LINK_UNKNOWN;
  59 
  60         return (rc);
  61 }
  62 
  63         __checkReturn   efx_rc_t
  64 siena_mac_up(
  65         __in            efx_nic_t *enp,
  66         __out           boolean_t *mac_upp)
  67 {
  68         siena_link_state_t sls;
  69         efx_rc_t rc;
  70 
  71         /*
  72          * Because Siena doesn't *require* polling, we can't rely on
  73          * siena_mac_poll() being executed to populate epp->ep_mac_up.
  74          */
  75         if ((rc = siena_phy_get_link(enp, &sls)) != 0)
  76                 goto fail1;
  77 
  78         *mac_upp = sls.sls_mac_up;
  79 
  80         return (0);
  81 
  82 fail1:
  83         EFSYS_PROBE1(fail1, efx_rc_t, rc);
  84 
  85         return (rc);
  86 }
  87 
  88         __checkReturn   efx_rc_t
  89 siena_mac_reconfigure(
  90         __in            efx_nic_t *enp)
  91 {
  92         efx_port_t *epp = &(enp->en_port);
  93         efx_oword_t multicast_hash[2];
  94         efx_mcdi_req_t req;
  95         uint8_t payload[MAX(MAX(MC_CMD_SET_MAC_IN_LEN,
  96                                 MC_CMD_SET_MAC_OUT_LEN),
  97                             MAX(MC_CMD_SET_MCAST_HASH_IN_LEN,
  98                                 MC_CMD_SET_MCAST_HASH_OUT_LEN))];
  99         unsigned int fcntl;
 100         efx_rc_t rc;
 101 
 102         (void) memset(payload, 0, sizeof (payload));
 103         req.emr_cmd = MC_CMD_SET_MAC;
 104         req.emr_in_buf = payload;
 105         req.emr_in_length = MC_CMD_SET_MAC_IN_LEN;
 106         req.emr_out_buf = payload;
 107         req.emr_out_length = MC_CMD_SET_MAC_OUT_LEN;
 108 
 109         MCDI_IN_SET_DWORD(req, SET_MAC_IN_MTU, epp->ep_mac_pdu);
 110         MCDI_IN_SET_DWORD(req, SET_MAC_IN_DRAIN, epp->ep_mac_drain ? 1 : 0);
 111         EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, SET_MAC_IN_ADDR),
 112                             epp->ep_mac_addr);
 113         MCDI_IN_POPULATE_DWORD_2(req, SET_MAC_IN_REJECT,
 114                             SET_MAC_IN_REJECT_UNCST, !epp->ep_all_unicst,
 115                             SET_MAC_IN_REJECT_BRDCST, !epp->ep_brdcst);
 116 
 117         if (epp->ep_fcntl_autoneg)
 118                 /* efx_fcntl_set() has already set the phy capabilities */
 119                 fcntl = MC_CMD_FCNTL_AUTO;
 120         else if (epp->ep_fcntl & EFX_FCNTL_RESPOND)
 121                 fcntl = (epp->ep_fcntl & EFX_FCNTL_GENERATE)
 122                         ? MC_CMD_FCNTL_BIDIR
 123                         : MC_CMD_FCNTL_RESPOND;
 124         else
 125                 fcntl = MC_CMD_FCNTL_OFF;
 126 
 127         MCDI_IN_SET_DWORD(req, SET_MAC_IN_FCNTL, fcntl);
 128 
 129         efx_mcdi_execute(enp, &req);
 130 
 131         if (req.emr_rc != 0) {
 132                 rc = req.emr_rc;
 133                 goto fail1;
 134         }
 135 
 136         /* Push multicast hash */
 137 
 138         if (epp->ep_all_mulcst) {
 139                 /* A hash matching all multicast is all 1s */
 140                 EFX_SET_OWORD(multicast_hash[0]);
 141                 EFX_SET_OWORD(multicast_hash[1]);
 142         } else if (epp->ep_mulcst) {
 143                 /* Use the hash set by the multicast list */
 144                 multicast_hash[0] = epp->ep_multicst_hash[0];
 145                 multicast_hash[1] = epp->ep_multicst_hash[1];
 146         } else {
 147                 /* A hash matching no traffic is simply 0 */
 148                 EFX_ZERO_OWORD(multicast_hash[0]);
 149                 EFX_ZERO_OWORD(multicast_hash[1]);
 150         }
 151 
 152         /*
 153          * Broadcast packets go through the multicast hash filter.
 154          * The IEEE 802.3 CRC32 of the broadcast address is 0xbe2612ff
 155          * so we always add bit 0xff to the mask (bit 0x7f in the
 156          * second octword).
 157          */
 158         if (epp->ep_brdcst) {
 159                 /*
 160                  * NB: due to constant folding, some of this evaluates
 161                  * to null expressions, giving E_EXPR_NULL_EFFECT during
 162                  * lint.  No good way to fix this without explicit coding
 163                  * the individual word/bit setting. So just suppress lint
 164                  * for this one line.
 165                  */
 166                 /* LINTED */
 167                 EFX_SET_OWORD_BIT(multicast_hash[1], 0x7f);
 168         }
 169 
 170         (void) memset(payload, 0, sizeof (payload));
 171         req.emr_cmd = MC_CMD_SET_MCAST_HASH;
 172         req.emr_in_buf = payload;
 173         req.emr_in_length = MC_CMD_SET_MCAST_HASH_IN_LEN;
 174         req.emr_out_buf = payload;
 175         req.emr_out_length = MC_CMD_SET_MCAST_HASH_OUT_LEN;
 176 
 177         (void) memcpy(MCDI_IN2(req, uint8_t, SET_MCAST_HASH_IN_HASH0),
 178             multicast_hash, sizeof (multicast_hash));
 179 
 180         efx_mcdi_execute(enp, &req);
 181 
 182         if (req.emr_rc != 0) {
 183                 rc = req.emr_rc;
 184                 goto fail2;
 185         }
 186 
 187         return (0);
 188 
 189 fail2:
 190         EFSYS_PROBE(fail2);
 191 fail1:
 192         EFSYS_PROBE1(fail1, efx_rc_t, rc);
 193 
 194         return (rc);
 195 }
 196 
 197 #if EFSYS_OPT_LOOPBACK
 198 
 199         __checkReturn   efx_rc_t
 200 siena_mac_loopback_set(
 201         __in            efx_nic_t *enp,
 202         __in            efx_link_mode_t link_mode,
 203         __in            efx_loopback_type_t loopback_type)
 204 {
 205         efx_port_t *epp = &(enp->en_port);
 206         const efx_phy_ops_t *epop = epp->ep_epop;
 207         efx_loopback_type_t old_loopback_type;
 208         efx_link_mode_t old_loopback_link_mode;
 209         efx_rc_t rc;
 210 
 211         /* The PHY object handles this on Siena */
 212         old_loopback_type = epp->ep_loopback_type;
 213         old_loopback_link_mode = epp->ep_loopback_link_mode;
 214         epp->ep_loopback_type = loopback_type;
 215         epp->ep_loopback_link_mode = link_mode;
 216 
 217         if ((rc = epop->epo_reconfigure(enp)) != 0)
 218                 goto fail1;
 219 
 220         return (0);
 221 
 222 fail1:
 223         EFSYS_PROBE(fail2);
 224 
 225         epp->ep_loopback_type = old_loopback_type;
 226         epp->ep_loopback_link_mode = old_loopback_link_mode;
 227 
 228         return (rc);
 229 }
 230 
 231 #endif  /* EFSYS_OPT_LOOPBACK */
 232 
 233 #if EFSYS_OPT_MAC_STATS
 234 
 235 #define SIENA_MAC_STAT_READ(_esmp, _field, _eqp)                        \
 236         EFSYS_MEM_READQ((_esmp), (_field) * sizeof (efx_qword_t), _eqp)
 237 
 238         __checkReturn                   efx_rc_t
 239 siena_mac_stats_update(
 240         __in                            efx_nic_t *enp,
 241         __in                            efsys_mem_t *esmp,
 242         __inout_ecount(EFX_MAC_NSTATS)  efsys_stat_t *stat,
 243         __inout_opt                     uint32_t *generationp)
 244 {
 245         efx_qword_t value;
 246         efx_qword_t generation_start;
 247         efx_qword_t generation_end;
 248 
 249         _NOTE(ARGUNUSED(enp))
 250 
 251         /* Read END first so we don't race with the MC */
 252         EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFX_MAC_STATS_SIZE);
 253         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_END,
 254                             &generation_end);
 255         EFSYS_MEM_READ_BARRIER();
 256 
 257         /* TX */
 258         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PKTS, &value);
 259         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value);
 260         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_CONTROL_PKTS, &value);
 261         EFSYS_STAT_SUBR_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value);
 262 
 263         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PAUSE_PKTS, &value);
 264         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PAUSE_PKTS]), &value);
 265 
 266         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_UNICAST_PKTS, &value);
 267         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_UNICST_PKTS]), &value);
 268 
 269         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTICAST_PKTS, &value);
 270         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULTICST_PKTS]), &value);
 271 
 272         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BROADCAST_PKTS, &value);
 273         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_BRDCST_PKTS]), &value);
 274 
 275         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BYTES, &value);
 276         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_OCTETS]), &value);
 277 
 278         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LT64_PKTS, &value);
 279         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
 280         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_64_PKTS, &value);
 281         EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
 282 
 283         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_65_TO_127_PKTS, &value);
 284         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_65_TO_127_PKTS]), &value);
 285 
 286         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_128_TO_255_PKTS, &value);
 287         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_128_TO_255_PKTS]), &value);
 288 
 289         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_256_TO_511_PKTS, &value);
 290         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_256_TO_511_PKTS]), &value);
 291 
 292         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_512_TO_1023_PKTS, &value);
 293         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_512_TO_1023_PKTS]), &value);
 294 
 295         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_1024_TO_15XX_PKTS, &value);
 296         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_1024_TO_15XX_PKTS]), &value);
 297 
 298         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS, &value);
 299         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value);
 300         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_GTJUMBO_PKTS, &value);
 301         EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value);
 302 
 303         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BAD_FCS_PKTS, &value);
 304         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_ERRORS]), &value);
 305 
 306         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS, &value);
 307         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_SGL_COL_PKTS]), &value);
 308 
 309         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS,
 310                             &value);
 311         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULT_COL_PKTS]), &value);
 312 
 313         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS,
 314                             &value);
 315         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_COL_PKTS]), &value);
 316 
 317         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LATE_COLLISION_PKTS, &value);
 318         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LATE_COL_PKTS]), &value);
 319 
 320         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_DEFERRED_PKTS, &value);
 321         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_DEF_PKTS]), &value);
 322 
 323         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS,
 324             &value);
 325         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_DEF_PKTS]), &value);
 326 
 327         /* RX */
 328         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BYTES, &value);
 329         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_OCTETS]), &value);
 330 
 331         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PKTS, &value);
 332         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PKTS]), &value);
 333 
 334         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNICAST_PKTS, &value);
 335         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_UNICST_PKTS]), &value);
 336 
 337         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MULTICAST_PKTS, &value);
 338         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MULTICST_PKTS]), &value);
 339 
 340         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BROADCAST_PKTS, &value);
 341         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_BRDCST_PKTS]), &value);
 342 
 343         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PAUSE_PKTS, &value);
 344         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PAUSE_PKTS]), &value);
 345 
 346         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNDERSIZE_PKTS, &value);
 347         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value);
 348         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_64_PKTS, &value);
 349         EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value);
 350 
 351         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_65_TO_127_PKTS, &value);
 352         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_65_TO_127_PKTS]), &value);
 353 
 354         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_128_TO_255_PKTS, &value);
 355         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_128_TO_255_PKTS]), &value);
 356 
 357         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_256_TO_511_PKTS, &value);
 358         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_256_TO_511_PKTS]), &value);
 359 
 360         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_512_TO_1023_PKTS, &value);
 361         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_512_TO_1023_PKTS]), &value);
 362 
 363         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_1024_TO_15XX_PKTS, &value);
 364         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_1024_TO_15XX_PKTS]), &value);
 365 
 366         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS, &value);
 367         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value);
 368         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_GTJUMBO_PKTS, &value);
 369         EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value);
 370 
 371         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BAD_FCS_PKTS, &value);
 372         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FCS_ERRORS]), &value);
 373 
 374         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_OVERFLOW_PKTS, &value);
 375         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_DROP_EVENTS]), &value);
 376 
 377         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_FALSE_CARRIER_PKTS, &value);
 378         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FALSE_CARRIER_ERRORS]), &value);
 379 
 380         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS, &value);
 381         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_SYMBOL_ERRORS]), &value);
 382 
 383         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_ALIGN_ERROR_PKTS, &value);
 384         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_ALIGN_ERRORS]), &value);
 385 
 386         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS, &value);
 387         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_INTERNAL_ERRORS]), &value);
 388 
 389         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_JABBER_PKTS, &value);
 390         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_JABBER_PKTS]), &value);
 391 
 392         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_CHAR_ERR, &value);
 393         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_CHAR_ERR]),
 394                             &(value.eq_dword[0]));
 395         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_CHAR_ERR]),
 396                             &(value.eq_dword[1]));
 397 
 398         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_CHAR_ERR, &value);
 399         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_CHAR_ERR]),
 400                             &(value.eq_dword[0]));
 401         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_CHAR_ERR]),
 402                             &(value.eq_dword[1]));
 403 
 404         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_DISP_ERR, &value);
 405         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_DISP_ERR]),
 406                             &(value.eq_dword[0]));
 407         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_DISP_ERR]),
 408                             &(value.eq_dword[1]));
 409 
 410         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_DISP_ERR, &value);
 411         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_DISP_ERR]),
 412                             &(value.eq_dword[0]));
 413         EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_DISP_ERR]),
 414                             &(value.eq_dword[1]));
 415 
 416         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MATCH_FAULT, &value);
 417         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MATCH_FAULT]), &value);
 418 
 419         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_NODESC_DROPS, &value);
 420         EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_NODESC_DROP_CNT]), &value);
 421 
 422         EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFX_MAC_STATS_SIZE);
 423         EFSYS_MEM_READ_BARRIER();
 424         SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_START,
 425                             &generation_start);
 426 
 427         /* Check that we didn't read the stats in the middle of a DMA */
 428         /* Not a good enough check ? */
 429         if (memcmp(&generation_start, &generation_end,
 430             sizeof (generation_start)))
 431                 return (EAGAIN);
 432 
 433         if (generationp)
 434                 *generationp = EFX_QWORD_FIELD(generation_start, EFX_DWORD_0);
 435 
 436         return (0);
 437 }
 438 
 439 #endif  /* EFSYS_OPT_MAC_STATS */
 440 
 441 #endif  /* EFSYS_OPT_SIENA */