net/sfc/base: import libefx base
authorAndrew Rybchenko <arybchenko@solarflare.com>
Tue, 29 Nov 2016 16:18:34 +0000 (16:18 +0000)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 17 Jan 2017 18:39:25 +0000 (19:39 +0100)
libefx is a platform-independent library to implement drivers
for Solarflare network adapters. It provides unified adapter
family independent interface (if possible).

Driver must provide efsys.h header which defines options
(EFSYS_OPT_*) to be used and macros/functions to allocate
memory, read/write DMA-mapped memory, read/write PCI BAR
space, locks, barriers etc.

efx.h and efx_types.h provide external interfaces intended
to be used by drivers. Other header files are internal.

From Solarflare Communications Inc.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
18 files changed:
drivers/net/sfc/base/README [new file with mode: 0644]
drivers/net/sfc/base/efx.h [new file with mode: 0644]
drivers/net/sfc/base/efx_check.h [new file with mode: 0644]
drivers/net/sfc/base/efx_crc32.c [new file with mode: 0644]
drivers/net/sfc/base/efx_ev.c [new file with mode: 0644]
drivers/net/sfc/base/efx_hash.c [new file with mode: 0644]
drivers/net/sfc/base/efx_impl.h [new file with mode: 0644]
drivers/net/sfc/base/efx_intr.c [new file with mode: 0644]
drivers/net/sfc/base/efx_mac.c [new file with mode: 0644]
drivers/net/sfc/base/efx_mon.c [new file with mode: 0644]
drivers/net/sfc/base/efx_nic.c [new file with mode: 0644]
drivers/net/sfc/base/efx_phy.c [new file with mode: 0644]
drivers/net/sfc/base/efx_phy_ids.h [new file with mode: 0644]
drivers/net/sfc/base/efx_port.c [new file with mode: 0644]
drivers/net/sfc/base/efx_rx.c [new file with mode: 0644]
drivers/net/sfc/base/efx_sram.c [new file with mode: 0644]
drivers/net/sfc/base/efx_tx.c [new file with mode: 0644]
drivers/net/sfc/base/efx_types.h [new file with mode: 0644]

diff --git a/drivers/net/sfc/base/README b/drivers/net/sfc/base/README
new file mode 100644 (file)
index 0000000..9019e8b
--- /dev/null
@@ -0,0 +1,36 @@
+
+   Copyright (c) 2006-2016 Solarflare Communications Inc.
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+   2. Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+   OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+   EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Solarflare libefx driver library
+================================
+
+This directory contains source code of Solarflare Communications libefx
+driver library of version v4.10.0.1012.
+
+Updating
+========
+
+The source code in this directory should not be modified.
+Please contact the driver maintainers to request changes.
diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
new file mode 100644 (file)
index 0000000..572520d
--- /dev/null
@@ -0,0 +1,1067 @@
+/*
+ * Copyright (c) 2006-2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#ifndef        _SYS_EFX_H
+#define        _SYS_EFX_H
+
+#include "efsys.h"
+#include "efx_check.h"
+#include "efx_phy_ids.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define        EFX_STATIC_ASSERT(_cond)                \
+       ((void)sizeof(char[(_cond) ? 1 : -1]))
+
+#define        EFX_ARRAY_SIZE(_array)                  \
+       (sizeof(_array) / sizeof((_array)[0]))
+
+#define        EFX_FIELD_OFFSET(_type, _field)         \
+       ((size_t) &(((_type *)0)->_field))
+
+/* Return codes */
+
+typedef __success(return == 0) int efx_rc_t;
+
+
+/* Chip families */
+
+typedef enum efx_family_e {
+       EFX_FAMILY_INVALID,
+       EFX_FAMILY_FALCON,      /* Obsolete and not supported */
+       EFX_FAMILY_SIENA,
+       EFX_FAMILY_HUNTINGTON,
+       EFX_FAMILY_MEDFORD,
+       EFX_FAMILY_NTYPES
+} efx_family_t;
+
+extern __checkReturn   efx_rc_t
+efx_family(
+       __in            uint16_t venid,
+       __in            uint16_t devid,
+       __out           efx_family_t *efp);
+
+
+#define        EFX_PCI_VENID_SFC                       0x1924
+
+#define        EFX_PCI_DEVID_FALCON                    0x0710  /* SFC4000 */
+
+#define        EFX_PCI_DEVID_BETHPAGE                  0x0803  /* SFC9020 */
+#define        EFX_PCI_DEVID_SIENA                     0x0813  /* SFL9021 */
+#define        EFX_PCI_DEVID_SIENA_F1_UNINIT           0x0810
+
+#define        EFX_PCI_DEVID_HUNTINGTON_PF_UNINIT      0x0901
+#define        EFX_PCI_DEVID_FARMINGDALE               0x0903  /* SFC9120 PF */
+#define        EFX_PCI_DEVID_GREENPORT                 0x0923  /* SFC9140 PF */
+
+#define        EFX_PCI_DEVID_FARMINGDALE_VF            0x1903  /* SFC9120 VF */
+#define        EFX_PCI_DEVID_GREENPORT_VF              0x1923  /* SFC9140 VF */
+
+#define        EFX_PCI_DEVID_MEDFORD_PF_UNINIT         0x0913
+#define        EFX_PCI_DEVID_MEDFORD                   0x0A03  /* SFC9240 PF */
+#define        EFX_PCI_DEVID_MEDFORD_VF                0x1A03  /* SFC9240 VF */
+
+#define        EFX_MEM_BAR     2
+
+/* Error codes */
+
+enum {
+       EFX_ERR_INVALID,
+       EFX_ERR_SRAM_OOB,
+       EFX_ERR_BUFID_DC_OOB,
+       EFX_ERR_MEM_PERR,
+       EFX_ERR_RBUF_OWN,
+       EFX_ERR_TBUF_OWN,
+       EFX_ERR_RDESQ_OWN,
+       EFX_ERR_TDESQ_OWN,
+       EFX_ERR_EVQ_OWN,
+       EFX_ERR_EVFF_OFLO,
+       EFX_ERR_ILL_ADDR,
+       EFX_ERR_SRAM_PERR,
+       EFX_ERR_NCODES
+};
+
+/* Calculate the IEEE 802.3 CRC32 of a MAC addr */
+extern __checkReturn           uint32_t
+efx_crc32_calculate(
+       __in                    uint32_t crc_init,
+       __in_ecount(length)     uint8_t const *input,
+       __in                    int length);
+
+
+/* Type prototypes */
+
+typedef struct efx_rxq_s       efx_rxq_t;
+
+/* NIC */
+
+typedef struct efx_nic_s       efx_nic_t;
+
+extern __checkReturn   efx_rc_t
+efx_nic_create(
+       __in            efx_family_t family,
+       __in            efsys_identifier_t *esip,
+       __in            efsys_bar_t *esbp,
+       __in            efsys_lock_t *eslp,
+       __deref_out     efx_nic_t **enpp);
+
+extern __checkReturn   efx_rc_t
+efx_nic_probe(
+       __in            efx_nic_t *enp);
+
+extern __checkReturn   efx_rc_t
+efx_nic_init(
+       __in            efx_nic_t *enp);
+
+extern __checkReturn   efx_rc_t
+efx_nic_reset(
+       __in            efx_nic_t *enp);
+
+extern         void
+efx_nic_fini(
+       __in            efx_nic_t *enp);
+
+extern         void
+efx_nic_unprobe(
+       __in            efx_nic_t *enp);
+
+extern         void
+efx_nic_destroy(
+       __in    efx_nic_t *enp);
+
+#define        EFX_PCIE_LINK_SPEED_GEN1                1
+#define        EFX_PCIE_LINK_SPEED_GEN2                2
+#define        EFX_PCIE_LINK_SPEED_GEN3                3
+
+typedef enum efx_pcie_link_performance_e {
+       EFX_PCIE_LINK_PERFORMANCE_UNKNOWN_BANDWIDTH,
+       EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_BANDWIDTH,
+       EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_LATENCY,
+       EFX_PCIE_LINK_PERFORMANCE_OPTIMAL
+} efx_pcie_link_performance_t;
+
+extern __checkReturn   efx_rc_t
+efx_nic_calculate_pcie_link_bandwidth(
+       __in            uint32_t pcie_link_width,
+       __in            uint32_t pcie_link_gen,
+       __out           uint32_t *bandwidth_mbpsp);
+
+extern __checkReturn   efx_rc_t
+efx_nic_check_pcie_link_speed(
+       __in            efx_nic_t *enp,
+       __in            uint32_t pcie_link_width,
+       __in            uint32_t pcie_link_gen,
+       __out           efx_pcie_link_performance_t *resultp);
+
+/* INTR */
+
+#define        EFX_NINTR_SIENA 1024
+
+typedef enum efx_intr_type_e {
+       EFX_INTR_INVALID = 0,
+       EFX_INTR_LINE,
+       EFX_INTR_MESSAGE,
+       EFX_INTR_NTYPES
+} efx_intr_type_t;
+
+#define        EFX_INTR_SIZE   (sizeof (efx_oword_t))
+
+extern __checkReturn   efx_rc_t
+efx_intr_init(
+       __in            efx_nic_t *enp,
+       __in            efx_intr_type_t type,
+       __in            efsys_mem_t *esmp);
+
+extern                 void
+efx_intr_enable(
+       __in            efx_nic_t *enp);
+
+extern                 void
+efx_intr_disable(
+       __in            efx_nic_t *enp);
+
+extern                 void
+efx_intr_disable_unlocked(
+       __in            efx_nic_t *enp);
+
+#define        EFX_INTR_NEVQS  32
+
+extern __checkReturn   efx_rc_t
+efx_intr_trigger(
+       __in            efx_nic_t *enp,
+       __in            unsigned int level);
+
+extern                 void
+efx_intr_status_line(
+       __in            efx_nic_t *enp,
+       __out           boolean_t *fatalp,
+       __out           uint32_t *maskp);
+
+extern                 void
+efx_intr_status_message(
+       __in            efx_nic_t *enp,
+       __in            unsigned int message,
+       __out           boolean_t *fatalp);
+
+extern                 void
+efx_intr_fatal(
+       __in            efx_nic_t *enp);
+
+extern                 void
+efx_intr_fini(
+       __in            efx_nic_t *enp);
+
+/* MAC */
+
+typedef enum efx_link_mode_e {
+       EFX_LINK_UNKNOWN = 0,
+       EFX_LINK_DOWN,
+       EFX_LINK_10HDX,
+       EFX_LINK_10FDX,
+       EFX_LINK_100HDX,
+       EFX_LINK_100FDX,
+       EFX_LINK_1000HDX,
+       EFX_LINK_1000FDX,
+       EFX_LINK_10000FDX,
+       EFX_LINK_40000FDX,
+       EFX_LINK_NMODES
+} efx_link_mode_t;
+
+#define        EFX_MAC_ADDR_LEN 6
+
+#define        EFX_MAC_ADDR_IS_MULTICAST(_address) (((uint8_t *)_address)[0] & 0x01)
+
+#define        EFX_MAC_MULTICAST_LIST_MAX      256
+
+#define        EFX_MAC_SDU_MAX 9202
+
+#define        EFX_MAC_PDU_ADJUSTMENT                                  \
+       (/* EtherII */ 14                                       \
+           + /* VLAN */ 4                                      \
+           + /* CRC */ 4                                       \
+           + /* bug16011 */ 16)                                \
+
+#define        EFX_MAC_PDU(_sdu)                                       \
+       P2ROUNDUP((_sdu) + EFX_MAC_PDU_ADJUSTMENT, 8)
+
+/*
+ * Due to the P2ROUNDUP in EFX_MAC_PDU(), EFX_MAC_SDU_FROM_PDU() may give
+ * the SDU rounded up slightly.
+ */
+#define        EFX_MAC_SDU_FROM_PDU(_pdu)      ((_pdu) - EFX_MAC_PDU_ADJUSTMENT)
+
+#define        EFX_MAC_PDU_MIN 60
+#define        EFX_MAC_PDU_MAX EFX_MAC_PDU(EFX_MAC_SDU_MAX)
+
+extern __checkReturn   efx_rc_t
+efx_mac_pdu_get(
+       __in            efx_nic_t *enp,
+       __out           size_t *pdu);
+
+extern __checkReturn   efx_rc_t
+efx_mac_pdu_set(
+       __in            efx_nic_t *enp,
+       __in            size_t pdu);
+
+extern __checkReturn   efx_rc_t
+efx_mac_addr_set(
+       __in            efx_nic_t *enp,
+       __in            uint8_t *addr);
+
+extern __checkReturn                   efx_rc_t
+efx_mac_filter_set(
+       __in                            efx_nic_t *enp,
+       __in                            boolean_t all_unicst,
+       __in                            boolean_t mulcst,
+       __in                            boolean_t all_mulcst,
+       __in                            boolean_t brdcst);
+
+extern __checkReturn   efx_rc_t
+efx_mac_multicast_list_set(
+       __in                            efx_nic_t *enp,
+       __in_ecount(6*count)            uint8_t const *addrs,
+       __in                            int count);
+
+extern __checkReturn   efx_rc_t
+efx_mac_filter_default_rxq_set(
+       __in            efx_nic_t *enp,
+       __in            efx_rxq_t *erp,
+       __in            boolean_t using_rss);
+
+extern                 void
+efx_mac_filter_default_rxq_clear(
+       __in            efx_nic_t *enp);
+
+extern __checkReturn   efx_rc_t
+efx_mac_drain(
+       __in            efx_nic_t *enp,
+       __in            boolean_t enabled);
+
+extern __checkReturn   efx_rc_t
+efx_mac_up(
+       __in            efx_nic_t *enp,
+       __out           boolean_t *mac_upp);
+
+#define        EFX_FCNTL_RESPOND       0x00000001
+#define        EFX_FCNTL_GENERATE      0x00000002
+
+extern __checkReturn   efx_rc_t
+efx_mac_fcntl_set(
+       __in            efx_nic_t *enp,
+       __in            unsigned int fcntl,
+       __in            boolean_t autoneg);
+
+extern                 void
+efx_mac_fcntl_get(
+       __in            efx_nic_t *enp,
+       __out           unsigned int *fcntl_wantedp,
+       __out           unsigned int *fcntl_linkp);
+
+
+/* MON */
+
+typedef enum efx_mon_type_e {
+       EFX_MON_INVALID = 0,
+       EFX_MON_SFC90X0,
+       EFX_MON_SFC91X0,
+       EFX_MON_SFC92X0,
+       EFX_MON_NTYPES
+} efx_mon_type_t;
+
+#if EFSYS_OPT_NAMES
+
+extern         const char *
+efx_mon_name(
+       __in    efx_nic_t *enp);
+
+#endif /* EFSYS_OPT_NAMES */
+
+extern __checkReturn   efx_rc_t
+efx_mon_init(
+       __in            efx_nic_t *enp);
+
+extern         void
+efx_mon_fini(
+       __in    efx_nic_t *enp);
+
+/* PHY */
+
+extern __checkReturn   efx_rc_t
+efx_phy_verify(
+       __in            efx_nic_t *enp);
+
+extern __checkReturn   efx_rc_t
+efx_port_init(
+       __in            efx_nic_t *enp);
+
+extern __checkReturn   efx_rc_t
+efx_port_poll(
+       __in            efx_nic_t *enp,
+       __out_opt       efx_link_mode_t *link_modep);
+
+extern         void
+efx_port_fini(
+       __in    efx_nic_t *enp);
+
+typedef enum efx_phy_cap_type_e {
+       EFX_PHY_CAP_INVALID = 0,
+       EFX_PHY_CAP_10HDX,
+       EFX_PHY_CAP_10FDX,
+       EFX_PHY_CAP_100HDX,
+       EFX_PHY_CAP_100FDX,
+       EFX_PHY_CAP_1000HDX,
+       EFX_PHY_CAP_1000FDX,
+       EFX_PHY_CAP_10000FDX,
+       EFX_PHY_CAP_PAUSE,
+       EFX_PHY_CAP_ASYM,
+       EFX_PHY_CAP_AN,
+       EFX_PHY_CAP_40000FDX,
+       EFX_PHY_CAP_NTYPES
+} efx_phy_cap_type_t;
+
+
+#define        EFX_PHY_CAP_CURRENT     0x00000000
+#define        EFX_PHY_CAP_DEFAULT     0x00000001
+#define        EFX_PHY_CAP_PERM        0x00000002
+
+extern         void
+efx_phy_adv_cap_get(
+       __in            efx_nic_t *enp,
+       __in            uint32_t flag,
+       __out           uint32_t *maskp);
+
+extern __checkReturn   efx_rc_t
+efx_phy_adv_cap_set(
+       __in            efx_nic_t *enp,
+       __in            uint32_t mask);
+
+extern                 void
+efx_phy_lp_cap_get(
+       __in            efx_nic_t *enp,
+       __out           uint32_t *maskp);
+
+extern __checkReturn   efx_rc_t
+efx_phy_oui_get(
+       __in            efx_nic_t *enp,
+       __out           uint32_t *ouip);
+
+typedef enum efx_phy_media_type_e {
+       EFX_PHY_MEDIA_INVALID = 0,
+       EFX_PHY_MEDIA_XAUI,
+       EFX_PHY_MEDIA_CX4,
+       EFX_PHY_MEDIA_KX4,
+       EFX_PHY_MEDIA_XFP,
+       EFX_PHY_MEDIA_SFP_PLUS,
+       EFX_PHY_MEDIA_BASE_T,
+       EFX_PHY_MEDIA_QSFP_PLUS,
+       EFX_PHY_MEDIA_NTYPES
+} efx_phy_media_type_t;
+
+/* Get the type of medium currently used.  If the board has ports for
+ * modules, a module is present, and we recognise the media type of
+ * the module, then this will be the media type of the module.
+ * Otherwise it will be the media type of the port.
+ */
+extern                 void
+efx_phy_media_type_get(
+       __in            efx_nic_t *enp,
+       __out           efx_phy_media_type_t *typep);
+
+extern                                 efx_rc_t
+efx_phy_module_get_info(
+       __in                            efx_nic_t *enp,
+       __in                            uint8_t dev_addr,
+       __in                            uint8_t offset,
+       __in                            uint8_t len,
+       __out_bcount(len)               uint8_t *data);
+
+
+#define        EFX_FEATURE_IPV6                0x00000001
+#define        EFX_FEATURE_LFSR_HASH_INSERT    0x00000002
+#define        EFX_FEATURE_LINK_EVENTS         0x00000004
+#define        EFX_FEATURE_PERIODIC_MAC_STATS  0x00000008
+#define        EFX_FEATURE_MCDI                0x00000020
+#define        EFX_FEATURE_LOOKAHEAD_SPLIT     0x00000040
+#define        EFX_FEATURE_MAC_HEADER_FILTERS  0x00000080
+#define        EFX_FEATURE_TURBO               0x00000100
+#define        EFX_FEATURE_MCDI_DMA            0x00000200
+#define        EFX_FEATURE_TX_SRC_FILTERS      0x00000400
+#define        EFX_FEATURE_PIO_BUFFERS         0x00000800
+#define        EFX_FEATURE_FW_ASSISTED_TSO     0x00001000
+#define        EFX_FEATURE_FW_ASSISTED_TSO_V2  0x00002000
+#define        EFX_FEATURE_PACKED_STREAM       0x00004000
+
+typedef struct efx_nic_cfg_s {
+       uint32_t                enc_board_type;
+       uint32_t                enc_phy_type;
+#if EFSYS_OPT_NAMES
+       char                    enc_phy_name[21];
+#endif
+       char                    enc_phy_revision[21];
+       efx_mon_type_t          enc_mon_type;
+       unsigned int            enc_features;
+       uint8_t                 enc_mac_addr[6];
+       uint8_t                 enc_port;       /* PHY port number */
+       uint32_t                enc_intr_vec_base;
+       uint32_t                enc_intr_limit;
+       uint32_t                enc_evq_limit;
+       uint32_t                enc_txq_limit;
+       uint32_t                enc_rxq_limit;
+       uint32_t                enc_txq_max_ndescs;
+       uint32_t                enc_buftbl_limit;
+       uint32_t                enc_piobuf_limit;
+       uint32_t                enc_piobuf_size;
+       uint32_t                enc_piobuf_min_alloc_size;
+       uint32_t                enc_evq_timer_quantum_ns;
+       uint32_t                enc_evq_timer_max_us;
+       uint32_t                enc_clk_mult;
+       uint32_t                enc_rx_prefix_size;
+       uint32_t                enc_rx_buf_align_start;
+       uint32_t                enc_rx_buf_align_end;
+       boolean_t               enc_bug26807_workaround;
+       boolean_t               enc_bug35388_workaround;
+       boolean_t               enc_bug41750_workaround;
+       boolean_t               enc_bug61265_workaround;
+       boolean_t               enc_rx_batching_enabled;
+       /* Maximum number of descriptors completed in an rx event. */
+       uint32_t                enc_rx_batch_max;
+       /* Number of rx descriptors the hardware requires for a push. */
+       uint32_t                enc_rx_push_align;
+       /*
+        * Maximum number of bytes into the packet the TCP header can start for
+        * the hardware to apply TSO packet edits.
+        */
+       uint32_t                enc_tx_tso_tcp_header_offset_limit;
+       boolean_t               enc_fw_assisted_tso_enabled;
+       boolean_t               enc_fw_assisted_tso_v2_enabled;
+       /* Number of TSO contexts on the NIC (FATSOv2) */
+       uint32_t                enc_fw_assisted_tso_v2_n_contexts;
+       boolean_t               enc_hw_tx_insert_vlan_enabled;
+       /* Number of PFs on the NIC */
+       uint32_t                enc_hw_pf_count;
+       /* Datapath firmware vadapter/vport/vswitch support */
+       boolean_t               enc_datapath_cap_evb;
+       boolean_t               enc_rx_disable_scatter_supported;
+       boolean_t               enc_allow_set_mac_with_installed_filters;
+       boolean_t               enc_enhanced_set_mac_supported;
+       boolean_t               enc_init_evq_v2_supported;
+       boolean_t               enc_rx_packed_stream_supported;
+       boolean_t               enc_rx_var_packed_stream_supported;
+       boolean_t               enc_pm_and_rxdp_counters;
+       boolean_t               enc_mac_stats_40g_tx_size_bins;
+       /* External port identifier */
+       uint8_t                 enc_external_port;
+       uint32_t                enc_mcdi_max_payload_length;
+       /* VPD may be per-PF or global */
+       boolean_t               enc_vpd_is_global;
+       /* Minimum unidirectional bandwidth in Mb/s to max out all ports */
+       uint32_t                enc_required_pcie_bandwidth_mbps;
+       uint32_t                enc_max_pcie_link_gen;
+       /* Firmware verifies integrity of NVRAM updates */
+       uint32_t                enc_fw_verified_nvram_update_required;
+} efx_nic_cfg_t;
+
+#define        EFX_PCI_FUNCTION_IS_PF(_encp)   ((_encp)->enc_vf == 0xffff)
+#define        EFX_PCI_FUNCTION_IS_VF(_encp)   ((_encp)->enc_vf != 0xffff)
+
+#define        EFX_PCI_FUNCTION(_encp) \
+       (EFX_PCI_FUNCTION_IS_PF(_encp) ? (_encp)->enc_pf : (_encp)->enc_vf)
+
+#define        EFX_PCI_VF_PARENT(_encp)        ((_encp)->enc_pf)
+
+extern                 const efx_nic_cfg_t *
+efx_nic_cfg_get(
+       __in            efx_nic_t *enp);
+
+/* Driver resource limits (minimum required/maximum usable). */
+typedef struct efx_drv_limits_s {
+       uint32_t        edl_min_evq_count;
+       uint32_t        edl_max_evq_count;
+
+       uint32_t        edl_min_rxq_count;
+       uint32_t        edl_max_rxq_count;
+
+       uint32_t        edl_min_txq_count;
+       uint32_t        edl_max_txq_count;
+
+       /* PIO blocks (sub-allocated from piobuf) */
+       uint32_t        edl_min_pio_alloc_size;
+       uint32_t        edl_max_pio_alloc_count;
+} efx_drv_limits_t;
+
+extern __checkReturn   efx_rc_t
+efx_nic_set_drv_limits(
+       __inout         efx_nic_t *enp,
+       __in            efx_drv_limits_t *edlp);
+
+typedef enum efx_nic_region_e {
+       EFX_REGION_VI,                  /* Memory BAR UC mapping */
+       EFX_REGION_PIO_WRITE_VI,        /* Memory BAR WC mapping */
+} efx_nic_region_t;
+
+extern __checkReturn   efx_rc_t
+efx_nic_get_bar_region(
+       __in            efx_nic_t *enp,
+       __in            efx_nic_region_t region,
+       __out           uint32_t *offsetp,
+       __out           size_t *sizep);
+
+extern __checkReturn   efx_rc_t
+efx_nic_get_vi_pool(
+       __in            efx_nic_t *enp,
+       __out           uint32_t *evq_countp,
+       __out           uint32_t *rxq_countp,
+       __out           uint32_t *txq_countp);
+
+
+/* NVRAM */
+
+extern __checkReturn   efx_rc_t
+efx_sram_buf_tbl_set(
+       __in            efx_nic_t *enp,
+       __in            uint32_t id,
+       __in            efsys_mem_t *esmp,
+       __in            size_t n);
+
+extern         void
+efx_sram_buf_tbl_clear(
+       __in    efx_nic_t *enp,
+       __in    uint32_t id,
+       __in    size_t n);
+
+#define        EFX_BUF_TBL_SIZE        0x20000
+
+#define        EFX_BUF_SIZE            4096
+
+/* EV */
+
+typedef struct efx_evq_s       efx_evq_t;
+
+extern __checkReturn   efx_rc_t
+efx_ev_init(
+       __in            efx_nic_t *enp);
+
+extern         void
+efx_ev_fini(
+       __in            efx_nic_t *enp);
+
+#define        EFX_EVQ_MAXNEVS         32768
+#define        EFX_EVQ_MINNEVS         512
+
+#define        EFX_EVQ_SIZE(_nevs)     ((_nevs) * sizeof (efx_qword_t))
+#define        EFX_EVQ_NBUFS(_nevs)    (EFX_EVQ_SIZE(_nevs) / EFX_BUF_SIZE)
+
+#define        EFX_EVQ_FLAGS_TYPE_MASK         (0x3)
+#define        EFX_EVQ_FLAGS_TYPE_AUTO         (0x0)
+#define        EFX_EVQ_FLAGS_TYPE_THROUGHPUT   (0x1)
+#define        EFX_EVQ_FLAGS_TYPE_LOW_LATENCY  (0x2)
+
+#define        EFX_EVQ_FLAGS_NOTIFY_MASK       (0xC)
+#define        EFX_EVQ_FLAGS_NOTIFY_INTERRUPT  (0x0)   /* Interrupting (default) */
+#define        EFX_EVQ_FLAGS_NOTIFY_DISABLED   (0x4)   /* Non-interrupting */
+
+extern __checkReturn   efx_rc_t
+efx_ev_qcreate(
+       __in            efx_nic_t *enp,
+       __in            unsigned int index,
+       __in            efsys_mem_t *esmp,
+       __in            size_t n,
+       __in            uint32_t id,
+       __in            uint32_t us,
+       __in            uint32_t flags,
+       __deref_out     efx_evq_t **eepp);
+
+extern         void
+efx_ev_qpost(
+       __in            efx_evq_t *eep,
+       __in            uint16_t data);
+
+typedef __checkReturn  boolean_t
+(*efx_initialized_ev_t)(
+       __in_opt        void *arg);
+
+#define        EFX_PKT_UNICAST         0x0004
+#define        EFX_PKT_START           0x0008
+
+#define        EFX_PKT_VLAN_TAGGED     0x0010
+#define        EFX_CKSUM_TCPUDP        0x0020
+#define        EFX_CKSUM_IPV4          0x0040
+#define        EFX_PKT_CONT            0x0080
+
+#define        EFX_CHECK_VLAN          0x0100
+#define        EFX_PKT_TCP             0x0200
+#define        EFX_PKT_UDP             0x0400
+#define        EFX_PKT_IPV4            0x0800
+
+#define        EFX_PKT_IPV6            0x1000
+#define        EFX_PKT_PREFIX_LEN      0x2000
+#define        EFX_ADDR_MISMATCH       0x4000
+#define        EFX_DISCARD             0x8000
+
+/*
+ * The following flags are used only for packed stream
+ * mode. The values for the flags are reused to fit into 16 bit,
+ * since EFX_PKT_START and EFX_PKT_CONT are never used in
+ * packed stream mode
+ */
+#define        EFX_PKT_PACKED_STREAM_NEW_BUFFER        EFX_PKT_START
+#define        EFX_PKT_PACKED_STREAM_PARSE_INCOMPLETE  EFX_PKT_CONT
+
+
+#define        EFX_EV_RX_NLABELS       32
+#define        EFX_EV_TX_NLABELS       32
+
+typedef        __checkReturn   boolean_t
+(*efx_rx_ev_t)(
+       __in_opt        void *arg,
+       __in            uint32_t label,
+       __in            uint32_t id,
+       __in            uint32_t size,
+       __in            uint16_t flags);
+
+typedef        __checkReturn   boolean_t
+(*efx_tx_ev_t)(
+       __in_opt        void *arg,
+       __in            uint32_t label,
+       __in            uint32_t id);
+
+#define        EFX_EXCEPTION_RX_RECOVERY       0x00000001
+#define        EFX_EXCEPTION_RX_DSC_ERROR      0x00000002
+#define        EFX_EXCEPTION_TX_DSC_ERROR      0x00000003
+#define        EFX_EXCEPTION_UNKNOWN_SENSOREVT 0x00000004
+#define        EFX_EXCEPTION_FWALERT_SRAM      0x00000005
+#define        EFX_EXCEPTION_UNKNOWN_FWALERT   0x00000006
+#define        EFX_EXCEPTION_RX_ERROR          0x00000007
+#define        EFX_EXCEPTION_TX_ERROR          0x00000008
+#define        EFX_EXCEPTION_EV_ERROR          0x00000009
+
+typedef        __checkReturn   boolean_t
+(*efx_exception_ev_t)(
+       __in_opt        void *arg,
+       __in            uint32_t label,
+       __in            uint32_t data);
+
+typedef        __checkReturn   boolean_t
+(*efx_rxq_flush_done_ev_t)(
+       __in_opt        void *arg,
+       __in            uint32_t rxq_index);
+
+typedef        __checkReturn   boolean_t
+(*efx_rxq_flush_failed_ev_t)(
+       __in_opt        void *arg,
+       __in            uint32_t rxq_index);
+
+typedef        __checkReturn   boolean_t
+(*efx_txq_flush_done_ev_t)(
+       __in_opt        void *arg,
+       __in            uint32_t txq_index);
+
+typedef        __checkReturn   boolean_t
+(*efx_software_ev_t)(
+       __in_opt        void *arg,
+       __in            uint16_t magic);
+
+typedef        __checkReturn   boolean_t
+(*efx_sram_ev_t)(
+       __in_opt        void *arg,
+       __in            uint32_t code);
+
+#define        EFX_SRAM_CLEAR          0
+#define        EFX_SRAM_UPDATE         1
+#define        EFX_SRAM_ILLEGAL_CLEAR  2
+
+typedef        __checkReturn   boolean_t
+(*efx_wake_up_ev_t)(
+       __in_opt        void *arg,
+       __in            uint32_t label);
+
+typedef        __checkReturn   boolean_t
+(*efx_timer_ev_t)(
+       __in_opt        void *arg,
+       __in            uint32_t label);
+
+typedef __checkReturn  boolean_t
+(*efx_link_change_ev_t)(
+       __in_opt        void *arg,
+       __in            efx_link_mode_t link_mode);
+
+typedef struct efx_ev_callbacks_s {
+       efx_initialized_ev_t            eec_initialized;
+       efx_rx_ev_t                     eec_rx;
+       efx_tx_ev_t                     eec_tx;
+       efx_exception_ev_t              eec_exception;
+       efx_rxq_flush_done_ev_t         eec_rxq_flush_done;
+       efx_rxq_flush_failed_ev_t       eec_rxq_flush_failed;
+       efx_txq_flush_done_ev_t         eec_txq_flush_done;
+       efx_software_ev_t               eec_software;
+       efx_sram_ev_t                   eec_sram;
+       efx_wake_up_ev_t                eec_wake_up;
+       efx_timer_ev_t                  eec_timer;
+       efx_link_change_ev_t            eec_link_change;
+} efx_ev_callbacks_t;
+
+extern __checkReturn   boolean_t
+efx_ev_qpending(
+       __in            efx_evq_t *eep,
+       __in            unsigned int count);
+
+extern                 void
+efx_ev_qpoll(
+       __in            efx_evq_t *eep,
+       __inout         unsigned int *countp,
+       __in            const efx_ev_callbacks_t *eecp,
+       __in_opt        void *arg);
+
+extern __checkReturn   efx_rc_t
+efx_ev_usecs_to_ticks(
+       __in            efx_nic_t *enp,
+       __in            unsigned int usecs,
+       __out           unsigned int *ticksp);
+
+extern __checkReturn   efx_rc_t
+efx_ev_qmoderate(
+       __in            efx_evq_t *eep,
+       __in            unsigned int us);
+
+extern __checkReturn   efx_rc_t
+efx_ev_qprime(
+       __in            efx_evq_t *eep,
+       __in            unsigned int count);
+
+extern         void
+efx_ev_qdestroy(
+       __in    efx_evq_t *eep);
+
+/* RX */
+
+extern __checkReturn   efx_rc_t
+efx_rx_init(
+       __inout         efx_nic_t *enp);
+
+extern         void
+efx_rx_fini(
+       __in            efx_nic_t *enp);
+
+extern __checkReturn   efx_rc_t
+efx_pseudo_hdr_pkt_length_get(
+       __in            efx_rxq_t *erp,
+       __in            uint8_t *buffer,
+       __out           uint16_t *pkt_lengthp);
+
+#define        EFX_RXQ_MAXNDESCS               4096
+#define        EFX_RXQ_MINNDESCS               512
+
+#define        EFX_RXQ_SIZE(_ndescs)           ((_ndescs) * sizeof (efx_qword_t))
+#define        EFX_RXQ_NBUFS(_ndescs)          (EFX_RXQ_SIZE(_ndescs) / EFX_BUF_SIZE)
+#define        EFX_RXQ_LIMIT(_ndescs)          ((_ndescs) - 16)
+#define        EFX_RXQ_DC_NDESCS(_dcsize)      (8 << _dcsize)
+
+typedef enum efx_rxq_type_e {
+       EFX_RXQ_TYPE_DEFAULT,
+       EFX_RXQ_TYPE_SCATTER,
+       EFX_RXQ_TYPE_PACKED_STREAM_1M,
+       EFX_RXQ_TYPE_PACKED_STREAM_512K,
+       EFX_RXQ_TYPE_PACKED_STREAM_256K,
+       EFX_RXQ_TYPE_PACKED_STREAM_128K,
+       EFX_RXQ_TYPE_PACKED_STREAM_64K,
+       EFX_RXQ_NTYPES
+} efx_rxq_type_t;
+
+extern __checkReturn   efx_rc_t
+efx_rx_qcreate(
+       __in            efx_nic_t *enp,
+       __in            unsigned int index,
+       __in            unsigned int label,
+       __in            efx_rxq_type_t type,
+       __in            efsys_mem_t *esmp,
+       __in            size_t n,
+       __in            uint32_t id,
+       __in            efx_evq_t *eep,
+       __deref_out     efx_rxq_t **erpp);
+
+typedef struct efx_buffer_s {
+       efsys_dma_addr_t        eb_addr;
+       size_t                  eb_size;
+       boolean_t               eb_eop;
+} efx_buffer_t;
+
+typedef struct efx_desc_s {
+       efx_qword_t ed_eq;
+} efx_desc_t;
+
+extern                 void
+efx_rx_qpost(
+       __in            efx_rxq_t *erp,
+       __in_ecount(n)  efsys_dma_addr_t *addrp,
+       __in            size_t size,
+       __in            unsigned int n,
+       __in            unsigned int completed,
+       __in            unsigned int added);
+
+extern         void
+efx_rx_qpush(
+       __in    efx_rxq_t *erp,
+       __in    unsigned int added,
+       __inout unsigned int *pushedp);
+
+extern __checkReturn   efx_rc_t
+efx_rx_qflush(
+       __in    efx_rxq_t *erp);
+
+extern         void
+efx_rx_qenable(
+       __in    efx_rxq_t *erp);
+
+extern         void
+efx_rx_qdestroy(
+       __in    efx_rxq_t *erp);
+
+/* TX */
+
+typedef struct efx_txq_s       efx_txq_t;
+
+extern __checkReturn   efx_rc_t
+efx_tx_init(
+       __in            efx_nic_t *enp);
+
+extern         void
+efx_tx_fini(
+       __in    efx_nic_t *enp);
+
+#define        EFX_TXQ_MINNDESCS               512
+
+#define        EFX_TXQ_SIZE(_ndescs)           ((_ndescs) * sizeof (efx_qword_t))
+#define        EFX_TXQ_NBUFS(_ndescs)          (EFX_TXQ_SIZE(_ndescs) / EFX_BUF_SIZE)
+#define        EFX_TXQ_LIMIT(_ndescs)          ((_ndescs) - 16)
+#define        EFX_TXQ_DC_NDESCS(_dcsize)      (8 << _dcsize)
+
+#define        EFX_TXQ_MAX_BUFS 8 /* Maximum independent of EFX_BUG35388_WORKAROUND. */
+
+#define        EFX_TXQ_CKSUM_IPV4      0x0001
+#define        EFX_TXQ_CKSUM_TCPUDP    0x0002
+#define        EFX_TXQ_FATSOV2         0x0004
+
+extern __checkReturn   efx_rc_t
+efx_tx_qcreate(
+       __in            efx_nic_t *enp,
+       __in            unsigned int index,
+       __in            unsigned int label,
+       __in            efsys_mem_t *esmp,
+       __in            size_t n,
+       __in            uint32_t id,
+       __in            uint16_t flags,
+       __in            efx_evq_t *eep,
+       __deref_out     efx_txq_t **etpp,
+       __out           unsigned int *addedp);
+
+extern __checkReturn   efx_rc_t
+efx_tx_qpost(
+       __in            efx_txq_t *etp,
+       __in_ecount(n)  efx_buffer_t *eb,
+       __in            unsigned int n,
+       __in            unsigned int completed,
+       __inout         unsigned int *addedp);
+
+extern __checkReturn   efx_rc_t
+efx_tx_qpace(
+       __in            efx_txq_t *etp,
+       __in            unsigned int ns);
+
+extern                 void
+efx_tx_qpush(
+       __in            efx_txq_t *etp,
+       __in            unsigned int added,
+       __in            unsigned int pushed);
+
+extern __checkReturn   efx_rc_t
+efx_tx_qflush(
+       __in            efx_txq_t *etp);
+
+extern                 void
+efx_tx_qenable(
+       __in            efx_txq_t *etp);
+
+extern __checkReturn   efx_rc_t
+efx_tx_qpio_enable(
+       __in            efx_txq_t *etp);
+
+extern                 void
+efx_tx_qpio_disable(
+       __in            efx_txq_t *etp);
+
+extern __checkReturn   efx_rc_t
+efx_tx_qpio_write(
+       __in                    efx_txq_t *etp,
+       __in_ecount(buf_length) uint8_t *buffer,
+       __in                    size_t buf_length,
+       __in                    size_t pio_buf_offset);
+
+extern __checkReturn   efx_rc_t
+efx_tx_qpio_post(
+       __in                    efx_txq_t *etp,
+       __in                    size_t pkt_length,
+       __in                    unsigned int completed,
+       __inout                 unsigned int *addedp);
+
+extern __checkReturn   efx_rc_t
+efx_tx_qdesc_post(
+       __in            efx_txq_t *etp,
+       __in_ecount(n)  efx_desc_t *ed,
+       __in            unsigned int n,
+       __in            unsigned int completed,
+       __inout         unsigned int *addedp);
+
+extern void
+efx_tx_qdesc_dma_create(
+       __in    efx_txq_t *etp,
+       __in    efsys_dma_addr_t addr,
+       __in    size_t size,
+       __in    boolean_t eop,
+       __out   efx_desc_t *edp);
+
+extern void
+efx_tx_qdesc_tso_create(
+       __in    efx_txq_t *etp,
+       __in    uint16_t ipv4_id,
+       __in    uint32_t tcp_seq,
+       __in    uint8_t  tcp_flags,
+       __out   efx_desc_t *edp);
+
+/* Number of FATSOv2 option descriptors */
+#define        EFX_TX_FATSOV2_OPT_NDESCS               2
+
+/* Maximum number of DMA segments per TSO packet (not superframe) */
+#define        EFX_TX_FATSOV2_DMA_SEGS_PER_PKT_MAX     24
+
+extern void
+efx_tx_qdesc_tso2_create(
+       __in                    efx_txq_t *etp,
+       __in                    uint16_t ipv4_id,
+       __in                    uint32_t tcp_seq,
+       __in                    uint16_t tcp_mss,
+       __out_ecount(count)     efx_desc_t *edp,
+       __in                    int count);
+
+extern void
+efx_tx_qdesc_vlantci_create(
+       __in    efx_txq_t *etp,
+       __in    uint16_t tci,
+       __out   efx_desc_t *edp);
+
+extern         void
+efx_tx_qdestroy(
+       __in    efx_txq_t *etp);
+
+
+/* FILTER */
+
+/* HASH */
+
+extern __checkReturn           uint32_t
+efx_hash_dwords(
+       __in_ecount(count)      uint32_t const *input,
+       __in                    size_t count,
+       __in                    uint32_t init);
+
+extern __checkReturn           uint32_t
+efx_hash_bytes(
+       __in_ecount(length)     uint8_t const *input,
+       __in                    size_t length,
+       __in                    uint32_t init);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_EFX_H */
diff --git a/drivers/net/sfc/base/efx_check.h b/drivers/net/sfc/base/efx_check.h
new file mode 100644 (file)
index 0000000..78cfd8e
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2012-2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#ifndef _SYS_EFX_CHECK_H
+#define        _SYS_EFX_CHECK_H
+
+#include "efsys.h"
+
+/*
+ * Check that the efsys.h header in client code has a valid combination of
+ * EFSYS_OPT_xxx options.
+ *
+ * NOTE: Keep checks for obsolete options here to ensure that they are removed
+ * from client code (and do not reappear in merges from other branches).
+ */
+
+#ifdef EFSYS_OPT_FALCON
+# error "FALCON is obsolete and is not supported."
+#endif
+
+#if EFSYS_OPT_CHECK_REG
+/* Verify chip implements accessed registers */
+#  error "CHECK_REG requires SIENA or HUNTINGTON or MEDFORD"
+#endif /* EFSYS_OPT_CHECK_REG */
+
+#if EFSYS_OPT_DECODE_INTR_FATAL
+/* Decode fatal errors */
+#  error "INTR_FATAL requires SIENA"
+#endif /* EFSYS_OPT_DECODE_INTR_FATAL */
+
+#ifdef EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE
+# error "FALCON_NIC_CFG_OVERRIDE is obsolete and is not supported."
+#endif
+
+#ifdef EFSYS_OPT_MAC_FALCON_GMAC
+# error "MAC_FALCON_GMAC is obsolete and is not supported."
+#endif
+
+#ifdef EFSYS_OPT_MAC_FALCON_XMAC
+# error "MAC_FALCON_XMAC is obsolete and is not supported."
+#endif
+
+#ifdef EFSYS_OPT_MON_LM87
+# error "MON_LM87 is obsolete and is not supported."
+#endif
+
+#ifdef EFSYS_OPT_MON_MAX6647
+# error "MON_MAX6647 is obsolete and is not supported."
+#endif
+
+#ifdef EFSYS_OPT_MON_NULL
+# error "MON_NULL is obsolete and is not supported."
+#endif
+
+#ifdef EFSYS_OPT_MON_SIENA
+#  error "MON_SIENA is obsolete (replaced by MON_MCDI)."
+#endif
+
+#ifdef EFSYS_OPT_MON_HUNTINGTON
+#  error "MON_HUNTINGTON is obsolete (replaced by MON_MCDI)."
+#endif
+
+#if EFSYS_OPT_NAMES
+/* Support printable names for statistics */
+# if !(EFSYS_OPT_LOOPBACK || EFSYS_OPT_MAC_STATS || EFSYS_OPT_MCDI || \
+       EFSYS_MON_STATS || EFSYS_OPT_PHY_STATS || EFSYS_OPT_QSTATS)
+#  error "NAMES requires LOOPBACK or xxxSTATS or MCDI"
+# endif
+#endif /* EFSYS_OPT_NAMES */
+
+#ifdef EFSYS_OPT_NVRAM_FALCON_BOOTROM
+# error "NVRAM_FALCON_BOOTROM is obsolete and is not supported."
+#endif
+
+#ifdef EFSYS_OPT_NVRAM_SFT9001
+# error "NVRAM_SFT9001 is obsolete and is not supported."
+#endif
+
+#ifdef EFSYS_OPT_NVRAM_SFX7101
+# error "NVRAM_SFX7101 is obsolete and is not supported."
+#endif
+
+#ifdef EFSYS_OPT_PCIE_TUNE
+# error "PCIE_TUNE is obsolete and is not supported."
+#endif
+
+#ifdef EFSYS_OPT_PHY_BIST
+# error "PHY_BIST is obsolete (replaced by BIST)."
+#endif
+
+#ifdef EFSYS_OPT_PHY_NULL
+# error "PHY_NULL is obsolete and is not supported."
+#endif
+
+#ifdef EFSYS_OPT_PHY_PM8358
+# error "PHY_PM8358 is obsolete and is not supported."
+#endif
+
+#ifdef EFSYS_OPT_PHY_PROPS
+# error "PHY_PROPS is obsolete and is not supported."
+#endif
+
+#ifdef EFSYS_OPT_PHY_QT2022C2
+# error "PHY_QT2022C2 is obsolete and is not supported."
+#endif
+
+#ifdef EFSYS_OPT_PHY_QT2025C
+# error "PHY_QT2025C is obsolete and is not supported."
+#endif
+
+#ifdef EFSYS_OPT_PHY_SFT9001
+# error "PHY_SFT9001 is obsolete and is not supported."
+#endif
+
+#ifdef EFSYS_OPT_PHY_SFX7101
+# error "PHY_SFX7101 is obsolete and is not supported."
+#endif
+
+#ifdef EFSYS_OPT_PHY_TXC43128
+# error "PHY_TXC43128 is obsolete and is not supported."
+#endif
+
+#ifdef EFSYS_OPT_RX_HDR_SPLIT
+# error "RX_HDR_SPLIT is obsolete and is not supported"
+#endif
+
+#ifdef EFSYS_OPT_STAT_NAME
+# error "STAT_NAME is obsolete (replaced by NAMES)."
+#endif
+
+#ifdef EFSYS_OPT_WOL
+# error "WOL is obsolete and is not supported"
+#endif /* EFSYS_OPT_WOL */
+
+#ifdef EFSYS_OPT_MCAST_FILTER_LIST
+#  error "MCAST_FILTER_LIST is obsolete and is not supported"
+#endif
+
+#if EFSYS_OPT_ALLOW_UNCONFIGURED_NIC
+/* Support adapters with missing static config (for factory use only) */
+#  error "ALLOW_UNCONFIGURED_NIC requires MEDFORD"
+#endif /* EFSYS_OPT_ALLOW_UNCONFIGURED_NIC */
+
+#endif /* _SYS_EFX_CHECK_H */
diff --git a/drivers/net/sfc/base/efx_crc32.c b/drivers/net/sfc/base/efx_crc32.c
new file mode 100644 (file)
index 0000000..27e2708
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2013-2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include "efx.h"
+#include "efx_impl.h"
+
+/*
+ * Precomputed table for computing IEEE 802.3 CRC32
+ * with polynomial 0x04c11db7 (bit-reversed 0xedb88320)
+ */
+
+static const uint32_t efx_crc32_table[256] = {
+    0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+    0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+    0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+    0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+    0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+    0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+    0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+    0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+    0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+    0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+    0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+    0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+    0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+    0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+    0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+    0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+    0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+    0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+    0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+    0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+    0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+    0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+    0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+    0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+    0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+    0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+    0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+    0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+    0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+    0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+    0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+    0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+    0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+    0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+    0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+    0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+    0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+    0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+    0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+    0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+    0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+    0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+    0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+    0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+    0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+    0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+    0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+    0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+    0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+    0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+    0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+    0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+    0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+    0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+    0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+    0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+    0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+    0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+    0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+    0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+    0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+    0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+    0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+    0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+/* Calculate the IEEE 802.3 CRC32 of a MAC addr */
+       __checkReturn           uint32_t
+efx_crc32_calculate(
+       __in                    uint32_t crc_init,
+       __in_ecount(length)     uint8_t const *input,
+       __in                    int length)
+{
+       int index;
+       uint32_t crc = crc_init;
+
+       for (index = 0; index < length; index++) {
+               uint32_t data = *(input++);
+               crc = (crc >> 8) ^ efx_crc32_table[(crc ^ data) & 0xff];
+       }
+
+       return (crc);
+}
diff --git a/drivers/net/sfc/base/efx_ev.c b/drivers/net/sfc/base/efx_ev.c
new file mode 100644 (file)
index 0000000..2bd365f
--- /dev/null
@@ -0,0 +1,432 @@
+/*
+ * Copyright (c) 2007-2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include "efx.h"
+#include "efx_impl.h"
+
+#define        EFX_EV_QSTAT_INCR(_eep, _stat)
+
+#define        EFX_EV_PRESENT(_qword)                                          \
+       (EFX_QWORD_FIELD((_qword), EFX_DWORD_0) != 0xffffffff &&        \
+       EFX_QWORD_FIELD((_qword), EFX_DWORD_1) != 0xffffffff)
+
+
+
+       __checkReturn   efx_rc_t
+efx_ev_init(
+       __in            efx_nic_t *enp)
+{
+       const efx_ev_ops_t *eevop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
+
+       if (enp->en_mod_flags & EFX_MOD_EV) {
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       switch (enp->en_family) {
+
+       default:
+               EFSYS_ASSERT(0);
+               rc = ENOTSUP;
+               goto fail1;
+       }
+
+       EFSYS_ASSERT3U(enp->en_ev_qcount, ==, 0);
+
+       if ((rc = eevop->eevo_init(enp)) != 0)
+               goto fail2;
+
+       enp->en_eevop = eevop;
+       enp->en_mod_flags |= EFX_MOD_EV;
+       return (0);
+
+fail2:
+       EFSYS_PROBE(fail2);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       enp->en_eevop = NULL;
+       enp->en_mod_flags &= ~EFX_MOD_EV;
+       return (rc);
+}
+
+               void
+efx_ev_fini(
+       __in    efx_nic_t *enp)
+{
+       const efx_ev_ops_t *eevop = enp->en_eevop;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_EV);
+       EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
+       EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
+       EFSYS_ASSERT3U(enp->en_ev_qcount, ==, 0);
+
+       eevop->eevo_fini(enp);
+
+       enp->en_eevop = NULL;
+       enp->en_mod_flags &= ~EFX_MOD_EV;
+}
+
+
+       __checkReturn   efx_rc_t
+efx_ev_qcreate(
+       __in            efx_nic_t *enp,
+       __in            unsigned int index,
+       __in            efsys_mem_t *esmp,
+       __in            size_t n,
+       __in            uint32_t id,
+       __in            uint32_t us,
+       __in            uint32_t flags,
+       __deref_out     efx_evq_t **eepp)
+{
+       const efx_ev_ops_t *eevop = enp->en_eevop;
+       efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+       efx_evq_t *eep;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_EV);
+
+       EFSYS_ASSERT3U(enp->en_ev_qcount + 1, <, encp->enc_evq_limit);
+
+       switch (flags & EFX_EVQ_FLAGS_NOTIFY_MASK) {
+       case EFX_EVQ_FLAGS_NOTIFY_INTERRUPT:
+               break;
+       case EFX_EVQ_FLAGS_NOTIFY_DISABLED:
+               if (us != 0) {
+                       rc = EINVAL;
+                       goto fail1;
+               }
+               break;
+       default:
+               rc = EINVAL;
+               goto fail2;
+       }
+
+       /* Allocate an EVQ object */
+       EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_evq_t), eep);
+       if (eep == NULL) {
+               rc = ENOMEM;
+               goto fail3;
+       }
+
+       eep->ee_magic = EFX_EVQ_MAGIC;
+       eep->ee_enp = enp;
+       eep->ee_index = index;
+       eep->ee_mask = n - 1;
+       eep->ee_flags = flags;
+       eep->ee_esmp = esmp;
+
+       /*
+        * Set outputs before the queue is created because interrupts may be
+        * raised for events immediately after the queue is created, before the
+        * function call below returns. See bug58606.
+        *
+        * The eepp pointer passed in by the client must therefore point to data
+        * shared with the client's event processing context.
+        */
+       enp->en_ev_qcount++;
+       *eepp = eep;
+
+       if ((rc = eevop->eevo_qcreate(enp, index, esmp, n, id, us, flags,
+           eep)) != 0)
+               goto fail4;
+
+       return (0);
+
+fail4:
+       EFSYS_PROBE(fail4);
+
+       *eepp = NULL;
+       enp->en_ev_qcount--;
+       EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_evq_t), eep);
+fail3:
+       EFSYS_PROBE(fail3);
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       return (rc);
+}
+
+               void
+efx_ev_qdestroy(
+       __in    efx_evq_t *eep)
+{
+       efx_nic_t *enp = eep->ee_enp;
+       const efx_ev_ops_t *eevop = enp->en_eevop;
+
+       EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
+
+       EFSYS_ASSERT(enp->en_ev_qcount != 0);
+       --enp->en_ev_qcount;
+
+       eevop->eevo_qdestroy(eep);
+
+       /* Free the EVQ object */
+       EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_evq_t), eep);
+}
+
+       __checkReturn   efx_rc_t
+efx_ev_qprime(
+       __in            efx_evq_t *eep,
+       __in            unsigned int count)
+{
+       efx_nic_t *enp = eep->ee_enp;
+       const efx_ev_ops_t *eevop = enp->en_eevop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
+
+       if (!(enp->en_mod_flags & EFX_MOD_INTR)) {
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       if ((rc = eevop->eevo_qprime(eep, count)) != 0)
+               goto fail2;
+
+       return (0);
+
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       return (rc);
+}
+
+       __checkReturn   boolean_t
+efx_ev_qpending(
+       __in            efx_evq_t *eep,
+       __in            unsigned int count)
+{
+       size_t offset;
+       efx_qword_t qword;
+
+       EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
+
+       offset = (count & eep->ee_mask) * sizeof (efx_qword_t);
+       EFSYS_MEM_READQ(eep->ee_esmp, offset, &qword);
+
+       return (EFX_EV_PRESENT(qword));
+}
+
+#define        EFX_EV_BATCH    8
+
+                       void
+efx_ev_qpoll(
+       __in            efx_evq_t *eep,
+       __inout         unsigned int *countp,
+       __in            const efx_ev_callbacks_t *eecp,
+       __in_opt        void *arg)
+{
+       efx_qword_t ev[EFX_EV_BATCH];
+       unsigned int batch;
+       unsigned int total;
+       unsigned int count;
+       unsigned int index;
+       size_t offset;
+
+       /* Ensure events codes match for EF10 (Huntington/Medford) and Siena */
+       EFX_STATIC_ASSERT(ESF_DZ_EV_CODE_LBN == FSF_AZ_EV_CODE_LBN);
+       EFX_STATIC_ASSERT(ESF_DZ_EV_CODE_WIDTH == FSF_AZ_EV_CODE_WIDTH);
+
+       EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_RX_EV == FSE_AZ_EV_CODE_RX_EV);
+       EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_TX_EV == FSE_AZ_EV_CODE_TX_EV);
+       EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_DRIVER_EV == FSE_AZ_EV_CODE_DRIVER_EV);
+       EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_DRV_GEN_EV ==
+           FSE_AZ_EV_CODE_DRV_GEN_EV);
+
+       EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
+       EFSYS_ASSERT(countp != NULL);
+       EFSYS_ASSERT(eecp != NULL);
+
+       count = *countp;
+       do {
+               /* Read up until the end of the batch period */
+               batch = EFX_EV_BATCH - (count & (EFX_EV_BATCH - 1));
+               offset = (count & eep->ee_mask) * sizeof (efx_qword_t);
+               for (total = 0; total < batch; ++total) {
+                       EFSYS_MEM_READQ(eep->ee_esmp, offset, &(ev[total]));
+
+                       if (!EFX_EV_PRESENT(ev[total]))
+                               break;
+
+                       EFSYS_PROBE3(event, unsigned int, eep->ee_index,
+                           uint32_t, EFX_QWORD_FIELD(ev[total], EFX_DWORD_1),
+                           uint32_t, EFX_QWORD_FIELD(ev[total], EFX_DWORD_0));
+
+                       offset += sizeof (efx_qword_t);
+               }
+
+               /* Process the batch of events */
+               for (index = 0; index < total; ++index) {
+                       boolean_t should_abort;
+                       uint32_t code;
+
+                       EFX_EV_QSTAT_INCR(eep, EV_ALL);
+
+                       code = EFX_QWORD_FIELD(ev[index], FSF_AZ_EV_CODE);
+                       switch (code) {
+                       case FSE_AZ_EV_CODE_RX_EV:
+                               should_abort = eep->ee_rx(eep,
+                                   &(ev[index]), eecp, arg);
+                               break;
+                       case FSE_AZ_EV_CODE_TX_EV:
+                               should_abort = eep->ee_tx(eep,
+                                   &(ev[index]), eecp, arg);
+                               break;
+                       case FSE_AZ_EV_CODE_DRIVER_EV:
+                               should_abort = eep->ee_driver(eep,
+                                   &(ev[index]), eecp, arg);
+                               break;
+                       case FSE_AZ_EV_CODE_DRV_GEN_EV:
+                               should_abort = eep->ee_drv_gen(eep,
+                                   &(ev[index]), eecp, arg);
+                               break;
+                       case FSE_AZ_EV_CODE_GLOBAL_EV:
+                               if (eep->ee_global) {
+                                       should_abort = eep->ee_global(eep,
+                                           &(ev[index]), eecp, arg);
+                                       break;
+                               }
+                               /* else fallthrough */
+                       default:
+                               EFSYS_PROBE3(bad_event,
+                                   unsigned int, eep->ee_index,
+                                   uint32_t,
+                                   EFX_QWORD_FIELD(ev[index], EFX_DWORD_1),
+                                   uint32_t,
+                                   EFX_QWORD_FIELD(ev[index], EFX_DWORD_0));
+
+                               EFSYS_ASSERT(eecp->eec_exception != NULL);
+                               (void) eecp->eec_exception(arg,
+                                       EFX_EXCEPTION_EV_ERROR, code);
+                               should_abort = B_TRUE;
+                       }
+                       if (should_abort) {
+                               /* Ignore subsequent events */
+                               total = index + 1;
+                               break;
+                       }
+               }
+
+               /*
+                * Now that the hardware has most likely moved onto dma'ing
+                * into the next cache line, clear the processed events. Take
+                * care to only clear out events that we've processed
+                */
+               EFX_SET_QWORD(ev[0]);
+               offset = (count & eep->ee_mask) * sizeof (efx_qword_t);
+               for (index = 0; index < total; ++index) {
+                       EFSYS_MEM_WRITEQ(eep->ee_esmp, offset, &(ev[0]));
+                       offset += sizeof (efx_qword_t);
+               }
+
+               count += total;
+
+       } while (total == batch);
+
+       *countp = count;
+}
+
+                       void
+efx_ev_qpost(
+       __in    efx_evq_t *eep,
+       __in    uint16_t data)
+{
+       efx_nic_t *enp = eep->ee_enp;
+       const efx_ev_ops_t *eevop = enp->en_eevop;
+
+       EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
+
+       EFSYS_ASSERT(eevop != NULL &&
+           eevop->eevo_qpost != NULL);
+
+       eevop->eevo_qpost(eep, data);
+}
+
+       __checkReturn   efx_rc_t
+efx_ev_usecs_to_ticks(
+       __in            efx_nic_t *enp,
+       __in            unsigned int us,
+       __out           unsigned int *ticksp)
+{
+       efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+       unsigned int ticks;
+
+       /* Convert microseconds to a timer tick count */
+       if (us == 0)
+               ticks = 0;
+       else if (us * 1000 < encp->enc_evq_timer_quantum_ns)
+               ticks = 1;      /* Never round down to zero */
+       else
+               ticks = us * 1000 / encp->enc_evq_timer_quantum_ns;
+
+       *ticksp = ticks;
+       return (0);
+}
+
+       __checkReturn   efx_rc_t
+efx_ev_qmoderate(
+       __in            efx_evq_t *eep,
+       __in            unsigned int us)
+{
+       efx_nic_t *enp = eep->ee_enp;
+       const efx_ev_ops_t *eevop = enp->en_eevop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
+
+       if ((eep->ee_flags & EFX_EVQ_FLAGS_NOTIFY_MASK) ==
+           EFX_EVQ_FLAGS_NOTIFY_DISABLED) {
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       if ((rc = eevop->eevo_qmoderate(eep, us)) != 0)
+               goto fail2;
+
+       return (0);
+
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       return (rc);
+}
+
diff --git a/drivers/net/sfc/base/efx_hash.c b/drivers/net/sfc/base/efx_hash.c
new file mode 100644 (file)
index 0000000..3cc0d20
--- /dev/null
@@ -0,0 +1,328 @@
+/*
+ * Copyright 2006 Bob Jenkins
+ *
+ * Derived from public domain source, see
+ *     <http://burtleburtle.net/bob/c/lookup3.c>:
+ *
+ * "lookup3.c, by Bob Jenkins, May 2006, Public Domain.
+ *
+ *  These are functions for producing 32-bit hashes for hash table lookup...
+ *  ...You can use this free for any purpose.  It's in the public domain.
+ *  It has no warranty."
+ *
+ * Copyright (c) 2014-2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include "efx.h"
+#include "efx_impl.h"
+
+/* Hash initial value */
+#define        EFX_HASH_INITIAL_VALUE  0xdeadbeef
+
+/*
+ * Rotate a 32-bit value left
+ *
+ * Allow platform to provide an intrinsic or optimised routine and
+ * fall-back to a simple shift based implementation.
+ */
+#if EFSYS_HAS_ROTL_DWORD
+
+#define        EFX_HASH_ROTATE(_value, _shift)                                 \
+       EFSYS_ROTL_DWORD(_value, _shift)
+
+#else
+
+#define        EFX_HASH_ROTATE(_value, _shift)                                 \
+       (((_value) << (_shift)) | ((_value) >> (32 - (_shift))))
+
+#endif
+
+/* Mix three 32-bit values reversibly */
+#define        EFX_HASH_MIX(_a, _b, _c)                                        \
+       do {                                                            \
+               _a -= _c;                                               \
+               _a ^= EFX_HASH_ROTATE(_c, 4);                           \
+               _c += _b;                                               \
+               _b -= _a;                                               \
+               _b ^= EFX_HASH_ROTATE(_a, 6);                           \
+               _a += _c;                                               \
+               _c -= _b;                                               \
+               _c ^= EFX_HASH_ROTATE(_b, 8);                           \
+               _b += _a;                                               \
+               _a -= _c;                                               \
+               _a ^= EFX_HASH_ROTATE(_c, 16);                          \
+               _c += _b;                                               \
+               _b -= _a;                                               \
+               _b ^= EFX_HASH_ROTATE(_a, 19);                          \
+               _a += _c;                                               \
+               _c -= _b;                                               \
+               _c ^= EFX_HASH_ROTATE(_b, 4);                           \
+               _b += _a;                                               \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+/* Final mixing of three 32-bit values into one (_c) */
+#define        EFX_HASH_FINALISE(_a, _b, _c)                                   \
+       do {                                                            \
+               _c ^= _b;                                               \
+               _c -= EFX_HASH_ROTATE(_b, 14);                          \
+               _a ^= _c;                                               \
+               _a -= EFX_HASH_ROTATE(_c, 11);                          \
+               _b ^= _a;                                               \
+               _b -= EFX_HASH_ROTATE(_a, 25);                          \
+               _c ^= _b;                                               \
+               _c -= EFX_HASH_ROTATE(_b, 16);                          \
+               _a ^= _c;                                               \
+               _a -= EFX_HASH_ROTATE(_c, 4);                           \
+               _b ^= _a;                                               \
+               _b -= EFX_HASH_ROTATE(_a, 14);                          \
+               _c ^= _b;                                               \
+               _c -= EFX_HASH_ROTATE(_b, 24);                          \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+
+/* Produce a 32-bit hash from 32-bit aligned input */
+       __checkReturn           uint32_t
+efx_hash_dwords(
+       __in_ecount(count)      uint32_t const *input,
+       __in                    size_t count,
+       __in                    uint32_t init)
+{
+       uint32_t a;
+       uint32_t b;
+       uint32_t c;
+
+       /* Set up the initial internal state */
+       a = b = c = EFX_HASH_INITIAL_VALUE +
+               (((uint32_t)count) * sizeof (uint32_t)) + init;
+
+       /* Handle all but the last three dwords of the input */
+       while (count > 3) {
+               a += input[0];
+               b += input[1];
+               c += input[2];
+               EFX_HASH_MIX(a, b, c);
+
+               count -= 3;
+               input += 3;
+       }
+
+       /* Handle the left-overs */
+       switch (count) {
+       case 3:
+               c += input[2];
+               /* Fall-through */
+       case 2:
+               b += input[1];
+               /* Fall-through */
+       case 1:
+               a += input[0];
+               EFX_HASH_FINALISE(a, b, c);
+               break;
+
+       case 0:
+               /* Should only get here if count parameter was zero */
+               break;
+       }
+
+       return (c);
+}
+
+#if EFSYS_IS_BIG_ENDIAN
+
+/* Produce a 32-bit hash from arbitrarily aligned input */
+       __checkReturn           uint32_t
+efx_hash_bytes(
+       __in_ecount(length)     uint8_t const *input,
+       __in                    size_t length,
+       __in                    uint32_t init)
+{
+       uint32_t a;
+       uint32_t b;
+       uint32_t c;
+
+       /* Set up the initial internal state */
+       a = b = c = EFX_HASH_INITIAL_VALUE + (uint32_t)length + init;
+
+       /* Handle all but the last twelve bytes of the input */
+       while (length > 12) {
+               a += ((uint32_t)input[0]) << 24;
+               a += ((uint32_t)input[1]) << 16;
+               a += ((uint32_t)input[2]) << 8;
+               a += ((uint32_t)input[3]);
+               b += ((uint32_t)input[4]) << 24;
+               b += ((uint32_t)input[5]) << 16;
+               b += ((uint32_t)input[6]) << 8;
+               b += ((uint32_t)input[7]);
+               c += ((uint32_t)input[8]) << 24;
+               c += ((uint32_t)input[9]) << 16;
+               c += ((uint32_t)input[10]) << 8;
+               c += ((uint32_t)input[11]);
+               EFX_HASH_MIX(a, b, c);
+               length -= 12;
+               input += 12;
+       }
+
+       /* Handle the left-overs */
+       switch (length) {
+       case 12:
+               c += ((uint32_t)input[11]);
+               /* Fall-through */
+       case 11:
+               c += ((uint32_t)input[10]) << 8;
+               /* Fall-through */
+       case 10:
+               c += ((uint32_t)input[9]) << 16;
+               /* Fall-through */
+       case 9:
+               c += ((uint32_t)input[8]) << 24;
+               /* Fall-through */
+       case 8:
+               b += ((uint32_t)input[7]);
+               /* Fall-through */
+       case 7:
+               b += ((uint32_t)input[6]) << 8;
+               /* Fall-through */
+       case 6:
+               b += ((uint32_t)input[5]) << 16;
+               /* Fall-through */
+       case 5:
+               b += ((uint32_t)input[4]) << 24;
+               /* Fall-through */
+       case 4:
+               a += ((uint32_t)input[3]);
+               /* Fall-through */
+       case 3:
+               a += ((uint32_t)input[2]) << 8;
+               /* Fall-through */
+       case 2:
+               a += ((uint32_t)input[1]) << 16;
+               /* Fall-through */
+       case 1:
+               a += ((uint32_t)input[0]) << 24;
+               EFX_HASH_FINALISE(a, b, c);
+               break;
+
+       case 0:
+               /* Should only get here if length parameter was zero */
+               break;
+       }
+
+       return (c);
+}
+
+#elif EFSYS_IS_LITTLE_ENDIAN
+
+/* Produce a 32-bit hash from arbitrarily aligned input */
+       __checkReturn           uint32_t
+efx_hash_bytes(
+       __in_ecount(length)     uint8_t const *input,
+       __in                    size_t length,
+       __in                    uint32_t init)
+{
+       uint32_t a;
+       uint32_t b;
+       uint32_t c;
+
+       /* Set up the initial internal state */
+       a = b = c = EFX_HASH_INITIAL_VALUE + (uint32_t)length + init;
+
+       /* Handle all but the last twelve bytes of the input */
+       while (length > 12) {
+               a += ((uint32_t)input[0]);
+               a += ((uint32_t)input[1]) << 8;
+               a += ((uint32_t)input[2]) << 16;
+               a += ((uint32_t)input[3]) << 24;
+               b += ((uint32_t)input[4]);
+               b += ((uint32_t)input[5]) << 8;
+               b += ((uint32_t)input[6]) << 16;
+               b += ((uint32_t)input[7]) << 24;
+               c += ((uint32_t)input[8]);
+               c += ((uint32_t)input[9]) << 8;
+               c += ((uint32_t)input[10]) << 16;
+               c += ((uint32_t)input[11]) << 24;
+               EFX_HASH_MIX(a, b, c);
+               length -= 12;
+               input += 12;
+       }
+
+       /* Handle the left-overs */
+       switch (length) {
+       case 12:
+               c += ((uint32_t)input[11]) << 24;
+               /* Fall-through */
+       case 11:
+               c += ((uint32_t)input[10]) << 16;
+               /* Fall-through */
+       case 10:
+               c += ((uint32_t)input[9]) << 8;
+               /* Fall-through */
+       case 9:
+               c += ((uint32_t)input[8]);
+               /* Fall-through */
+       case 8:
+               b += ((uint32_t)input[7]) << 24;
+               /* Fall-through */
+       case 7:
+               b += ((uint32_t)input[6]) << 16;
+               /* Fall-through */
+       case 6:
+               b += ((uint32_t)input[5]) << 8;
+               /* Fall-through */
+       case 5:
+               b += ((uint32_t)input[4]);
+               /* Fall-through */
+       case 4:
+               a += ((uint32_t)input[3]) << 24;
+               /* Fall-through */
+       case 3:
+               a += ((uint32_t)input[2]) << 16;
+               /* Fall-through */
+       case 2:
+               a += ((uint32_t)input[1]) << 8;
+               /* Fall-through */
+       case 1:
+               a += ((uint32_t)input[0]);
+               EFX_HASH_FINALISE(a, b, c);
+               break;
+
+       case 0:
+               /* Should only get here if length parameter was zero */
+               break;
+       }
+
+       return (c);
+}
+
+#else
+
+#error "Neither of EFSYS_IS_{BIG,LITTLE}_ENDIAN is set"
+
+#endif
diff --git a/drivers/net/sfc/base/efx_impl.h b/drivers/net/sfc/base/efx_impl.h
new file mode 100644 (file)
index 0000000..15bca37
--- /dev/null
@@ -0,0 +1,658 @@
+/*
+ * Copyright (c) 2007-2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#ifndef        _SYS_EFX_IMPL_H
+#define        _SYS_EFX_IMPL_H
+
+#include "efx.h"
+#include "efx_regs.h"
+#include "efx_regs_ef10.h"
+
+/* FIXME: Add definition for driver generated software events */
+#ifndef        ESE_DZ_EV_CODE_DRV_GEN_EV
+#define        ESE_DZ_EV_CODE_DRV_GEN_EV FSE_AZ_EV_CODE_DRV_GEN_EV
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define        EFX_MOD_MCDI            0x00000001
+#define        EFX_MOD_PROBE           0x00000002
+#define        EFX_MOD_NVRAM           0x00000004
+#define        EFX_MOD_VPD             0x00000008
+#define        EFX_MOD_NIC             0x00000010
+#define        EFX_MOD_INTR            0x00000020
+#define        EFX_MOD_EV              0x00000040
+#define        EFX_MOD_RX              0x00000080
+#define        EFX_MOD_TX              0x00000100
+#define        EFX_MOD_PORT            0x00000200
+#define        EFX_MOD_MON             0x00000400
+#define        EFX_MOD_FILTER          0x00001000
+#define        EFX_MOD_LIC             0x00002000
+
+#define        EFX_RESET_PHY           0x00000001
+#define        EFX_RESET_RXQ_ERR       0x00000002
+#define        EFX_RESET_TXQ_ERR       0x00000004
+
+typedef enum efx_mac_type_e {
+       EFX_MAC_INVALID = 0,
+       EFX_MAC_SIENA,
+       EFX_MAC_HUNTINGTON,
+       EFX_MAC_MEDFORD,
+       EFX_MAC_NTYPES
+} efx_mac_type_t;
+
+typedef struct efx_ev_ops_s {
+       efx_rc_t        (*eevo_init)(efx_nic_t *);
+       void            (*eevo_fini)(efx_nic_t *);
+       efx_rc_t        (*eevo_qcreate)(efx_nic_t *, unsigned int,
+                                         efsys_mem_t *, size_t, uint32_t,
+                                         uint32_t, uint32_t, efx_evq_t *);
+       void            (*eevo_qdestroy)(efx_evq_t *);
+       efx_rc_t        (*eevo_qprime)(efx_evq_t *, unsigned int);
+       void            (*eevo_qpost)(efx_evq_t *, uint16_t);
+       efx_rc_t        (*eevo_qmoderate)(efx_evq_t *, unsigned int);
+} efx_ev_ops_t;
+
+typedef struct efx_tx_ops_s {
+       efx_rc_t        (*etxo_init)(efx_nic_t *);
+       void            (*etxo_fini)(efx_nic_t *);
+       efx_rc_t        (*etxo_qcreate)(efx_nic_t *,
+                                       unsigned int, unsigned int,
+                                       efsys_mem_t *, size_t,
+                                       uint32_t, uint16_t,
+                                       efx_evq_t *, efx_txq_t *,
+                                       unsigned int *);
+       void            (*etxo_qdestroy)(efx_txq_t *);
+       efx_rc_t        (*etxo_qpost)(efx_txq_t *, efx_buffer_t *,
+                                     unsigned int, unsigned int,
+                                     unsigned int *);
+       void            (*etxo_qpush)(efx_txq_t *, unsigned int, unsigned int);
+       efx_rc_t        (*etxo_qpace)(efx_txq_t *, unsigned int);
+       efx_rc_t        (*etxo_qflush)(efx_txq_t *);
+       void            (*etxo_qenable)(efx_txq_t *);
+       efx_rc_t        (*etxo_qpio_enable)(efx_txq_t *);
+       void            (*etxo_qpio_disable)(efx_txq_t *);
+       efx_rc_t        (*etxo_qpio_write)(efx_txq_t *, uint8_t *, size_t,
+                                          size_t);
+       efx_rc_t        (*etxo_qpio_post)(efx_txq_t *, size_t, unsigned int,
+                                          unsigned int *);
+       efx_rc_t        (*etxo_qdesc_post)(efx_txq_t *, efx_desc_t *,
+                                     unsigned int, unsigned int,
+                                     unsigned int *);
+       void            (*etxo_qdesc_dma_create)(efx_txq_t *, efsys_dma_addr_t,
+                                               size_t, boolean_t,
+                                               efx_desc_t *);
+       void            (*etxo_qdesc_tso_create)(efx_txq_t *, uint16_t,
+                                               uint32_t, uint8_t,
+                                               efx_desc_t *);
+       void            (*etxo_qdesc_tso2_create)(efx_txq_t *, uint16_t,
+                                               uint32_t, uint16_t,
+                                               efx_desc_t *, int);
+       void            (*etxo_qdesc_vlantci_create)(efx_txq_t *, uint16_t,
+                                               efx_desc_t *);
+} efx_tx_ops_t;
+
+typedef struct efx_rx_ops_s {
+       efx_rc_t        (*erxo_init)(efx_nic_t *);
+       void            (*erxo_fini)(efx_nic_t *);
+       efx_rc_t        (*erxo_prefix_pktlen)(efx_nic_t *, uint8_t *,
+                                             uint16_t *);
+       void            (*erxo_qpost)(efx_rxq_t *, efsys_dma_addr_t *, size_t,
+                                     unsigned int, unsigned int,
+                                     unsigned int);
+       void            (*erxo_qpush)(efx_rxq_t *, unsigned int, unsigned int *);
+       efx_rc_t        (*erxo_qflush)(efx_rxq_t *);
+       void            (*erxo_qenable)(efx_rxq_t *);
+       efx_rc_t        (*erxo_qcreate)(efx_nic_t *enp, unsigned int,
+                                       unsigned int, efx_rxq_type_t,
+                                       efsys_mem_t *, size_t, uint32_t,
+                                       efx_evq_t *, efx_rxq_t *);
+       void            (*erxo_qdestroy)(efx_rxq_t *);
+} efx_rx_ops_t;
+
+typedef struct efx_mac_ops_s {
+       efx_rc_t        (*emo_poll)(efx_nic_t *, efx_link_mode_t *);
+       efx_rc_t        (*emo_up)(efx_nic_t *, boolean_t *);
+       efx_rc_t        (*emo_addr_set)(efx_nic_t *);
+       efx_rc_t        (*emo_pdu_set)(efx_nic_t *);
+       efx_rc_t        (*emo_pdu_get)(efx_nic_t *, size_t *);
+       efx_rc_t        (*emo_reconfigure)(efx_nic_t *);
+       efx_rc_t        (*emo_multicast_list_set)(efx_nic_t *);
+       efx_rc_t        (*emo_filter_default_rxq_set)(efx_nic_t *,
+                                                     efx_rxq_t *, boolean_t);
+       void            (*emo_filter_default_rxq_clear)(efx_nic_t *);
+} efx_mac_ops_t;
+
+typedef struct efx_phy_ops_s {
+       efx_rc_t        (*epo_power)(efx_nic_t *, boolean_t); /* optional */
+       efx_rc_t        (*epo_reset)(efx_nic_t *);
+       efx_rc_t        (*epo_reconfigure)(efx_nic_t *);
+       efx_rc_t        (*epo_verify)(efx_nic_t *);
+       efx_rc_t        (*epo_oui_get)(efx_nic_t *, uint32_t *);
+} efx_phy_ops_t;
+
+
+typedef struct efx_port_s {
+       efx_mac_type_t          ep_mac_type;
+       uint32_t                ep_phy_type;
+       uint8_t                 ep_port;
+       uint32_t                ep_mac_pdu;
+       uint8_t                 ep_mac_addr[6];
+       efx_link_mode_t         ep_link_mode;
+       boolean_t               ep_all_unicst;
+       boolean_t               ep_mulcst;
+       boolean_t               ep_all_mulcst;
+       boolean_t               ep_brdcst;
+       unsigned int            ep_fcntl;
+       boolean_t               ep_fcntl_autoneg;
+       efx_oword_t             ep_multicst_hash[2];
+       uint8_t                 ep_mulcst_addr_list[EFX_MAC_ADDR_LEN *
+                                                   EFX_MAC_MULTICAST_LIST_MAX];
+       uint32_t                ep_mulcst_addr_count;
+       efx_phy_media_type_t    ep_fixed_port_type;
+       efx_phy_media_type_t    ep_module_type;
+       uint32_t                ep_adv_cap_mask;
+       uint32_t                ep_lp_cap_mask;
+       uint32_t                ep_default_adv_cap_mask;
+       uint32_t                ep_phy_cap_mask;
+       boolean_t               ep_mac_drain;
+       boolean_t               ep_mac_stats_pending;
+       const efx_mac_ops_t     *ep_emop;
+       const efx_phy_ops_t     *ep_epop;
+} efx_port_t;
+
+typedef struct efx_mon_ops_s {
+} efx_mon_ops_t;
+
+typedef struct efx_mon_s {
+       efx_mon_type_t          em_type;
+       const efx_mon_ops_t     *em_emop;
+} efx_mon_t;
+
+typedef struct efx_intr_ops_s {
+       efx_rc_t        (*eio_init)(efx_nic_t *, efx_intr_type_t, efsys_mem_t *);
+       void            (*eio_enable)(efx_nic_t *);
+       void            (*eio_disable)(efx_nic_t *);
+       void            (*eio_disable_unlocked)(efx_nic_t *);
+       efx_rc_t        (*eio_trigger)(efx_nic_t *, unsigned int);
+       void            (*eio_status_line)(efx_nic_t *, boolean_t *, uint32_t *);
+       void            (*eio_status_message)(efx_nic_t *, unsigned int,
+                                boolean_t *);
+       void            (*eio_fatal)(efx_nic_t *);
+       void            (*eio_fini)(efx_nic_t *);
+} efx_intr_ops_t;
+
+typedef struct efx_intr_s {
+       const efx_intr_ops_t    *ei_eiop;
+       efsys_mem_t             *ei_esmp;
+       efx_intr_type_t         ei_type;
+       unsigned int            ei_level;
+} efx_intr_t;
+
+typedef struct efx_nic_ops_s {
+       efx_rc_t        (*eno_probe)(efx_nic_t *);
+       efx_rc_t        (*eno_board_cfg)(efx_nic_t *);
+       efx_rc_t        (*eno_set_drv_limits)(efx_nic_t *, efx_drv_limits_t*);
+       efx_rc_t        (*eno_reset)(efx_nic_t *);
+       efx_rc_t        (*eno_init)(efx_nic_t *);
+       efx_rc_t        (*eno_get_vi_pool)(efx_nic_t *, uint32_t *);
+       efx_rc_t        (*eno_get_bar_region)(efx_nic_t *, efx_nic_region_t,
+                                       uint32_t *, size_t *);
+       void            (*eno_fini)(efx_nic_t *);
+       void            (*eno_unprobe)(efx_nic_t *);
+} efx_nic_ops_t;
+
+#ifndef EFX_TXQ_LIMIT_TARGET
+#define        EFX_TXQ_LIMIT_TARGET 259
+#endif
+#ifndef EFX_RXQ_LIMIT_TARGET
+#define        EFX_RXQ_LIMIT_TARGET 512
+#endif
+#ifndef EFX_TXQ_DC_SIZE
+#define        EFX_TXQ_DC_SIZE 1 /* 16 descriptors */
+#endif
+#ifndef EFX_RXQ_DC_SIZE
+#define        EFX_RXQ_DC_SIZE 3 /* 64 descriptors */
+#endif
+
+typedef struct efx_drv_cfg_s {
+       uint32_t                edc_min_vi_count;
+       uint32_t                edc_max_vi_count;
+
+       uint32_t                edc_max_piobuf_count;
+       uint32_t                edc_pio_alloc_size;
+} efx_drv_cfg_t;
+
+struct efx_nic_s {
+       uint32_t                en_magic;
+       efx_family_t            en_family;
+       uint32_t                en_features;
+       efsys_identifier_t      *en_esip;
+       efsys_lock_t            *en_eslp;
+       efsys_bar_t             *en_esbp;
+       unsigned int            en_mod_flags;
+       unsigned int            en_reset_flags;
+       efx_nic_cfg_t           en_nic_cfg;
+       efx_drv_cfg_t           en_drv_cfg;
+       efx_port_t              en_port;
+       efx_mon_t               en_mon;
+       efx_intr_t              en_intr;
+       uint32_t                en_ev_qcount;
+       uint32_t                en_rx_qcount;
+       uint32_t                en_tx_qcount;
+       const efx_nic_ops_t     *en_enop;
+       const efx_ev_ops_t      *en_eevop;
+       const efx_tx_ops_t      *en_etxop;
+       const efx_rx_ops_t      *en_erxop;
+       uint32_t                en_vport_id;
+       union {
+               int     enu_unused;
+       } en_u;
+};
+
+
+#define        EFX_NIC_MAGIC   0x02121996
+
+typedef        boolean_t (*efx_ev_handler_t)(efx_evq_t *, efx_qword_t *,
+    const efx_ev_callbacks_t *, void *);
+
+typedef struct efx_evq_rxq_state_s {
+       unsigned int                    eers_rx_read_ptr;
+       unsigned int                    eers_rx_mask;
+} efx_evq_rxq_state_t;
+
+struct efx_evq_s {
+       uint32_t                        ee_magic;
+       efx_nic_t                       *ee_enp;
+       unsigned int                    ee_index;
+       unsigned int                    ee_mask;
+       efsys_mem_t                     *ee_esmp;
+
+       efx_ev_handler_t                ee_rx;
+       efx_ev_handler_t                ee_tx;
+       efx_ev_handler_t                ee_driver;
+       efx_ev_handler_t                ee_global;
+       efx_ev_handler_t                ee_drv_gen;
+
+       efx_evq_rxq_state_t             ee_rxq_state[EFX_EV_RX_NLABELS];
+
+       uint32_t                        ee_flags;
+};
+
+#define        EFX_EVQ_MAGIC   0x08081997
+
+#define        EFX_EVQ_SIENA_TIMER_QUANTUM_NS  6144 /* 768 cycles */
+
+struct efx_rxq_s {
+       uint32_t                        er_magic;
+       efx_nic_t                       *er_enp;
+       efx_evq_t                       *er_eep;
+       unsigned int                    er_index;
+       unsigned int                    er_label;
+       unsigned int                    er_mask;
+       efsys_mem_t                     *er_esmp;
+};
+
+#define        EFX_RXQ_MAGIC   0x15022005
+
+struct efx_txq_s {
+       uint32_t                        et_magic;
+       efx_nic_t                       *et_enp;
+       unsigned int                    et_index;
+       unsigned int                    et_mask;
+       efsys_mem_t                     *et_esmp;
+};
+
+#define        EFX_TXQ_MAGIC   0x05092005
+
+#define        EFX_MAC_ADDR_COPY(_dst, _src)                                   \
+       do {                                                            \
+               (_dst)[0] = (_src)[0];                                  \
+               (_dst)[1] = (_src)[1];                                  \
+               (_dst)[2] = (_src)[2];                                  \
+               (_dst)[3] = (_src)[3];                                  \
+               (_dst)[4] = (_src)[4];                                  \
+               (_dst)[5] = (_src)[5];                                  \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_MAC_BROADCAST_ADDR_SET(_dst)                                \
+       do {                                                            \
+               uint16_t *_d = (uint16_t *)(_dst);                      \
+               _d[0] = 0xffff;                                         \
+               _d[1] = 0xffff;                                         \
+               _d[2] = 0xffff;                                         \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#if EFSYS_OPT_CHECK_REG
+#define        EFX_CHECK_REG(_enp, _reg)                                       \
+       do {                                                            \
+               const char *name = #_reg;                               \
+               char min = name[4];                                     \
+               char max = name[5];                                     \
+               char rev;                                               \
+                                                                       \
+               switch ((_enp)->en_family) {                            \
+               case EFX_FAMILY_SIENA:                                  \
+                       rev = 'C';                                      \
+                       break;                                          \
+                                                                       \
+               case EFX_FAMILY_HUNTINGTON:                             \
+                       rev = 'D';                                      \
+                       break;                                          \
+                                                                       \
+               case EFX_FAMILY_MEDFORD:                                \
+                       rev = 'E';                                      \
+                       break;                                          \
+                                                                       \
+               default:                                                \
+                       rev = '?';                                      \
+                       break;                                          \
+               }                                                       \
+                                                                       \
+               EFSYS_ASSERT3S(rev, >=, min);                           \
+               EFSYS_ASSERT3S(rev, <=, max);                           \
+                                                                       \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+#else
+#define        EFX_CHECK_REG(_enp, _reg) do {                                  \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+#endif
+
+#define        EFX_BAR_READD(_enp, _reg, _edp, _lock)                          \
+       do {                                                            \
+               EFX_CHECK_REG((_enp), (_reg));                          \
+               EFSYS_BAR_READD((_enp)->en_esbp, _reg ## _OFST,         \
+                   (_edp), (_lock));                                   \
+               EFSYS_PROBE3(efx_bar_readd, const char *, #_reg,        \
+                   uint32_t, _reg ## _OFST,                            \
+                   uint32_t, (_edp)->ed_u32[0]);                       \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_BAR_WRITED(_enp, _reg, _edp, _lock)                         \
+       do {                                                            \
+               EFX_CHECK_REG((_enp), (_reg));                          \
+               EFSYS_PROBE3(efx_bar_writed, const char *, #_reg,       \
+                   uint32_t, _reg ## _OFST,                            \
+                   uint32_t, (_edp)->ed_u32[0]);                       \
+               EFSYS_BAR_WRITED((_enp)->en_esbp, _reg ## _OFST,        \
+                   (_edp), (_lock));                                   \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_BAR_READQ(_enp, _reg, _eqp)                                 \
+       do {                                                            \
+               EFX_CHECK_REG((_enp), (_reg));                          \
+               EFSYS_BAR_READQ((_enp)->en_esbp, _reg ## _OFST,         \
+                   (_eqp));                                            \
+               EFSYS_PROBE4(efx_bar_readq, const char *, #_reg,        \
+                   uint32_t, _reg ## _OFST,                            \
+                   uint32_t, (_eqp)->eq_u32[1],                        \
+                   uint32_t, (_eqp)->eq_u32[0]);                       \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_BAR_WRITEQ(_enp, _reg, _eqp)                                \
+       do {                                                            \
+               EFX_CHECK_REG((_enp), (_reg));                          \
+               EFSYS_PROBE4(efx_bar_writeq, const char *, #_reg,       \
+                   uint32_t, _reg ## _OFST,                            \
+                   uint32_t, (_eqp)->eq_u32[1],                        \
+                   uint32_t, (_eqp)->eq_u32[0]);                       \
+               EFSYS_BAR_WRITEQ((_enp)->en_esbp, _reg ## _OFST,        \
+                   (_eqp));                                            \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_BAR_READO(_enp, _reg, _eop)                                 \
+       do {                                                            \
+               EFX_CHECK_REG((_enp), (_reg));                          \
+               EFSYS_BAR_READO((_enp)->en_esbp, _reg ## _OFST,         \
+                   (_eop), B_TRUE);                                    \
+               EFSYS_PROBE6(efx_bar_reado, const char *, #_reg,        \
+                   uint32_t, _reg ## _OFST,                            \
+                   uint32_t, (_eop)->eo_u32[3],                        \
+                   uint32_t, (_eop)->eo_u32[2],                        \
+                   uint32_t, (_eop)->eo_u32[1],                        \
+                   uint32_t, (_eop)->eo_u32[0]);                       \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_BAR_WRITEO(_enp, _reg, _eop)                                \
+       do {                                                            \
+               EFX_CHECK_REG((_enp), (_reg));                          \
+               EFSYS_PROBE6(efx_bar_writeo, const char *, #_reg,       \
+                   uint32_t, _reg ## _OFST,                            \
+                   uint32_t, (_eop)->eo_u32[3],                        \
+                   uint32_t, (_eop)->eo_u32[2],                        \
+                   uint32_t, (_eop)->eo_u32[1],                        \
+                   uint32_t, (_eop)->eo_u32[0]);                       \
+               EFSYS_BAR_WRITEO((_enp)->en_esbp, _reg ## _OFST,        \
+                   (_eop), B_TRUE);                                    \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_BAR_TBL_READD(_enp, _reg, _index, _edp, _lock)              \
+       do {                                                            \
+               EFX_CHECK_REG((_enp), (_reg));                          \
+               EFSYS_BAR_READD((_enp)->en_esbp,                        \
+                   (_reg ## _OFST + ((_index) * _reg ## _STEP)),       \
+                   (_edp), (_lock));                                   \
+               EFSYS_PROBE4(efx_bar_tbl_readd, const char *, #_reg,    \
+                   uint32_t, (_index),                                 \
+                   uint32_t, _reg ## _OFST,                            \
+                   uint32_t, (_edp)->ed_u32[0]);                       \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_BAR_TBL_WRITED(_enp, _reg, _index, _edp, _lock)             \
+       do {                                                            \
+               EFX_CHECK_REG((_enp), (_reg));                          \
+               EFSYS_PROBE4(efx_bar_tbl_writed, const char *, #_reg,   \
+                   uint32_t, (_index),                                 \
+                   uint32_t, _reg ## _OFST,                            \
+                   uint32_t, (_edp)->ed_u32[0]);                       \
+               EFSYS_BAR_WRITED((_enp)->en_esbp,                       \
+                   (_reg ## _OFST + ((_index) * _reg ## _STEP)),       \
+                   (_edp), (_lock));                                   \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_BAR_TBL_WRITED2(_enp, _reg, _index, _edp, _lock)            \
+       do {                                                            \
+               EFX_CHECK_REG((_enp), (_reg));                          \
+               EFSYS_PROBE4(efx_bar_tbl_writed, const char *, #_reg,   \
+                   uint32_t, (_index),                                 \
+                   uint32_t, _reg ## _OFST,                            \
+                   uint32_t, (_edp)->ed_u32[0]);                       \
+               EFSYS_BAR_WRITED((_enp)->en_esbp,                       \
+                   (_reg ## _OFST +                                    \
+                   (2 * sizeof (efx_dword_t)) +                        \
+                   ((_index) * _reg ## _STEP)),                        \
+                   (_edp), (_lock));                                   \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_BAR_TBL_WRITED3(_enp, _reg, _index, _edp, _lock)            \
+       do {                                                            \
+               EFX_CHECK_REG((_enp), (_reg));                          \
+               EFSYS_PROBE4(efx_bar_tbl_writed, const char *, #_reg,   \
+                   uint32_t, (_index),                                 \
+                   uint32_t, _reg ## _OFST,                            \
+                   uint32_t, (_edp)->ed_u32[0]);                       \
+               EFSYS_BAR_WRITED((_enp)->en_esbp,                       \
+                   (_reg ## _OFST +                                    \
+                   (3 * sizeof (efx_dword_t)) +                        \
+                   ((_index) * _reg ## _STEP)),                        \
+                   (_edp), (_lock));                                   \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_BAR_TBL_READQ(_enp, _reg, _index, _eqp)                     \
+       do {                                                            \
+               EFX_CHECK_REG((_enp), (_reg));                          \
+               EFSYS_BAR_READQ((_enp)->en_esbp,                        \
+                   (_reg ## _OFST + ((_index) * _reg ## _STEP)),       \
+                   (_eqp));                                            \
+               EFSYS_PROBE5(efx_bar_tbl_readq, const char *, #_reg,    \
+                   uint32_t, (_index),                                 \
+                   uint32_t, _reg ## _OFST,                            \
+                   uint32_t, (_eqp)->eq_u32[1],                        \
+                   uint32_t, (_eqp)->eq_u32[0]);                       \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_BAR_TBL_WRITEQ(_enp, _reg, _index, _eqp)                    \
+       do {                                                            \
+               EFX_CHECK_REG((_enp), (_reg));                          \
+               EFSYS_PROBE5(efx_bar_tbl_writeq, const char *, #_reg,   \
+                   uint32_t, (_index),                                 \
+                   uint32_t, _reg ## _OFST,                            \
+                   uint32_t, (_eqp)->eq_u32[1],                        \
+                   uint32_t, (_eqp)->eq_u32[0]);                       \
+               EFSYS_BAR_WRITEQ((_enp)->en_esbp,                       \
+                   (_reg ## _OFST + ((_index) * _reg ## _STEP)),       \
+                   (_eqp));                                            \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_BAR_TBL_READO(_enp, _reg, _index, _eop, _lock)              \
+       do {                                                            \
+               EFX_CHECK_REG((_enp), (_reg));                          \
+               EFSYS_BAR_READO((_enp)->en_esbp,                        \
+                   (_reg ## _OFST + ((_index) * _reg ## _STEP)),       \
+                   (_eop), (_lock));                                   \
+               EFSYS_PROBE7(efx_bar_tbl_reado, const char *, #_reg,    \
+                   uint32_t, (_index),                                 \
+                   uint32_t, _reg ## _OFST,                            \
+                   uint32_t, (_eop)->eo_u32[3],                        \
+                   uint32_t, (_eop)->eo_u32[2],                        \
+                   uint32_t, (_eop)->eo_u32[1],                        \
+                   uint32_t, (_eop)->eo_u32[0]);                       \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_BAR_TBL_WRITEO(_enp, _reg, _index, _eop, _lock)             \
+       do {                                                            \
+               EFX_CHECK_REG((_enp), (_reg));                          \
+               EFSYS_PROBE7(efx_bar_tbl_writeo, const char *, #_reg,   \
+                   uint32_t, (_index),                                 \
+                   uint32_t, _reg ## _OFST,                            \
+                   uint32_t, (_eop)->eo_u32[3],                        \
+                   uint32_t, (_eop)->eo_u32[2],                        \
+                   uint32_t, (_eop)->eo_u32[1],                        \
+                   uint32_t, (_eop)->eo_u32[0]);                       \
+               EFSYS_BAR_WRITEO((_enp)->en_esbp,                       \
+                   (_reg ## _OFST + ((_index) * _reg ## _STEP)),       \
+                   (_eop), (_lock));                                   \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+/*
+ * Allow drivers to perform optimised 128-bit doorbell writes.
+ * The DMA descriptor pointers (RX_DESC_UPD and TX_DESC_UPD) are
+ * special-cased in the BIU on the Falcon/Siena and EF10 architectures to avoid
+ * the need for locking in the host, and are the only ones known to be safe to
+ * use 128-bites write with.
+ */
+#define        EFX_BAR_TBL_DOORBELL_WRITEO(_enp, _reg, _index, _eop)           \
+       do {                                                            \
+               EFX_CHECK_REG((_enp), (_reg));                          \
+               EFSYS_PROBE7(efx_bar_tbl_doorbell_writeo,               \
+                   const char *,                                       \
+                   #_reg,                                              \
+                   uint32_t, (_index),                                 \
+                   uint32_t, _reg ## _OFST,                            \
+                   uint32_t, (_eop)->eo_u32[3],                        \
+                   uint32_t, (_eop)->eo_u32[2],                        \
+                   uint32_t, (_eop)->eo_u32[1],                        \
+                   uint32_t, (_eop)->eo_u32[0]);                       \
+               EFSYS_BAR_DOORBELL_WRITEO((_enp)->en_esbp,              \
+                   (_reg ## _OFST + ((_index) * _reg ## _STEP)),       \
+                   (_eop));                                            \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_DMA_SYNC_QUEUE_FOR_DEVICE(_esmp, _entries, _wptr, _owptr)   \
+       do {                                                            \
+               unsigned int _new = (_wptr);                            \
+               unsigned int _old = (_owptr);                           \
+                                                                       \
+               if ((_new) >= (_old))                                   \
+                       EFSYS_DMA_SYNC_FOR_DEVICE((_esmp),              \
+                           (_old) * sizeof (efx_desc_t),               \
+                           ((_new) - (_old)) * sizeof (efx_desc_t));   \
+               else                                                    \
+                       /*                                              \
+                        * It is cheaper to sync entire map than sync   \
+                        * two parts especially when offset/size are    \
+                        * ignored and entire map is synced in any case.\
+                        */                                             \
+                       EFSYS_DMA_SYNC_FOR_DEVICE((_esmp),              \
+                           0,                                          \
+                           (_entries) * sizeof (efx_desc_t));          \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+extern __checkReturn   efx_rc_t
+efx_nic_biu_test(
+       __in            efx_nic_t *enp);
+
+extern __checkReturn   efx_rc_t
+efx_mac_select(
+       __in            efx_nic_t *enp);
+
+extern void
+efx_mac_multicast_hash_compute(
+       __in_ecount(6*count)            uint8_t const *addrs,
+       __in                            int count,
+       __out                           efx_oword_t *hash_low,
+       __out                           efx_oword_t *hash_high);
+
+extern __checkReturn   efx_rc_t
+efx_phy_probe(
+       __in            efx_nic_t *enp);
+
+extern                 void
+efx_phy_unprobe(
+       __in            efx_nic_t *enp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_EFX_IMPL_H */
diff --git a/drivers/net/sfc/base/efx_intr.c b/drivers/net/sfc/base/efx_intr.c
new file mode 100644 (file)
index 0000000..fb1812b
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2007-2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include "efx.h"
+#include "efx_impl.h"
+
+
+       __checkReturn   efx_rc_t
+efx_intr_init(
+       __in            efx_nic_t *enp,
+       __in            efx_intr_type_t type,
+       __in            efsys_mem_t *esmp)
+{
+       efx_intr_t *eip = &(enp->en_intr);
+       const efx_intr_ops_t *eiop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
+
+       if (enp->en_mod_flags & EFX_MOD_INTR) {
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       eip->ei_esmp = esmp;
+       eip->ei_type = type;
+       eip->ei_level = 0;
+
+       enp->en_mod_flags |= EFX_MOD_INTR;
+
+       switch (enp->en_family) {
+
+       default:
+               EFSYS_ASSERT(B_FALSE);
+               rc = ENOTSUP;
+               goto fail2;
+       }
+
+       if ((rc = eiop->eio_init(enp, type, esmp)) != 0)
+               goto fail3;
+
+       eip->ei_eiop = eiop;
+
+       return (0);
+
+fail3:
+       EFSYS_PROBE(fail3);
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+               void
+efx_intr_fini(
+       __in    efx_nic_t *enp)
+{
+       efx_intr_t *eip = &(enp->en_intr);
+       const efx_intr_ops_t *eiop = eip->ei_eiop;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
+
+       eiop->eio_fini(enp);
+
+       enp->en_mod_flags &= ~EFX_MOD_INTR;
+}
+
+                       void
+efx_intr_enable(
+       __in            efx_nic_t *enp)
+{
+       efx_intr_t *eip = &(enp->en_intr);
+       const efx_intr_ops_t *eiop = eip->ei_eiop;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
+
+       eiop->eio_enable(enp);
+}
+
+                       void
+efx_intr_disable(
+       __in            efx_nic_t *enp)
+{
+       efx_intr_t *eip = &(enp->en_intr);
+       const efx_intr_ops_t *eiop = eip->ei_eiop;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
+
+       eiop->eio_disable(enp);
+}
+
+                       void
+efx_intr_disable_unlocked(
+       __in            efx_nic_t *enp)
+{
+       efx_intr_t *eip = &(enp->en_intr);
+       const efx_intr_ops_t *eiop = eip->ei_eiop;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
+
+       eiop->eio_disable_unlocked(enp);
+}
+
+
+       __checkReturn   efx_rc_t
+efx_intr_trigger(
+       __in            efx_nic_t *enp,
+       __in            unsigned int level)
+{
+       efx_intr_t *eip = &(enp->en_intr);
+       const efx_intr_ops_t *eiop = eip->ei_eiop;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
+
+       return (eiop->eio_trigger(enp, level));
+}
+
+                       void
+efx_intr_status_line(
+       __in            efx_nic_t *enp,
+       __out           boolean_t *fatalp,
+       __out           uint32_t *qmaskp)
+{
+       efx_intr_t *eip = &(enp->en_intr);
+       const efx_intr_ops_t *eiop = eip->ei_eiop;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
+
+       eiop->eio_status_line(enp, fatalp, qmaskp);
+}
+
+                       void
+efx_intr_status_message(
+       __in            efx_nic_t *enp,
+       __in            unsigned int message,
+       __out           boolean_t *fatalp)
+{
+       efx_intr_t *eip = &(enp->en_intr);
+       const efx_intr_ops_t *eiop = eip->ei_eiop;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
+
+       eiop->eio_status_message(enp, message, fatalp);
+}
+
+               void
+efx_intr_fatal(
+       __in    efx_nic_t *enp)
+{
+       efx_intr_t *eip = &(enp->en_intr);
+       const efx_intr_ops_t *eiop = eip->ei_eiop;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
+
+       eiop->eio_fatal(enp);
+}
+
+
+/* ************************************************************************* */
+/* ************************************************************************* */
+/* ************************************************************************* */
+
diff --git a/drivers/net/sfc/base/efx_mac.c b/drivers/net/sfc/base/efx_mac.c
new file mode 100644 (file)
index 0000000..169dcf1
--- /dev/null
@@ -0,0 +1,489 @@
+/*
+ * Copyright (c) 2007-2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include "efx.h"
+#include "efx_impl.h"
+
+       __checkReturn                   efx_rc_t
+efx_mac_pdu_set(
+       __in                            efx_nic_t *enp,
+       __in                            size_t pdu)
+{
+       efx_port_t *epp = &(enp->en_port);
+       const efx_mac_ops_t *emop = epp->ep_emop;
+       uint32_t old_pdu;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+       EFSYS_ASSERT(emop != NULL);
+
+       if (pdu < EFX_MAC_PDU_MIN) {
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       if (pdu > EFX_MAC_PDU_MAX) {
+               rc = EINVAL;
+               goto fail2;
+       }
+
+       old_pdu = epp->ep_mac_pdu;
+       epp->ep_mac_pdu = (uint32_t)pdu;
+       if ((rc = emop->emo_pdu_set(enp)) != 0)
+               goto fail3;
+
+       return (0);
+
+fail3:
+       EFSYS_PROBE(fail3);
+
+       epp->ep_mac_pdu = old_pdu;
+
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+       __checkReturn   efx_rc_t
+efx_mac_pdu_get(
+       __in            efx_nic_t *enp,
+       __out           size_t *pdu)
+{
+       efx_port_t *epp = &(enp->en_port);
+       const efx_mac_ops_t *emop = epp->ep_emop;
+       efx_rc_t rc;
+
+       if ((rc = emop->emo_pdu_get(enp, pdu)) != 0)
+               goto fail1;
+
+       return (0);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+       __checkReturn                   efx_rc_t
+efx_mac_addr_set(
+       __in                            efx_nic_t *enp,
+       __in                            uint8_t *addr)
+{
+       efx_port_t *epp = &(enp->en_port);
+       const efx_mac_ops_t *emop = epp->ep_emop;
+       uint8_t old_addr[6];
+       uint32_t oui;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+
+       if (EFX_MAC_ADDR_IS_MULTICAST(addr)) {
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       oui = addr[0] << 16 | addr[1] << 8 | addr[2];
+       if (oui == 0x000000) {
+               rc = EINVAL;
+               goto fail2;
+       }
+
+       EFX_MAC_ADDR_COPY(old_addr, epp->ep_mac_addr);
+       EFX_MAC_ADDR_COPY(epp->ep_mac_addr, addr);
+       if ((rc = emop->emo_addr_set(enp)) != 0)
+               goto fail3;
+
+       return (0);
+
+fail3:
+       EFSYS_PROBE(fail3);
+
+       EFX_MAC_ADDR_COPY(epp->ep_mac_addr, old_addr);
+
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+       __checkReturn                   efx_rc_t
+efx_mac_filter_set(
+       __in                            efx_nic_t *enp,
+       __in                            boolean_t all_unicst,
+       __in                            boolean_t mulcst,
+       __in                            boolean_t all_mulcst,
+       __in                            boolean_t brdcst)
+{
+       efx_port_t *epp = &(enp->en_port);
+       const efx_mac_ops_t *emop = epp->ep_emop;
+       boolean_t old_all_unicst;
+       boolean_t old_mulcst;
+       boolean_t old_all_mulcst;
+       boolean_t old_brdcst;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+
+       old_all_unicst = epp->ep_all_unicst;
+       old_mulcst = epp->ep_mulcst;
+       old_all_mulcst = epp->ep_all_mulcst;
+       old_brdcst = epp->ep_brdcst;
+
+       epp->ep_all_unicst = all_unicst;
+       epp->ep_mulcst = mulcst;
+       epp->ep_all_mulcst = all_mulcst;
+       epp->ep_brdcst = brdcst;
+
+       if ((rc = emop->emo_reconfigure(enp)) != 0)
+               goto fail1;
+
+       return (0);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       epp->ep_all_unicst = old_all_unicst;
+       epp->ep_mulcst = old_mulcst;
+       epp->ep_all_mulcst = old_all_mulcst;
+       epp->ep_brdcst = old_brdcst;
+
+       return (rc);
+}
+
+       __checkReturn                   efx_rc_t
+efx_mac_drain(
+       __in                            efx_nic_t *enp,
+       __in                            boolean_t enabled)
+{
+       efx_port_t *epp = &(enp->en_port);
+       const efx_mac_ops_t *emop = epp->ep_emop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+       EFSYS_ASSERT(emop != NULL);
+
+       if (epp->ep_mac_drain == enabled)
+               return (0);
+
+       epp->ep_mac_drain = enabled;
+
+       if ((rc = emop->emo_reconfigure(enp)) != 0)
+               goto fail1;
+
+       return (0);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+       __checkReturn   efx_rc_t
+efx_mac_up(
+       __in            efx_nic_t *enp,
+       __out           boolean_t *mac_upp)
+{
+       efx_port_t *epp = &(enp->en_port);
+       const efx_mac_ops_t *emop = epp->ep_emop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+
+       if ((rc = emop->emo_up(enp, mac_upp)) != 0)
+               goto fail1;
+
+       return (0);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+       __checkReturn                   efx_rc_t
+efx_mac_fcntl_set(
+       __in                            efx_nic_t *enp,
+       __in                            unsigned int fcntl,
+       __in                            boolean_t autoneg)
+{
+       efx_port_t *epp = &(enp->en_port);
+       const efx_mac_ops_t *emop = epp->ep_emop;
+       const efx_phy_ops_t *epop = epp->ep_epop;
+       unsigned int old_fcntl;
+       boolean_t old_autoneg;
+       unsigned int old_adv_cap;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+
+       if ((fcntl & ~(EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE)) != 0) {
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       /*
+        * Ignore a request to set flow control auto-negotiation
+        * if the PHY doesn't support it.
+        */
+       if (~epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN))
+               autoneg = B_FALSE;
+
+       old_fcntl = epp->ep_fcntl;
+       old_autoneg = epp->ep_fcntl_autoneg;
+       old_adv_cap = epp->ep_adv_cap_mask;
+
+       epp->ep_fcntl = fcntl;
+       epp->ep_fcntl_autoneg = autoneg;
+
+       /*
+        * Always encode the flow control settings in the advertised
+        * capabilities even if we are not trying to auto-negotiate
+        * them and reconfigure both the PHY and the MAC.
+        */
+       if (fcntl & EFX_FCNTL_RESPOND)
+               epp->ep_adv_cap_mask |=    (1 << EFX_PHY_CAP_PAUSE |
+                                           1 << EFX_PHY_CAP_ASYM);
+       else
+               epp->ep_adv_cap_mask &=   ~(1 << EFX_PHY_CAP_PAUSE |
+                                           1 << EFX_PHY_CAP_ASYM);
+
+       if (fcntl & EFX_FCNTL_GENERATE)
+               epp->ep_adv_cap_mask ^= (1 << EFX_PHY_CAP_ASYM);
+
+       if ((rc = epop->epo_reconfigure(enp)) != 0)
+               goto fail2;
+
+       if ((rc = emop->emo_reconfigure(enp)) != 0)
+               goto fail3;
+
+       return (0);
+
+fail3:
+       EFSYS_PROBE(fail3);
+
+fail2:
+       EFSYS_PROBE(fail2);
+
+       epp->ep_fcntl = old_fcntl;
+       epp->ep_fcntl_autoneg = old_autoneg;
+       epp->ep_adv_cap_mask = old_adv_cap;
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+                       void
+efx_mac_fcntl_get(
+       __in            efx_nic_t *enp,
+       __out           unsigned int *fcntl_wantedp,
+       __out           unsigned int *fcntl_linkp)
+{
+       efx_port_t *epp = &(enp->en_port);
+       unsigned int wanted = 0;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+
+       /*
+        * Decode the requested flow control settings from the PHY
+        * advertised capabilities.
+        */
+       if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_PAUSE))
+               wanted = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
+       if (epp->ep_adv_cap_mask & (1 << EFX_PHY_CAP_ASYM))
+               wanted ^= EFX_FCNTL_GENERATE;
+
+       *fcntl_linkp = epp->ep_fcntl;
+       *fcntl_wantedp = wanted;
+}
+
+       __checkReturn   efx_rc_t
+efx_mac_multicast_list_set(
+       __in                            efx_nic_t *enp,
+       __in_ecount(6*count)            uint8_t const *addrs,
+       __in                            int count)
+{
+       efx_port_t *epp = &(enp->en_port);
+       const efx_mac_ops_t *emop = epp->ep_emop;
+       uint8_t *old_mulcst_addr_list = NULL;
+       uint32_t old_mulcst_addr_count;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+
+       if (count > EFX_MAC_MULTICAST_LIST_MAX) {
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       old_mulcst_addr_count = epp->ep_mulcst_addr_count;
+       if (old_mulcst_addr_count > 0) {
+               /* Allocate memory to store old list (instead of using stack) */
+               EFSYS_KMEM_ALLOC(enp->en_esip,
+                               old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
+                               old_mulcst_addr_list);
+               if (old_mulcst_addr_list == NULL) {
+                       rc = ENOMEM;
+                       goto fail2;
+               }
+
+               /* Save the old list in case we need to rollback */
+               memcpy(old_mulcst_addr_list, epp->ep_mulcst_addr_list,
+                       old_mulcst_addr_count * EFX_MAC_ADDR_LEN);
+       }
+
+       /* Store the new list */
+       memcpy(epp->ep_mulcst_addr_list, addrs,
+               count * EFX_MAC_ADDR_LEN);
+       epp->ep_mulcst_addr_count = count;
+
+       if ((rc = emop->emo_multicast_list_set(enp)) != 0)
+               goto fail3;
+
+       if (old_mulcst_addr_count > 0) {
+               EFSYS_KMEM_FREE(enp->en_esip,
+                               old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
+                               old_mulcst_addr_list);
+       }
+
+       return (0);
+
+fail3:
+       EFSYS_PROBE(fail3);
+
+       /* Restore original list on failure */
+       epp->ep_mulcst_addr_count = old_mulcst_addr_count;
+       if (old_mulcst_addr_count > 0) {
+               memcpy(epp->ep_mulcst_addr_list, old_mulcst_addr_list,
+                       old_mulcst_addr_count * EFX_MAC_ADDR_LEN);
+
+               EFSYS_KMEM_FREE(enp->en_esip,
+                               old_mulcst_addr_count * EFX_MAC_ADDR_LEN,
+                               old_mulcst_addr_list);
+       }
+
+fail2:
+       EFSYS_PROBE(fail2);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+
+}
+
+       __checkReturn   efx_rc_t
+efx_mac_filter_default_rxq_set(
+       __in            efx_nic_t *enp,
+       __in            efx_rxq_t *erp,
+       __in            boolean_t using_rss)
+{
+       efx_port_t *epp = &(enp->en_port);
+       const efx_mac_ops_t *emop = epp->ep_emop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+
+       if (emop->emo_filter_default_rxq_set != NULL) {
+               rc = emop->emo_filter_default_rxq_set(enp, erp, using_rss);
+               if (rc != 0)
+                       goto fail1;
+       }
+
+       return (0);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+                       void
+efx_mac_filter_default_rxq_clear(
+       __in            efx_nic_t *enp)
+{
+       efx_port_t *epp = &(enp->en_port);
+       const efx_mac_ops_t *emop = epp->ep_emop;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+
+       if (emop->emo_filter_default_rxq_clear != NULL)
+               emop->emo_filter_default_rxq_clear(enp);
+}
+
+
+       __checkReturn                   efx_rc_t
+efx_mac_select(
+       __in                            efx_nic_t *enp)
+{
+       efx_port_t *epp = &(enp->en_port);
+       efx_mac_type_t type = EFX_MAC_INVALID;
+       const efx_mac_ops_t *emop;
+       int rc = EINVAL;
+
+       switch (enp->en_family) {
+
+       default:
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       EFSYS_ASSERT(type != EFX_MAC_INVALID);
+       EFSYS_ASSERT3U(type, <, EFX_MAC_NTYPES);
+       EFSYS_ASSERT(emop != NULL);
+
+       epp->ep_emop = emop;
+       epp->ep_mac_type = type;
+
+       return (0);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+
diff --git a/drivers/net/sfc/base/efx_mon.c b/drivers/net/sfc/base/efx_mon.c
new file mode 100644 (file)
index 0000000..d3ed40d
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2007-2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include "efx.h"
+#include "efx_impl.h"
+
+#if EFSYS_OPT_NAMES
+
+static const char * const __efx_mon_name[] = {
+       "",
+       "sfx90x0",
+       "sfx91x0",
+       "sfx92x0"
+};
+
+               const char *
+efx_mon_name(
+       __in    efx_nic_t *enp)
+{
+       efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+
+       EFSYS_ASSERT(encp->enc_mon_type != EFX_MON_INVALID);
+       EFSYS_ASSERT3U(encp->enc_mon_type, <, EFX_MON_NTYPES);
+       return (__efx_mon_name[encp->enc_mon_type]);
+}
+
+#endif /* EFSYS_OPT_NAMES */
+
+
+       __checkReturn   efx_rc_t
+efx_mon_init(
+       __in            efx_nic_t *enp)
+{
+       efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+       efx_mon_t *emp = &(enp->en_mon);
+       const efx_mon_ops_t *emop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+
+       if (enp->en_mod_flags & EFX_MOD_MON) {
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       enp->en_mod_flags |= EFX_MOD_MON;
+
+       emp->em_type = encp->enc_mon_type;
+
+       EFSYS_ASSERT(encp->enc_mon_type != EFX_MON_INVALID);
+       switch (emp->em_type) {
+       default:
+               rc = ENOTSUP;
+               goto fail2;
+       }
+
+       emp->em_emop = emop;
+       return (0);
+
+fail2:
+       EFSYS_PROBE(fail2);
+
+       emp->em_type = EFX_MON_INVALID;
+
+       enp->en_mod_flags &= ~EFX_MOD_MON;
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+               void
+efx_mon_fini(
+       __in    efx_nic_t *enp)
+{
+       efx_mon_t *emp = &(enp->en_mon);
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MON);
+
+       emp->em_emop = NULL;
+
+       emp->em_type = EFX_MON_INVALID;
+
+       enp->en_mod_flags &= ~EFX_MOD_MON;
+}
diff --git a/drivers/net/sfc/base/efx_nic.c b/drivers/net/sfc/base/efx_nic.c
new file mode 100644 (file)
index 0000000..805136c
--- /dev/null
@@ -0,0 +1,549 @@
+/*
+ * Copyright (c) 2007-2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include "efx.h"
+#include "efx_impl.h"
+
+       __checkReturn   efx_rc_t
+efx_family(
+       __in            uint16_t venid,
+       __in            uint16_t devid,
+       __out           efx_family_t *efp)
+{
+       if (venid == EFX_PCI_VENID_SFC) {
+               switch (devid) {
+
+               case EFX_PCI_DEVID_FALCON:      /* Obsolete, not supported */
+               default:
+                       break;
+               }
+       }
+
+       *efp = EFX_FAMILY_INVALID;
+       return (ENOTSUP);
+}
+
+
+#define        EFX_BIU_MAGIC0  0x01234567
+#define        EFX_BIU_MAGIC1  0xfedcba98
+
+       __checkReturn   efx_rc_t
+efx_nic_biu_test(
+       __in            efx_nic_t *enp)
+{
+       efx_oword_t oword;
+       efx_rc_t rc;
+
+       /*
+        * Write magic values to scratch registers 0 and 1, then
+        * verify that the values were written correctly.  Interleave
+        * the accesses to ensure that the BIU is not just reading
+        * back the cached value that was last written.
+        */
+       EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC0);
+       EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
+
+       EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC1);
+       EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
+
+       EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
+       if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC0) {
+               rc = EIO;
+               goto fail1;
+       }
+
+       EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
+       if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC1) {
+               rc = EIO;
+               goto fail2;
+       }
+
+       /*
+        * Perform the same test, with the values swapped.  This
+        * ensures that subsequent tests don't start with the correct
+        * values already written into the scratch registers.
+        */
+       EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC1);
+       EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
+
+       EFX_POPULATE_OWORD_1(oword, FRF_AZ_DRIVER_DW0, EFX_BIU_MAGIC0);
+       EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
+
+       EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword, B_TRUE);
+       if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC1) {
+               rc = EIO;
+               goto fail3;
+       }
+
+       EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
+       if (EFX_OWORD_FIELD(oword, FRF_AZ_DRIVER_DW0) != EFX_BIU_MAGIC0) {
+               rc = EIO;
+               goto fail4;
+       }
+
+       return (0);
+
+fail4:
+       EFSYS_PROBE(fail4);
+fail3:
+       EFSYS_PROBE(fail3);
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+
+       __checkReturn   efx_rc_t
+efx_nic_create(
+       __in            efx_family_t family,
+       __in            efsys_identifier_t *esip,
+       __in            efsys_bar_t *esbp,
+       __in            efsys_lock_t *eslp,
+       __deref_out     efx_nic_t **enpp)
+{
+       efx_nic_t *enp;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(family, >, EFX_FAMILY_INVALID);
+       EFSYS_ASSERT3U(family, <, EFX_FAMILY_NTYPES);
+
+       /* Allocate a NIC object */
+       EFSYS_KMEM_ALLOC(esip, sizeof (efx_nic_t), enp);
+
+       if (enp == NULL) {
+               rc = ENOMEM;
+               goto fail1;
+       }
+
+       enp->en_magic = EFX_NIC_MAGIC;
+
+       switch (family) {
+
+       default:
+               rc = ENOTSUP;
+               goto fail2;
+       }
+
+       enp->en_family = family;
+       enp->en_esip = esip;
+       enp->en_esbp = esbp;
+       enp->en_eslp = eslp;
+
+       *enpp = enp;
+
+       return (0);
+
+fail2:
+       EFSYS_PROBE(fail2);
+
+       enp->en_magic = 0;
+
+       /* Free the NIC object */
+       EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+       __checkReturn   efx_rc_t
+efx_nic_probe(
+       __in            efx_nic_t *enp)
+{
+       const efx_nic_ops_t *enop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROBE));
+
+       enop = enp->en_enop;
+       if ((rc = enop->eno_probe(enp)) != 0)
+               goto fail1;
+
+       if ((rc = efx_phy_probe(enp)) != 0)
+               goto fail2;
+
+       enp->en_mod_flags |= EFX_MOD_PROBE;
+
+       return (0);
+
+fail2:
+       EFSYS_PROBE(fail2);
+
+       enop->eno_unprobe(enp);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+       __checkReturn   efx_rc_t
+efx_nic_set_drv_limits(
+       __inout         efx_nic_t *enp,
+       __in            efx_drv_limits_t *edlp)
+{
+       const efx_nic_ops_t *enop = enp->en_enop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+
+       if (enop->eno_set_drv_limits != NULL) {
+               if ((rc = enop->eno_set_drv_limits(enp, edlp)) != 0)
+                       goto fail1;
+       }
+
+       return (0);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+       __checkReturn   efx_rc_t
+efx_nic_get_bar_region(
+       __in            efx_nic_t *enp,
+       __in            efx_nic_region_t region,
+       __out           uint32_t *offsetp,
+       __out           size_t *sizep)
+{
+       const efx_nic_ops_t *enop = enp->en_enop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
+
+       if (enop->eno_get_bar_region == NULL) {
+               rc = ENOTSUP;
+               goto fail1;
+       }
+       if ((rc = (enop->eno_get_bar_region)(enp,
+                   region, offsetp, sizep)) != 0) {
+               goto fail2;
+       }
+
+       return (0);
+
+fail2:
+       EFSYS_PROBE(fail2);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+
+       __checkReturn   efx_rc_t
+efx_nic_get_vi_pool(
+       __in            efx_nic_t *enp,
+       __out           uint32_t *evq_countp,
+       __out           uint32_t *rxq_countp,
+       __out           uint32_t *txq_countp)
+{
+       const efx_nic_ops_t *enop = enp->en_enop;
+       efx_nic_cfg_t *encp = &enp->en_nic_cfg;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
+
+       if (enop->eno_get_vi_pool != NULL) {
+               uint32_t vi_count = 0;
+
+               if ((rc = (enop->eno_get_vi_pool)(enp, &vi_count)) != 0)
+                       goto fail1;
+
+               *evq_countp = vi_count;
+               *rxq_countp = vi_count;
+               *txq_countp = vi_count;
+       } else {
+               /* Use NIC limits as default value */
+               *evq_countp = encp->enc_evq_limit;
+               *rxq_countp = encp->enc_rxq_limit;
+               *txq_countp = encp->enc_txq_limit;
+       }
+
+       return (0);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+
+       __checkReturn   efx_rc_t
+efx_nic_init(
+       __in            efx_nic_t *enp)
+{
+       const efx_nic_ops_t *enop = enp->en_enop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+
+       if (enp->en_mod_flags & EFX_MOD_NIC) {
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       if ((rc = enop->eno_init(enp)) != 0)
+               goto fail2;
+
+       enp->en_mod_flags |= EFX_MOD_NIC;
+
+       return (0);
+
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+                       void
+efx_nic_fini(
+       __in            efx_nic_t *enp)
+{
+       const efx_nic_ops_t *enop = enp->en_enop;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
+       EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_NIC);
+       EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
+       EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
+       EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
+       EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
+
+       enop->eno_fini(enp);
+
+       enp->en_mod_flags &= ~EFX_MOD_NIC;
+}
+
+                       void
+efx_nic_unprobe(
+       __in            efx_nic_t *enp)
+{
+       const efx_nic_ops_t *enop = enp->en_enop;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+       EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_NIC));
+       EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_INTR));
+       EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
+       EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_RX));
+       EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_TX));
+
+       efx_phy_unprobe(enp);
+
+       enop->eno_unprobe(enp);
+
+       enp->en_mod_flags &= ~EFX_MOD_PROBE;
+}
+
+                       void
+efx_nic_destroy(
+       __in    efx_nic_t *enp)
+{
+       efsys_identifier_t *esip = enp->en_esip;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0);
+
+       enp->en_family = EFX_FAMILY_INVALID;
+       enp->en_esip = NULL;
+       enp->en_esbp = NULL;
+       enp->en_eslp = NULL;
+
+       enp->en_enop = NULL;
+
+       enp->en_magic = 0;
+
+       /* Free the NIC object */
+       EFSYS_KMEM_FREE(esip, sizeof (efx_nic_t), enp);
+}
+
+       __checkReturn   efx_rc_t
+efx_nic_reset(
+       __in            efx_nic_t *enp)
+{
+       const efx_nic_ops_t *enop = enp->en_enop;
+       unsigned int mod_flags;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE);
+       /*
+        * All modules except the MCDI, PROBE, NVRAM, VPD, MON
+        * (which we do not reset here) must have been shut down or never
+        * initialized.
+        *
+        * A rule of thumb here is: If the controller or MC reboots, is *any*
+        * state lost. If it's lost and needs reapplying, then the module
+        * *must* not be initialised during the reset.
+        */
+       mod_flags = enp->en_mod_flags;
+       mod_flags &= ~(EFX_MOD_MCDI | EFX_MOD_PROBE | EFX_MOD_NVRAM |
+                   EFX_MOD_VPD | EFX_MOD_MON);
+       EFSYS_ASSERT3U(mod_flags, ==, 0);
+       if (mod_flags != 0) {
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       if ((rc = enop->eno_reset(enp)) != 0)
+               goto fail2;
+
+       return (0);
+
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+                       const efx_nic_cfg_t *
+efx_nic_cfg_get(
+       __in            efx_nic_t *enp)
+{
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+
+       return (&(enp->en_nic_cfg));
+}
+
+       __checkReturn   efx_rc_t
+efx_nic_calculate_pcie_link_bandwidth(
+       __in            uint32_t pcie_link_width,
+       __in            uint32_t pcie_link_gen,
+       __out           uint32_t *bandwidth_mbpsp)
+{
+       uint32_t lane_bandwidth;
+       uint32_t total_bandwidth;
+       efx_rc_t rc;
+
+       if ((pcie_link_width == 0) || (pcie_link_width > 16) ||
+           !ISP2(pcie_link_width)) {
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       switch (pcie_link_gen) {
+       case EFX_PCIE_LINK_SPEED_GEN1:
+               /* 2.5 Gb/s raw bandwidth with 8b/10b encoding */
+               lane_bandwidth = 2000;
+               break;
+       case EFX_PCIE_LINK_SPEED_GEN2:
+               /* 5.0 Gb/s raw bandwidth with 8b/10b encoding */
+               lane_bandwidth = 4000;
+               break;
+       case EFX_PCIE_LINK_SPEED_GEN3:
+               /* 8.0 Gb/s raw bandwidth with 128b/130b encoding */
+               lane_bandwidth = 7877;
+               break;
+       default:
+               rc = EINVAL;
+               goto fail2;
+       }
+
+       total_bandwidth = lane_bandwidth * pcie_link_width;
+       *bandwidth_mbpsp = total_bandwidth;
+
+       return (0);
+
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+
+       __checkReturn   efx_rc_t
+efx_nic_check_pcie_link_speed(
+       __in            efx_nic_t *enp,
+       __in            uint32_t pcie_link_width,
+       __in            uint32_t pcie_link_gen,
+       __out           efx_pcie_link_performance_t *resultp)
+{
+       efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+       uint32_t bandwidth;
+       efx_pcie_link_performance_t result;
+       efx_rc_t rc;
+
+       if ((encp->enc_required_pcie_bandwidth_mbps == 0) ||
+           (pcie_link_width == 0) || (pcie_link_width == 32) ||
+           (pcie_link_gen == 0)) {
+               /*
+                * No usable info on what is required and/or in use. In virtual
+                * machines, sometimes the PCIe link width is reported as 0 or
+                * 32, or the speed as 0.
+                */
+               result = EFX_PCIE_LINK_PERFORMANCE_UNKNOWN_BANDWIDTH;
+               goto out;
+       }
+
+       /* Calculate the available bandwidth in megabits per second */
+       rc = efx_nic_calculate_pcie_link_bandwidth(pcie_link_width,
+                                           pcie_link_gen, &bandwidth);
+       if (rc != 0)
+               goto fail1;
+
+       if (bandwidth < encp->enc_required_pcie_bandwidth_mbps) {
+               result = EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_BANDWIDTH;
+       } else if (pcie_link_gen < encp->enc_max_pcie_link_gen) {
+               /* The link provides enough bandwidth but not optimal latency */
+               result = EFX_PCIE_LINK_PERFORMANCE_SUBOPTIMAL_LATENCY;
+       } else {
+               result = EFX_PCIE_LINK_PERFORMANCE_OPTIMAL;
+       }
+
+out:
+       *resultp = result;
+
+       return (0);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
diff --git a/drivers/net/sfc/base/efx_phy.c b/drivers/net/sfc/base/efx_phy.c
new file mode 100644 (file)
index 0000000..7b9a330
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2007-2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include "efx.h"
+#include "efx_impl.h"
+
+
+       __checkReturn   efx_rc_t
+efx_phy_probe(
+       __in            efx_nic_t *enp)
+{
+       efx_port_t *epp = &(enp->en_port);
+       efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+       const efx_phy_ops_t *epop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+
+       epp->ep_port = encp->enc_port;
+       epp->ep_phy_type = encp->enc_phy_type;
+
+       /* Hook in operations structure */
+       switch (enp->en_family) {
+       default:
+               rc = ENOTSUP;
+               goto fail1;
+       }
+
+       epp->ep_epop = epop;
+
+       return (0);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       epp->ep_port = 0;
+       epp->ep_phy_type = 0;
+
+       return (rc);
+}
+
+       __checkReturn   efx_rc_t
+efx_phy_verify(
+       __in            efx_nic_t *enp)
+{
+       efx_port_t *epp = &(enp->en_port);
+       const efx_phy_ops_t *epop = epp->ep_epop;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+
+       return (epop->epo_verify(enp));
+}
+
+                       void
+efx_phy_adv_cap_get(
+       __in            efx_nic_t *enp,
+       __in            uint32_t flag,
+       __out           uint32_t *maskp)
+{
+       efx_port_t *epp = &(enp->en_port);
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+
+       switch (flag) {
+       case EFX_PHY_CAP_CURRENT:
+               *maskp = epp->ep_adv_cap_mask;
+               break;
+       case EFX_PHY_CAP_DEFAULT:
+               *maskp = epp->ep_default_adv_cap_mask;
+               break;
+       case EFX_PHY_CAP_PERM:
+               *maskp = epp->ep_phy_cap_mask;
+               break;
+       default:
+               EFSYS_ASSERT(B_FALSE);
+               break;
+       }
+}
+
+       __checkReturn   efx_rc_t
+efx_phy_adv_cap_set(
+       __in            efx_nic_t *enp,
+       __in            uint32_t mask)
+{
+       efx_port_t *epp = &(enp->en_port);
+       const efx_phy_ops_t *epop = epp->ep_epop;
+       uint32_t old_mask;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+
+       if ((mask & ~epp->ep_phy_cap_mask) != 0) {
+               rc = ENOTSUP;
+               goto fail1;
+       }
+
+       if (epp->ep_adv_cap_mask == mask)
+               goto done;
+
+       old_mask = epp->ep_adv_cap_mask;
+       epp->ep_adv_cap_mask = mask;
+
+       if ((rc = epop->epo_reconfigure(enp)) != 0)
+               goto fail2;
+
+done:
+       return (0);
+
+fail2:
+       EFSYS_PROBE(fail2);
+
+       epp->ep_adv_cap_mask = old_mask;
+       /* Reconfigure for robustness */
+       if (epop->epo_reconfigure(enp) != 0) {
+               /*
+                * We may have an inconsistent view of our advertised speed
+                * capabilities.
+                */
+               EFSYS_ASSERT(0);
+       }
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+       void
+efx_phy_lp_cap_get(
+       __in            efx_nic_t *enp,
+       __out           uint32_t *maskp)
+{
+       efx_port_t *epp = &(enp->en_port);
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+
+       *maskp = epp->ep_lp_cap_mask;
+}
+
+       __checkReturn   efx_rc_t
+efx_phy_oui_get(
+       __in            efx_nic_t *enp,
+       __out           uint32_t *ouip)
+{
+       efx_port_t *epp = &(enp->en_port);
+       const efx_phy_ops_t *epop = epp->ep_epop;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+
+       return (epop->epo_oui_get(enp, ouip));
+}
+
+                       void
+efx_phy_media_type_get(
+       __in            efx_nic_t *enp,
+       __out           efx_phy_media_type_t *typep)
+{
+       efx_port_t *epp = &(enp->en_port);
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+
+       if (epp->ep_module_type != EFX_PHY_MEDIA_INVALID)
+               *typep = epp->ep_module_type;
+       else
+               *typep = epp->ep_fixed_port_type;
+}
+
+       __checkReturn   efx_rc_t
+efx_phy_module_get_info(
+       __in                    efx_nic_t *enp,
+       __in                    uint8_t dev_addr,
+       __in                    uint8_t offset,
+       __in                    uint8_t len,
+       __out_bcount(len)       uint8_t *data)
+{
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT(data != NULL);
+
+       if ((uint32_t)offset + len > 0xff) {
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       if ((rc = efx_mcdi_phy_module_get_info(enp, dev_addr,
+           offset, len, data)) != 0)
+               goto fail2;
+
+       return (0);
+
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+
+                       void
+efx_phy_unprobe(
+       __in    efx_nic_t *enp)
+{
+       efx_port_t *epp = &(enp->en_port);
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+
+       epp->ep_epop = NULL;
+
+       epp->ep_adv_cap_mask = 0;
+
+       epp->ep_port = 0;
+       epp->ep_phy_type = 0;
+}
diff --git a/drivers/net/sfc/base/efx_phy_ids.h b/drivers/net/sfc/base/efx_phy_ids.h
new file mode 100644 (file)
index 0000000..9d9a0f9
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013-2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#ifndef        _SYS_EFX_PHY_IDS_H
+#define        _SYS_EFX_PHY_IDS_H
+
+#define        EFX_PHY_NULL    0
+
+typedef enum efx_phy_type_e {                  /* GENERATED BY scripts/genfwdef */
+       EFX_PHY_TXC43128 = 1,
+       EFX_PHY_SFX7101 = 3,
+       EFX_PHY_QT2022C2 = 4,
+       EFX_PHY_PM8358 = 6,
+       EFX_PHY_SFT9001A = 8,
+       EFX_PHY_QT2025C = 9,
+       EFX_PHY_SFT9001B = 10,
+       EFX_PHY_QLX111V = 12,
+       EFX_PHY_QT2025_KR = 17,
+       EFX_PHY_AEL3020 = 18,
+       EFX_PHY_XFI_FARMI = 19,
+} efx_phy_type_t;
+
+
+#endif /* _SYS_EFX_PHY_IDS_H */
diff --git a/drivers/net/sfc/base/efx_port.c b/drivers/net/sfc/base/efx_port.c
new file mode 100644 (file)
index 0000000..291a8e9
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2009-2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include "efx.h"
+#include "efx_impl.h"
+
+       __checkReturn   efx_rc_t
+efx_port_init(
+       __in            efx_nic_t *enp)
+{
+       efx_port_t *epp = &(enp->en_port);
+       const efx_phy_ops_t *epop = epp->ep_epop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
+
+       if (enp->en_mod_flags & EFX_MOD_PORT) {
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       enp->en_mod_flags |= EFX_MOD_PORT;
+
+       epp->ep_mac_type = EFX_MAC_INVALID;
+       epp->ep_link_mode = EFX_LINK_UNKNOWN;
+       epp->ep_mac_drain = B_TRUE;
+
+       /* Configure the MAC */
+       if ((rc = efx_mac_select(enp)) != 0)
+               goto fail1;
+
+       epp->ep_emop->emo_reconfigure(enp);
+
+       /* Pick up current phy capababilities */
+       efx_port_poll(enp, NULL);
+
+       /*
+        * Turn on the PHY if available, otherwise reset it, and
+        * reconfigure it with the current configuration.
+        */
+       if (epop->epo_power != NULL) {
+               if ((rc = epop->epo_power(enp, B_TRUE)) != 0)
+                       goto fail2;
+       } else {
+               if ((rc = epop->epo_reset(enp)) != 0)
+                       goto fail2;
+       }
+
+       EFSYS_ASSERT(enp->en_reset_flags & EFX_RESET_PHY);
+       enp->en_reset_flags &= ~EFX_RESET_PHY;
+
+       if ((rc = epop->epo_reconfigure(enp)) != 0)
+               goto fail3;
+
+       return (0);
+
+fail3:
+       EFSYS_PROBE(fail3);
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       enp->en_mod_flags &= ~EFX_MOD_PORT;
+
+       return (rc);
+}
+
+       __checkReturn   efx_rc_t
+efx_port_poll(
+       __in            efx_nic_t *enp,
+       __out_opt       efx_link_mode_t *link_modep)
+{
+       efx_port_t *epp = &(enp->en_port);
+       const efx_mac_ops_t *emop = epp->ep_emop;
+       efx_link_mode_t ignore_link_mode;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+
+       EFSYS_ASSERT(emop != NULL);
+       EFSYS_ASSERT(!epp->ep_mac_stats_pending);
+
+       if (link_modep == NULL)
+               link_modep = &ignore_link_mode;
+
+       if ((rc = emop->emo_poll(enp, link_modep)) != 0)
+               goto fail1;
+
+       return (0);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+                       void
+efx_port_fini(
+       __in            efx_nic_t *enp)
+{
+       efx_port_t *epp = &(enp->en_port);
+       const efx_phy_ops_t *epop = epp->ep_epop;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+
+       EFSYS_ASSERT(epp->ep_mac_drain);
+
+       epp->ep_emop = NULL;
+       epp->ep_mac_type = EFX_MAC_INVALID;
+       epp->ep_mac_drain = B_FALSE;
+
+       /* Turn off the PHY */
+       if (epop->epo_power != NULL)
+               (void) epop->epo_power(enp, B_FALSE);
+
+       enp->en_mod_flags &= ~EFX_MOD_PORT;
+}
diff --git a/drivers/net/sfc/base/efx_rx.c b/drivers/net/sfc/base/efx_rx.c
new file mode 100644 (file)
index 0000000..fd0af87
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2007-2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include "efx.h"
+#include "efx_impl.h"
+
+
+       __checkReturn   efx_rc_t
+efx_rx_init(
+       __inout         efx_nic_t *enp)
+{
+       const efx_rx_ops_t *erxop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
+
+       if (!(enp->en_mod_flags & EFX_MOD_EV)) {
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       if (enp->en_mod_flags & EFX_MOD_RX) {
+               rc = EINVAL;
+               goto fail2;
+       }
+
+       switch (enp->en_family) {
+
+       default:
+               EFSYS_ASSERT(0);
+               rc = ENOTSUP;
+               goto fail3;
+       }
+
+       if ((rc = erxop->erxo_init(enp)) != 0)
+               goto fail4;
+
+       enp->en_erxop = erxop;
+       enp->en_mod_flags |= EFX_MOD_RX;
+       return (0);
+
+fail4:
+       EFSYS_PROBE(fail4);
+fail3:
+       EFSYS_PROBE(fail3);
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       enp->en_erxop = NULL;
+       enp->en_mod_flags &= ~EFX_MOD_RX;
+       return (rc);
+}
+
+                       void
+efx_rx_fini(
+       __in            efx_nic_t *enp)
+{
+       const efx_rx_ops_t *erxop = enp->en_erxop;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
+       EFSYS_ASSERT3U(enp->en_rx_qcount, ==, 0);
+
+       erxop->erxo_fini(enp);
+
+       enp->en_erxop = NULL;
+       enp->en_mod_flags &= ~EFX_MOD_RX;
+}
+
+                       void
+efx_rx_qpost(
+       __in            efx_rxq_t *erp,
+       __in_ecount(n)  efsys_dma_addr_t *addrp,
+       __in            size_t size,
+       __in            unsigned int n,
+       __in            unsigned int completed,
+       __in            unsigned int added)
+{
+       efx_nic_t *enp = erp->er_enp;
+       const efx_rx_ops_t *erxop = enp->en_erxop;
+
+       EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
+
+       erxop->erxo_qpost(erp, addrp, size, n, completed, added);
+}
+
+                       void
+efx_rx_qpush(
+       __in            efx_rxq_t *erp,
+       __in            unsigned int added,
+       __inout         unsigned int *pushedp)
+{
+       efx_nic_t *enp = erp->er_enp;
+       const efx_rx_ops_t *erxop = enp->en_erxop;
+
+       EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
+
+       erxop->erxo_qpush(erp, added, pushedp);
+}
+
+       __checkReturn   efx_rc_t
+efx_rx_qflush(
+       __in            efx_rxq_t *erp)
+{
+       efx_nic_t *enp = erp->er_enp;
+       const efx_rx_ops_t *erxop = enp->en_erxop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
+
+       if ((rc = erxop->erxo_qflush(erp)) != 0)
+               goto fail1;
+
+       return (0);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+                       void
+efx_rx_qenable(
+       __in            efx_rxq_t *erp)
+{
+       efx_nic_t *enp = erp->er_enp;
+       const efx_rx_ops_t *erxop = enp->en_erxop;
+
+       EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
+
+       erxop->erxo_qenable(erp);
+}
+
+       __checkReturn   efx_rc_t
+efx_rx_qcreate(
+       __in            efx_nic_t *enp,
+       __in            unsigned int index,
+       __in            unsigned int label,
+       __in            efx_rxq_type_t type,
+       __in            efsys_mem_t *esmp,
+       __in            size_t n,
+       __in            uint32_t id,
+       __in            efx_evq_t *eep,
+       __deref_out     efx_rxq_t **erpp)
+{
+       const efx_rx_ops_t *erxop = enp->en_erxop;
+       efx_rxq_t *erp;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
+
+       /* Allocate an RXQ object */
+       EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_rxq_t), erp);
+
+       if (erp == NULL) {
+               rc = ENOMEM;
+               goto fail1;
+       }
+
+       erp->er_magic = EFX_RXQ_MAGIC;
+       erp->er_enp = enp;
+       erp->er_index = index;
+       erp->er_mask = n - 1;
+       erp->er_esmp = esmp;
+
+       if ((rc = erxop->erxo_qcreate(enp, index, label, type, esmp, n, id,
+           eep, erp)) != 0)
+               goto fail2;
+
+       enp->en_rx_qcount++;
+       *erpp = erp;
+
+       return (0);
+
+fail2:
+       EFSYS_PROBE(fail2);
+
+       EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+                       void
+efx_rx_qdestroy(
+       __in            efx_rxq_t *erp)
+{
+       efx_nic_t *enp = erp->er_enp;
+       const efx_rx_ops_t *erxop = enp->en_erxop;
+
+       EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
+
+       erxop->erxo_qdestroy(erp);
+}
+
+       __checkReturn   efx_rc_t
+efx_pseudo_hdr_pkt_length_get(
+       __in            efx_rxq_t *erp,
+       __in            uint8_t *buffer,
+       __out           uint16_t *lengthp)
+{
+       efx_nic_t *enp = erp->er_enp;
+       const efx_rx_ops_t *erxop = enp->en_erxop;
+
+       EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
+
+       return (erxop->erxo_prefix_pktlen(enp, buffer, lengthp));
+}
+
diff --git a/drivers/net/sfc/base/efx_sram.c b/drivers/net/sfc/base/efx_sram.c
new file mode 100644 (file)
index 0000000..0f16376
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2007-2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include "efx.h"
+#include "efx_impl.h"
+
+       __checkReturn   efx_rc_t
+efx_sram_buf_tbl_set(
+       __in            efx_nic_t *enp,
+       __in            uint32_t id,
+       __in            efsys_mem_t *esmp,
+       __in            size_t n)
+{
+       efx_qword_t qword;
+       uint32_t start = id;
+       uint32_t stop = start + n;
+       efsys_dma_addr_t addr;
+       efx_oword_t oword;
+       unsigned int count;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
+
+       if (stop >= EFX_BUF_TBL_SIZE) {
+               rc = EFBIG;
+               goto fail1;
+       }
+
+       /* Add the entries into the buffer table */
+       addr = EFSYS_MEM_ADDR(esmp);
+       for (id = start; id != stop; id++) {
+               EFX_POPULATE_QWORD_5(qword,
+                   FRF_AZ_IP_DAT_BUF_SIZE, 0, FRF_AZ_BUF_ADR_REGION, 0,
+                   FRF_AZ_BUF_ADR_FBUF_DW0,
+                   (uint32_t)((addr >> 12) & 0xffffffff),
+                   FRF_AZ_BUF_ADR_FBUF_DW1,
+                   (uint32_t)((addr >> 12) >> 32),
+                   FRF_AZ_BUF_OWNER_ID_FBUF, 0);
+
+               EFX_BAR_TBL_WRITEQ(enp, FR_AZ_BUF_FULL_TBL,
+                                   id, &qword);
+
+               addr += EFX_BUF_SIZE;
+       }
+
+       EFSYS_PROBE2(buf, uint32_t, start, uint32_t, stop - 1);
+
+       /* Flush the write buffer */
+       EFX_POPULATE_OWORD_2(oword, FRF_AZ_BUF_UPD_CMD, 1,
+           FRF_AZ_BUF_CLR_CMD, 0);
+       EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_UPD_REG, &oword);
+
+       /* Poll for the last entry being written to the buffer table */
+       EFSYS_ASSERT3U(id, ==, stop);
+       addr -= EFX_BUF_SIZE;
+
+       count = 0;
+       do {
+               EFSYS_PROBE1(wait, unsigned int, count);
+
+               /* Spin for 1 ms */
+               EFSYS_SPIN(1000);
+
+               EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_FULL_TBL,
+                                   id - 1, &qword);
+
+               if (EFX_QWORD_FIELD(qword, FRF_AZ_BUF_ADR_FBUF_DW0) ==
+                   (uint32_t)((addr >> 12) & 0xffffffff) &&
+                   EFX_QWORD_FIELD(qword, FRF_AZ_BUF_ADR_FBUF_DW1) ==
+                   (uint32_t)((addr >> 12) >> 32))
+                       goto verify;
+
+       } while (++count < 100);
+
+       rc = ETIMEDOUT;
+       goto fail2;
+
+verify:
+       /* Verify the rest of the entries in the buffer table */
+       while (--id != start) {
+               addr -= EFX_BUF_SIZE;
+
+               /* Read the buffer table entry */
+               EFX_BAR_TBL_READQ(enp, FR_AZ_BUF_FULL_TBL,
+                                   id - 1, &qword);
+
+               if (EFX_QWORD_FIELD(qword, FRF_AZ_BUF_ADR_FBUF_DW0) !=
+                   (uint32_t)((addr >> 12) & 0xffffffff) ||
+                   EFX_QWORD_FIELD(qword, FRF_AZ_BUF_ADR_FBUF_DW1) !=
+                   (uint32_t)((addr >> 12) >> 32)) {
+                       rc = EFAULT;
+                       goto fail3;
+               }
+       }
+
+       return (0);
+
+fail3:
+       EFSYS_PROBE(fail3);
+
+       id = stop;
+
+fail2:
+       EFSYS_PROBE(fail2);
+
+       EFX_POPULATE_OWORD_4(oword, FRF_AZ_BUF_UPD_CMD, 0,
+           FRF_AZ_BUF_CLR_CMD, 1, FRF_AZ_BUF_CLR_END_ID, id - 1,
+           FRF_AZ_BUF_CLR_START_ID, start);
+       EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_UPD_REG, &oword);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       return (rc);
+}
+
+               void
+efx_sram_buf_tbl_clear(
+       __in    efx_nic_t *enp,
+       __in    uint32_t id,
+       __in    size_t n)
+{
+       efx_oword_t oword;
+       uint32_t start = id;
+       uint32_t stop = start + n;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
+
+       EFSYS_ASSERT3U(stop, <, EFX_BUF_TBL_SIZE);
+
+       EFSYS_PROBE2(buf, uint32_t, start, uint32_t, stop - 1);
+
+       EFX_POPULATE_OWORD_4(oword, FRF_AZ_BUF_UPD_CMD, 0,
+           FRF_AZ_BUF_CLR_CMD, 1, FRF_AZ_BUF_CLR_END_ID, stop - 1,
+           FRF_AZ_BUF_CLR_START_ID, start);
+       EFX_BAR_WRITEO(enp, FR_AZ_BUF_TBL_UPD_REG, &oword);
+}
+
+
diff --git a/drivers/net/sfc/base/efx_tx.c b/drivers/net/sfc/base/efx_tx.c
new file mode 100644 (file)
index 0000000..4f0099f
--- /dev/null
@@ -0,0 +1,463 @@
+/*
+ * Copyright (c) 2007-2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ */
+
+#include "efx.h"
+#include "efx_impl.h"
+
+#define        EFX_TX_QSTAT_INCR(_etp, _stat)
+
+
+       __checkReturn   efx_rc_t
+efx_tx_init(
+       __in            efx_nic_t *enp)
+{
+       const efx_tx_ops_t *etxop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
+
+       if (!(enp->en_mod_flags & EFX_MOD_EV)) {
+               rc = EINVAL;
+               goto fail1;
+       }
+
+       if (enp->en_mod_flags & EFX_MOD_TX) {
+               rc = EINVAL;
+               goto fail2;
+       }
+
+       switch (enp->en_family) {
+
+       default:
+               EFSYS_ASSERT(0);
+               rc = ENOTSUP;
+               goto fail3;
+       }
+
+       EFSYS_ASSERT3U(enp->en_tx_qcount, ==, 0);
+
+       if ((rc = etxop->etxo_init(enp)) != 0)
+               goto fail4;
+
+       enp->en_etxop = etxop;
+       enp->en_mod_flags |= EFX_MOD_TX;
+       return (0);
+
+fail4:
+       EFSYS_PROBE(fail4);
+fail3:
+       EFSYS_PROBE(fail3);
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+       enp->en_etxop = NULL;
+       enp->en_mod_flags &= ~EFX_MOD_TX;
+       return (rc);
+}
+
+                       void
+efx_tx_fini(
+       __in    efx_nic_t *enp)
+{
+       const efx_tx_ops_t *etxop = enp->en_etxop;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX);
+       EFSYS_ASSERT3U(enp->en_tx_qcount, ==, 0);
+
+       etxop->etxo_fini(enp);
+
+       enp->en_etxop = NULL;
+       enp->en_mod_flags &= ~EFX_MOD_TX;
+}
+
+       __checkReturn   efx_rc_t
+efx_tx_qcreate(
+       __in            efx_nic_t *enp,
+       __in            unsigned int index,
+       __in            unsigned int label,
+       __in            efsys_mem_t *esmp,
+       __in            size_t n,
+       __in            uint32_t id,
+       __in            uint16_t flags,
+       __in            efx_evq_t *eep,
+       __deref_out     efx_txq_t **etpp,
+       __out           unsigned int *addedp)
+{
+       const efx_tx_ops_t *etxop = enp->en_etxop;
+       efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+       efx_txq_t *etp;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+       EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX);
+
+       EFSYS_ASSERT3U(enp->en_tx_qcount + 1, <, encp->enc_txq_limit);
+
+       /* Allocate an TXQ object */
+       EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_txq_t), etp);
+
+       if (etp == NULL) {
+               rc = ENOMEM;
+               goto fail1;
+       }
+
+       etp->et_magic = EFX_TXQ_MAGIC;
+       etp->et_enp = enp;
+       etp->et_index = index;
+       etp->et_mask = n - 1;
+       etp->et_esmp = esmp;
+
+       /* Initial descriptor index may be modified by etxo_qcreate */
+       *addedp = 0;
+
+       if ((rc = etxop->etxo_qcreate(enp, index, label, esmp,
+           n, id, flags, eep, etp, addedp)) != 0)
+               goto fail2;
+
+       enp->en_tx_qcount++;
+       *etpp = etp;
+
+       return (0);
+
+fail2:
+       EFSYS_PROBE(fail2);
+       EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_txq_t), etp);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       return (rc);
+}
+
+               void
+efx_tx_qdestroy(
+       __in    efx_txq_t *etp)
+{
+       efx_nic_t *enp = etp->et_enp;
+       const efx_tx_ops_t *etxop = enp->en_etxop;
+
+       EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+       EFSYS_ASSERT(enp->en_tx_qcount != 0);
+       --enp->en_tx_qcount;
+
+       etxop->etxo_qdestroy(etp);
+
+       /* Free the TXQ object */
+       EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_txq_t), etp);
+}
+
+       __checkReturn   efx_rc_t
+efx_tx_qpost(
+       __in            efx_txq_t *etp,
+       __in_ecount(n)  efx_buffer_t *eb,
+       __in            unsigned int n,
+       __in            unsigned int completed,
+       __inout         unsigned int *addedp)
+{
+       efx_nic_t *enp = etp->et_enp;
+       const efx_tx_ops_t *etxop = enp->en_etxop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+       if ((rc = etxop->etxo_qpost(etp, eb,
+           n, completed, addedp)) != 0)
+               goto fail1;
+
+       return (0);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       return (rc);
+}
+
+                       void
+efx_tx_qpush(
+       __in    efx_txq_t *etp,
+       __in    unsigned int added,
+       __in    unsigned int pushed)
+{
+       efx_nic_t *enp = etp->et_enp;
+       const efx_tx_ops_t *etxop = enp->en_etxop;
+
+       EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+       etxop->etxo_qpush(etp, added, pushed);
+}
+
+       __checkReturn   efx_rc_t
+efx_tx_qpace(
+       __in            efx_txq_t *etp,
+       __in            unsigned int ns)
+{
+       efx_nic_t *enp = etp->et_enp;
+       const efx_tx_ops_t *etxop = enp->en_etxop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+       if ((rc = etxop->etxo_qpace(etp, ns)) != 0)
+               goto fail1;
+
+       return (0);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       return (rc);
+}
+
+       __checkReturn   efx_rc_t
+efx_tx_qflush(
+       __in    efx_txq_t *etp)
+{
+       efx_nic_t *enp = etp->et_enp;
+       const efx_tx_ops_t *etxop = enp->en_etxop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+       if ((rc = etxop->etxo_qflush(etp)) != 0)
+               goto fail1;
+
+       return (0);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       return (rc);
+}
+
+                       void
+efx_tx_qenable(
+       __in    efx_txq_t *etp)
+{
+       efx_nic_t *enp = etp->et_enp;
+       const efx_tx_ops_t *etxop = enp->en_etxop;
+
+       EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+       etxop->etxo_qenable(etp);
+}
+
+       __checkReturn   efx_rc_t
+efx_tx_qpio_enable(
+       __in    efx_txq_t *etp)
+{
+       efx_nic_t *enp = etp->et_enp;
+       const efx_tx_ops_t *etxop = enp->en_etxop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+       if (~enp->en_features & EFX_FEATURE_PIO_BUFFERS) {
+               rc = ENOTSUP;
+               goto fail1;
+       }
+       if (etxop->etxo_qpio_enable == NULL) {
+               rc = ENOTSUP;
+               goto fail2;
+       }
+       if ((rc = etxop->etxo_qpio_enable(etp)) != 0)
+               goto fail3;
+
+       return (0);
+
+fail3:
+       EFSYS_PROBE(fail3);
+fail2:
+       EFSYS_PROBE(fail2);
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       return (rc);
+}
+
+               void
+efx_tx_qpio_disable(
+       __in    efx_txq_t *etp)
+{
+       efx_nic_t *enp = etp->et_enp;
+       const efx_tx_ops_t *etxop = enp->en_etxop;
+
+       EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+       if (etxop->etxo_qpio_disable != NULL)
+               etxop->etxo_qpio_disable(etp);
+}
+
+       __checkReturn   efx_rc_t
+efx_tx_qpio_write(
+       __in                    efx_txq_t *etp,
+       __in_ecount(buf_length) uint8_t *buffer,
+       __in                    size_t buf_length,
+       __in                    size_t pio_buf_offset)
+{
+       efx_nic_t *enp = etp->et_enp;
+       const efx_tx_ops_t *etxop = enp->en_etxop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+       if (etxop->etxo_qpio_write != NULL) {
+               if ((rc = etxop->etxo_qpio_write(etp, buffer, buf_length,
+                                               pio_buf_offset)) != 0)
+                       goto fail1;
+               return (0);
+       }
+
+       return (ENOTSUP);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       return (rc);
+}
+
+       __checkReturn   efx_rc_t
+efx_tx_qpio_post(
+       __in                    efx_txq_t *etp,
+       __in                    size_t pkt_length,
+       __in                    unsigned int completed,
+       __inout                 unsigned int *addedp)
+{
+       efx_nic_t *enp = etp->et_enp;
+       const efx_tx_ops_t *etxop = enp->en_etxop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+       if (etxop->etxo_qpio_post != NULL) {
+               if ((rc = etxop->etxo_qpio_post(etp, pkt_length, completed,
+                                               addedp)) != 0)
+                       goto fail1;
+               return (0);
+       }
+
+       return (ENOTSUP);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       return (rc);
+}
+
+       __checkReturn   efx_rc_t
+efx_tx_qdesc_post(
+       __in            efx_txq_t *etp,
+       __in_ecount(n)  efx_desc_t *ed,
+       __in            unsigned int n,
+       __in            unsigned int completed,
+       __inout         unsigned int *addedp)
+{
+       efx_nic_t *enp = etp->et_enp;
+       const efx_tx_ops_t *etxop = enp->en_etxop;
+       efx_rc_t rc;
+
+       EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+       if ((rc = etxop->etxo_qdesc_post(etp, ed,
+           n, completed, addedp)) != 0)
+               goto fail1;
+
+       return (0);
+
+fail1:
+       EFSYS_PROBE1(fail1, efx_rc_t, rc);
+       return (rc);
+}
+
+       void
+efx_tx_qdesc_dma_create(
+       __in    efx_txq_t *etp,
+       __in    efsys_dma_addr_t addr,
+       __in    size_t size,
+       __in    boolean_t eop,
+       __out   efx_desc_t *edp)
+{
+       efx_nic_t *enp = etp->et_enp;
+       const efx_tx_ops_t *etxop = enp->en_etxop;
+
+       EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+       EFSYS_ASSERT(etxop->etxo_qdesc_dma_create != NULL);
+
+       etxop->etxo_qdesc_dma_create(etp, addr, size, eop, edp);
+}
+
+       void
+efx_tx_qdesc_tso_create(
+       __in    efx_txq_t *etp,
+       __in    uint16_t ipv4_id,
+       __in    uint32_t tcp_seq,
+       __in    uint8_t  tcp_flags,
+       __out   efx_desc_t *edp)
+{
+       efx_nic_t *enp = etp->et_enp;
+       const efx_tx_ops_t *etxop = enp->en_etxop;
+
+       EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+       EFSYS_ASSERT(etxop->etxo_qdesc_tso_create != NULL);
+
+       etxop->etxo_qdesc_tso_create(etp, ipv4_id, tcp_seq, tcp_flags, edp);
+}
+
+       void
+efx_tx_qdesc_tso2_create(
+       __in                    efx_txq_t *etp,
+       __in                    uint16_t ipv4_id,
+       __in                    uint32_t tcp_seq,
+       __in                    uint16_t mss,
+       __out_ecount(count)     efx_desc_t *edp,
+       __in                    int count)
+{
+       efx_nic_t *enp = etp->et_enp;
+       const efx_tx_ops_t *etxop = enp->en_etxop;
+
+       EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+       EFSYS_ASSERT(etxop->etxo_qdesc_tso2_create != NULL);
+
+       etxop->etxo_qdesc_tso2_create(etp, ipv4_id, tcp_seq, mss, edp, count);
+}
+
+       void
+efx_tx_qdesc_vlantci_create(
+       __in    efx_txq_t *etp,
+       __in    uint16_t tci,
+       __out   efx_desc_t *edp)
+{
+       efx_nic_t *enp = etp->et_enp;
+       const efx_tx_ops_t *etxop = enp->en_etxop;
+
+       EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+       EFSYS_ASSERT(etxop->etxo_qdesc_vlantci_create != NULL);
+
+       etxop->etxo_qdesc_vlantci_create(etp, tci, edp);
+}
+
+
diff --git a/drivers/net/sfc/base/efx_types.h b/drivers/net/sfc/base/efx_types.h
new file mode 100644 (file)
index 0000000..b8ee14a
--- /dev/null
@@ -0,0 +1,1647 @@
+/*
+ * Copyright (c) 2007-2016 Solarflare Communications Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of the FreeBSD Project.
+ *
+ * Ackowledgement to Fen Systems Ltd.
+ */
+
+#ifndef        _SYS_EFX_TYPES_H
+#define        _SYS_EFX_TYPES_H
+
+#include "efsys.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Bitfield access
+ *
+ * Solarflare NICs make extensive use of bitfields up to 128 bits
+ * wide.  Since there is no native 128-bit datatype on most systems,
+ * and since 64-bit datatypes are inefficient on 32-bit systems and
+ * vice versa, we wrap accesses in a way that uses the most efficient
+ * datatype.
+ *
+ * The NICs are PCI devices and therefore little-endian.  Since most
+ * of the quantities that we deal with are DMAed to/from host memory,
+ * we define   our datatypes (efx_oword_t, efx_qword_t and efx_dword_t)
+ * to be little-endian.
+ *
+ * In the less common case of using PIO for individual register
+ * writes, we construct the little-endian datatype in host memory and
+ * then use non-swapping register access primitives, rather than
+ * constructing a native-endian datatype and relying on implicit
+ * byte-swapping.  (We use a similar strategy for register reads.)
+ */
+
+/*
+ * NOTE: Field definitions here and elsewhere are done in terms of a lowest
+ *       bit number (LBN) and a width.
+ */
+
+#define        EFX_DUMMY_FIELD_LBN 0
+#define        EFX_DUMMY_FIELD_WIDTH 0
+
+#define        EFX_BYTE_0_LBN 0
+#define        EFX_BYTE_0_WIDTH 8
+
+#define        EFX_BYTE_1_LBN 8
+#define        EFX_BYTE_1_WIDTH 8
+
+#define        EFX_BYTE_2_LBN 16
+#define        EFX_BYTE_2_WIDTH 8
+
+#define        EFX_BYTE_3_LBN 24
+#define        EFX_BYTE_3_WIDTH 8
+
+#define        EFX_BYTE_4_LBN 32
+#define        EFX_BYTE_4_WIDTH 8
+
+#define        EFX_BYTE_5_LBN 40
+#define        EFX_BYTE_5_WIDTH 8
+
+#define        EFX_BYTE_6_LBN 48
+#define        EFX_BYTE_6_WIDTH 8
+
+#define        EFX_BYTE_7_LBN 56
+#define        EFX_BYTE_7_WIDTH 8
+
+#define        EFX_WORD_0_LBN 0
+#define        EFX_WORD_0_WIDTH 16
+
+#define        EFX_WORD_1_LBN 16
+#define        EFX_WORD_1_WIDTH 16
+
+#define        EFX_WORD_2_LBN 32
+#define        EFX_WORD_2_WIDTH 16
+
+#define        EFX_WORD_3_LBN 48
+#define        EFX_WORD_3_WIDTH 16
+
+#define        EFX_DWORD_0_LBN 0
+#define        EFX_DWORD_0_WIDTH 32
+
+#define        EFX_DWORD_1_LBN 32
+#define        EFX_DWORD_1_WIDTH 32
+
+#define        EFX_DWORD_2_LBN 64
+#define        EFX_DWORD_2_WIDTH 32
+
+#define        EFX_DWORD_3_LBN 96
+#define        EFX_DWORD_3_WIDTH 32
+
+/* There are intentionally no EFX_QWORD_0 or EFX_QWORD_1 field definitions
+ * here as the implementaion of EFX_QWORD_FIELD and EFX_OWORD_FIELD do not
+ * support field widths larger than 32 bits.
+ */
+
+/* Specified attribute (i.e. LBN ow WIDTH) of the specified field */
+#define        EFX_VAL(_field, _attribute)                                     \
+       _field ## _ ## _attribute
+
+/* Lowest bit number of the specified field */
+#define        EFX_LOW_BIT(_field)                                             \
+       EFX_VAL(_field, LBN)
+
+/* Width of the specified field */
+#define        EFX_WIDTH(_field)                                               \
+       EFX_VAL(_field, WIDTH)
+
+/* Highest bit number of the specified field */
+#define        EFX_HIGH_BIT(_field)                                            \
+       (EFX_LOW_BIT(_field) + EFX_WIDTH(_field) - 1)
+
+/*
+ * 64-bit mask equal in width to the specified field.
+ *
+ * For example, a field with width 5 would have a mask of 0x000000000000001f.
+ */
+#define        EFX_MASK64(_field)                                              \
+       ((EFX_WIDTH(_field) == 64) ? ~((uint64_t)0) :                   \
+           (((((uint64_t)1) << EFX_WIDTH(_field))) - 1))
+/*
+ * 32-bit mask equal in width to the specified field.
+ *
+ * For example, a field with width 5 would have a mask of 0x0000001f.
+ */
+#define        EFX_MASK32(_field)                                              \
+       ((EFX_WIDTH(_field) == 32) ? ~((uint32_t)0) :                   \
+           (((((uint32_t)1) << EFX_WIDTH(_field))) - 1))
+
+/*
+ * 16-bit mask equal in width to the specified field.
+ *
+ * For example, a field with width 5 would have a mask of 0x001f.
+ */
+#define        EFX_MASK16(_field)                                              \
+       ((EFX_WIDTH(_field) == 16) ? 0xffffu :                          \
+           (uint16_t)((1 << EFX_WIDTH(_field)) - 1))
+
+/*
+ * 8-bit mask equal in width to the specified field.
+ *
+ * For example, a field with width 5 would have a mask of 0x1f.
+ */
+#define        EFX_MASK8(_field)                                               \
+       ((uint8_t)((1 << EFX_WIDTH(_field)) - 1))
+
+#pragma pack(1)
+
+/*
+ * A byte (i.e. 8-bit) datatype
+ */
+typedef union efx_byte_u {
+       uint8_t eb_u8[1];
+} efx_byte_t;
+
+/*
+ * A word (i.e. 16-bit) datatype
+ *
+ * This datatype is defined to be little-endian.
+ */
+typedef union efx_word_u {
+       efx_byte_t ew_byte[2];
+       uint16_t ew_u16[1];
+       uint8_t ew_u8[2];
+} efx_word_t;
+
+/*
+ * A doubleword (i.e. 32-bit) datatype
+ *
+ * This datatype is defined to be little-endian.
+ */
+typedef union efx_dword_u {
+       efx_byte_t ed_byte[4];
+       efx_word_t ed_word[2];
+       uint32_t ed_u32[1];
+       uint16_t ed_u16[2];
+       uint8_t ed_u8[4];
+} efx_dword_t;
+
+/*
+ * A quadword (i.e. 64-bit) datatype
+ *
+ * This datatype is defined to be little-endian.
+ */
+typedef union efx_qword_u {
+       efx_byte_t eq_byte[8];
+       efx_word_t eq_word[4];
+       efx_dword_t eq_dword[2];
+#if EFSYS_HAS_UINT64
+       uint64_t eq_u64[1];
+#endif
+       uint32_t eq_u32[2];
+       uint16_t eq_u16[4];
+       uint8_t eq_u8[8];
+} efx_qword_t;
+
+/*
+ * An octword (i.e. 128-bit) datatype
+ *
+ * This datatype is defined to be little-endian.
+ */
+typedef union efx_oword_u {
+       efx_byte_t eo_byte[16];
+       efx_word_t eo_word[8];
+       efx_dword_t eo_dword[4];
+       efx_qword_t eo_qword[2];
+#if EFSYS_HAS_SSE2_M128
+       __m128i eo_u128[1];
+#endif
+#if EFSYS_HAS_UINT64
+       uint64_t eo_u64[2];
+#endif
+       uint32_t eo_u32[4];
+       uint16_t eo_u16[8];
+       uint8_t eo_u8[16];
+} efx_oword_t;
+
+#pragma pack()
+
+#define        __SWAP16(_x)                            \
+       ((((_x) & 0xff) << 8) |                 \
+       (((_x) >> 8) & 0xff))
+
+#define        __SWAP32(_x)                            \
+       ((__SWAP16((_x) & 0xffff) << 16) |      \
+       __SWAP16(((_x) >> 16) & 0xffff))
+
+#define        __SWAP64(_x)                            \
+       ((__SWAP32((_x) & 0xffffffff) << 32) |  \
+       __SWAP32(((_x) >> 32) & 0xffffffff))
+
+#define        __NOSWAP16(_x)          (_x)
+#define        __NOSWAP32(_x)          (_x)
+#define        __NOSWAP64(_x)          (_x)
+
+#if EFSYS_IS_BIG_ENDIAN
+
+#define        __CPU_TO_LE_16(_x)      ((uint16_t)__SWAP16(_x))
+#define        __LE_TO_CPU_16(_x)      ((uint16_t)__SWAP16(_x))
+#define        __CPU_TO_BE_16(_x)      ((uint16_t)__NOSWAP16(_x))
+#define        __BE_TO_CPU_16(_x)      ((uint16_t)__NOSWAP16(_x))
+
+#define        __CPU_TO_LE_32(_x)      ((uint32_t)__SWAP32(_x))
+#define        __LE_TO_CPU_32(_x)      ((uint32_t)__SWAP32(_x))
+#define        __CPU_TO_BE_32(_x)      ((uint32_t)__NOSWAP32(_x))
+#define        __BE_TO_CPU_32(_x)      ((uint32_t)__NOSWAP32(_x))
+
+#define        __CPU_TO_LE_64(_x)      ((uint64_t)__SWAP64(_x))
+#define        __LE_TO_CPU_64(_x)      ((uint64_t)__SWAP64(_x))
+#define        __CPU_TO_BE_64(_x)      ((uint64_t)__NOSWAP64(_x))
+#define        __BE_TO_CPU_64(_x)      ((uint64_t)__NOSWAP64(_x))
+
+#elif EFSYS_IS_LITTLE_ENDIAN
+
+#define        __CPU_TO_LE_16(_x)      ((uint16_t)__NOSWAP16(_x))
+#define        __LE_TO_CPU_16(_x)      ((uint16_t)__NOSWAP16(_x))
+#define        __CPU_TO_BE_16(_x)      ((uint16_t)__SWAP16(_x))
+#define        __BE_TO_CPU_16(_x)      ((uint16_t)__SWAP16(_x))
+
+#define        __CPU_TO_LE_32(_x)      ((uint32_t)__NOSWAP32(_x))
+#define        __LE_TO_CPU_32(_x)      ((uint32_t)__NOSWAP32(_x))
+#define        __CPU_TO_BE_32(_x)      ((uint32_t)__SWAP32(_x))
+#define        __BE_TO_CPU_32(_x)      ((uint32_t)__SWAP32(_x))
+
+#define        __CPU_TO_LE_64(_x)      ((uint64_t)__NOSWAP64(_x))
+#define        __LE_TO_CPU_64(_x)      ((uint64_t)__NOSWAP64(_x))
+#define        __CPU_TO_BE_64(_x)      ((uint64_t)__SWAP64(_x))
+#define        __BE_TO_CPU_64(_x)      ((uint64_t)__SWAP64(_x))
+
+#else
+
+#error "Neither of EFSYS_IS_{BIG,LITTLE}_ENDIAN is set"
+
+#endif
+
+#define        __NATIVE_8(_x)  (uint8_t)(_x)
+
+/* Format string for printing an efx_byte_t */
+#define        EFX_BYTE_FMT "0x%02x"
+
+/* Format string for printing an efx_word_t */
+#define        EFX_WORD_FMT "0x%04x"
+
+/* Format string for printing an efx_dword_t */
+#define        EFX_DWORD_FMT "0x%08x"
+
+/* Format string for printing an efx_qword_t */
+#define        EFX_QWORD_FMT "0x%08x:%08x"
+
+/* Format string for printing an efx_oword_t */
+#define        EFX_OWORD_FMT "0x%08x:%08x:%08x:%08x"
+
+/* Parameters for printing an efx_byte_t */
+#define        EFX_BYTE_VAL(_byte)                                     \
+       ((unsigned int)__NATIVE_8((_byte).eb_u8[0]))
+
+/* Parameters for printing an efx_word_t */
+#define        EFX_WORD_VAL(_word)                                     \
+       ((unsigned int)__LE_TO_CPU_16((_word).ew_u16[0]))
+
+/* Parameters for printing an efx_dword_t */
+#define        EFX_DWORD_VAL(_dword)                                   \
+       ((unsigned int)__LE_TO_CPU_32((_dword).ed_u32[0]))
+
+/* Parameters for printing an efx_qword_t */
+#define        EFX_QWORD_VAL(_qword)                                   \
+       ((unsigned int)__LE_TO_CPU_32((_qword).eq_u32[1])),     \
+       ((unsigned int)__LE_TO_CPU_32((_qword).eq_u32[0]))
+
+/* Parameters for printing an efx_oword_t */
+#define        EFX_OWORD_VAL(_oword)                                   \
+       ((unsigned int)__LE_TO_CPU_32((_oword).eo_u32[3])),     \
+       ((unsigned int)__LE_TO_CPU_32((_oword).eo_u32[2])),     \
+       ((unsigned int)__LE_TO_CPU_32((_oword).eo_u32[1])),     \
+       ((unsigned int)__LE_TO_CPU_32((_oword).eo_u32[0]))
+
+/*
+ * Stop lint complaining about some shifts.
+ */
+#ifdef __lint
+extern int fix_lint;
+#define        FIX_LINT(_x)    (_x + fix_lint)
+#else
+#define        FIX_LINT(_x)    (_x)
+#endif
+
+/*
+ * Extract bit field portion [low,high) from the native-endian element
+ * which contains bits [min,max).
+ *
+ * For example, suppose "element" represents the high 32 bits of a
+ * 64-bit value, and we wish to extract the bits belonging to the bit
+ * field occupying bits 28-45 of this 64-bit value.
+ *
+ * Then EFX_EXTRACT(_element, 32, 63, 28, 45) would give
+ *
+ *   (_element) << 4
+ *
+ * The result will contain the relevant bits filled in in the range
+ * [0,high-low), with garbage in bits [high-low+1,...).
+ */
+#define        EFX_EXTRACT_NATIVE(_element, _min, _max, _low, _high)           \
+       ((FIX_LINT(_low > _max) || FIX_LINT(_high < _min)) ?            \
+               0U :                                                    \
+               ((_low > _min) ?                                        \
+                       ((_element) >> (_low - _min)) :                 \
+                       ((_element) << (_min - _low))))
+
+/*
+ * Extract bit field portion [low,high) from the 64-bit little-endian
+ * element which contains bits [min,max)
+ */
+#define        EFX_EXTRACT64(_element, _min, _max, _low, _high)                \
+       EFX_EXTRACT_NATIVE(__LE_TO_CPU_64(_element), _min, _max, _low, _high)
+
+/*
+ * Extract bit field portion [low,high) from the 32-bit little-endian
+ * element which contains bits [min,max)
+ */
+#define        EFX_EXTRACT32(_element, _min, _max, _low, _high)                \
+       EFX_EXTRACT_NATIVE(__LE_TO_CPU_32(_element), _min, _max, _low, _high)
+
+/*
+ * Extract bit field portion [low,high) from the 16-bit little-endian
+ * element which contains bits [min,max)
+ */
+#define        EFX_EXTRACT16(_element, _min, _max, _low, _high)                \
+       EFX_EXTRACT_NATIVE(__LE_TO_CPU_16(_element), _min, _max, _low, _high)
+
+/*
+ * Extract bit field portion [low,high) from the 8-bit
+ * element which contains bits [min,max)
+ */
+#define        EFX_EXTRACT8(_element, _min, _max, _low, _high)                 \
+       EFX_EXTRACT_NATIVE(__NATIVE_8(_element), _min, _max, _low, _high)
+
+#define        EFX_EXTRACT_OWORD64(_oword, _low, _high)                        \
+       (EFX_EXTRACT64((_oword).eo_u64[0], FIX_LINT(0), FIX_LINT(63),   \
+           _low, _high) |                                              \
+       EFX_EXTRACT64((_oword).eo_u64[1], FIX_LINT(64), FIX_LINT(127),  \
+           _low, _high))
+
+#define        EFX_EXTRACT_OWORD32(_oword, _low, _high)                        \
+       (EFX_EXTRACT32((_oword).eo_u32[0], FIX_LINT(0), FIX_LINT(31),   \
+           _low, _high) |                                              \
+       EFX_EXTRACT32((_oword).eo_u32[1], FIX_LINT(32), FIX_LINT(63),   \
+           _low, _high) |                                              \
+       EFX_EXTRACT32((_oword).eo_u32[2], FIX_LINT(64), FIX_LINT(95),   \
+           _low, _high) |                                              \
+       EFX_EXTRACT32((_oword).eo_u32[3], FIX_LINT(96), FIX_LINT(127),  \
+           _low, _high))
+
+#define        EFX_EXTRACT_QWORD64(_qword, _low, _high)                        \
+       (EFX_EXTRACT64((_qword).eq_u64[0], FIX_LINT(0), FIX_LINT(63),   \
+           _low, _high))
+
+#define        EFX_EXTRACT_QWORD32(_qword, _low, _high)                        \
+       (EFX_EXTRACT32((_qword).eq_u32[0], FIX_LINT(0), FIX_LINT(31),   \
+           _low, _high) |                                              \
+       EFX_EXTRACT32((_qword).eq_u32[1], FIX_LINT(32), FIX_LINT(63),   \
+           _low, _high))
+
+#define        EFX_EXTRACT_DWORD(_dword, _low, _high)                          \
+       (EFX_EXTRACT32((_dword).ed_u32[0], FIX_LINT(0), FIX_LINT(31),   \
+           _low, _high))
+
+#define        EFX_EXTRACT_WORD(_word, _low, _high)                            \
+       (EFX_EXTRACT16((_word).ew_u16[0], FIX_LINT(0), FIX_LINT(15),    \
+           _low, _high))
+
+#define        EFX_EXTRACT_BYTE(_byte, _low, _high)                            \
+       (EFX_EXTRACT8((_byte).eb_u8[0], FIX_LINT(0), FIX_LINT(7),       \
+           _low, _high))
+
+
+#define        EFX_OWORD_FIELD64(_oword, _field)                               \
+       ((uint32_t)EFX_EXTRACT_OWORD64(_oword, EFX_LOW_BIT(_field),     \
+           EFX_HIGH_BIT(_field)) & EFX_MASK32(_field))
+
+#define        EFX_OWORD_FIELD32(_oword, _field)                               \
+       (EFX_EXTRACT_OWORD32(_oword, EFX_LOW_BIT(_field),               \
+           EFX_HIGH_BIT(_field)) & EFX_MASK32(_field))
+
+#define        EFX_QWORD_FIELD64(_qword, _field)                               \
+       ((uint32_t)EFX_EXTRACT_QWORD64(_qword, EFX_LOW_BIT(_field),     \
+           EFX_HIGH_BIT(_field)) & EFX_MASK32(_field))
+
+#define        EFX_QWORD_FIELD32(_qword, _field)                               \
+       (EFX_EXTRACT_QWORD32(_qword, EFX_LOW_BIT(_field),               \
+           EFX_HIGH_BIT(_field)) & EFX_MASK32(_field))
+
+#define        EFX_DWORD_FIELD(_dword, _field)                                 \
+       (EFX_EXTRACT_DWORD(_dword, EFX_LOW_BIT(_field),                 \
+           EFX_HIGH_BIT(_field)) & EFX_MASK32(_field))
+
+#define        EFX_WORD_FIELD(_word, _field)                                   \
+       (EFX_EXTRACT_WORD(_word, EFX_LOW_BIT(_field),                   \
+           EFX_HIGH_BIT(_field)) & EFX_MASK16(_field))
+
+#define        EFX_BYTE_FIELD(_byte, _field)                                   \
+       (EFX_EXTRACT_BYTE(_byte, EFX_LOW_BIT(_field),                   \
+           EFX_HIGH_BIT(_field)) & EFX_MASK8(_field))
+
+
+#define        EFX_OWORD_IS_EQUAL64(_oword_a, _oword_b)                        \
+       ((_oword_a).eo_u64[0] == (_oword_b).eo_u64[0] &&                \
+           (_oword_a).eo_u64[1] == (_oword_b).eo_u64[1])
+
+#define        EFX_OWORD_IS_EQUAL32(_oword_a, _oword_b)                        \
+       ((_oword_a).eo_u32[0] == (_oword_b).eo_u32[0] &&                \
+           (_oword_a).eo_u32[1] == (_oword_b).eo_u32[1] &&             \
+           (_oword_a).eo_u32[2] == (_oword_b).eo_u32[2] &&             \
+           (_oword_a).eo_u32[3] == (_oword_b).eo_u32[3])
+
+#define        EFX_QWORD_IS_EQUAL64(_qword_a, _qword_b)                        \
+       ((_qword_a).eq_u64[0] == (_qword_b).eq_u64[0])
+
+#define        EFX_QWORD_IS_EQUAL32(_qword_a, _qword_b)                        \
+       ((_qword_a).eq_u32[0] == (_qword_b).eq_u32[0] &&                \
+           (_qword_a).eq_u32[1] == (_qword_b).eq_u32[1])
+
+#define        EFX_DWORD_IS_EQUAL(_dword_a, _dword_b)                          \
+       ((_dword_a).ed_u32[0] == (_dword_b).ed_u32[0])
+
+#define        EFX_WORD_IS_EQUAL(_word_a, _word_b)                             \
+       ((_word_a).ew_u16[0] == (_word_b).ew_u16[0])
+
+#define        EFX_BYTE_IS_EQUAL(_byte_a, _byte_b)                             \
+       ((_byte_a).eb_u8[0] == (_byte_b).eb_u8[0])
+
+
+#define        EFX_OWORD_IS_ZERO64(_oword)                                     \
+       (((_oword).eo_u64[0] |                                          \
+           (_oword).eo_u64[1]) == 0)
+
+#define        EFX_OWORD_IS_ZERO32(_oword)                                     \
+       (((_oword).eo_u32[0] |                                          \
+           (_oword).eo_u32[1] |                                        \
+           (_oword).eo_u32[2] |                                        \
+           (_oword).eo_u32[3]) == 0)
+
+#define        EFX_QWORD_IS_ZERO64(_qword)                                     \
+       (((_qword).eq_u64[0]) == 0)
+
+#define        EFX_QWORD_IS_ZERO32(_qword)                                     \
+       (((_qword).eq_u32[0] |                                          \
+           (_qword).eq_u32[1]) == 0)
+
+#define        EFX_DWORD_IS_ZERO(_dword)                                       \
+       (((_dword).ed_u32[0]) == 0)
+
+#define        EFX_WORD_IS_ZERO(_word)                                         \
+       (((_word).ew_u16[0]) == 0)
+
+#define        EFX_BYTE_IS_ZERO(_byte)                                         \
+       (((_byte).eb_u8[0]) == 0)
+
+
+#define        EFX_OWORD_IS_SET64(_oword)                                      \
+       (((_oword).eo_u64[0] &                                          \
+           (_oword).eo_u64[1]) == ~((uint64_t)0))
+
+#define        EFX_OWORD_IS_SET32(_oword)                                      \
+       (((_oword).eo_u32[0] &                                          \
+           (_oword).eo_u32[1] &                                        \
+           (_oword).eo_u32[2] &                                        \
+           (_oword).eo_u32[3]) == ~((uint32_t)0))
+
+#define        EFX_QWORD_IS_SET64(_qword)                                      \
+       (((_qword).eq_u64[0]) == ~((uint64_t)0))
+
+#define        EFX_QWORD_IS_SET32(_qword)                                      \
+       (((_qword).eq_u32[0] &                                          \
+           (_qword).eq_u32[1]) == ~((uint32_t)0))
+
+#define        EFX_DWORD_IS_SET(_dword)                                        \
+       ((_dword).ed_u32[0] == ~((uint32_t)0))
+
+#define        EFX_WORD_IS_SET(_word)                                          \
+       ((_word).ew_u16[0] == ~((uint16_t)0))
+
+#define        EFX_BYTE_IS_SET(_byte)                                          \
+       ((_byte).eb_u8[0] == ~((uint8_t)0))
+
+/*
+ * Construct bit field portion
+ *
+ * Creates the portion of the bit field [low,high) that lies within
+ * the range [min,max).
+ */
+
+#define        EFX_INSERT_NATIVE64(_min, _max, _low, _high, _value)            \
+       (((_low > _max) || (_high < _min)) ?                            \
+               0U :                                                    \
+               ((_low > _min) ?                                        \
+                       (((uint64_t)(_value)) << (_low - _min)) :       \
+                       (((uint64_t)(_value)) >> (_min - _low))))
+
+#define        EFX_INSERT_NATIVE32(_min, _max, _low, _high, _value)            \
+       (((_low > _max) || (_high < _min)) ?                            \
+               0U :                                                    \
+               ((_low > _min) ?                                        \
+                       (((uint32_t)(_value)) << (_low - _min)) :       \
+                       (((uint32_t)(_value)) >> (_min - _low))))
+
+#define        EFX_INSERT_NATIVE16(_min, _max, _low, _high, _value)            \
+       (((_low > _max) || (_high < _min)) ?                            \
+               0U :                                                    \
+               (uint16_t)((_low > _min) ?                              \
+                               ((_value) << (_low - _min)) :           \
+                               ((_value) >> (_min - _low))))
+
+#define        EFX_INSERT_NATIVE8(_min, _max, _low, _high, _value)             \
+       (((_low > _max) || (_high < _min)) ?                            \
+               0U :                                                    \
+               (uint8_t)((_low > _min) ?                               \
+                               ((_value) << (_low - _min)) :   \
+                               ((_value) >> (_min - _low))))
+
+/*
+ * Construct bit field portion
+ *
+ * Creates the portion of the named bit field that lies within the
+ * range [min,max).
+ */
+#define        EFX_INSERT_FIELD_NATIVE64(_min, _max, _field, _value)           \
+       EFX_INSERT_NATIVE64(_min, _max, EFX_LOW_BIT(_field),            \
+           EFX_HIGH_BIT(_field), _value)
+
+#define        EFX_INSERT_FIELD_NATIVE32(_min, _max, _field, _value)           \
+       EFX_INSERT_NATIVE32(_min, _max, EFX_LOW_BIT(_field),            \
+           EFX_HIGH_BIT(_field), _value)
+
+#define        EFX_INSERT_FIELD_NATIVE16(_min, _max, _field, _value)           \
+       EFX_INSERT_NATIVE16(_min, _max, EFX_LOW_BIT(_field),            \
+           EFX_HIGH_BIT(_field), _value)
+
+#define        EFX_INSERT_FIELD_NATIVE8(_min, _max, _field, _value)            \
+       EFX_INSERT_NATIVE8(_min, _max, EFX_LOW_BIT(_field),             \
+           EFX_HIGH_BIT(_field), _value)
+
+/*
+ * Construct bit field
+ *
+ * Creates the portion of the named bit fields that lie within the
+ * range [min,max).
+ */
+#define        EFX_INSERT_FIELDS64(_min, _max,                                 \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8, _field9, _value9,       \
+           _field10, _value10)                                         \
+       __CPU_TO_LE_64(                                                 \
+           EFX_INSERT_FIELD_NATIVE64(_min, _max, _field1, _value1) |   \
+           EFX_INSERT_FIELD_NATIVE64(_min, _max, _field2, _value2) |   \
+           EFX_INSERT_FIELD_NATIVE64(_min, _max, _field3, _value3) |   \
+           EFX_INSERT_FIELD_NATIVE64(_min, _max, _field4, _value4) |   \
+           EFX_INSERT_FIELD_NATIVE64(_min, _max, _field5, _value5) |   \
+           EFX_INSERT_FIELD_NATIVE64(_min, _max, _field6, _value6) |   \
+           EFX_INSERT_FIELD_NATIVE64(_min, _max, _field7, _value7) |   \
+           EFX_INSERT_FIELD_NATIVE64(_min, _max, _field8, _value8) |   \
+           EFX_INSERT_FIELD_NATIVE64(_min, _max, _field9, _value9) |   \
+           EFX_INSERT_FIELD_NATIVE64(_min, _max, _field10, _value10))
+
+#define        EFX_INSERT_FIELDS32(_min, _max,                                 \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8, _field9, _value9,       \
+           _field10, _value10)                                         \
+       __CPU_TO_LE_32(                                                 \
+           EFX_INSERT_FIELD_NATIVE32(_min, _max, _field1, _value1) |   \
+           EFX_INSERT_FIELD_NATIVE32(_min, _max, _field2, _value2) |   \
+           EFX_INSERT_FIELD_NATIVE32(_min, _max, _field3, _value3) |   \
+           EFX_INSERT_FIELD_NATIVE32(_min, _max, _field4, _value4) |   \
+           EFX_INSERT_FIELD_NATIVE32(_min, _max, _field5, _value5) |   \
+           EFX_INSERT_FIELD_NATIVE32(_min, _max, _field6, _value6) |   \
+           EFX_INSERT_FIELD_NATIVE32(_min, _max, _field7, _value7) |   \
+           EFX_INSERT_FIELD_NATIVE32(_min, _max, _field8, _value8) |   \
+           EFX_INSERT_FIELD_NATIVE32(_min, _max, _field9, _value9) |   \
+           EFX_INSERT_FIELD_NATIVE32(_min, _max, _field10, _value10))
+
+#define        EFX_INSERT_FIELDS16(_min, _max,                                 \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8, _field9, _value9,       \
+           _field10, _value10)                                         \
+       __CPU_TO_LE_16(                                                 \
+           EFX_INSERT_FIELD_NATIVE16(_min, _max, _field1, _value1) |   \
+           EFX_INSERT_FIELD_NATIVE16(_min, _max, _field2, _value2) |   \
+           EFX_INSERT_FIELD_NATIVE16(_min, _max, _field3, _value3) |   \
+           EFX_INSERT_FIELD_NATIVE16(_min, _max, _field4, _value4) |   \
+           EFX_INSERT_FIELD_NATIVE16(_min, _max, _field5, _value5) |   \
+           EFX_INSERT_FIELD_NATIVE16(_min, _max, _field6, _value6) |   \
+           EFX_INSERT_FIELD_NATIVE16(_min, _max, _field7, _value7) |   \
+           EFX_INSERT_FIELD_NATIVE16(_min, _max, _field8, _value8) |   \
+           EFX_INSERT_FIELD_NATIVE16(_min, _max, _field9, _value9) |   \
+           EFX_INSERT_FIELD_NATIVE16(_min, _max, _field10, _value10))
+
+#define        EFX_INSERT_FIELDS8(_min, _max,                                  \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8, _field9, _value9,       \
+           _field10, _value10)                                         \
+       __NATIVE_8(                                                     \
+           EFX_INSERT_FIELD_NATIVE8(_min, _max, _field1, _value1) |    \
+           EFX_INSERT_FIELD_NATIVE8(_min, _max, _field2, _value2) |    \
+           EFX_INSERT_FIELD_NATIVE8(_min, _max, _field3, _value3) |    \
+           EFX_INSERT_FIELD_NATIVE8(_min, _max, _field4, _value4) |    \
+           EFX_INSERT_FIELD_NATIVE8(_min, _max, _field5, _value5) |    \
+           EFX_INSERT_FIELD_NATIVE8(_min, _max, _field6, _value6) |    \
+           EFX_INSERT_FIELD_NATIVE8(_min, _max, _field7, _value7) |    \
+           EFX_INSERT_FIELD_NATIVE8(_min, _max, _field8, _value8) |    \
+           EFX_INSERT_FIELD_NATIVE8(_min, _max, _field9, _value9) |    \
+           EFX_INSERT_FIELD_NATIVE8(_min, _max, _field10, _value10))
+
+#define        EFX_POPULATE_OWORD64(_oword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8, _field9, _value9,       \
+           _field10, _value10)                                         \
+       do {                                                            \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_oword).eo_u64[0] = EFX_INSERT_FIELDS64(0, 63,         \
+                   _field1, _value1, _field2, _value2,                 \
+                   _field3, _value3, _field4, _value4,                 \
+                   _field5, _value5, _field6, _value6,                 \
+                   _field7, _value7, _field8, _value8,                 \
+                   _field9, _value9, _field10, _value10);              \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_oword).eo_u64[1] = EFX_INSERT_FIELDS64(64, 127,       \
+                   _field1, _value1, _field2, _value2,                 \
+                   _field3, _value3, _field4, _value4,                 \
+                   _field5, _value5, _field6, _value6,                 \
+                   _field7, _value7, _field8, _value8,                 \
+                   _field9, _value9, _field10, _value10);              \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_POPULATE_OWORD32(_oword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8, _field9, _value9,       \
+           _field10, _value10)                                         \
+       do {                                                            \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_oword).eo_u32[0] = EFX_INSERT_FIELDS32(0, 31,         \
+                   _field1, _value1, _field2, _value2,                 \
+                   _field3, _value3, _field4, _value4,                 \
+                   _field5, _value5, _field6, _value6,                 \
+                   _field7, _value7, _field8, _value8,                 \
+                   _field9, _value9, _field10, _value10);              \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_oword).eo_u32[1] = EFX_INSERT_FIELDS32(32, 63,        \
+                   _field1, _value1, _field2, _value2,                 \
+                   _field3, _value3, _field4, _value4,                 \
+                   _field5, _value5, _field6, _value6,                 \
+                   _field7, _value7, _field8, _value8,                 \
+                   _field9, _value9, _field10, _value10);              \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_oword).eo_u32[2] = EFX_INSERT_FIELDS32(64, 95,        \
+                   _field1, _value1, _field2, _value2,                 \
+                   _field3, _value3, _field4, _value4,                 \
+                   _field5, _value5, _field6, _value6,                 \
+                   _field7, _value7, _field8, _value8,                 \
+                   _field9, _value9, _field10, _value10);              \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_oword).eo_u32[3] = EFX_INSERT_FIELDS32(96, 127,       \
+                   _field1, _value1, _field2, _value2,                 \
+                   _field3, _value3, _field4, _value4,                 \
+                   _field5, _value5, _field6, _value6,                 \
+                   _field7, _value7, _field8, _value8,                 \
+                   _field9, _value9, _field10, _value10);              \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_POPULATE_QWORD64(_qword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8, _field9, _value9,       \
+           _field10, _value10)                                         \
+       do {                                                            \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_qword).eq_u64[0] = EFX_INSERT_FIELDS64(0, 63,         \
+                   _field1, _value1, _field2, _value2,                 \
+                   _field3, _value3, _field4, _value4,                 \
+                   _field5, _value5, _field6, _value6,                 \
+                   _field7, _value7, _field8, _value8,                 \
+                   _field9, _value9, _field10, _value10);              \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_POPULATE_QWORD32(_qword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8, _field9, _value9,       \
+           _field10, _value10)                                         \
+       do {                                                            \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_qword).eq_u32[0] = EFX_INSERT_FIELDS32(0, 31,         \
+                   _field1, _value1, _field2, _value2,                 \
+                   _field3, _value3, _field4, _value4,                 \
+                   _field5, _value5, _field6, _value6,                 \
+                   _field7, _value7, _field8, _value8,                 \
+                   _field9, _value9, _field10, _value10);              \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_qword).eq_u32[1] = EFX_INSERT_FIELDS32(32, 63,        \
+                   _field1, _value1, _field2, _value2,                 \
+                   _field3, _value3, _field4, _value4,                 \
+                   _field5, _value5, _field6, _value6,                 \
+                   _field7, _value7, _field8, _value8,                 \
+                   _field9, _value9, _field10, _value10);              \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_POPULATE_DWORD(_dword,                                      \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8, _field9, _value9,       \
+           _field10, _value10)                                         \
+       do {                                                            \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_dword).ed_u32[0] = EFX_INSERT_FIELDS32(0, 31,         \
+                   _field1, _value1, _field2, _value2,                 \
+                   _field3, _value3, _field4, _value4,                 \
+                   _field5, _value5, _field6, _value6,                 \
+                   _field7, _value7, _field8, _value8,                 \
+                   _field9, _value9, _field10, _value10);              \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_POPULATE_WORD(_word,                                        \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8, _field9, _value9,       \
+           _field10, _value10)                                         \
+       do {                                                            \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_word).ew_u16[0] = EFX_INSERT_FIELDS16(0, 15,          \
+                   _field1, _value1, _field2, _value2,                 \
+                   _field3, _value3, _field4, _value4,                 \
+                   _field5, _value5, _field6, _value6,                 \
+                   _field7, _value7, _field8, _value8,                 \
+                   _field9, _value9, _field10, _value10);              \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_POPULATE_BYTE(_byte,                                        \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8, _field9, _value9,       \
+           _field10, _value10)                                         \
+       do {                                                            \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_byte).eb_u8[0] = EFX_INSERT_FIELDS8(0, 7,             \
+                   _field1, _value1, _field2, _value2,                 \
+                   _field3, _value3, _field4, _value4,                 \
+                   _field5, _value5, _field6, _value6,                 \
+                   _field7, _value7, _field8, _value8,                 \
+                   _field9, _value9, _field10, _value10);              \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+/* Populate an octword field with various numbers of arguments */
+#define        EFX_POPULATE_OWORD_10 EFX_POPULATE_OWORD
+
+#define        EFX_POPULATE_OWORD_9(_oword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8, _field9, _value9)       \
+       EFX_POPULATE_OWORD_10(_oword, EFX_DUMMY_FIELD, 0,               \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8, _field9, _value9)
+
+#define        EFX_POPULATE_OWORD_8(_oword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8)                         \
+       EFX_POPULATE_OWORD_9(_oword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8)
+
+#define        EFX_POPULATE_OWORD_7(_oword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7)                                           \
+       EFX_POPULATE_OWORD_8(_oword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7)
+
+#define        EFX_POPULATE_OWORD_6(_oword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6)       \
+       EFX_POPULATE_OWORD_7(_oword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6)
+
+#define        EFX_POPULATE_OWORD_5(_oword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5)                         \
+       EFX_POPULATE_OWORD_6(_oword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5)
+
+#define        EFX_POPULATE_OWORD_4(_oword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4)                                           \
+       EFX_POPULATE_OWORD_5(_oword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4)
+
+#define        EFX_POPULATE_OWORD_3(_oword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3)       \
+       EFX_POPULATE_OWORD_4(_oword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1, _field2, _value2, _field3, _value3)
+
+#define        EFX_POPULATE_OWORD_2(_oword,                                    \
+           _field1, _value1, _field2, _value2)                         \
+       EFX_POPULATE_OWORD_3(_oword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1, _field2, _value2)
+
+#define        EFX_POPULATE_OWORD_1(_oword,                                    \
+           _field1, _value1)                                           \
+       EFX_POPULATE_OWORD_2(_oword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1)
+
+#define        EFX_ZERO_OWORD(_oword)                                          \
+       EFX_POPULATE_OWORD_1(_oword, EFX_DUMMY_FIELD, 0)
+
+#define        EFX_SET_OWORD(_oword)                                           \
+       EFX_POPULATE_OWORD_4(_oword,                                    \
+           EFX_DWORD_0, 0xffffffff, EFX_DWORD_1, 0xffffffff,           \
+           EFX_DWORD_2, 0xffffffff, EFX_DWORD_3, 0xffffffff)
+
+/* Populate a quadword field with various numbers of arguments */
+#define        EFX_POPULATE_QWORD_10 EFX_POPULATE_QWORD
+
+#define        EFX_POPULATE_QWORD_9(_qword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8, _field9, _value9)       \
+       EFX_POPULATE_QWORD_10(_qword, EFX_DUMMY_FIELD, 0,               \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8, _field9, _value9)
+
+#define        EFX_POPULATE_QWORD_8(_qword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8)                         \
+       EFX_POPULATE_QWORD_9(_qword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8)
+
+#define        EFX_POPULATE_QWORD_7(_qword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7)                                           \
+       EFX_POPULATE_QWORD_8(_qword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7)
+
+#define        EFX_POPULATE_QWORD_6(_qword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6)       \
+       EFX_POPULATE_QWORD_7(_qword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6)
+
+#define        EFX_POPULATE_QWORD_5(_qword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5)                         \
+       EFX_POPULATE_QWORD_6(_qword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5)
+
+#define        EFX_POPULATE_QWORD_4(_qword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4)                                           \
+       EFX_POPULATE_QWORD_5(_qword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4)
+
+#define        EFX_POPULATE_QWORD_3(_qword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3)       \
+       EFX_POPULATE_QWORD_4(_qword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1, _field2, _value2, _field3, _value3)
+
+#define        EFX_POPULATE_QWORD_2(_qword,                                    \
+           _field1, _value1, _field2, _value2)                         \
+       EFX_POPULATE_QWORD_3(_qword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1, _field2, _value2)
+
+#define        EFX_POPULATE_QWORD_1(_qword,                                    \
+           _field1, _value1)                                           \
+       EFX_POPULATE_QWORD_2(_qword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1)
+
+#define        EFX_ZERO_QWORD(_qword)                                          \
+       EFX_POPULATE_QWORD_1(_qword, EFX_DUMMY_FIELD, 0)
+
+#define        EFX_SET_QWORD(_qword)                                           \
+       EFX_POPULATE_QWORD_2(_qword,                                    \
+           EFX_DWORD_0, 0xffffffff, EFX_DWORD_1, 0xffffffff)
+
+/* Populate a dword field with various numbers of arguments */
+#define        EFX_POPULATE_DWORD_10 EFX_POPULATE_DWORD
+
+#define        EFX_POPULATE_DWORD_9(_dword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8, _field9, _value9)       \
+       EFX_POPULATE_DWORD_10(_dword, EFX_DUMMY_FIELD, 0,               \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8, _field9, _value9)
+
+#define        EFX_POPULATE_DWORD_8(_dword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8)                         \
+       EFX_POPULATE_DWORD_9(_dword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8)
+
+#define        EFX_POPULATE_DWORD_7(_dword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7)                                           \
+       EFX_POPULATE_DWORD_8(_dword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7)
+
+#define        EFX_POPULATE_DWORD_6(_dword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6)       \
+       EFX_POPULATE_DWORD_7(_dword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6)
+
+#define        EFX_POPULATE_DWORD_5(_dword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5)                         \
+       EFX_POPULATE_DWORD_6(_dword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5)
+
+#define        EFX_POPULATE_DWORD_4(_dword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4)                                           \
+       EFX_POPULATE_DWORD_5(_dword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4)
+
+#define        EFX_POPULATE_DWORD_3(_dword,                                    \
+           _field1, _value1, _field2, _value2, _field3, _value3)       \
+       EFX_POPULATE_DWORD_4(_dword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1, _field2, _value2, _field3, _value3)
+
+#define        EFX_POPULATE_DWORD_2(_dword,                                    \
+           _field1, _value1, _field2, _value2)                         \
+       EFX_POPULATE_DWORD_3(_dword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1, _field2, _value2)
+
+#define        EFX_POPULATE_DWORD_1(_dword,                                    \
+           _field1, _value1)                                           \
+       EFX_POPULATE_DWORD_2(_dword, EFX_DUMMY_FIELD, 0,                \
+           _field1, _value1)
+
+#define        EFX_ZERO_DWORD(_dword)                                          \
+       EFX_POPULATE_DWORD_1(_dword, EFX_DUMMY_FIELD, 0)
+
+#define        EFX_SET_DWORD(_dword)                                           \
+       EFX_POPULATE_DWORD_1(_dword,                                    \
+           EFX_DWORD_0, 0xffffffff)
+
+/* Populate a word field with various numbers of arguments */
+#define        EFX_POPULATE_WORD_10 EFX_POPULATE_WORD
+
+#define        EFX_POPULATE_WORD_9(_word,                                      \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8, _field9, _value9)       \
+       EFX_POPULATE_WORD_10(_word, EFX_DUMMY_FIELD, 0,                 \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8, _field9, _value9)
+
+#define        EFX_POPULATE_WORD_8(_word,                                      \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8)                         \
+       EFX_POPULATE_WORD_9(_word, EFX_DUMMY_FIELD, 0,                  \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8)
+
+#define        EFX_POPULATE_WORD_7(_word,                                      \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7)                                           \
+       EFX_POPULATE_WORD_8(_word, EFX_DUMMY_FIELD, 0,                  \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7)
+
+#define        EFX_POPULATE_WORD_6(_word,                                      \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6)       \
+       EFX_POPULATE_WORD_7(_word, EFX_DUMMY_FIELD, 0,                  \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6)
+
+#define        EFX_POPULATE_WORD_5(_word,                                      \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5)                         \
+       EFX_POPULATE_WORD_6(_word, EFX_DUMMY_FIELD, 0,                  \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5)
+
+#define        EFX_POPULATE_WORD_4(_word,                                      \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4)                                           \
+       EFX_POPULATE_WORD_5(_word, EFX_DUMMY_FIELD, 0,                  \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4)
+
+#define        EFX_POPULATE_WORD_3(_word,                                      \
+           _field1, _value1, _field2, _value2, _field3, _value3)       \
+       EFX_POPULATE_WORD_4(_word, EFX_DUMMY_FIELD, 0,                  \
+           _field1, _value1, _field2, _value2, _field3, _value3)
+
+#define        EFX_POPULATE_WORD_2(_word,                                      \
+           _field1, _value1, _field2, _value2)                         \
+       EFX_POPULATE_WORD_3(_word, EFX_DUMMY_FIELD, 0,                  \
+           _field1, _value1, _field2, _value2)
+
+#define        EFX_POPULATE_WORD_1(_word,                                      \
+           _field1, _value1)                                           \
+       EFX_POPULATE_WORD_2(_word, EFX_DUMMY_FIELD, 0,                  \
+           _field1, _value1)
+
+#define        EFX_ZERO_WORD(_word)                                            \
+       EFX_POPULATE_WORD_1(_word, EFX_DUMMY_FIELD, 0)
+
+#define        EFX_SET_WORD(_word)                                             \
+       EFX_POPULATE_WORD_1(_word,                                      \
+           EFX_WORD_0, 0xffff)
+
+/* Populate a byte field with various numbers of arguments */
+#define        EFX_POPULATE_BYTE_10 EFX_POPULATE_BYTE
+
+#define        EFX_POPULATE_BYTE_9(_byte,                                      \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8, _field9, _value9)       \
+       EFX_POPULATE_BYTE_10(_byte, EFX_DUMMY_FIELD, 0,                 \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8, _field9, _value9)
+
+#define        EFX_POPULATE_BYTE_8(_byte,                                      \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8)                         \
+       EFX_POPULATE_BYTE_9(_byte, EFX_DUMMY_FIELD, 0,                  \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7, _field8, _value8)
+
+#define        EFX_POPULATE_BYTE_7(_byte,                                      \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7)                                           \
+       EFX_POPULATE_BYTE_8(_byte, EFX_DUMMY_FIELD, 0,                  \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6,       \
+           _field7, _value7)
+
+#define        EFX_POPULATE_BYTE_6(_byte,                                      \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6)       \
+       EFX_POPULATE_BYTE_7(_byte, EFX_DUMMY_FIELD, 0,                  \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5, _field6, _value6)
+
+#define        EFX_POPULATE_BYTE_5(_byte,                                      \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5)                         \
+       EFX_POPULATE_BYTE_6(_byte, EFX_DUMMY_FIELD, 0,                  \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4, _field5, _value5)
+
+#define        EFX_POPULATE_BYTE_4(_byte,                                      \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4)                                           \
+       EFX_POPULATE_BYTE_5(_byte, EFX_DUMMY_FIELD, 0,                  \
+           _field1, _value1, _field2, _value2, _field3, _value3,       \
+           _field4, _value4)
+
+#define        EFX_POPULATE_BYTE_3(_byte,                                      \
+           _field1, _value1, _field2, _value2, _field3, _value3)       \
+       EFX_POPULATE_BYTE_4(_byte, EFX_DUMMY_FIELD, 0,                  \
+           _field1, _value1, _field2, _value2, _field3, _value3)
+
+#define        EFX_POPULATE_BYTE_2(_byte,                                      \
+           _field1, _value1, _field2, _value2)                         \
+       EFX_POPULATE_BYTE_3(_byte, EFX_DUMMY_FIELD, 0,                  \
+           _field1, _value1, _field2, _value2)
+
+#define        EFX_POPULATE_BYTE_1(_byte,                                      \
+           _field1, _value1)                                           \
+       EFX_POPULATE_BYTE_2(_byte, EFX_DUMMY_FIELD, 0,                  \
+           _field1, _value1)
+
+#define        EFX_ZERO_BYTE(_byte)                                            \
+       EFX_POPULATE_BYTE_1(_byte, EFX_DUMMY_FIELD, 0)
+
+#define        EFX_SET_BYTE(_byte)                                             \
+       EFX_POPULATE_BYTE_1(_byte,                                      \
+           EFX_BYTE_0, 0xff)
+
+/*
+ * Modify a named field within an already-populated structure.  Used
+ * for read-modify-write operations.
+ */
+
+#define        EFX_INSERT_FIELD64(_min, _max, _field, _value)                  \
+       __CPU_TO_LE_64(EFX_INSERT_FIELD_NATIVE64(_min, _max, _field, _value))
+
+#define        EFX_INSERT_FIELD32(_min, _max, _field, _value)                  \
+       __CPU_TO_LE_32(EFX_INSERT_FIELD_NATIVE32(_min, _max, _field, _value))
+
+#define        EFX_INSERT_FIELD16(_min, _max, _field, _value)                  \
+       __CPU_TO_LE_16(EFX_INSERT_FIELD_NATIVE16(_min, _max, _field, _value))
+
+#define        EFX_INSERT_FIELD8(_min, _max, _field, _value)                   \
+       __NATIVE_8(EFX_INSERT_FIELD_NATIVE8(_min, _max, _field, _value))
+
+#define        EFX_INPLACE_MASK64(_min, _max, _field)                          \
+       EFX_INSERT_FIELD64(_min, _max, _field, EFX_MASK64(_field))
+
+#define        EFX_INPLACE_MASK32(_min, _max, _field)                          \
+       EFX_INSERT_FIELD32(_min, _max, _field, EFX_MASK32(_field))
+
+#define        EFX_INPLACE_MASK16(_min, _max, _field)                          \
+       EFX_INSERT_FIELD16(_min, _max, _field, EFX_MASK16(_field))
+
+#define        EFX_INPLACE_MASK8(_min, _max, _field)                           \
+       EFX_INSERT_FIELD8(_min, _max, _field, EFX_MASK8(_field))
+
+#define        EFX_SET_OWORD_FIELD64(_oword, _field, _value)                   \
+       do {                                                            \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_oword).eo_u64[0] = (((_oword).eo_u64[0] &             \
+                   ~EFX_INPLACE_MASK64(0, 63, _field)) |               \
+                   EFX_INSERT_FIELD64(0, 63, _field, _value));         \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_oword).eo_u64[1] = (((_oword).eo_u64[1] &             \
+                   ~EFX_INPLACE_MASK64(64, 127, _field)) |             \
+                   EFX_INSERT_FIELD64(64, 127, _field, _value));       \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_SET_OWORD_FIELD32(_oword, _field, _value)                   \
+       do {                                                            \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_oword).eo_u32[0] = (((_oword).eo_u32[0] &             \
+                   ~EFX_INPLACE_MASK32(0, 31, _field)) |               \
+                   EFX_INSERT_FIELD32(0, 31, _field, _value));         \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_oword).eo_u32[1] = (((_oword).eo_u32[1] &             \
+                   ~EFX_INPLACE_MASK32(32, 63, _field)) |              \
+                   EFX_INSERT_FIELD32(32, 63, _field, _value));        \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_oword).eo_u32[2] = (((_oword).eo_u32[2] &             \
+                   ~EFX_INPLACE_MASK32(64, 95, _field)) |              \
+                   EFX_INSERT_FIELD32(64, 95, _field, _value));        \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_oword).eo_u32[3] = (((_oword).eo_u32[3] &             \
+                   ~EFX_INPLACE_MASK32(96, 127, _field)) |             \
+                   EFX_INSERT_FIELD32(96, 127, _field, _value));       \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_SET_QWORD_FIELD64(_qword, _field, _value)                   \
+       do {                                                            \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_qword).eq_u64[0] = (((_qword).eq_u64[0] &             \
+                   ~EFX_INPLACE_MASK64(0, 63, _field)) |               \
+                   EFX_INSERT_FIELD64(0, 63, _field, _value));         \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_SET_QWORD_FIELD32(_qword, _field, _value)                   \
+       do {                                                            \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_qword).eq_u32[0] = (((_qword).eq_u32[0] &             \
+                   ~EFX_INPLACE_MASK32(0, 31, _field)) |               \
+                   EFX_INSERT_FIELD32(0, 31, _field, _value));         \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_qword).eq_u32[1] = (((_qword).eq_u32[1] &             \
+                   ~EFX_INPLACE_MASK32(32, 63, _field)) |              \
+                   EFX_INSERT_FIELD32(32, 63, _field, _value));        \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_SET_DWORD_FIELD(_dword, _field, _value)                     \
+       do {                                                            \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_dword).ed_u32[0] = (((_dword).ed_u32[0] &             \
+                   ~EFX_INPLACE_MASK32(0, 31, _field)) |               \
+                   EFX_INSERT_FIELD32(0, 31, _field, _value));         \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_SET_WORD_FIELD(_word, _field, _value)                       \
+       do {                                                            \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_word).ew_u16[0] = (((_word).ew_u16[0] &               \
+                   ~EFX_INPLACE_MASK16(0, 15, _field)) |               \
+                   EFX_INSERT_FIELD16(0, 15, _field, _value));         \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_SET_BYTE_FIELD(_byte, _field, _value)                       \
+       do {                                                            \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_byte).eb_u8[0] = (((_byte).eb_u8[0] &                 \
+                   ~EFX_INPLACE_MASK8(0, 7, _field)) |                 \
+                   EFX_INSERT_FIELD8(0, 7, _field, _value));           \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+/*
+ * Set or clear a numbered bit within an octword.
+ */
+
+#define        EFX_SHIFT64(_bit, _base)                                        \
+       (((_bit) >= (_base) && (_bit) < (_base) + 64) ?                 \
+               ((uint64_t)1 << ((_bit) - (_base))) :                   \
+               0U)
+
+#define        EFX_SHIFT32(_bit, _base)                                        \
+       (((_bit) >= (_base) && (_bit) < (_base) + 32) ?                 \
+               ((uint32_t)1 << ((_bit) - (_base))) :                   \
+               0U)
+
+#define        EFX_SHIFT16(_bit, _base)                                        \
+       (((_bit) >= (_base) && (_bit) < (_base) + 16) ?                 \
+               (uint16_t)(1 << ((_bit) - (_base))) :                   \
+               0U)
+
+#define        EFX_SHIFT8(_bit, _base)                                         \
+       (((_bit) >= (_base) && (_bit) < (_base) + 8) ?                  \
+               (uint8_t)(1 << ((_bit) - (_base))) :                    \
+               0U)
+
+#define        EFX_SET_OWORD_BIT64(_oword, _bit)                               \
+       do {                                                            \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_oword).eo_u64[0] |=                                   \
+                   __CPU_TO_LE_64(EFX_SHIFT64(_bit, FIX_LINT(0)));     \
+               (_oword).eo_u64[1] |=                                   \
+                   __CPU_TO_LE_64(EFX_SHIFT64(_bit, FIX_LINT(64)));    \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_SET_OWORD_BIT32(_oword, _bit)                               \
+       do {                                                            \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_oword).eo_u32[0] |=                                   \
+                   __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(0)));     \
+               (_oword).eo_u32[1] |=                                   \
+                   __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(32)));    \
+               (_oword).eo_u32[2] |=                                   \
+                   __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(64)));    \
+               (_oword).eo_u32[3] |=                                   \
+                   __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(96)));    \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_CLEAR_OWORD_BIT64(_oword, _bit)                             \
+       do {                                                            \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_oword).eo_u64[0] &=                                   \
+                   __CPU_TO_LE_64(~EFX_SHIFT64(_bit, FIX_LINT(0)));    \
+               (_oword).eo_u64[1] &=                                   \
+                   __CPU_TO_LE_64(~EFX_SHIFT64(_bit, FIX_LINT(64)));   \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_CLEAR_OWORD_BIT32(_oword, _bit)                             \
+       do {                                                            \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_oword).eo_u32[0] &=                                   \
+                   __CPU_TO_LE_32(~EFX_SHIFT32(_bit, FIX_LINT(0)));    \
+               (_oword).eo_u32[1] &=                                   \
+                   __CPU_TO_LE_32(~EFX_SHIFT32(_bit, FIX_LINT(32)));   \
+               (_oword).eo_u32[2] &=                                   \
+                   __CPU_TO_LE_32(~EFX_SHIFT32(_bit, FIX_LINT(64)));   \
+               (_oword).eo_u32[3] &=                                   \
+                   __CPU_TO_LE_32(~EFX_SHIFT32(_bit, FIX_LINT(96)));   \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_TEST_OWORD_BIT64(_oword, _bit)                              \
+       (((_oword).eo_u64[0] &                                          \
+                   __CPU_TO_LE_64(EFX_SHIFT64(_bit, FIX_LINT(0)))) ||  \
+       ((_oword).eo_u64[1] &                                           \
+                   __CPU_TO_LE_64(EFX_SHIFT64(_bit, FIX_LINT(64)))))
+
+#define        EFX_TEST_OWORD_BIT32(_oword, _bit)                              \
+       (((_oword).eo_u32[0] &                                          \
+                   __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(0)))) ||  \
+       ((_oword).eo_u32[1] &                                           \
+                   __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(32)))) || \
+       ((_oword).eo_u32[2] &                                           \
+                   __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(64)))) || \
+       ((_oword).eo_u32[3] &                                           \
+                   __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(96)))))
+
+
+#define        EFX_SET_QWORD_BIT64(_qword, _bit)                               \
+       do {                                                            \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_qword).eq_u64[0] |=                                   \
+                   __CPU_TO_LE_64(EFX_SHIFT64(_bit, FIX_LINT(0)));     \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_SET_QWORD_BIT32(_qword, _bit)                               \
+       do {                                                            \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_qword).eq_u32[0] |=                                   \
+                   __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(0)));     \
+               (_qword).eq_u32[1] |=                                   \
+                   __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(32)));    \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_CLEAR_QWORD_BIT64(_qword, _bit)                             \
+       do {                                                            \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_qword).eq_u64[0] &=                                   \
+                   __CPU_TO_LE_64(~EFX_SHIFT64(_bit, FIX_LINT(0)));    \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_CLEAR_QWORD_BIT32(_qword, _bit)                             \
+       do {                                                            \
+               _NOTE(CONSTANTCONDITION)                                \
+               (_qword).eq_u32[0] &=                                   \
+                   __CPU_TO_LE_32(~EFX_SHIFT32(_bit, FIX_LINT(0)));    \
+               (_qword).eq_u32[1] &=                                   \
+                   __CPU_TO_LE_32(~EFX_SHIFT32(_bit, FIX_LINT(32)));   \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_TEST_QWORD_BIT64(_qword, _bit)                              \
+       (((_qword).eq_u64[0] &                                          \
+                   __CPU_TO_LE_64(EFX_SHIFT64(_bit, FIX_LINT(0)))) != 0)
+
+#define        EFX_TEST_QWORD_BIT32(_qword, _bit)                              \
+       (((_qword).eq_u32[0] &                                          \
+                   __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(0)))) ||  \
+       ((_qword).eq_u32[1] &                                           \
+                   __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(32)))))
+
+
+#define        EFX_SET_DWORD_BIT(_dword, _bit)                                 \
+       do {                                                            \
+               (_dword).ed_u32[0] |=                                   \
+                   __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(0)));     \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_CLEAR_DWORD_BIT(_dword, _bit)                               \
+       do {                                                            \
+               (_dword).ed_u32[0] &=                                   \
+                   __CPU_TO_LE_32(~EFX_SHIFT32(_bit, FIX_LINT(0)));    \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_TEST_DWORD_BIT(_dword, _bit)                                \
+       (((_dword).ed_u32[0] &                                          \
+                   __CPU_TO_LE_32(EFX_SHIFT32(_bit, FIX_LINT(0)))) != 0)
+
+
+#define        EFX_SET_WORD_BIT(_word, _bit)                                   \
+       do {                                                            \
+               (_word).ew_u16[0] |=                                    \
+                   __CPU_TO_LE_16(EFX_SHIFT16(_bit, FIX_LINT(0)));     \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_CLEAR_WORD_BIT(_word, _bit)                                 \
+       do {                                                            \
+               (_word).ew_u32[0] &=                                    \
+                   __CPU_TO_LE_16(~EFX_SHIFT16(_bit, FIX_LINT(0)));    \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_TEST_WORD_BIT(_word, _bit)                                  \
+       (((_word).ew_u16[0] &                                           \
+                   __CPU_TO_LE_16(EFX_SHIFT16(_bit, FIX_LINT(0)))) != 0)
+
+
+#define        EFX_SET_BYTE_BIT(_byte, _bit)                                   \
+       do {                                                            \
+               (_byte).eb_u8[0] |=                                     \
+                   __NATIVE_8(EFX_SHIFT8(_bit, FIX_LINT(0)));          \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_CLEAR_BYTE_BIT(_byte, _bit)                                 \
+       do {                                                            \
+               (_byte).eb_u8[0] &=                                     \
+                   __NATIVE_8(~EFX_SHIFT8(_bit, FIX_LINT(0)));         \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_TEST_BYTE_BIT(_byte, _bit)                                  \
+       (((_byte).eb_u8[0] &                                            \
+                   __NATIVE_8(EFX_SHIFT8(_bit, FIX_LINT(0)))) != 0)
+
+
+#define        EFX_OR_OWORD64(_oword1, _oword2)                                \
+       do {                                                            \
+               (_oword1).eo_u64[0] |= (_oword2).eo_u64[0];             \
+               (_oword1).eo_u64[1] |= (_oword2).eo_u64[1];             \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_OR_OWORD32(_oword1, _oword2)                                \
+       do {                                                            \
+               (_oword1).eo_u32[0] |= (_oword2).eo_u32[0];             \
+               (_oword1).eo_u32[1] |= (_oword2).eo_u32[1];             \
+               (_oword1).eo_u32[2] |= (_oword2).eo_u32[2];             \
+               (_oword1).eo_u32[3] |= (_oword2).eo_u32[3];             \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_AND_OWORD64(_oword1, _oword2)                               \
+       do {                                                            \
+               (_oword1).eo_u64[0] &= (_oword2).eo_u64[0];             \
+               (_oword1).eo_u64[1] &= (_oword2).eo_u64[1];             \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_AND_OWORD32(_oword1, _oword2)                               \
+       do {                                                            \
+               (_oword1).eo_u32[0] &= (_oword2).eo_u32[0];             \
+               (_oword1).eo_u32[1] &= (_oword2).eo_u32[1];             \
+               (_oword1).eo_u32[2] &= (_oword2).eo_u32[2];             \
+               (_oword1).eo_u32[3] &= (_oword2).eo_u32[3];             \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_OR_QWORD64(_qword1, _qword2)                                \
+       do {                                                            \
+               (_qword1).eq_u64[0] |= (_qword2).eq_u64[0];             \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_OR_QWORD32(_qword1, _qword2)                                \
+       do {                                                            \
+               (_qword1).eq_u32[0] |= (_qword2).eq_u32[0];             \
+               (_qword1).eq_u32[1] |= (_qword2).eq_u32[1];             \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_AND_QWORD64(_qword1, _qword2)                               \
+       do {                                                            \
+               (_qword1).eq_u64[0] &= (_qword2).eq_u64[0];             \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_AND_QWORD32(_qword1, _qword2)                               \
+       do {                                                            \
+               (_qword1).eq_u32[0] &= (_qword2).eq_u32[0];             \
+               (_qword1).eq_u32[1] &= (_qword2).eq_u32[1];             \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_OR_DWORD(_dword1, _dword2)                                  \
+       do {                                                            \
+               (_dword1).ed_u32[0] |= (_dword2).ed_u32[0];             \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_AND_DWORD(_dword1, _dword2)                                 \
+       do {                                                            \
+               (_dword1).ed_u32[0] &= (_dword2).ed_u32[0];             \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_OR_WORD(_word1, _word2)                                     \
+       do {                                                            \
+               (_word1).ew_u16[0] |= (_word2).ew_u16[0];               \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_AND_WORD(_word1, _word2)                                    \
+       do {                                                            \
+               (_word1).ew_u16[0] &= (_word2).ew_u16[0];               \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_OR_BYTE(_byte1, _byte2)                                     \
+       do {                                                            \
+               (_byte1).eb_u8[0] |= (_byte2).eb_u8[0];                 \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#define        EFX_AND_BYTE(_byte1, _byte2)                                    \
+       do {                                                            \
+               (_byte1).eb_u8[0] &= (_byte2).eb_u8[0];                 \
+       _NOTE(CONSTANTCONDITION)                                        \
+       } while (B_FALSE)
+
+#if EFSYS_USE_UINT64
+#define        EFX_OWORD_FIELD         EFX_OWORD_FIELD64
+#define        EFX_QWORD_FIELD         EFX_QWORD_FIELD64
+#define        EFX_OWORD_IS_EQUAL      EFX_OWORD_IS_EQUAL64
+#define        EFX_QWORD_IS_EQUAL      EFX_QWORD_IS_EQUAL64
+#define        EFX_OWORD_IS_ZERO       EFX_OWORD_IS_ZERO64
+#define        EFX_QWORD_IS_ZERO       EFX_QWORD_IS_ZERO64
+#define        EFX_OWORD_IS_SET        EFX_OWORD_IS_SET64
+#define        EFX_QWORD_IS_SET        EFX_QWORD_IS_SET64
+#define        EFX_POPULATE_OWORD      EFX_POPULATE_OWORD64
+#define        EFX_POPULATE_QWORD      EFX_POPULATE_QWORD64
+#define        EFX_SET_OWORD_FIELD     EFX_SET_OWORD_FIELD64
+#define        EFX_SET_QWORD_FIELD     EFX_SET_QWORD_FIELD64
+#define        EFX_SET_OWORD_BIT       EFX_SET_OWORD_BIT64
+#define        EFX_CLEAR_OWORD_BIT     EFX_CLEAR_OWORD_BIT64
+#define        EFX_TEST_OWORD_BIT      EFX_TEST_OWORD_BIT64
+#define        EFX_SET_QWORD_BIT       EFX_SET_QWORD_BIT64
+#define        EFX_CLEAR_QWORD_BIT     EFX_CLEAR_QWORD_BIT64
+#define        EFX_TEST_QWORD_BIT      EFX_TEST_QWORD_BIT64
+#define        EFX_OR_OWORD            EFX_OR_OWORD64
+#define        EFX_AND_OWORD           EFX_AND_OWORD64
+#define        EFX_OR_QWORD            EFX_OR_QWORD64
+#define        EFX_AND_QWORD           EFX_AND_QWORD64
+#else
+#define        EFX_OWORD_FIELD         EFX_OWORD_FIELD32
+#define        EFX_QWORD_FIELD         EFX_QWORD_FIELD32
+#define        EFX_OWORD_IS_EQUAL      EFX_OWORD_IS_EQUAL32
+#define        EFX_QWORD_IS_EQUAL      EFX_QWORD_IS_EQUAL32
+#define        EFX_OWORD_IS_ZERO       EFX_OWORD_IS_ZERO32
+#define        EFX_QWORD_IS_ZERO       EFX_QWORD_IS_ZERO32
+#define        EFX_OWORD_IS_SET        EFX_OWORD_IS_SET32
+#define        EFX_QWORD_IS_SET        EFX_QWORD_IS_SET32
+#define        EFX_POPULATE_OWORD      EFX_POPULATE_OWORD32
+#define        EFX_POPULATE_QWORD      EFX_POPULATE_QWORD32
+#define        EFX_SET_OWORD_FIELD     EFX_SET_OWORD_FIELD32
+#define        EFX_SET_QWORD_FIELD     EFX_SET_QWORD_FIELD32
+#define        EFX_SET_OWORD_BIT       EFX_SET_OWORD_BIT32
+#define        EFX_CLEAR_OWORD_BIT     EFX_CLEAR_OWORD_BIT32
+#define        EFX_TEST_OWORD_BIT      EFX_TEST_OWORD_BIT32
+#define        EFX_SET_QWORD_BIT       EFX_SET_QWORD_BIT32
+#define        EFX_CLEAR_QWORD_BIT     EFX_CLEAR_QWORD_BIT32
+#define        EFX_TEST_QWORD_BIT      EFX_TEST_QWORD_BIT32
+#define        EFX_OR_OWORD            EFX_OR_OWORD32
+#define        EFX_AND_OWORD           EFX_AND_OWORD32
+#define        EFX_OR_QWORD            EFX_OR_QWORD32
+#define        EFX_AND_QWORD           EFX_AND_QWORD32
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_EFX_TYPES_H */