summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorarybchik <arybchik@FreeBSD.org>2015-06-18 15:46:39 +0000
committerarybchik <arybchik@FreeBSD.org>2015-06-18 15:46:39 +0000
commit60da1828ed66b85f8f0d8c927122747ca725d307 (patch)
treec2b907dbbc1143c27d2d1a4f9b3049c0624e9da6
parent7f9011de0cc3acf0dd3716194c1a65149ce3b571 (diff)
downloadFreeBSD-src-60da1828ed66b85f8f0d8c927122747ca725d307.zip
FreeBSD-src-60da1828ed66b85f8f0d8c927122747ca725d307.tar.gz
MFC: r283514
sfxge: add 7xxx NICs family support Support 7xxx adapters including firmware-assisted TSO and VLAN tagging: - Solarflare Flareon Ultra 7000 series 10/40G adapters: - Solarflare SFN7042Q QSFP+ Server Adapter - Solarflare SFN7142Q QSFP+ Server Adapter - Solarflare Flareon Ultra 7000 series 10G adapters: - Solarflare SFN7022F SFP+ Server Adapter - Solarflare SFN7122F SFP+ Server Adapter - Solarflare SFN7322F Precision Time Synchronization Server Adapter - Solarflare Flareon 7000 series 10G adapters: - Solarflare SFN7002F SFP+ Server Adapter Support utilities to configure adapters and update firmware. The work is done by Solarflare developers (Andy Moreton, Andrew Lee and many others), Artem V. Andreev <Artem.Andreev at oktetlabs.ru> and me. Sponsored by: Solarflare Communications, Inc.
-rw-r--r--share/man/man4/sfxge.445
-rw-r--r--sys/conf/files31
-rw-r--r--sys/conf/files.amd6477
-rw-r--r--sys/dev/sfxge/common/ef10_tlv_layout.h691
-rw-r--r--sys/dev/sfxge/common/efsys.h114
-rw-r--r--sys/dev/sfxge/common/efx.h909
-rw-r--r--sys/dev/sfxge/common/efx_bootcfg.c45
-rw-r--r--sys/dev/sfxge/common/efx_check.h388
-rw-r--r--sys/dev/sfxge/common/efx_crc32.c127
-rw-r--r--sys/dev/sfxge/common/efx_ev.c686
-rw-r--r--sys/dev/sfxge/common/efx_filter.c1722
-rw-r--r--sys/dev/sfxge/common/efx_hash.c333
-rw-r--r--sys/dev/sfxge/common/efx_impl.h659
-rw-r--r--sys/dev/sfxge/common/efx_intr.c436
-rw-r--r--sys/dev/sfxge/common/efx_mac.c481
-rw-r--r--sys/dev/sfxge/common/efx_mcdi.c1607
-rw-r--r--sys/dev/sfxge/common/efx_mcdi.h164
-rw-r--r--sys/dev/sfxge/common/efx_mon.c156
-rw-r--r--sys/dev/sfxge/common/efx_nic.c511
-rw-r--r--sys/dev/sfxge/common/efx_nvram.c556
-rw-r--r--sys/dev/sfxge/common/efx_phy.c199
-rw-r--r--sys/dev/sfxge/common/efx_phy_ids.h53
-rw-r--r--sys/dev/sfxge/common/efx_port.c76
-rw-r--r--sys/dev/sfxge/common/efx_regs.h45
-rw-r--r--sys/dev/sfxge/common/efx_regs_ef10.h1168
-rw-r--r--sys/dev/sfxge/common/efx_regs_mcdi.h9206
-rw-r--r--sys/dev/sfxge/common/efx_regs_pci.h734
-rw-r--r--sys/dev/sfxge/common/efx_rx.c921
-rw-r--r--sys/dev/sfxge/common/efx_sram.c75
-rw-r--r--sys/dev/sfxge/common/efx_tx.c868
-rw-r--r--sys/dev/sfxge/common/efx_types.h122
-rw-r--r--sys/dev/sfxge/common/efx_vpd.c76
-rw-r--r--sys/dev/sfxge/common/efx_wol.c92
-rw-r--r--sys/dev/sfxge/common/hunt_ev.c1010
-rw-r--r--sys/dev/sfxge/common/hunt_filter.c1376
-rw-r--r--sys/dev/sfxge/common/hunt_impl.h1015
-rw-r--r--sys/dev/sfxge/common/hunt_intr.c155
-rw-r--r--sys/dev/sfxge/common/hunt_mac.c685
-rw-r--r--sys/dev/sfxge/common/hunt_mcdi.c465
-rw-r--r--sys/dev/sfxge/common/hunt_nic.c1741
-rw-r--r--sys/dev/sfxge/common/hunt_nvram.c1538
-rw-r--r--sys/dev/sfxge/common/hunt_phy.c701
-rw-r--r--sys/dev/sfxge/common/hunt_rx.c765
-rw-r--r--sys/dev/sfxge/common/hunt_sram.c69
-rwxr-xr-xsys/dev/sfxge/common/hunt_tx.c679
-rw-r--r--sys/dev/sfxge/common/hunt_vpd.c435
-rw-r--r--sys/dev/sfxge/common/mcdi_mon.c552
-rw-r--r--sys/dev/sfxge/common/mcdi_mon.h76
-rw-r--r--sys/dev/sfxge/common/siena_flash.h130
-rw-r--r--sys/dev/sfxge/common/siena_impl.h157
-rw-r--r--sys/dev/sfxge/common/siena_mac.c250
-rw-r--r--sys/dev/sfxge/common/siena_mcdi.c354
-rw-r--r--sys/dev/sfxge/common/siena_mon.c284
-rw-r--r--sys/dev/sfxge/common/siena_nic.c663
-rw-r--r--sys/dev/sfxge/common/siena_nvram.c252
-rw-r--r--sys/dev/sfxge/common/siena_phy.c221
-rw-r--r--sys/dev/sfxge/common/siena_sram.c43
-rw-r--r--sys/dev/sfxge/common/siena_vpd.c81
-rw-r--r--sys/dev/sfxge/sfxge.c339
-rw-r--r--sys/dev/sfxge/sfxge.h82
-rw-r--r--sys/dev/sfxge/sfxge_dma.c45
-rw-r--r--sys/dev/sfxge/sfxge_ev.c113
-rw-r--r--sys/dev/sfxge/sfxge_intr.c58
-rw-r--r--sys/dev/sfxge/sfxge_ioc.h112
-rw-r--r--sys/dev/sfxge/sfxge_mcdi.c179
-rw-r--r--sys/dev/sfxge/sfxge_nvram.c203
-rw-r--r--sys/dev/sfxge/sfxge_port.c194
-rw-r--r--sys/dev/sfxge/sfxge_rx.c183
-rw-r--r--sys/dev/sfxge/sfxge_rx.h56
-rw-r--r--sys/dev/sfxge/sfxge_tx.c501
-rw-r--r--sys/dev/sfxge/sfxge_tx.h51
-rw-r--r--sys/dev/sfxge/sfxge_version.h44
-rw-r--r--sys/modules/sfxge/Makefile21
73 files changed, 32780 insertions, 6471 deletions
diff --git a/share/man/man4/sfxge.4 b/share/man/man4/sfxge.4
index 3b67d08..c6319fc 100644
--- a/share/man/man4/sfxge.4
+++ b/share/man/man4/sfxge.4
@@ -1,26 +1,30 @@
-.\" Copyright (c) 2011 Solarflare Communications, Inc.
+.\" Copyright (c) 2011-2015 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.
+.\" modification, are permitted provided that the following conditions are met:
.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+.\" 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.
.\"
.\" $FreeBSD$
.\"
@@ -116,6 +120,9 @@ If a packet is dropped, the
.Va tx_put_overflow
counter is incremented and the local sender receives ENOBUFS.
The value must be greater than or equal to 0.
+.It Va hw.sfxge.tso_fw_assisted
+Enable/disable usage of FW-assisted TSO if supported by NIC firmware.
+Enabled by default.
.It Va hw.sfxge.N.max_rss_channels
The maximum number of allocated RSS channels for the Nth adapter.
If set to 0 or unset, the number of channels is determined by the number
diff --git a/sys/conf/files b/sys/conf/files
index dc1fed3..875f6d6 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -2135,37 +2135,6 @@ dev/sdhci/sdhci.c optional sdhci
dev/sdhci/sdhci_if.m optional sdhci
dev/sdhci/sdhci_pci.c optional sdhci pci
dev/sf/if_sf.c optional sf pci
-dev/sfxge/common/efx_bootcfg.c optional sfxge pci
-dev/sfxge/common/efx_ev.c optional sfxge pci
-dev/sfxge/common/efx_filter.c optional sfxge pci
-dev/sfxge/common/efx_intr.c optional sfxge pci
-dev/sfxge/common/efx_mac.c optional sfxge pci
-dev/sfxge/common/efx_mcdi.c optional sfxge pci
-dev/sfxge/common/efx_mon.c optional sfxge pci
-dev/sfxge/common/efx_nic.c optional sfxge pci
-dev/sfxge/common/efx_nvram.c optional sfxge pci
-dev/sfxge/common/efx_phy.c optional sfxge pci
-dev/sfxge/common/efx_port.c optional sfxge pci
-dev/sfxge/common/efx_rx.c optional sfxge pci
-dev/sfxge/common/efx_sram.c optional sfxge pci
-dev/sfxge/common/efx_tx.c optional sfxge pci
-dev/sfxge/common/efx_vpd.c optional sfxge pci
-dev/sfxge/common/efx_wol.c optional sfxge pci
-dev/sfxge/common/siena_mac.c optional sfxge pci
-dev/sfxge/common/siena_mon.c optional sfxge pci
-dev/sfxge/common/siena_nic.c optional sfxge pci
-dev/sfxge/common/siena_nvram.c optional sfxge pci
-dev/sfxge/common/siena_phy.c optional sfxge pci
-dev/sfxge/common/siena_sram.c optional sfxge pci
-dev/sfxge/common/siena_vpd.c optional sfxge pci
-dev/sfxge/sfxge.c optional sfxge pci
-dev/sfxge/sfxge_dma.c optional sfxge pci
-dev/sfxge/sfxge_ev.c optional sfxge pci
-dev/sfxge/sfxge_intr.c optional sfxge pci
-dev/sfxge/sfxge_mcdi.c optional sfxge pci
-dev/sfxge/sfxge_port.c optional sfxge pci
-dev/sfxge/sfxge_rx.c optional sfxge pci
-dev/sfxge/sfxge_tx.c optional sfxge pci
dev/sge/if_sge.c optional sge pci
dev/si/si.c optional si
dev/si/si2_z280.c optional si
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
index 312fc3c..ce1fc3a 100644
--- a/sys/conf/files.amd64
+++ b/sys/conf/files.amd64
@@ -299,37 +299,52 @@ dev/qlxgbe/ql_isr.c optional qlxgbe pci
dev/qlxgbe/ql_misc.c optional qlxgbe pci
dev/qlxgbe/ql_os.c optional qlxgbe pci
dev/qlxgbe/ql_reset.c optional qlxgbe pci
-dev/sfxge/common/efx_bootcfg.c optional sfxge inet pci
-dev/sfxge/common/efx_ev.c optional sfxge inet pci
-dev/sfxge/common/efx_filter.c optional sfxge inet pci
-dev/sfxge/common/efx_intr.c optional sfxge inet pci
-dev/sfxge/common/efx_mac.c optional sfxge inet pci
-dev/sfxge/common/efx_mcdi.c optional sfxge inet pci
-dev/sfxge/common/efx_mon.c optional sfxge inet pci
-dev/sfxge/common/efx_nic.c optional sfxge inet pci
-dev/sfxge/common/efx_nvram.c optional sfxge inet pci
-dev/sfxge/common/efx_phy.c optional sfxge inet pci
-dev/sfxge/common/efx_port.c optional sfxge inet pci
-dev/sfxge/common/efx_rx.c optional sfxge inet pci
-dev/sfxge/common/efx_sram.c optional sfxge inet pci
-dev/sfxge/common/efx_tx.c optional sfxge inet pci
-dev/sfxge/common/efx_vpd.c optional sfxge inet pci
-dev/sfxge/common/efx_wol.c optional sfxge inet pci
-dev/sfxge/common/siena_mac.c optional sfxge inet pci
-dev/sfxge/common/siena_mon.c optional sfxge inet pci
-dev/sfxge/common/siena_nic.c optional sfxge inet pci
-dev/sfxge/common/siena_nvram.c optional sfxge inet pci
-dev/sfxge/common/siena_phy.c optional sfxge inet pci
-dev/sfxge/common/siena_sram.c optional sfxge inet pci
-dev/sfxge/common/siena_vpd.c optional sfxge inet pci
-dev/sfxge/sfxge.c optional sfxge inet pci
-dev/sfxge/sfxge_dma.c optional sfxge inet pci
-dev/sfxge/sfxge_ev.c optional sfxge inet pci
-dev/sfxge/sfxge_intr.c optional sfxge inet pci
-dev/sfxge/sfxge_mcdi.c optional sfxge inet pci
-dev/sfxge/sfxge_port.c optional sfxge inet pci
-dev/sfxge/sfxge_rx.c optional sfxge inet pci
-dev/sfxge/sfxge_tx.c optional sfxge inet pci
+dev/sfxge/common/efx_bootcfg.c optional sfxge pci
+dev/sfxge/common/efx_crc32.c optional sfxge pci
+dev/sfxge/common/efx_ev.c optional sfxge pci
+dev/sfxge/common/efx_filter.c optional sfxge pci
+dev/sfxge/common/efx_hash.c optional sfxge pci
+dev/sfxge/common/efx_intr.c optional sfxge pci
+dev/sfxge/common/efx_mac.c optional sfxge pci
+dev/sfxge/common/efx_mcdi.c optional sfxge pci
+dev/sfxge/common/efx_mon.c optional sfxge pci
+dev/sfxge/common/efx_nic.c optional sfxge pci
+dev/sfxge/common/efx_nvram.c optional sfxge pci
+dev/sfxge/common/efx_phy.c optional sfxge pci
+dev/sfxge/common/efx_port.c optional sfxge pci
+dev/sfxge/common/efx_rx.c optional sfxge pci
+dev/sfxge/common/efx_sram.c optional sfxge pci
+dev/sfxge/common/efx_tx.c optional sfxge pci
+dev/sfxge/common/efx_vpd.c optional sfxge pci
+dev/sfxge/common/efx_wol.c optional sfxge pci
+dev/sfxge/common/hunt_ev.c optional sfxge pci
+dev/sfxge/common/hunt_filter.c optional sfxge pci
+dev/sfxge/common/hunt_intr.c optional sfxge pci
+dev/sfxge/common/hunt_mac.c optional sfxge pci
+dev/sfxge/common/hunt_mcdi.c optional sfxge pci
+dev/sfxge/common/hunt_nic.c optional sfxge pci
+dev/sfxge/common/hunt_nvram.c optional sfxge pci
+dev/sfxge/common/hunt_phy.c optional sfxge pci
+dev/sfxge/common/hunt_rx.c optional sfxge pci
+dev/sfxge/common/hunt_sram.c optional sfxge pci
+dev/sfxge/common/hunt_tx.c optional sfxge pci
+dev/sfxge/common/hunt_vpd.c optional sfxge pci
+dev/sfxge/common/siena_mac.c optional sfxge pci
+dev/sfxge/common/siena_mcdi.c optional sfxge pci
+dev/sfxge/common/siena_nic.c optional sfxge pci
+dev/sfxge/common/siena_nvram.c optional sfxge pci
+dev/sfxge/common/siena_phy.c optional sfxge pci
+dev/sfxge/common/siena_sram.c optional sfxge pci
+dev/sfxge/common/siena_vpd.c optional sfxge pci
+dev/sfxge/sfxge.c optional sfxge pci
+dev/sfxge/sfxge_dma.c optional sfxge pci
+dev/sfxge/sfxge_ev.c optional sfxge pci
+dev/sfxge/sfxge_intr.c optional sfxge pci
+dev/sfxge/sfxge_mcdi.c optional sfxge pci
+dev/sfxge/sfxge_nvram.c optional sfxge pci
+dev/sfxge/sfxge_port.c optional sfxge pci
+dev/sfxge/sfxge_rx.c optional sfxge pci
+dev/sfxge/sfxge_tx.c optional sfxge pci
dev/sio/sio.c optional sio
dev/sio/sio_isa.c optional sio isa
dev/sio/sio_pccard.c optional sio pccard
diff --git a/sys/dev/sfxge/common/ef10_tlv_layout.h b/sys/dev/sfxge/common/ef10_tlv_layout.h
new file mode 100644
index 0000000..e413a5d
--- /dev/null
+++ b/sys/dev/sfxge/common/ef10_tlv_layout.h
@@ -0,0 +1,691 @@
+/*-
+ * Copyright (c) 2012-2015 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.
+ *
+ * $FreeBSD$
+ */
+
+/* These structures define the layouts for the TLV items stored in static and
+ * dynamic configuration partitions in NVRAM for EF10 (Huntington etc.).
+ *
+ * They contain the same sort of information that was kept in the
+ * siena_mc_static_config_hdr_t and siena_mc_dynamic_config_hdr_t structures
+ * (defined in <ci/mgmt/mc_flash_layout.h> and <ci/mgmt/mc_dynamic_cfg.h>) for
+ * Siena.
+ *
+ * These are used directly by the MC and should also be usable directly on host
+ * systems which are little-endian and do not do strange things with structure
+ * padding. (Big-endian host systems will require some byte-swapping.)
+ *
+ * -----
+ *
+ * Please refer to SF-108797-SW for a general overview of the TLV partition
+ * format.
+ *
+ * -----
+ *
+ * The current tag IDs have a general structure: with the exception of the
+ * special values defined in the document, they are of the form 0xLTTTNNNN,
+ * where:
+ *
+ * - L is a location, indicating where this tag is expected to be found:
+ * 0 for static configuration, or 1 for dynamic configuration. Other
+ * values are reserved.
+ *
+ * - TTT is a type, which is just a unique value. The same type value
+ * might appear in both locations, indicating a relationship between
+ * the items (e.g. static and dynamic VPD below).
+ *
+ * - NNNN is an index of some form. Some item types are per-port, some
+ * are per-PF, some are per-partition-type.
+ *
+ * -----
+ *
+ * As with the previous Siena structures, each structure here is laid out
+ * carefully: values are aligned to their natural boundary, with explicit
+ * padding fields added where necessary. (No, technically this does not
+ * absolutely guarantee portability. But, in practice, compilers are generally
+ * sensible enough not to introduce completely pointless padding, and it works
+ * well enough.)
+ */
+
+
+#ifndef CI_MGMT_TLV_LAYOUT_H
+#define CI_MGMT_TLV_LAYOUT_H
+
+
+/* ----------------------------------------------------------------------------
+ * General structure (defined by SF-108797-SW)
+ * ----------------------------------------------------------------------------
+ */
+
+
+/* The "end" tag.
+ *
+ * (Note that this is *not* followed by length or value fields: anything after
+ * the tag itself is irrelevant.)
+ */
+
+#define TLV_TAG_END (0xEEEEEEEE)
+
+
+/* Other special reserved tag values.
+ */
+
+#define TLV_TAG_SKIP (0x00000000)
+#define TLV_TAG_INVALID (0xFFFFFFFF)
+
+
+/* TLV partition header.
+ *
+ * In a TLV partition, this must be the first item in the sequence, at offset
+ * 0.
+ */
+
+#define TLV_TAG_PARTITION_HEADER (0xEF10DA7A)
+
+struct tlv_partition_header {
+ uint32_t tag;
+ uint32_t length;
+ uint16_t type_id;
+ uint16_t reserved;
+ uint32_t generation;
+ uint32_t total_length;
+};
+
+
+/* TLV partition trailer.
+ *
+ * In a TLV partition, this must be the last item in the sequence, immediately
+ * preceding the TLV_TAG_END word.
+ */
+
+#define TLV_TAG_PARTITION_TRAILER (0xEF101A57)
+
+struct tlv_partition_trailer {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t generation;
+ uint32_t checksum;
+};
+
+
+/* Appendable TLV partition header.
+ *
+ * In an appendable TLV partition, this must be the first item in the sequence,
+ * at offset 0. (Note that, unlike the configuration partitions, there is no
+ * trailer before the TLV_TAG_END word.)
+ */
+
+#define TLV_TAG_APPENDABLE_PARTITION_HEADER (0xEF10ADA7)
+
+struct tlv_appendable_partition_header {
+ uint32_t tag;
+ uint32_t length;
+ uint16_t type_id;
+ uint16_t reserved;
+};
+
+
+/* ----------------------------------------------------------------------------
+ * Configuration items
+ * ----------------------------------------------------------------------------
+ */
+
+
+/* NIC global capabilities.
+ */
+
+#define TLV_TAG_GLOBAL_CAPABILITIES (0x00010000)
+
+struct tlv_global_capabilities {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t flags;
+};
+
+
+/* Siena-style per-port MAC address allocation.
+ *
+ * There are <count> addresses, starting at <base_address> and incrementing
+ * by adding <stride> to the low-order byte(s).
+ *
+ * (See also TLV_TAG_GLOBAL_MAC for an alternative, specifying a global pool
+ * of contiguous MAC addresses for the firmware to allocate as it sees fit.)
+ */
+
+#define TLV_TAG_PORT_MAC(port) (0x00020000 + (port))
+
+struct tlv_port_mac {
+ uint32_t tag;
+ uint32_t length;
+ uint8_t base_address[6];
+ uint16_t reserved;
+ uint16_t count;
+ uint16_t stride;
+};
+
+
+/* Static VPD.
+ *
+ * This is the portion of VPD which is set at manufacturing time and not
+ * expected to change. It is formatted as a standard PCI VPD block.
+ */
+
+#define TLV_TAG_PF_STATIC_VPD(pf) (0x00030000 + (pf))
+
+struct tlv_pf_static_vpd {
+ uint32_t tag;
+ uint32_t length;
+ uint8_t bytes[];
+};
+
+
+/* Dynamic VPD.
+ *
+ * This is the portion of VPD which may be changed (e.g. by firmware updates).
+ * It is formatted as a standard PCI VPD block.
+ */
+
+#define TLV_TAG_PF_DYNAMIC_VPD(pf) (0x10030000 + (pf))
+
+struct tlv_pf_dynamic_vpd {
+ uint32_t tag;
+ uint32_t length;
+ uint8_t bytes[];
+};
+
+
+/* "DBI" PCI config space changes.
+ *
+ * This is a set of edits made to the default PCI config space values before
+ * the device is allowed to enumerate.
+ */
+
+#define TLV_TAG_PF_DBI(pf) (0x00040000 + (pf))
+
+struct tlv_pf_dbi {
+ uint32_t tag;
+ uint32_t length;
+ struct {
+ uint16_t addr;
+ uint16_t byte_enables;
+ uint32_t value;
+ } items[];
+};
+
+
+/* Partition subtype codes.
+ *
+ * A subtype may optionally be stored for each type of partition present in
+ * the NVRAM. For example, this may be used to allow a generic firmware update
+ * utility to select a specific variant of firmware for a specific variant of
+ * board.
+ *
+ * The description[] field is an optional string which is returned in the
+ * MC_CMD_NVRAM_METADATA response if present.
+ */
+
+#define TLV_TAG_PARTITION_SUBTYPE(type) (0x00050000 + (type))
+
+struct tlv_partition_subtype {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t subtype;
+ uint8_t description[];
+};
+
+
+/* Partition version codes.
+ *
+ * A version may optionally be stored for each type of partition present in
+ * the NVRAM. This provides a standard way of tracking the currently stored
+ * version of each of the various component images.
+ */
+
+#define TLV_TAG_PARTITION_VERSION(type) (0x10060000 + (type))
+
+struct tlv_partition_version {
+ uint32_t tag;
+ uint32_t length;
+ uint16_t version_w;
+ uint16_t version_x;
+ uint16_t version_y;
+ uint16_t version_z;
+};
+
+/* Global PCIe configuration */
+
+#define TLV_TAG_GLOBAL_PCIE_CONFIG (0x10070000)
+
+struct tlv_pcie_config {
+ uint32_t tag;
+ uint32_t length;
+ int16_t max_pf_number; /**< Largest PF RID (lower PFs may be hidden) */
+ uint16_t pf_aper; /**< BIU aperture for PF BAR2 */
+ uint16_t vf_aper; /**< BIU aperture for VF BAR0 */
+ uint16_t int_aper; /**< BIU aperture for PF BAR4 and VF BAR2 */
+#define TLV_MAX_PF_DEFAULT (-1) /* Use FW default for largest PF RID */
+#define TLV_APER_DEFAULT (0xFFFF) /* Use FW default for a given aperture */
+};
+
+/* Per-PF configuration. Note that not all these fields are necessarily useful
+ * as the apertures are constrained by the BIU settings (the one case we do
+ * use is to make BAR2 bigger than the BIU thinks to reserve space), but we can
+ * tidy things up later */
+
+#define TLV_TAG_PF_PCIE_CONFIG(pf) (0x10080000 + (pf))
+
+struct tlv_per_pf_pcie_config {
+ uint32_t tag;
+ uint32_t length;
+ uint8_t vfs_total;
+ uint8_t port_allocation;
+ uint16_t vectors_per_pf;
+ uint16_t vectors_per_vf;
+ uint8_t pf_bar0_aperture;
+ uint8_t pf_bar2_aperture;
+ uint8_t vf_bar0_aperture;
+ uint8_t vf_base;
+ uint16_t supp_pagesz;
+ uint16_t msix_vec_base;
+};
+
+
+/* Development ONLY. This is a single TLV tag for all the gubbins
+ * that can be set through the MC command-line other than the PCIe
+ * settings. This is a temporary measure. */
+#define TLV_TAG_TMP_GUBBINS (0x10090000)
+
+struct tlv_tmp_gubbins {
+ uint32_t tag;
+ uint32_t length;
+ /* Consumed by dpcpu.c */
+ uint64_t tx0_tags; /* Bitmap */
+ uint64_t tx1_tags; /* Bitmap */
+ uint64_t dl_tags; /* Bitmap */
+ uint32_t flags;
+#define TLV_DPCPU_TX_STRIPE (1) /* TX striping is on */
+#define TLV_DPCPU_BIU_TAGS (2) /* Use BIU tag manager */
+#define TLV_DPCPU_TX0_TAGS (4) /* tx0_tags is valid */
+#define TLV_DPCPU_TX1_TAGS (8) /* tx1_tags is valid */
+#define TLV_DPCPU_DL_TAGS (16) /* dl_tags is valid */
+ /* Consumed by features.c */
+ uint32_t dut_features; /* All 1s -> leave alone */
+ int8_t with_rmon; /* 0 -> off, 1 -> on, -1 -> leave alone */
+ /* Consumed by clocks_hunt.c */
+ int8_t clk_mode; /* 0 -> off, 1 -> on, -1 -> leave alone */
+ /* Consumed by sram.c */
+ int8_t rx_dc_size; /* -1 -> leave alone */
+ int8_t tx_dc_size;
+ int16_t num_q_allocs;
+};
+
+/* Global port configuration
+ *
+ * This is now deprecated in favour of a platform-provided default
+ * and dynamic config override via tlv_global_port_options.
+ */
+#define TLV_TAG_GLOBAL_PORT_CONFIG (0x000a0000)
+
+struct tlv_global_port_config {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t ports_per_core;
+ uint32_t max_port_speed;
+};
+
+
+/* Firmware options.
+ *
+ * This is intended for user-configurable selection of optional firmware
+ * features and variants.
+ *
+ * Initially, this consists only of the satellite CPU firmware variant
+ * selection, but this tag could be extended in the future (using the
+ * tag length to determine whether additional fields are present).
+ */
+
+#define TLV_TAG_FIRMWARE_OPTIONS (0x100b0000)
+
+struct tlv_firmware_options {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t firmware_variant;
+#define TLV_FIRMWARE_VARIANT_DRIVER_SELECTED (0xffffffff)
+
+/* These are the values for overriding the driver's choice; the definitions
+ * are taken from MCDI so that they don't get out of step. Include
+ * <ci/mgmt/mc_driver_pcol.h> or the equivalent from your driver's tree if
+ * you need to use these constants.
+ */
+#define TLV_FIRMWARE_VARIANT_FULL_FEATURED MC_CMD_FW_FULL_FEATURED
+#define TLV_FIRMWARE_VARIANT_LOW_LATENCY MC_CMD_FW_LOW_LATENCY
+#define TLV_FIRMWARE_VARIANT_PACKED_STREAM MC_CMD_FW_PACKED_STREAM
+#define TLV_FIRMWARE_VARIANT_HIGH_TX_RATE MC_CMD_FW_HIGH_TX_RATE
+#define TLV_FIRMWARE_VARIANT_PACKED_STREAM_HASH_MODE_1 \
+ MC_CMD_FW_PACKED_STREAM_HASH_MODE_1
+};
+
+/* Voltage settings
+ *
+ * Intended for boards with A0 silicon where the core voltage may
+ * need tweaking. Most likely set once when the pass voltage is
+ * determined. */
+
+#define TLV_TAG_0V9_SETTINGS (0x000c0000)
+
+struct tlv_0v9_settings {
+ uint32_t tag;
+ uint32_t length;
+ uint16_t flags; /* Boards with high 0v9 settings may need active cooling */
+#define TLV_TAG_0V9_REQUIRES_FAN (1)
+ uint16_t target_voltage; /* In millivolts */
+ /* Since the limits are meant to be centred to the target (and must at least
+ * contain it) they need setting as well. */
+ uint16_t warn_low; /* In millivolts */
+ uint16_t warn_high; /* In millivolts */
+ uint16_t panic_low; /* In millivolts */
+ uint16_t panic_high; /* In millivolts */
+};
+
+
+/* Clock configuration */
+
+#define TLV_TAG_CLOCK_CONFIG (0x000d0000)
+
+struct tlv_clock_config {
+ uint32_t tag;
+ uint32_t length;
+ uint16_t clk_sys; /* MHz */
+ uint16_t clk_dpcpu; /* MHz */
+ uint16_t clk_icore; /* MHz */
+ uint16_t clk_pcs; /* MHz */
+};
+
+#define TLV_TAG_CLOCK_CONFIG_MEDFORD (0x00100000)
+
+struct tlv_clock_config_medford {
+ uint32_t tag;
+ uint32_t length;
+ uint16_t clk_sys; /* MHz */
+ uint16_t clk_mc; /* MHz */
+ uint16_t clk_rmon; /* MHz */
+ uint16_t clk_vswitch; /* MHz */
+ uint16_t clk_dpcpu; /* MHz */
+ uint16_t clk_pcs; /* MHz */
+};
+
+
+/* EF10-style global pool of MAC addresses.
+ *
+ * There are <count> addresses, starting at <base_address>, which are
+ * contiguous. Firmware is responsible for allocating addresses from this
+ * pool to ports / PFs as appropriate.
+ */
+
+#define TLV_TAG_GLOBAL_MAC (0x000e0000)
+
+struct tlv_global_mac {
+ uint32_t tag;
+ uint32_t length;
+ uint8_t base_address[6];
+ uint16_t reserved1;
+ uint16_t count;
+ uint16_t reserved2;
+};
+
+#define TLV_TAG_ATB_0V9_TARGET (0x000f0000)
+
+/* The target value for the 0v9 power rail measured on-chip at the
+ * analogue test bus */
+struct tlv_0v9_atb_target {
+ uint32_t tag;
+ uint32_t length;
+ uint16_t millivolts;
+ uint16_t reserved;
+};
+
+/* Global PCIe configuration, second revision. This represents the visible PFs
+ * by a bitmap rather than having the number of the highest visible one. As such
+ * it can (for a 16-PF chip) represent a superset of what TLV_TAG_GLOBAL_PCIE_CONFIG
+ * can and it should be used in place of that tag in future (but compatibility with
+ * the old tag will be left in the firmware indefinitely). */
+
+#define TLV_TAG_GLOBAL_PCIE_CONFIG_R2 (0x10100000)
+
+struct tlv_pcie_config_r2 {
+ uint32_t tag;
+ uint32_t length;
+ uint16_t visible_pfs; /**< Bitmap of visible PFs */
+ uint16_t pf_aper; /**< BIU aperture for PF BAR2 */
+ uint16_t vf_aper; /**< BIU aperture for VF BAR0 */
+ uint16_t int_aper; /**< BIU aperture for PF BAR4 and VF BAR2 */
+};
+
+/* Dynamic port mode.
+ *
+ * Allows selecting alternate port configuration for platforms that support it
+ * (e.g. 1x40G vs 2x10G on Milano, 1x40G vs 4x10G on Medford). This affects the
+ * number of externally visible ports (and, hence, PF to port mapping), so must
+ * be done at boot time.
+ *
+ * This tag supercedes tlv_global_port_config.
+ */
+
+#define TLV_TAG_GLOBAL_PORT_MODE (0x10110000)
+
+struct tlv_global_port_mode {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t port_mode;
+#define TLV_PORT_MODE_DEFAULT (0xffffffff) /* Default for given platform */
+#define TLV_PORT_MODE_10G (0) /* 10G, single SFP/10G-KR */
+#define TLV_PORT_MODE_40G (1) /* 40G, single QSFP/40G-KR */
+#define TLV_PORT_MODE_10G_10G (2) /* 2x10G, dual SFP/10G-KR or single QSFP */
+#define TLV_PORT_MODE_40G_40G (3) /* 40G + 40G, dual QSFP/40G-KR (Greenport, Medford) */
+#define TLV_PORT_MODE_10G_10G_10G_10G (4) /* 2x10G + 2x10G, quad SFP/10G-KR or dual QSFP (Greenport, Medford) */
+#define TLV_PORT_MODE_10G_10G_10G_10G_Q (5) /* 4x10G, single QSFP, cage 0 (Medford) */
+#define TLV_PORT_MODE_40G_10G_10G (6) /* 1x40G + 2x10G, dual QSFP (Greenport, Medford) */
+#define TLV_PORT_MODE_10G_10G_40G (7) /* 2x10G + 1x40G, dual QSFP (Greenport, Medford) */
+#define TLV_PORT_MODE_10G_10G_10G_10G_Q2 (8) /* 4x10G, single QSFP, cage 1 (Medford) */
+#define TLV_PORT_MODE_MAX TLV_PORT_MODE_10G_10G_10G_10G_Q2
+};
+
+/* Type of the v-switch created implicitly by the firmware */
+
+#define TLV_TAG_VSWITCH_TYPE(port) (0x10120000 + (port))
+
+struct tlv_vswitch_type {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t vswitch_type;
+#define TLV_VSWITCH_TYPE_DEFAULT (0xffffffff) /* Firmware default; equivalent to no TLV present for a given port */
+#define TLV_VSWITCH_TYPE_NONE (0)
+#define TLV_VSWITCH_TYPE_VLAN (1)
+#define TLV_VSWITCH_TYPE_VEB (2)
+#define TLV_VSWITCH_TYPE_VEPA (3)
+#define TLV_VSWITCH_TYPE_MUX (4)
+#define TLV_VSWITCH_TYPE_TEST (5)
+};
+
+/* A VLAN tag for the v-port created implicitly by the firmware */
+
+#define TLV_TAG_VPORT_VLAN_TAG(pf) (0x10130000 + (pf))
+
+struct tlv_vport_vlan_tag {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t vlan_tag;
+#define TLV_VPORT_NO_VLAN_TAG (0xFFFFFFFF) /* Default in the absence of TLV for a given PF */
+};
+
+/* Offset to be applied to the 0v9 setting, wherever it came from */
+
+#define TLV_TAG_ATB_0V9_OFFSET (0x10140000)
+
+struct tlv_0v9_atb_offset {
+ uint32_t tag;
+ uint32_t length;
+ int16_t offset_millivolts;
+ uint16_t reserved;
+};
+
+/* A privilege mask given on reset to all non-admin PCIe functions (that is other than first-PF-per-port).
+ * The meaning of particular bits is defined in mcdi_ef10.yml under MC_CMD_PRIVILEGE_MASK, see also bug 44583.
+ * TLV_TAG_PRIVILEGE_MASK_ADD specifies bits that should be added (ORed) to firmware default while
+ * TLV_TAG_PRIVILEGE_MASK_REM specifies bits that should be removed (ANDed) from firmware default:
+ * Initial_privilege_mask = (firmware_default_mask | privilege_mask_add) & ~privilege_mask_rem */
+
+#define TLV_TAG_PRIVILEGE_MASK (0x10150000) /* legacy symbol - do not use */
+
+struct tlv_privilege_mask { /* legacy structure - do not use */
+ uint32_t tag;
+ uint32_t length;
+ uint32_t privilege_mask;
+};
+
+#define TLV_TAG_PRIVILEGE_MASK_ADD (0x10150000)
+
+struct tlv_privilege_mask_add {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t privilege_mask_add;
+};
+
+#define TLV_TAG_PRIVILEGE_MASK_REM (0x10160000)
+
+struct tlv_privilege_mask_rem {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t privilege_mask_rem;
+};
+
+/* Additional privileges given to all PFs.
+ * This tag takes precedence over TLV_TAG_PRIVILEGE_MASK_REM. */
+
+#define TLV_TAG_PRIVILEGE_MASK_ADD_ALL_PFS (0x10190000)
+
+struct tlv_privilege_mask_add_all_pfs {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t privilege_mask_add;
+};
+
+/* Additional privileges given to a selected PF.
+ * This tag takes precedence over TLV_TAG_PRIVILEGE_MASK_REM. */
+
+#define TLV_TAG_PRIVILEGE_MASK_ADD_SINGLE_PF(pf) (0x101A0000 + (pf))
+
+struct tlv_privilege_mask_add_single_pf {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t privilege_mask_add;
+};
+
+/* Turning on/off the PFIOV mode.
+ * This tag only takes effect if TLV_TAG_VSWITCH_TYPE is missing or set to DEFAULT. */
+
+#define TLV_TAG_PFIOV(port) (0x10170000 + (port))
+
+struct tlv_pfiov {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t pfiov;
+#define TLV_PFIOV_OFF (0) /* Default */
+#define TLV_PFIOV_ON (1)
+};
+
+/* Multicast filter chaining mode selection.
+ *
+ * When enabled, multicast packets are delivered to all recipients of all
+ * matching multicast filters, with the exception that IP multicast filters
+ * will steal traffic from MAC multicast filters on a per-function basis.
+ * (New behaviour.)
+ *
+ * When disabled, multicast packets will always be delivered only to the
+ * recipients of the highest priority matching multicast filter.
+ * (Legacy behaviour.)
+ *
+ * The DEFAULT mode (which is the same as the tag not being present at all)
+ * is equivalent to ENABLED in production builds, and DISABLED in eftest
+ * builds.
+ *
+ * This option is intended to provide run-time control over this feature
+ * while it is being stabilised and may be withdrawn at some point in the
+ * future; the new behaviour is intended to become the standard behaviour.
+ */
+
+#define TLV_TAG_MCAST_FILTER_CHAINING (0x10180000)
+
+struct tlv_mcast_filter_chaining {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t mode;
+#define TLV_MCAST_FILTER_CHAINING_DEFAULT (0xffffffff)
+#define TLV_MCAST_FILTER_CHAINING_DISABLED (0)
+#define TLV_MCAST_FILTER_CHAINING_ENABLED (1)
+};
+
+
+/* Pacer rate limit per PF */
+#define TLV_TAG_RATE_LIMIT(pf) (0x101b0000 + (pf))
+
+struct tlv_rate_limit {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t rate_mbps;
+};
+
+
+/* OCSD Enable/Disable
+ *
+ * This setting allows OCSD to be disabled. This is a requirement for HP
+ * servers to support PCI passthrough for virtualization.
+ *
+ * The DEFAULT mode (which is the same as the tag not being present) is
+ * equivalent to ENABLED.
+ *
+ * This option is not used by the MCFW, and is entirely handled by the various
+ * drivers that support OCSD, by reading the setting before they attempt
+ * to enable OCSD.
+ *
+ * bit0: OCSD Disabled/Enabled
+ */
+
+#define TLV_TAG_OCSD (0x101C0000)
+
+struct tlv_ocsd {
+ uint32_t tag;
+ uint32_t length;
+ uint32_t mode;
+#define TLV_OCSD_DISABLED 0
+#define TLV_OCSD_ENABLED 1 /* Default */
+};
+
+#endif /* CI_MGMT_TLV_LAYOUT_H */
diff --git a/sys/dev/sfxge/common/efsys.h b/sys/dev/sfxge/common/efsys.h
index 5407426..bb03091 100644
--- a/sys/dev/sfxge/common/efsys.h
+++ b/sys/dev/sfxge/common/efsys.h
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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.
*
* $FreeBSD$
*/
@@ -56,6 +60,7 @@ extern "C" {
#else
#define EFSYS_USE_UINT64 0
#endif
+#define EFSYS_HAS_SSE2_M128 0
#if _BYTE_ORDER == _BIG_ENDIAN
#define EFSYS_IS_BIG_ENDIAN 1
#define EFSYS_IS_LITTLE_ENDIAN 0
@@ -90,6 +95,10 @@ extern "C" {
#define P2ROUNDUP(x, align) (-(-(x) & -(align)))
#endif
+#ifndef P2ALIGN
+#define P2ALIGN(_x, _a) ((_x) & -(_a))
+#endif
+
#ifndef IS2P
#define ISP2(x) (((x) & ((x) - 1)) == 0)
#endif
@@ -176,7 +185,7 @@ prefetch_read_once(void *addr)
#endif
static __inline void
sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map,
- struct mbuf *m, bus_dma_segment_t *seg)
+ struct mbuf *m, bus_dma_segment_t *seg)
{
#if defined(__i386__) || defined(__amd64__)
seg->ds_addr = pmap_kextract(mtod(m, vm_offset_t));
@@ -188,10 +197,6 @@ sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map,
#endif
}
-/* Modifiers used for DOS builds */
-#define __cs
-#define __far
-
/* Modifiers used for Windows builds */
#define __in
#define __in_opt
@@ -231,6 +236,7 @@ sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map,
#define EFSYS_OPT_FALCON 0
#define EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE 0
#define EFSYS_OPT_SIENA 1
+#define EFSYS_OPT_HUNTINGTON 1
#ifdef DEBUG
#define EFSYS_OPT_CHECK_REG 1
#else
@@ -248,19 +254,19 @@ sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map,
#define EFSYS_OPT_MON_NULL 0
#define EFSYS_OPT_MON_LM87 0
#define EFSYS_OPT_MON_MAX6647 0
-#define EFSYS_OPT_MON_SIENA 0
+#define EFSYS_OPT_MON_MCDI 0
#define EFSYS_OPT_MON_STATS 0
#define EFSYS_OPT_PHY_NULL 0
#define EFSYS_OPT_PHY_QT2022C2 0
#define EFSYS_OPT_PHY_SFX7101 0
#define EFSYS_OPT_PHY_TXC43128 0
-#define EFSYS_OPT_PHY_PM8358 0
#define EFSYS_OPT_PHY_SFT9001 0
#define EFSYS_OPT_PHY_QT2025C 0
#define EFSYS_OPT_PHY_STATS 1
#define EFSYS_OPT_PHY_PROPS 0
-#define EFSYS_OPT_PHY_BIST 1
+#define EFSYS_OPT_PHY_BIST 0
+#define EFSYS_OPT_BIST 1
#define EFSYS_OPT_PHY_LED_CONTROL 1
#define EFSYS_OPT_PHY_FLAGS 0
@@ -276,7 +282,8 @@ sfxge_map_mbuf_fast(bus_dma_tag_t tag, bus_dmamap_t map,
#define EFSYS_OPT_WOL 1
#define EFSYS_OPT_RX_SCALE 1
#define EFSYS_OPT_QSTATS 1
-#define EFSYS_OPT_FILTER 0
+#define EFSYS_OPT_FILTER 1
+#define EFSYS_OPT_MCAST_FILTER_LIST 1
#define EFSYS_OPT_RX_SCATTER 0
#define EFSYS_OPT_RX_HDR_SPLIT 0
@@ -618,6 +625,9 @@ typedef struct efsys_mem_s {
#define EFSYS_MEM_ADDR(_esmp) \
((_esmp)->esm_addr)
+#define EFSYS_MEM_IS_NULL(_esmp) \
+ ((_esmp)->esm_base == NULL)
+
/* BAR */
#define SFXGE_LOCK_NAME_MAX 16
@@ -880,6 +890,24 @@ typedef struct efsys_bar_s {
} while (B_FALSE)
#endif
+/*
+ * Guarantees 64bit aligned 64bit writes to write combined BAR mapping
+ * (required by PIO hardware)
+ */
+#define EFSYS_BAR_WC_WRITEQ(_esbp, _offset, _eqp) \
+ do { \
+ _NOTE(CONSTANTCONDITION) \
+ KASSERT(IS_P2ALIGNED(_offset, sizeof (efx_qword_t)), \
+ ("not power of 2 aligned")); \
+ \
+ (void) (_esbp); \
+ \
+ /* FIXME: Perform a 64-bit write */ \
+ KASSERT(0, ("not implemented")); \
+ \
+ _NOTE(CONSTANTCONDITION) \
+ } while (B_FALSE)
+
#if defined(SFXGE_USE_BUS_SPACE_8)
#define EFSYS_BAR_WRITEO(_esbp, _offset, _eop, _lock) \
do { \
@@ -979,6 +1007,13 @@ typedef struct efsys_bar_s {
} while (B_FALSE)
#endif
+/* Use the standard octo-word write for doorbell writes */
+#define EFSYS_BAR_DOORBELL_WRITEO(_esbp, _offset, _eop) \
+ do { \
+ EFSYS_BAR_WRITEO((_esbp), (_offset), (_eop), B_FALSE); \
+ _NOTE(CONSTANTCONDITION) \
+ } while (B_FALSE)
+
/* SPIN */
#define EFSYS_SPIN(_us) \
@@ -994,6 +1029,23 @@ typedef struct efsys_bar_s {
#define EFSYS_MEM_READ_BARRIER() rmb()
#define EFSYS_PIO_WRITE_BARRIER()
+/* DMA SYNC */
+#define EFSYS_DMA_SYNC_FOR_KERNEL(_esmp, _offset, _size) \
+ do { \
+ bus_dmamap_sync((_esmp)->esm_tag, \
+ (_esmp)->esm_map, \
+ BUS_DMASYNC_POSTREAD); \
+ _NOTE(CONSTANTCONDITION) \
+ } while (B_FALSE)
+
+#define EFSYS_DMA_SYNC_FOR_DEVICE(_esmp, _offset, _size) \
+ do { \
+ bus_dmamap_sync((_esmp)->esm_tag, \
+ (_esmp)->esm_map, \
+ BUS_DMASYNC_PREWRITE); \
+ _NOTE(CONSTANTCONDITION) \
+ } while (B_FALSE)
+
/* TIMESTAMP */
typedef clock_t efsys_timestamp_t;
@@ -1150,7 +1202,7 @@ extern void sfxge_err(efsys_identifier_t *, unsigned int,
#define EFSYS_ASSERT(_exp) do { \
if (!(_exp)) \
- panic(#_exp); \
+ panic("%s", #_exp); \
} while (0)
#define EFSYS_ASSERT3(_x, _op, _y, _t) do { \
@@ -1164,6 +1216,10 @@ extern void sfxge_err(efsys_identifier_t *, unsigned int,
#define EFSYS_ASSERT3S(_x, _op, _y) EFSYS_ASSERT3(_x, _op, _y, int64_t)
#define EFSYS_ASSERT3P(_x, _op, _y) EFSYS_ASSERT3(_x, _op, _y, uintptr_t)
+/* ROTATE */
+
+#define EFSYS_HAS_ROTL_DWORD 0
+
#ifdef __cplusplus
}
#endif
diff --git a/sys/dev/sfxge/common/efx.h b/sys/dev/sfxge/common/efx.h
index c5ef448..3435951 100644
--- a/sys/dev/sfxge/common/efx.h
+++ b/sys/dev/sfxge/common/efx.h
@@ -1,26 +1,31 @@
/*-
- * Copyright 2006-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2006-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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.
*
* $FreeBSD$
*/
@@ -29,6 +34,7 @@
#define _SYS_EFX_H
#include "efsys.h"
+#include "efx_phy_ids.h"
#ifdef __cplusplus
extern "C" {
@@ -38,14 +44,13 @@ extern "C" {
#define EFX_ARRAY_SIZE(_array) (sizeof(_array) / sizeof((_array)[0]))
-#ifndef EFSYS_MEM_IS_NULL
-#define EFSYS_MEM_IS_NULL(_esmp) ((_esmp)->esm_base == NULL)
-#endif
+#define EFX_FIELD_OFFSET(_type, _field) ((size_t) &(((_type *)0)->_field))
typedef enum efx_family_e {
EFX_FAMILY_INVALID,
EFX_FAMILY_FALCON,
EFX_FAMILY_SIENA,
+ EFX_FAMILY_HUNTINGTON,
EFX_FAMILY_NTYPES
} efx_family_t;
@@ -60,11 +65,23 @@ efx_infer_family(
__in efsys_bar_t *esbp,
__out efx_family_t *efp);
-#define EFX_PCI_VENID_SFC 0x1924
-#define EFX_PCI_DEVID_FALCON 0x0710
-#define EFX_PCI_DEVID_BETHPAGE 0x0803
-#define EFX_PCI_DEVID_SIENA 0x0813
-#define EFX_PCI_DEVID_SIENA_F1_UNINIT 0x0810
+#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_HUNTINGTON 0x0913 /* SFL9122 PF */
+#define EFX_PCI_DEVID_GREENPORT 0x0923 /* SFC9140 PF */
+
+#define EFX_PCI_DEVID_FARMINGDALE_VF 0x1903 /* SFC9120 VF */
+#define EFX_PCI_DEVID_HUNTINGTON_VF 0x1913 /* SFL9122 VF */
+#define EFX_PCI_DEVID_GREENPORT_VF 0x1923 /* SFC9140 VF */
+
#define EFX_MEM_BAR 2
@@ -86,10 +103,27 @@ enum {
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;
+#define EFX_NIC_FUNC_PRIMARY 0x00000001
+#define EFX_NIC_FUNC_LINKCTRL 0x00000002
+#define EFX_NIC_FUNC_TRUSTED 0x00000004
+
+
extern __checkReturn int
efx_nic_create(
__in efx_family_t family,
@@ -145,6 +179,11 @@ efx_nic_destroy(
#if EFSYS_OPT_MCDI
+#if EFSYS_OPT_HUNTINGTON
+/* Huntington requires MCDIv2 commands */
+#define WITH_MCDI_V2 1
+#endif
+
typedef struct efx_mcdi_req_s efx_mcdi_req_t;
typedef enum efx_mcdi_exception_e {
@@ -154,6 +193,7 @@ typedef enum efx_mcdi_exception_e {
typedef struct efx_mcdi_transport_s {
void *emt_context;
+ efsys_mem_t *emt_dma_mem;
void (*emt_execute)(void *, efx_mcdi_req_t *);
void (*emt_ev_cpl)(void *);
void (*emt_exception)(void *, efx_mcdi_exception_t);
@@ -168,6 +208,10 @@ extern __checkReturn int
efx_mcdi_reboot(
__in efx_nic_t *enp);
+ void
+efx_mcdi_new_epoch(
+ __in efx_nic_t *enp);
+
extern void
efx_mcdi_request_start(
__in efx_nic_t *enp,
@@ -251,7 +295,7 @@ efx_intr_fini(
#if EFSYS_OPT_MAC_STATS
-/* START MKCONFIG GENERATED EfxHeaderMacBlock bb8d39428b6fdcf5 */
+/* START MKCONFIG GENERATED EfxHeaderMacBlock e323546097fd7c65 */
typedef enum efx_mac_stat_e {
EFX_MAC_RX_OCTETS,
EFX_MAC_RX_PKTS,
@@ -304,6 +348,36 @@ typedef enum efx_mac_stat_e {
EFX_MAC_TX_LATE_COL_PKTS,
EFX_MAC_TX_DEF_PKTS,
EFX_MAC_TX_EX_DEF_PKTS,
+ EFX_MAC_PM_TRUNC_BB_OVERFLOW,
+ EFX_MAC_PM_DISCARD_BB_OVERFLOW,
+ EFX_MAC_PM_TRUNC_VFIFO_FULL,
+ EFX_MAC_PM_DISCARD_VFIFO_FULL,
+ EFX_MAC_PM_TRUNC_QBB,
+ EFX_MAC_PM_DISCARD_QBB,
+ EFX_MAC_PM_DISCARD_MAPPING,
+ EFX_MAC_RXDP_Q_DISABLED_PKTS,
+ EFX_MAC_RXDP_DI_DROPPED_PKTS,
+ EFX_MAC_RXDP_STREAMING_PKTS,
+ EFX_MAC_RXDP_HLB_FETCH,
+ EFX_MAC_RXDP_HLB_WAIT,
+ EFX_MAC_VADAPTER_RX_UNICAST_PACKETS,
+ EFX_MAC_VADAPTER_RX_UNICAST_BYTES,
+ EFX_MAC_VADAPTER_RX_MULTICAST_PACKETS,
+ EFX_MAC_VADAPTER_RX_MULTICAST_BYTES,
+ EFX_MAC_VADAPTER_RX_BROADCAST_PACKETS,
+ EFX_MAC_VADAPTER_RX_BROADCAST_BYTES,
+ EFX_MAC_VADAPTER_RX_BAD_PACKETS,
+ EFX_MAC_VADAPTER_RX_BAD_BYTES,
+ EFX_MAC_VADAPTER_RX_OVERFLOW,
+ EFX_MAC_VADAPTER_TX_UNICAST_PACKETS,
+ EFX_MAC_VADAPTER_TX_UNICAST_BYTES,
+ EFX_MAC_VADAPTER_TX_MULTICAST_PACKETS,
+ EFX_MAC_VADAPTER_TX_MULTICAST_BYTES,
+ EFX_MAC_VADAPTER_TX_BROADCAST_PACKETS,
+ EFX_MAC_VADAPTER_TX_BROADCAST_BYTES,
+ EFX_MAC_VADAPTER_TX_BAD_PACKETS,
+ EFX_MAC_VADAPTER_TX_BAD_BYTES,
+ EFX_MAC_VADAPTER_TX_OVERFLOW,
EFX_MAC_NSTATS
} efx_mac_stat_t;
@@ -321,9 +395,16 @@ typedef enum efx_link_mode_e {
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(_sdu) \
@@ -347,11 +428,29 @@ efx_mac_addr_set(
__in efx_nic_t *enp,
__in uint8_t *addr);
-extern __checkReturn int
+extern __checkReturn int
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 int
+efx_mac_multicast_list_set(
+ __in efx_nic_t *enp,
+ __in_ecount(6*count) uint8_t const *addrs,
+ __in int count);
+
+extern __checkReturn int
+efx_mac_filter_default_rxq_set(
__in efx_nic_t *enp,
- __in boolean_t unicst,
- __in boolean_t brdcst);
+ __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 int
efx_mac_drain(
@@ -381,15 +480,41 @@ efx_mac_fcntl_get(
#define EFX_MAC_HASH_BITS (1 << 8)
extern __checkReturn int
+efx_pktfilter_init(
+ __in efx_nic_t *enp);
+
+extern void
+efx_pktfilter_fini(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+efx_pktfilter_set(
+ __in efx_nic_t *enp,
+ __in boolean_t unicst,
+ __in boolean_t brdcst);
+
+extern __checkReturn int
efx_mac_hash_set(
__in efx_nic_t *enp,
__in_ecount(EFX_MAC_HASH_BITS) unsigned int const *bucket);
+#if EFSYS_OPT_MCAST_FILTER_LIST
+extern __checkReturn int
+efx_pktfilter_mcast_list_set(
+ __in efx_nic_t *enp,
+ __in uint8_t const *addrs,
+ __in int count);
+#endif /* EFSYS_OPT_MCAST_FILTER_LIST */
+
+extern __checkReturn int
+efx_pktfilter_mcast_all(
+ __in efx_nic_t *enp);
+
#if EFSYS_OPT_MAC_STATS
#if EFSYS_OPT_NAMES
-extern __checkReturn const char __cs *
+extern __checkReturn const char *
efx_mac_stat_name(
__in efx_nic_t *enp,
__in unsigned int id);
@@ -440,12 +565,13 @@ typedef enum efx_mon_type_e {
EFX_MON_LM87,
EFX_MON_MAX6647,
EFX_MON_SFC90X0,
+ EFX_MON_SFC91X0,
EFX_MON_NTYPES
} efx_mon_type_t;
#if EFSYS_OPT_NAMES
-extern const char __cs *
+extern const char *
efx_mon_name(
__in efx_nic_t *enp);
@@ -457,9 +583,10 @@ efx_mon_init(
#if EFSYS_OPT_MON_STATS
-#define EFX_MON_STATS_SIZE 0x100
+#define EFX_MON_STATS_PAGE_SIZE 0x100
+#define EFX_MON_MASK_ELEMENT_SIZE 32
-/* START MKCONFIG GENERATED MonitorHeaderStatsBlock 58706a378332aeee */
+/* START MKCONFIG GENERATED MonitorHeaderStatsBlock c79c86b62a144846 */
typedef enum efx_mon_stat_e {
EFX_MON_STAT_2_5V,
EFX_MON_STAT_VCCP1,
@@ -491,6 +618,45 @@ typedef enum efx_mon_stat_e {
EFX_MON_STAT_VAOE_IN,
EFX_MON_STAT_IAOE,
EFX_MON_STAT_IAOE_IN,
+ EFX_MON_STAT_NIC_POWER,
+ EFX_MON_STAT_0_9V,
+ EFX_MON_STAT_I0_9V,
+ EFX_MON_STAT_I1_2V,
+ EFX_MON_STAT_0_9V_ADC,
+ EFX_MON_STAT_INT_TEMP2,
+ EFX_MON_STAT_VREG_TEMP,
+ EFX_MON_STAT_VREG_0_9V_TEMP,
+ EFX_MON_STAT_VREG_1_2V_TEMP,
+ EFX_MON_STAT_INT_VPTAT,
+ EFX_MON_STAT_INT_ADC_TEMP,
+ EFX_MON_STAT_EXT_VPTAT,
+ EFX_MON_STAT_EXT_ADC_TEMP,
+ EFX_MON_STAT_AMBIENT_TEMP,
+ EFX_MON_STAT_AIRFLOW,
+ EFX_MON_STAT_VDD08D_VSS08D_CSR,
+ EFX_MON_STAT_VDD08D_VSS08D_CSR_EXTADC,
+ EFX_MON_STAT_HOTPOINT_TEMP,
+ EFX_MON_STAT_PHY_POWER_SWITCH_PORT0,
+ EFX_MON_STAT_PHY_POWER_SWITCH_PORT1,
+ EFX_MON_STAT_MUM_VCC,
+ EFX_MON_STAT_0V9_A,
+ EFX_MON_STAT_I0V9_A,
+ EFX_MON_STAT_0V9_A_TEMP,
+ EFX_MON_STAT_0V9_B,
+ EFX_MON_STAT_I0V9_B,
+ EFX_MON_STAT_0V9_B_TEMP,
+ EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY,
+ EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY_EXT_ADC,
+ EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY,
+ EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY_EXT_ADC,
+ EFX_MON_STAT_CONTROLLER_MASTER_VPTAT,
+ EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP,
+ EFX_MON_STAT_CONTROLLER_MASTER_VPTAT_EXT_ADC,
+ EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP_EXT_ADC,
+ EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT,
+ EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP,
+ EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT_EXT_ADC,
+ EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP_EXT_ADC,
EFX_MON_NSTATS
} efx_mon_stat_t;
@@ -501,16 +667,17 @@ typedef enum efx_mon_stat_state_e {
EFX_MON_STAT_STATE_WARNING = 1,
EFX_MON_STAT_STATE_FATAL = 2,
EFX_MON_STAT_STATE_BROKEN = 3,
+ EFX_MON_STAT_STATE_NO_READING = 4,
} efx_mon_stat_state_t;
-typedef struct efx_mon_stat_value_t {
+typedef struct efx_mon_stat_value_s {
uint16_t emsv_value;
uint16_t emsv_state;
} efx_mon_stat_value_t;
#if EFSYS_OPT_NAMES
-extern const char __cs *
+extern const char *
efx_mon_stat_name(
__in efx_nic_t *enp,
__in efx_mon_stat_t id);
@@ -540,16 +707,6 @@ efx_mon_fini(
#define MAXMMD ((1 << 5) - 1)
-/* PHY types */
-#define EFX_PHY_NULL 0x0
-#define EFX_PHY_TXC43128 0x1
-#define EFX_PHY_SFX7101 0x3
-#define EFX_PHY_QT2022C2 0x4
-#define EFX_PHY_SFT9001A 0x8
-#define EFX_PHY_QT2025C 0x9
-#define EFX_PHY_SFT9001B 0xa
-#define EFX_PHY_QLX111V 0xc
-
extern __checkReturn int
efx_phy_verify(
__in efx_nic_t *enp);
@@ -596,26 +753,38 @@ typedef enum efx_loopback_type_e {
EFX_LOOPBACK_PHY_XS = 15,
EFX_LOOPBACK_PCS = 16,
EFX_LOOPBACK_PMA_PMD = 17,
+ EFX_LOOPBACK_XPORT = 18,
+ EFX_LOOPBACK_XGMII_WS = 19,
+ EFX_LOOPBACK_XAUI_WS = 20,
+ EFX_LOOPBACK_XAUI_WS_FAR = 21,
+ EFX_LOOPBACK_XAUI_WS_NEAR = 22,
+ EFX_LOOPBACK_GMII_WS = 23,
+ EFX_LOOPBACK_XFI_WS = 24,
+ EFX_LOOPBACK_XFI_WS_FAR = 25,
+ EFX_LOOPBACK_PHYXS_WS = 26,
+ EFX_LOOPBACK_PMA_INT = 27,
+ EFX_LOOPBACK_SD_NEAR = 28,
+ EFX_LOOPBACK_SD_FAR = 29,
+ EFX_LOOPBACK_PMA_INT_WS = 30,
+ EFX_LOOPBACK_SD_FEP2_WS = 31,
+ EFX_LOOPBACK_SD_FEP1_5_WS = 32,
+ EFX_LOOPBACK_SD_FEP_WS = 33,
+ EFX_LOOPBACK_SD_FES_WS = 34,
EFX_LOOPBACK_NTYPES
} efx_loopback_type_t;
-#define EFX_LOOPBACK_MAC_MASK \
- ((1 << EFX_LOOPBACK_DATA) | \
- (1 << EFX_LOOPBACK_GMAC) | \
- (1 << EFX_LOOPBACK_XGMII) | \
- (1 << EFX_LOOPBACK_XGXS) | \
- (1 << EFX_LOOPBACK_XAUI) | \
- (1 << EFX_LOOPBACK_GMII) | \
- (1 << EFX_LOOPBACK_SGMII) | \
- (1 << EFX_LOOPBACK_XGBR) | \
- (1 << EFX_LOOPBACK_XFI) | \
- (1 << EFX_LOOPBACK_XAUI_FAR) | \
- (1 << EFX_LOOPBACK_GMII_FAR) | \
- (1 << EFX_LOOPBACK_SGMII_FAR) | \
- (1 << EFX_LOOPBACK_XFI_FAR))
-
-#define EFX_LOOPBACK_MASK \
- ((1 << EFX_LOOPBACK_NTYPES) - 1)
+typedef enum efx_loopback_kind_e {
+ EFX_LOOPBACK_KIND_OFF = 0,
+ EFX_LOOPBACK_KIND_ALL,
+ EFX_LOOPBACK_KIND_MAC,
+ EFX_LOOPBACK_KIND_PHY,
+ EFX_LOOPBACK_NKINDS
+} efx_loopback_kind_t;
+
+extern void
+efx_loopback_mask(
+ __in efx_loopback_kind_t loopback_kind,
+ __out efx_qword_t *maskp);
extern __checkReturn int
efx_port_loopback_set(
@@ -625,7 +794,7 @@ efx_port_loopback_set(
#if EFSYS_OPT_NAMES
-extern __checkReturn const char __cs *
+extern __checkReturn const char *
efx_loopback_type_name(
__in efx_nic_t *enp,
__in efx_loopback_type_t type);
@@ -637,7 +806,7 @@ efx_loopback_type_name(
extern __checkReturn int
efx_port_poll(
__in efx_nic_t *enp,
- __out efx_link_mode_t *link_modep);
+ __out_opt efx_link_mode_t *link_modep);
extern void
efx_port_fini(
@@ -655,6 +824,7 @@ typedef enum efx_phy_cap_type_e {
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;
@@ -692,6 +862,7 @@ typedef enum efx_phy_media_type_e {
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;
@@ -762,7 +933,7 @@ typedef enum efx_phy_stat_e {
#if EFSYS_OPT_NAMES
-extern const char __cs *
+extern const char *
efx_phy_stat_name(
__in efx_nic_t *enp,
__in efx_phy_stat_t stat);
@@ -783,7 +954,7 @@ efx_phy_stats_update(
#if EFSYS_OPT_NAMES
-extern const char __cs *
+extern const char *
efx_phy_prop_name(
__in efx_nic_t *enp,
__in unsigned int id);
@@ -807,22 +978,25 @@ efx_phy_prop_set(
#endif /* EFSYS_OPT_PHY_PROPS */
-#if EFSYS_OPT_PHY_BIST
-
-typedef enum efx_phy_bist_type_e {
- EFX_PHY_BIST_TYPE_UNKNOWN,
- EFX_PHY_BIST_TYPE_NORMAL,
- EFX_PHY_BIST_TYPE_CABLE_SHORT,
- EFX_PHY_BIST_TYPE_CABLE_LONG,
- EFX_PHY_BIST_TYPE_NTYPES,
-} efx_phy_bist_type_t;
-
-typedef enum efx_phy_bist_result_e {
- EFX_PHY_BIST_RESULT_UNKNOWN,
- EFX_PHY_BIST_RESULT_RUNNING,
- EFX_PHY_BIST_RESULT_PASSED,
- EFX_PHY_BIST_RESULT_FAILED,
-} efx_phy_bist_result_t;
+#if EFSYS_OPT_BIST
+
+typedef enum efx_bist_type_e {
+ EFX_BIST_TYPE_UNKNOWN,
+ EFX_BIST_TYPE_PHY_NORMAL,
+ EFX_BIST_TYPE_PHY_CABLE_SHORT,
+ EFX_BIST_TYPE_PHY_CABLE_LONG,
+ EFX_BIST_TYPE_MC_MEM, /* Test the MC DMEM and IMEM */
+ EFX_BIST_TYPE_SAT_MEM, /* Test the DMEM and IMEM of satellite cpus*/
+ EFX_BIST_TYPE_REG, /* Test the register memories */
+ EFX_BIST_TYPE_NTYPES,
+} efx_bist_type_t;
+
+typedef enum efx_bist_result_e {
+ EFX_BIST_RESULT_UNKNOWN,
+ EFX_BIST_RESULT_RUNNING,
+ EFX_BIST_RESULT_PASSED,
+ EFX_BIST_RESULT_FAILED,
+} efx_bist_result_t;
typedef enum efx_phy_cable_status_e {
EFX_PHY_CABLE_STATUS_OK,
@@ -833,39 +1007,53 @@ typedef enum efx_phy_cable_status_e {
EFX_PHY_CABLE_STATUS_BUSY,
} efx_phy_cable_status_t;
-typedef enum efx_phy_bist_value_e {
- EFX_PHY_BIST_CABLE_LENGTH_A,
- EFX_PHY_BIST_CABLE_LENGTH_B,
- EFX_PHY_BIST_CABLE_LENGTH_C,
- EFX_PHY_BIST_CABLE_LENGTH_D,
- EFX_PHY_BIST_CABLE_STATUS_A,
- EFX_PHY_BIST_CABLE_STATUS_B,
- EFX_PHY_BIST_CABLE_STATUS_C,
- EFX_PHY_BIST_CABLE_STATUS_D,
- EFX_PHY_BIST_FAULT_CODE,
- EFX_PHY_BIST_NVALUES,
-} efx_phy_bist_value_t;
+typedef enum efx_bist_value_e {
+ EFX_BIST_PHY_CABLE_LENGTH_A,
+ EFX_BIST_PHY_CABLE_LENGTH_B,
+ EFX_BIST_PHY_CABLE_LENGTH_C,
+ EFX_BIST_PHY_CABLE_LENGTH_D,
+ EFX_BIST_PHY_CABLE_STATUS_A,
+ EFX_BIST_PHY_CABLE_STATUS_B,
+ EFX_BIST_PHY_CABLE_STATUS_C,
+ EFX_BIST_PHY_CABLE_STATUS_D,
+ EFX_BIST_FAULT_CODE,
+ /* Memory BIST specific values. These match to the MC_CMD_BIST_POLL
+ * response. */
+ EFX_BIST_MEM_TEST,
+ EFX_BIST_MEM_ADDR,
+ EFX_BIST_MEM_BUS,
+ EFX_BIST_MEM_EXPECT,
+ EFX_BIST_MEM_ACTUAL,
+ EFX_BIST_MEM_ECC,
+ EFX_BIST_MEM_ECC_PARITY,
+ EFX_BIST_MEM_ECC_FATAL,
+ EFX_BIST_NVALUES,
+} efx_bist_value_t;
+
+extern __checkReturn int
+efx_bist_enable_offline(
+ __in efx_nic_t *enp);
extern __checkReturn int
-efx_phy_bist_start(
+efx_bist_start(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type);
+ __in efx_bist_type_t type);
extern __checkReturn int
-efx_phy_bist_poll(
+efx_bist_poll(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type,
- __out efx_phy_bist_result_t *resultp,
+ __in efx_bist_type_t type,
+ __out efx_bist_result_t *resultp,
__out_opt uint32_t *value_maskp,
__out_ecount_opt(count) unsigned long *valuesp,
__in size_t count);
extern void
-efx_phy_bist_stop(
+efx_bist_stop(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type);
+ __in efx_bist_type_t type);
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
#define EFX_FEATURE_IPV6 0x00000001
#define EFX_FEATURE_LFSR_HASH_INSERT 0x00000002
@@ -876,6 +1064,10 @@ efx_phy_bist_stop(
#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
typedef struct efx_nic_cfg_s {
uint32_t enc_board_type;
@@ -886,20 +1078,29 @@ typedef struct efx_nic_cfg_s {
char enc_phy_revision[21];
efx_mon_type_t enc_mon_type;
#if EFSYS_OPT_MON_STATS
- uint32_t enc_mon_stat_mask;
+ uint32_t enc_mon_stat_dma_buf_size;
+ uint32_t enc_mon_stat_mask[(EFX_MON_NSTATS + 31) / 32];
#endif
unsigned int enc_features;
uint8_t enc_mac_addr[6];
- uint8_t enc_port;
+ uint8_t enc_port; /* PHY port number */
+ uint32_t enc_func_flags;
+ 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_buftbl_limit;
+ uint32_t enc_piobuf_limit;
+ uint32_t enc_piobuf_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;
#if EFSYS_OPT_LOOPBACK
- uint32_t enc_loopback_types[EFX_LINK_NMODES];
+ efx_qword_t enc_loopback_types[EFX_LINK_NMODES];
#endif /* EFSYS_OPT_LOOPBACK */
#if EFSYS_OPT_PHY_FLAGS
uint32_t enc_phy_flags_mask;
@@ -914,23 +1115,100 @@ typedef struct efx_nic_cfg_s {
unsigned int enc_phy_nprops;
#endif /* EFSYS_OPT_PHY_PROPS */
#if EFSYS_OPT_SIENA
- uint8_t enc_siena_channel;
+ uint8_t enc_mcdi_mdio_channel;
#if EFSYS_OPT_PHY_STATS
- uint32_t enc_siena_phy_stat_mask;
+ uint32_t enc_mcdi_phy_stat_mask;
#endif /* EFSYS_OPT_PHY_STATS */
+#endif /* EFSYS_OPT_SIENA */
+#if (EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
#if EFSYS_OPT_MON_STATS
- uint32_t enc_siena_mon_stat_mask;
+ uint32_t *enc_mcdi_sensor_maskp;
+ uint32_t enc_mcdi_sensor_mask_size;
#endif /* EFSYS_OPT_MON_STATS */
-#endif /* EFSYS_OPT_SIENA */
-#if EFSYS_OPT_PHY_BIST
+#endif /* (EFSYS_OPT_SIENA | EFSYS_OPT_HUNTINGTON) */
+#if EFSYS_OPT_BIST
uint32_t enc_bist_mask;
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
+#if EFSYS_OPT_HUNTINGTON
+ uint32_t enc_pf;
+ uint32_t enc_vf;
+ uint32_t enc_privilege_mask;
+#endif /* EFSYS_OPT_HUNTINGTON */
+ boolean_t enc_bug26807_workaround;
+ boolean_t enc_bug35388_workaround;
+ boolean_t enc_bug41750_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_hw_tx_insert_vlan_enabled;
+ /* Datapath firmware vadapter/vport/vswitch support */
+ boolean_t enc_datapath_cap_evb;
+ /* External port identifier */
+ uint8_t enc_external_port;
} 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 int
+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 int
+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 int
+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);
+
+
#if EFSYS_OPT_VPD
typedef enum efx_vpd_tag_e {
@@ -1029,6 +1307,7 @@ typedef enum efx_nvram_type_e {
EFX_NVRAM_FCFW,
EFX_NVRAM_CPLD,
EFX_NVRAM_FPGA_BACKUP,
+ EFX_NVRAM_DYNAMIC_CFG,
EFX_NVRAM_NTYPES,
} efx_nvram_type_t;
@@ -1080,7 +1359,15 @@ extern __checkReturn int
efx_nvram_set_version(
__in efx_nic_t *enp,
__in efx_nvram_type_t type,
- __out uint16_t version[4]);
+ __in_ecount(4) uint16_t version[4]);
+
+/* Validate contents of TLV formatted partition */
+extern __checkReturn int
+efx_nvram_tlv_validate(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in_bcount(partn_size) caddr_t partn_data,
+ __in size_t partn_size);
extern __checkReturn int
efx_nvram_erase(
@@ -1246,12 +1533,11 @@ typedef struct efx_evq_s efx_evq_t;
#if EFSYS_OPT_QSTATS
-/* START MKCONFIG GENERATED EfxHeaderEventQueueBlock d5614a5d669c8ca3 */
+/* START MKCONFIG GENERATED EfxHeaderEventQueueBlock 6f3843f5fe7cc843 */
typedef enum efx_ev_qstat_e {
EV_ALL,
EV_RX,
EV_RX_OK,
- EV_RX_RECOVERY,
EV_RX_FRM_TRUNC,
EV_RX_TOBE_DISC,
EV_RX_PAUSE_FRM_ERR,
@@ -1269,16 +1555,14 @@ typedef enum efx_ev_qstat_e {
EV_RX_OTHER_IPV4,
EV_RX_OTHER_IPV6,
EV_RX_NON_IP,
- EV_RX_OVERRUN,
+ EV_RX_BATCH,
EV_TX,
EV_TX_WQ_FF_FULL,
EV_TX_PKT_ERR,
EV_TX_PKT_TOO_BIG,
EV_TX_UNEXPECTED,
EV_GLOBAL,
- EV_GLOBAL_PHY,
EV_GLOBAL_MNT,
- EV_GLOBAL_RX_RECOVERY,
EV_DRIVER,
EV_DRIVER_SRM_UPD_DONE,
EV_DRIVER_TX_DESCQ_FLS_DONE,
@@ -1303,13 +1587,9 @@ extern void
efx_ev_fini(
__in efx_nic_t *enp);
-#define EFX_MASK(_max, _min) (-((_max) << 1) ^ -(_min))
-
#define EFX_EVQ_MAXNEVS 32768
#define EFX_EVQ_MINNEVS 512
-#define EFX_EVQ_NEVS_MASK EFX_MASK(EFX_EVQ_MAXNEVS, EFX_EVQ_MINNEVS)
-
#define EFX_EVQ_SIZE(_nevs) ((_nevs) * sizeof (efx_qword_t))
#define EFX_EVQ_NBUFS(_nevs) (EFX_EVQ_SIZE(_nevs) / EFX_BUF_SIZE)
@@ -1345,6 +1625,7 @@ typedef __checkReturn boolean_t
#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
@@ -1371,6 +1652,9 @@ typedef __checkReturn boolean_t
#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)(
@@ -1460,7 +1744,7 @@ typedef struct efx_ev_callbacks_s {
#endif /* EFSYS_OPT_MON_STATS */
#if EFSYS_OPT_MAC_STATS
efx_mac_stats_ev_t eec_mac_stats;
-#endif /* EFSYS_OPT_MON_STATS */
+#endif /* EFSYS_OPT_MAC_STATS */
} efx_ev_callbacks_t;
extern __checkReturn boolean_t
@@ -1498,7 +1782,7 @@ efx_ev_qprime(
#if EFSYS_OPT_NAMES
-extern const char __cs *
+extern const char *
efx_ev_qstat_name(
__in efx_nic_t *enp,
__in unsigned int id);
@@ -1518,11 +1802,9 @@ efx_ev_qdestroy(
/* RX */
-typedef struct efx_rxq_s efx_rxq_t;
-
extern __checkReturn int
efx_rx_init(
- __in efx_nic_t *enp);
+ __inout efx_nic_t *enp);
extern void
efx_rx_fini(
@@ -1558,10 +1840,32 @@ typedef enum efx_rx_hash_type_e {
EFX_RX_HASH_TCPIPV6,
} efx_rx_hash_type_t;
+typedef enum efx_rx_hash_support_e {
+ EFX_RX_HASH_UNAVAILABLE = 0, /* Hardware hash not inserted */
+ EFX_RX_HASH_AVAILABLE /* Insert hash with/without RSS */
+} efx_rx_hash_support_t;
+
#define EFX_RSS_TBL_SIZE 128 /* Rows in RX indirection table */
#define EFX_MAXRSS 64 /* RX indirection entry range */
#define EFX_MAXRSS_LEGACY 16 /* See bug16611 and bug17213 */
+typedef enum efx_rx_scale_support_e {
+ EFX_RX_SCALE_UNAVAILABLE = 0, /* Not supported */
+ EFX_RX_SCALE_EXCLUSIVE, /* Writable key/indirection table */
+ EFX_RX_SCALE_SHARED /* Read-only key/indirection table */
+} efx_rx_scale_support_t;
+
+ extern __checkReturn int
+efx_rx_hash_support_get(
+ __in efx_nic_t *enp,
+ __out efx_rx_hash_support_t *supportp);
+
+
+extern __checkReturn int
+efx_rx_scale_support_get(
+ __in efx_nic_t *enp,
+ __out efx_rx_scale_support_t *supportp);
+
extern __checkReturn int
efx_rx_scale_mode_set(
__in efx_nic_t *enp,
@@ -1576,54 +1880,28 @@ efx_rx_scale_tbl_set(
__in size_t n);
extern __checkReturn int
-efx_rx_scale_toeplitz_ipv4_key_set(
+efx_rx_scale_key_set(
__in efx_nic_t *enp,
__in_ecount(n) uint8_t *key,
__in size_t n);
-extern __checkReturn int
-efx_rx_scale_toeplitz_ipv6_key_set(
+extern uint32_t
+efx_psuedo_hdr_hash_get(
__in efx_nic_t *enp,
- __in_ecount(n) uint8_t *key,
- __in size_t n);
-
-/*
- * The prefix is a byte array of one of the forms:
- *
- * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
- * XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.TT.TT.TT.TT
- * XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.LL.LL
- *
- * where:
- *
- * TT.TT.TT.TT is a 32-bit Toeplitz hash
- * LL.LL is a 16-bit LFSR hash
- *
- * Hash values are in network (big-endian) byte order.
- */
-
-#define EFX_RX_PREFIX_SIZE 16
-
-#define EFX_RX_HASH_VALUE(_func, _buffer) \
- (((_func) == EFX_RX_HASHALG_LFSR) ? \
- ((uint16_t)(((_buffer)[14] << 8) | (_buffer)[15])) : \
- ((uint32_t)(((_buffer)[12] << 24) | \
- ((_buffer)[13] << 16) | \
- ((_buffer)[14] << 8) | \
- (_buffer)[15])))
-
-#define EFX_RX_HASH_SIZE(_func) \
- (((_func) == EFX_RX_HASHALG_LFSR) ? \
- sizeof (uint16_t) : \
- sizeof (uint32_t))
+ __in efx_rx_hash_alg_t func,
+ __in uint8_t *buffer);
#endif /* EFSYS_OPT_RX_SCALE */
+extern __checkReturn int
+efx_psuedo_hdr_pkt_length_get(
+ __in efx_nic_t *enp,
+ __in uint8_t *buffer,
+ __out uint16_t *pkt_lengthp);
+
#define EFX_RXQ_MAXNDESCS 4096
#define EFX_RXQ_MINNDESCS 512
-#define EFX_RXQ_NDESCS_MASK EFX_MASK(EFX_RXQ_MAXNDESCS, EFX_RXQ_MINNDESCS)
-
#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)
@@ -1655,6 +1933,10 @@ typedef struct efx_buffer_s {
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,
@@ -1667,9 +1949,10 @@ efx_rx_qpost(
extern void
efx_rx_qpush(
__in efx_rxq_t *erp,
- __in unsigned int added);
+ __in unsigned int added,
+ __inout unsigned int *pushedp);
-extern void
+extern __checkReturn int
efx_rx_qflush(
__in efx_rxq_t *erp);
@@ -1687,10 +1970,10 @@ typedef struct efx_txq_s efx_txq_t;
#if EFSYS_OPT_QSTATS
-/* START MKCONFIG GENERATED EfxHeaderTransmitQueueBlock 536c5fa5014944bf */
+/* START MKCONFIG GENERATED EfxHeaderTransmitQueueBlock 12dff8778598b2db */
typedef enum efx_tx_qstat_e {
TX_POST,
- TX_UNALIGNED_SPLIT,
+ TX_POST_PIO,
TX_NQSTATS
} efx_tx_qstat_t;
@@ -1706,16 +1989,21 @@ extern void
efx_tx_fini(
__in efx_nic_t *enp);
-#define EFX_TXQ_MAXNDESCS 4096
-#define EFX_TXQ_MINNDESCS 512
+#define EFX_BUG35388_WORKAROUND(_encp) \
+ (((_encp) == NULL) ? 1 : ((_encp)->enc_bug35388_workaround != 0))
+
+#define EFX_TXQ_MAXNDESCS(_encp) \
+ ((EFX_BUG35388_WORKAROUND(_encp)) ? 2048 : 4096)
-#define EFX_TXQ_NDESCS_MASK EFX_MASK(EFX_TXQ_MAXNDESCS, EFX_TXQ_MINNDESCS)
+#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. */
+
extern __checkReturn int
efx_tx_qcreate(
__in efx_nic_t *enp,
@@ -1726,7 +2014,8 @@ efx_tx_qcreate(
__in uint32_t id,
__in uint16_t flags,
__in efx_evq_t *eep,
- __deref_out efx_txq_t **etpp);
+ __deref_out efx_txq_t **etpp,
+ __out unsigned int *addedp);
extern __checkReturn int
efx_tx_qpost(
@@ -1741,24 +2030,77 @@ efx_tx_qpace(
__in efx_txq_t *etp,
__in unsigned int ns);
-extern void
+extern void
efx_tx_qpush(
- __in efx_txq_t *etp,
- __in unsigned int added);
+ __in efx_txq_t *etp,
+ __in unsigned int added,
+ __in unsigned int pushed);
-extern void
+extern __checkReturn int
efx_tx_qflush(
- __in efx_txq_t *etp);
+ __in efx_txq_t *etp);
-extern void
+extern void
efx_tx_qenable(
- __in efx_txq_t *etp);
+ __in efx_txq_t *etp);
+
+extern __checkReturn int
+efx_tx_qpio_enable(
+ __in efx_txq_t *etp);
+
+extern void
+efx_tx_qpio_disable(
+ __in efx_txq_t *etp);
+
+extern __checkReturn int
+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 int
+efx_tx_qpio_post(
+ __in efx_txq_t *etp,
+ __in size_t pkt_length,
+ __in unsigned int completed,
+ __inout unsigned int *addedp);
+
+extern __checkReturn int
+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);
+
+extern void
+efx_tx_qdesc_vlantci_create(
+ __in efx_txq_t *etp,
+ __in uint16_t tci,
+ __out efx_desc_t *edp);
#if EFSYS_OPT_QSTATS
#if EFSYS_OPT_NAMES
-extern const char __cs *
+extern const char *
efx_tx_qstat_name(
__in efx_nic_t *etp,
__in unsigned int id);
@@ -1781,21 +2123,89 @@ efx_tx_qdestroy(
#if EFSYS_OPT_FILTER
+#define EFX_ETHER_TYPE_IPV4 0x0800
+#define EFX_ETHER_TYPE_IPV6 0x86DD
+
+#define EFX_IPPROTO_TCP 6
+#define EFX_IPPROTO_UDP 17
+
typedef enum efx_filter_flag_e {
EFX_FILTER_FLAG_RX_RSS = 0x01, /* use RSS to spread across
* multiple queues */
EFX_FILTER_FLAG_RX_SCATTER = 0x02, /* enable RX scatter */
- EFX_FILTER_FLAG_RX_OVERRIDE_IP = 0x04, /* MAC filter overrides
- * any matching IP filter */
+ EFX_FILTER_FLAG_RX_OVER_AUTO = 0x04, /* Override an automatic filter
+ * (priority EFX_FILTER_PRI_AUTO).
+ * May only be set by the filter
+ * implementation for each type.
+ * A removal request will
+ * restore the automatic filter
+ * in its place. */
+ EFX_FILTER_FLAG_RX = 0x08, /* Filter is for RX */
+ EFX_FILTER_FLAG_TX = 0x10, /* Filter is for TX */
} efx_filter_flag_t;
+typedef enum efx_filter_match_flags_e {
+ EFX_FILTER_MATCH_REM_HOST = 0x0001, /* Match by remote IP host
+ * address */
+ EFX_FILTER_MATCH_LOC_HOST = 0x0002, /* Match by local IP host
+ * address */
+ EFX_FILTER_MATCH_REM_MAC = 0x0004, /* Match by remote MAC address */
+ EFX_FILTER_MATCH_REM_PORT = 0x0008, /* Match by remote TCP/UDP port */
+ EFX_FILTER_MATCH_LOC_MAC = 0x0010, /* Match by remote TCP/UDP port */
+ EFX_FILTER_MATCH_LOC_PORT = 0x0020, /* Match by local TCP/UDP port */
+ EFX_FILTER_MATCH_ETHER_TYPE = 0x0040, /* Match by Ether-type */
+ EFX_FILTER_MATCH_INNER_VID = 0x0080, /* Match by inner VLAN ID */
+ EFX_FILTER_MATCH_OUTER_VID = 0x0100, /* Match by outer VLAN ID */
+ EFX_FILTER_MATCH_IP_PROTO = 0x0200, /* Match by IP transport
+ * protocol */
+ EFX_FILTER_MATCH_LOC_MAC_IG = 0x0400, /* Match by local MAC address
+ * I/G bit. Used for RX default
+ * unicast and multicast/
+ * broadcast filters. */
+} efx_filter_match_flags_t;
+
+typedef enum efx_filter_priority_s {
+ EFX_FILTER_PRI_HINT = 0, /* Performance hint */
+ EFX_FILTER_PRI_AUTO, /* Automatic filter based on device
+ * address list or hardware
+ * requirements. This may only be used
+ * by the filter implementation for
+ * each NIC type. */
+ EFX_FILTER_PRI_MANUAL, /* Manually configured filter */
+ EFX_FILTER_PRI_REQUIRED, /* Required for correct behaviour of the
+ * client (e.g. SR-IOV, HyperV VMQ etc.)
+ */
+} efx_filter_priority_t;
+
+/*
+ * FIXME: All these fields are assumed to be in little-endian byte order.
+ * It may be better for some to be big-endian. See bug42804.
+ */
+
typedef struct efx_filter_spec_s {
- uint8_t efs_type;
- uint8_t efs_flags;
- uint16_t efs_dmaq_id;
- uint32_t efs_dword[3];
+ uint32_t efs_match_flags:12;
+ uint32_t efs_priority:2;
+ uint32_t efs_flags:6;
+ uint32_t efs_dmaq_id:12;
+ uint32_t efs_rss_context;
+ uint16_t efs_outer_vid;
+ uint16_t efs_inner_vid;
+ uint8_t efs_loc_mac[EFX_MAC_ADDR_LEN];
+ uint8_t efs_rem_mac[EFX_MAC_ADDR_LEN];
+ uint16_t efs_ether_type;
+ uint8_t efs_ip_proto;
+ uint16_t efs_loc_port;
+ uint16_t efs_rem_port;
+ efx_oword_t efs_rem_host;
+ efx_oword_t efs_loc_host;
} efx_filter_spec_t;
+
+/* Default values for use in filter specifications */
+#define EFX_FILTER_SPEC_RSS_CONTEXT_DEFAULT 0xffffffff
+#define EFX_FILTER_SPEC_RX_DMAQ_ID_DROP 0xfff
+#define EFX_FILTER_SPEC_VID_UNSPEC 0xffff
+
extern __checkReturn int
efx_filter_init(
__in efx_nic_t *enp);
@@ -1805,115 +2215,82 @@ efx_filter_fini(
__in efx_nic_t *enp);
extern __checkReturn int
-efx_rx_filter_insert(
- __in efx_rxq_t *erp,
+efx_filter_insert(
+ __in efx_nic_t *enp,
__inout efx_filter_spec_t *spec);
extern __checkReturn int
-efx_rx_filter_remove(
- __in efx_rxq_t *erp,
+efx_filter_remove(
+ __in efx_nic_t *enp,
__inout efx_filter_spec_t *spec);
- void
+extern __checkReturn int
efx_filter_restore(
__in efx_nic_t *enp);
-extern void
-efx_filter_spec_rx_ipv4_tcp_full(
- __inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint32_t src_ip,
- __in uint16_t src_tcp,
- __in uint32_t dest_ip,
- __in uint16_t dest_tcp);
+extern __checkReturn int
+efx_filter_supported_filters(
+ __in efx_nic_t *enp,
+ __out uint32_t *list,
+ __out size_t *length);
extern void
-efx_filter_spec_rx_ipv4_tcp_wild(
+efx_filter_spec_init_rx(
__inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint32_t dest_ip,
- __in uint16_t dest_tcp);
+ __in efx_filter_priority_t priority,
+ __in efx_filter_flag_t flags,
+ __in efx_rxq_t *erp);
extern void
-efx_filter_spec_rx_ipv4_udp_full(
+efx_filter_spec_init_tx(
__inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint32_t src_ip,
- __in uint16_t src_udp,
- __in uint32_t dest_ip,
- __in uint16_t dest_udp);
+ __in efx_txq_t *etp);
-extern void
-efx_filter_spec_rx_ipv4_udp_wild(
+extern __checkReturn int
+efx_filter_spec_set_ipv4_local(
__inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint32_t dest_ip,
- __in uint16_t dest_udp);
+ __in uint8_t proto,
+ __in uint32_t host,
+ __in uint16_t port);
-extern void
-efx_filter_spec_rx_mac_full(
+extern __checkReturn int
+efx_filter_spec_set_ipv4_full(
__inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint16_t vlan_id,
- __in uint8_t *dest_mac);
+ __in uint8_t proto,
+ __in uint32_t lhost,
+ __in uint16_t lport,
+ __in uint32_t rhost,
+ __in uint16_t rport);
-extern void
-efx_filter_spec_rx_mac_wild(
+extern __checkReturn int
+efx_filter_spec_set_eth_local(
__inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint8_t *dest_mac);
-
+ __in uint16_t vid,
+ __in const uint8_t *addr);
extern __checkReturn int
-efx_tx_filter_insert(
- __in efx_txq_t *etp,
+efx_filter_spec_set_uc_def(
__inout efx_filter_spec_t *spec);
extern __checkReturn int
-efx_tx_filter_remove(
- __in efx_txq_t *etp,
+efx_filter_spec_set_mc_def(
__inout efx_filter_spec_t *spec);
-extern void
-efx_filter_spec_tx_ipv4_tcp_full(
- __inout efx_filter_spec_t *spec,
- __in uint32_t src_ip,
- __in uint16_t src_tcp,
- __in uint32_t dest_ip,
- __in uint16_t dest_tcp);
-
-extern void
-efx_filter_spec_tx_ipv4_tcp_wild(
- __inout efx_filter_spec_t *spec,
- __in uint32_t src_ip,
- __in uint16_t src_tcp);
-
-extern void
-efx_filter_spec_tx_ipv4_udp_full(
- __inout efx_filter_spec_t *spec,
- __in uint32_t src_ip,
- __in uint16_t src_udp,
- __in uint32_t dest_ip,
- __in uint16_t dest_udp);
-
-extern void
-efx_filter_spec_tx_ipv4_udp_wild(
- __inout efx_filter_spec_t *spec,
- __in uint32_t src_ip,
- __in uint16_t src_udp);
+#endif /* EFSYS_OPT_FILTER */
-extern void
-efx_filter_spec_tx_mac_full(
- __inout efx_filter_spec_t *spec,
- __in uint16_t vlan_id,
- __in uint8_t *src_mac);
+/* HASH */
-extern void
-efx_filter_spec_tx_mac_wild(
- __inout efx_filter_spec_t *spec,
- __in uint8_t *src_mac);
+extern __checkReturn uint32_t
+efx_hash_dwords(
+ __in_ecount(count) uint32_t const *input,
+ __in size_t count,
+ __in uint32_t init);
-#endif /* EFSYS_OPT_FILTER */
+extern __checkReturn uint32_t
+efx_hash_bytes(
+ __in_ecount(length) uint8_t const *input,
+ __in size_t length,
+ __in uint32_t init);
#ifdef __cplusplus
diff --git a/sys/dev/sfxge/common/efx_bootcfg.c b/sys/dev/sfxge/common/efx_bootcfg.c
index d770a5c..330f69d 100644
--- a/sys/dev/sfxge/common/efx_bootcfg.c
+++ b/sys/dev/sfxge/common/efx_bootcfg.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -64,7 +69,7 @@ efx_bootcfg_verify(
__in efx_nic_t *enp,
__in_bcount(size) caddr_t data,
__in size_t size,
- __out size_t *usedp)
+ __out_opt size_t *usedp)
{
size_t offset = 0;
size_t used = 0;
diff --git a/sys/dev/sfxge/common/efx_check.h b/sys/dev/sfxge/common/efx_check.h
new file mode 100644
index 0000000..9e590a4
--- /dev/null
+++ b/sys/dev/sfxge/common/efx_check.h
@@ -0,0 +1,388 @@
+/*-
+ * Copyright (c) 2012-2015 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.
+ *
+ * $FreeBSD$
+ */
+
+#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).
+ */
+
+/* Support NVRAM based boot config */
+#if EFSYS_OPT_BOOTCFG
+# if !EFSYS_OPT_NVRAM
+# error "BOOTCFG requires NVRAM"
+# endif
+#endif /* EFSYS_OPT_BOOTCFG */
+
+/* Verify chip implements accessed registers */
+#if EFSYS_OPT_CHECK_REG
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "CHECK_REG requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_CHECK_REG */
+
+/* Decode fatal errors */
+#if EFSYS_OPT_DECODE_INTR_FATAL
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA)
+# if EFSYS_OPT_HUNTINGTON
+# error "INTR_FATAL not supported on HUNTINGTON"
+# endif
+# error "INTR_FATAL requires FALCON or SIENA"
+# endif
+#endif /* EFSYS_OPT_DECODE_INTR_FATAL */
+
+/* Support diagnostic hardware tests */
+#if EFSYS_OPT_DIAG
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "DIAG requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_DIAG */
+
+/* Support optimized EVQ data access */
+#if EFSYS_OPT_EV_PREFETCH
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "EV_PREFETCH requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_EV_PREFETCH */
+
+/* Support overriding the NVRAM and VPD configuration */
+#if EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE
+# if !EFSYS_OPT_FALCON
+# error "FALCON_NIC_CFG_OVERRIDE requires FALCON"
+# endif
+#endif /* EFSYS_OPT_FALCON_NIC_CFG_OVERRIDE */
+
+/* Support hardware packet filters */
+#if EFSYS_OPT_FILTER
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "FILTER requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_FILTER */
+
+#if EFSYS_OPT_HUNTINGTON
+# if !EFSYS_OPT_FILTER
+# error "HUNTINGTON requires FILTER"
+# endif
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+/* Support hardware loopback modes */
+#if EFSYS_OPT_LOOPBACK
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "LOOPBACK requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_LOOPBACK */
+
+/* Support Falcon GMAC */
+#if EFSYS_OPT_MAC_FALCON_GMAC
+# if !EFSYS_OPT_FALCON
+# error "MAC_FALCON_GMAC requires FALCON"
+# endif
+#endif /* EFSYS_OPT_MAC_FALCON_GMAC */
+
+/* Support Falcon XMAC */
+#if EFSYS_OPT_MAC_FALCON_XMAC
+# if !EFSYS_OPT_FALCON
+# error "MAC_FALCON_XMAC requires FALCON"
+# endif
+#endif /* EFSYS_OPT_MAC_FALCON_XMAC */
+
+/* Support MAC statistics */
+#if EFSYS_OPT_MAC_STATS
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "MAC_STATS requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_MAC_STATS */
+
+/* Support management controller messages */
+#if EFSYS_OPT_MCDI
+# if !(EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# if EFSYS_OPT_FALCON
+# error "MCDI not supported on FALCON"
+# endif
+# error "MCDI requires SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_MCDI */
+
+#if EFSYS_OPT_SIENA && !EFSYS_OPT_MCDI
+# error "SIENA requires MCDI"
+#endif
+#if EFSYS_OPT_HUNTINGTON && !EFSYS_OPT_MCDI
+# error "HUNTINGTON requires MCDI"
+#endif
+
+/* Support LM87 monitor */
+#if EFSYS_OPT_MON_LM87
+# if !EFSYS_OPT_FALCON
+# error "MON_LM87 requires FALCON"
+# endif
+#endif /* EFSYS_OPT_MON_LM87 */
+
+/* Support MAX6647 monitor */
+#if EFSYS_OPT_MON_MAX6647
+# if !EFSYS_OPT_FALCON
+# error "MON_MAX6647 requires FALCON"
+# endif
+#endif /* EFSYS_OPT_MON_MAX6647 */
+
+/* Support null monitor */
+#if EFSYS_OPT_MON_NULL
+# if !EFSYS_OPT_FALCON
+# error "MON_NULL requires FALCON"
+# endif
+#endif /* EFSYS_OPT_MON_NULL */
+
+/* Support Siena monitor */
+#ifdef EFSYS_OPT_MON_SIENA
+# error "MON_SIENA is obsolete use MON_MCDI"
+#endif /* EFSYS_OPT_MON_SIENA*/
+
+/* Support Huntington monitor */
+#ifdef EFSYS_OPT_MON_HUNTINGTON
+# error "MON_HUNTINGTON is obsolete use MON_MCDI"
+#endif /* EFSYS_OPT_MON_HUNTINGTON*/
+
+/* Support monitor statistics (voltage/temperature) */
+#if EFSYS_OPT_MON_STATS
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "MON_STATS requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_MON_STATS */
+
+/* Support Monitor via mcdi */
+#if EFSYS_OPT_MON_MCDI
+# if !(EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "MON_MCDI requires SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_MON_MCDI*/
+
+/* Support printable names for statistics */
+#if EFSYS_OPT_NAMES
+# if !(EFSYS_OPT_LOOPBACK || EFSYS_OPT_MAC_STATS || EFSYS_OPT_MCDI || \
+ EFSYS_MON_STATS || EFSYS_OPT_PHY_PROPS || EFSYS_OPT_PHY_STATS || \
+ EFSYS_OPT_QSTATS)
+# error "NAMES requires LOOPBACK or xxxSTATS or MCDI or PHY_PROPS"
+# endif
+#endif /* EFSYS_OPT_NAMES */
+
+/* Support non volatile configuration */
+#if EFSYS_OPT_NVRAM
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "NVRAM requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_NVRAM */
+
+/* Support Falcon bootrom */
+#if EFSYS_OPT_NVRAM_FALCON_BOOTROM
+# if !EFSYS_OPT_NVRAM
+# error "NVRAM_FALCON_BOOTROM requires NVRAM"
+# endif
+# if !EFSYS_OPT_FALCON
+# error "NVRAM_FALCON_BOOTROM requires FALCON"
+# endif
+#endif /* EFSYS_OPT_NVRAM_FALCON_BOOTROM */
+
+/* Support NVRAM config for SFT9001 */
+#if EFSYS_OPT_NVRAM_SFT9001
+# if !EFSYS_OPT_NVRAM
+# error "NVRAM_SFT9001 requires NVRAM"
+# endif
+# if !EFSYS_OPT_FALCON
+# error "NVRAM_SFT9001 requires FALCON"
+# endif
+#endif /* EFSYS_OPT_NVRAM_SFT9001 */
+
+/* Support NVRAM config for SFX7101 */
+#if EFSYS_OPT_NVRAM_SFX7101
+# if !EFSYS_OPT_NVRAM
+# error "NVRAM_SFX7101 requires NVRAM"
+# endif
+# if !EFSYS_OPT_FALCON
+# error "NVRAM_SFX7101 requires FALCON"
+# endif
+#endif /* EFSYS_OPT_NVRAM_SFX7101 */
+
+/* Support PCIe interface tuning */
+#if EFSYS_OPT_PCIE_TUNE
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA)
+# error "PCIE_TUNE requires FALCON or SIENA"
+# endif
+#endif /* EFSYS_OPT_PCIE_TUNE */
+
+/* Support PHY BIST diagnostics */
+#if EFSYS_OPT_PHY_BIST
+# error "PHY_BIST is obsolete. It has been replaced by the BIST option."
+#endif /* EFSYS_OPT_PHY_BIST */
+
+/* Support PHY flags */
+#if EFSYS_OPT_PHY_FLAGS
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA)
+# error "PHY_FLAGS requires FALCON or SIENA"
+# endif
+#endif /* EFSYS_OPT_PHY_FLAGS */
+
+/* Support for PHY LED control */
+#if EFSYS_OPT_PHY_LED_CONTROL
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA)
+# error "PHY_LED_CONTROL requires FALCON or SIENA"
+# endif
+#endif /* EFSYS_OPT_PHY_LED_CONTROL */
+
+/* Support NULL PHY */
+#if EFSYS_OPT_PHY_NULL
+# if !EFSYS_OPT_FALCON
+# error "PHY_NULL requires FALCON"
+# endif
+#endif /* EFSYS_OPT_PHY_NULL */
+
+/* Obsolete option */
+#ifdef EFSYS_OPT_PHY_PM8358
+# error "EFSYS_OPT_PHY_PM8358 is obsolete and is not supported."
+#endif
+
+/* Support PHY properties */
+#if EFSYS_OPT_PHY_PROPS
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA)
+# error "PHY_PROPS requires FALCON or SIENA"
+# endif
+#endif /* EFSYS_OPT_PHY_PROPS */
+
+/* Support QT2022C2 PHY */
+#if EFSYS_OPT_PHY_QT2022C2
+# if !EFSYS_OPT_FALCON
+# error "PHY_QT2022C2 requires FALCON"
+# endif
+#endif /* EFSYS_OPT_PHY_QT2022C2 */
+
+/* Support QT2025C PHY (Wakefield NIC) */
+#if EFSYS_OPT_PHY_QT2025C
+# if !EFSYS_OPT_FALCON
+# error "PHY_QT2025C requires FALCON"
+# endif
+#endif /* EFSYS_OPT_PHY_QT2025C */
+
+/* Support SFT9001 PHY (Starbolt NIC) */
+#if EFSYS_OPT_PHY_SFT9001
+# if !EFSYS_OPT_FALCON
+# error "PHY_SFT9001 requires FALCON"
+# endif
+#endif /* EFSYS_OPT_PHY_SFT9001 */
+
+/* Support SFX7101 PHY (SFE4001 NIC) */
+#if EFSYS_OPT_PHY_SFX7101
+# if !EFSYS_OPT_FALCON
+# error "PHY_SFX7101 requires FALCON"
+# endif
+#endif /* EFSYS_OPT_PHY_SFX7101 */
+
+/* Support PHY statistics */
+#if EFSYS_OPT_PHY_STATS
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA)
+# error "PHY_STATS requires FALCON or SIENA"
+# endif
+#endif /* EFSYS_OPT_PHY_STATS */
+
+/* Support TXC43128 PHY (SFE4003 NIC) */
+#if EFSYS_OPT_PHY_TXC43128
+# if !EFSYS_OPT_FALCON
+# error "PHY_TXC43128 requires FALCON"
+# endif
+#endif /* EFSYS_OPT_PHY_TXC43128 */
+
+/* Support EVQ/RXQ/TXQ statistics */
+#if EFSYS_OPT_QSTATS
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "QSTATS requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_QSTATS */
+
+/* Support receive header split */
+#if EFSYS_OPT_RX_HDR_SPLIT
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "RX_HDR_SPLIT requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_RX_HDR_SPLIT */
+
+/* Support receive scaling (RSS) */
+#if EFSYS_OPT_RX_SCALE
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "RX_SCALE requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_RX_SCALE */
+
+/* Support receive scatter DMA */
+#if EFSYS_OPT_RX_SCATTER
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "RX_SCATTER requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_RX_SCATTER */
+
+/* Obsolete option */
+#ifdef EFSYS_OPT_STAT_NAME
+# error "EFSYS_OPT_STAT_NAME is obsolete (replaced by EFSYS_OPT_NAMES)."
+#endif
+
+/* Support PCI Vital Product Data (VPD) */
+#if EFSYS_OPT_VPD
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "VPD requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_VPD */
+
+/* Support Wake on LAN */
+#if EFSYS_OPT_WOL
+# if !EFSYS_OPT_SIENA
+# error "WOL requires SIENA"
+# endif
+#endif /* EFSYS_OPT_WOL */
+
+/* Support calculating multicast pktfilter in common code */
+#if EFSYS_OPT_MCAST_FILTER_LIST
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "MCAST_FILTER_LIST requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_MCAST_FILTER_LIST */
+
+/* Support BIST */
+#if EFSYS_OPT_BIST
+# if !(EFSYS_OPT_FALCON || EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON)
+# error "BIST requires FALCON or SIENA or HUNTINGTON"
+# endif
+#endif /* EFSYS_OPT_BIST */
+
+#endif /* _SYS_EFX_CHECK_H */
diff --git a/sys/dev/sfxge/common/efx_crc32.c b/sys/dev/sfxge/common/efx_crc32.c
new file mode 100644
index 0000000..7e4cfc4
--- /dev/null
+++ b/sys/dev/sfxge/common/efx_crc32.c
@@ -0,0 +1,127 @@
+/*-
+ * Copyright (c) 2013-2015 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_types.h"
+#include "efx_impl.h"
+
+/*
+ * Precomputed table for computing IEEE 802.3 CRC32
+ * with polynomial 0x04c11db7 (bit-reversed 0xedb88320)
+ */
+
+static const uint32_t 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) ^ crc32_table[(crc ^ data) & 0xff];
+ }
+
+ return (crc);
+}
diff --git a/sys/dev/sfxge/common/efx_ev.c b/sys/dev/sfxge/common/efx_ev.c
index fff7803..9669fc4 100644
--- a/sys/dev/sfxge/common/efx_ev.c
+++ b/sys/dev/sfxge/common/efx_ev.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -31,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include "efx_types.h"
#include "efx_regs.h"
#include "efx_impl.h"
+#include "mcdi_mon.h"
#if EFSYS_OPT_QSTATS
#define EFX_EV_QSTAT_INCR(_eep, _stat) \
@@ -42,11 +48,118 @@ __FBSDID("$FreeBSD$");
#define EFX_EV_QSTAT_INCR(_eep, _stat)
#endif
+#define EFX_EV_PRESENT(_qword) \
+ (EFX_QWORD_FIELD((_qword), EFX_DWORD_0) != 0xffffffff && \
+ EFX_QWORD_FIELD((_qword), EFX_DWORD_1) != 0xffffffff)
+
+
+
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+static __checkReturn int
+falconsiena_ev_init(
+ __in efx_nic_t *enp);
+
+static void
+falconsiena_ev_fini(
+ __in efx_nic_t *enp);
+
+static __checkReturn int
+falconsiena_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 efx_evq_t *eep);
+
+static void
+falconsiena_ev_qdestroy(
+ __in efx_evq_t *eep);
+
+static __checkReturn int
+falconsiena_ev_qprime(
+ __in efx_evq_t *eep,
+ __in unsigned int count);
+
+static void
+falconsiena_ev_qpoll(
+ __in efx_evq_t *eep,
+ __inout unsigned int *countp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg);
+
+static void
+falconsiena_ev_qpost(
+ __in efx_evq_t *eep,
+ __in uint16_t data);
+
+static __checkReturn int
+falconsiena_ev_qmoderate(
+ __in efx_evq_t *eep,
+ __in unsigned int us);
+
+#if EFSYS_OPT_QSTATS
+static void
+falconsiena_ev_qstats_update(
+ __in efx_evq_t *eep,
+ __inout_ecount(EV_NQSTATS) efsys_stat_t *stat);
+
+#endif
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_FALCON
+static efx_ev_ops_t __efx_ev_falcon_ops = {
+ falconsiena_ev_init, /* eevo_init */
+ falconsiena_ev_fini, /* eevo_fini */
+ falconsiena_ev_qcreate, /* eevo_qcreate */
+ falconsiena_ev_qdestroy, /* eevo_qdestroy */
+ falconsiena_ev_qprime, /* eevo_qprime */
+ falconsiena_ev_qpost, /* eevo_qpost */
+ falconsiena_ev_qmoderate, /* eevo_qmoderate */
+#if EFSYS_OPT_QSTATS
+ falconsiena_ev_qstats_update, /* eevo_qstats_update */
+#endif
+};
+#endif /* EFSYS_OPT_FALCON */
+
+#if EFSYS_OPT_SIENA
+static efx_ev_ops_t __efx_ev_siena_ops = {
+ falconsiena_ev_init, /* eevo_init */
+ falconsiena_ev_fini, /* eevo_fini */
+ falconsiena_ev_qcreate, /* eevo_qcreate */
+ falconsiena_ev_qdestroy, /* eevo_qdestroy */
+ falconsiena_ev_qprime, /* eevo_qprime */
+ falconsiena_ev_qpost, /* eevo_qpost */
+ falconsiena_ev_qmoderate, /* eevo_qmoderate */
+#if EFSYS_OPT_QSTATS
+ falconsiena_ev_qstats_update, /* eevo_qstats_update */
+#endif
+};
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+static efx_ev_ops_t __efx_ev_hunt_ops = {
+ hunt_ev_init, /* eevo_init */
+ hunt_ev_fini, /* eevo_fini */
+ hunt_ev_qcreate, /* eevo_qcreate */
+ hunt_ev_qdestroy, /* eevo_qdestroy */
+ hunt_ev_qprime, /* eevo_qprime */
+ hunt_ev_qpost, /* eevo_qpost */
+ hunt_ev_qmoderate, /* eevo_qmoderate */
+#if EFSYS_OPT_QSTATS
+ hunt_ev_qstats_update, /* eevo_qstats_update */
+#endif
+};
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+
__checkReturn int
efx_ev_init(
__in efx_nic_t *enp)
{
- efx_oword_t oword;
+ efx_ev_ops_t *eevop;
int rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
@@ -57,8 +170,290 @@ efx_ev_init(
goto fail1;
}
+ switch (enp->en_family) {
+#if EFSYS_OPT_FALCON
+ case EFX_FAMILY_FALCON:
+ eevop = (efx_ev_ops_t *)&__efx_ev_falcon_ops;
+ break;
+#endif /* EFSYS_OPT_FALCON */
+
+#if EFSYS_OPT_SIENA
+ case EFX_FAMILY_SIENA:
+ eevop = (efx_ev_ops_t *)&__efx_ev_siena_ops;
+ break;
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ eevop = (efx_ev_ops_t *)&__efx_ev_hunt_ops;
+ break;
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+ 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, int, rc);
+
+ enp->en_eevop = NULL;
+ enp->en_mod_flags &= ~EFX_MOD_EV;
+ return (rc);
+}
+
+ void
+efx_ev_fini(
+ __in efx_nic_t *enp)
+{
+ 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 int
+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,
+ __deref_out efx_evq_t **eepp)
+{
+ efx_ev_ops_t *eevop = enp->en_eevop;
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_evq_t *eep;
+ int 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);
+
+ /* Allocate an EVQ object */
+ EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_evq_t), eep);
+ if (eep == NULL) {
+ rc = ENOMEM;
+ goto fail1;
+ }
+
+ eep->ee_magic = EFX_EVQ_MAGIC;
+ eep->ee_enp = enp;
+ eep->ee_index = index;
+ eep->ee_mask = n - 1;
+ eep->ee_esmp = esmp;
+
+ if ((rc = eevop->eevo_qcreate(enp, index, esmp, n, id, eep)) != 0)
+ goto fail2;
+
+ enp->en_ev_qcount++;
+ *eepp = eep;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+ EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_evq_t), eep);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+
+ void
+efx_ev_qdestroy(
+ __in efx_evq_t *eep)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ 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 int
+efx_ev_qprime(
+ __in efx_evq_t *eep,
+ __in unsigned int count)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ efx_ev_ops_t *eevop = enp->en_eevop;
+ int 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, int, 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));
+}
+
+#if EFSYS_OPT_EV_PREFETCH
+
+ void
+efx_ev_qprefetch(
+ __in efx_evq_t *eep,
+ __in unsigned int count)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ unsigned int offset;
+
+ EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
+
+ offset = (count & eep->ee_mask) * sizeof (efx_qword_t);
+ EFSYS_MEM_PREFETCH(eep->ee_esmp, offset);
+}
+
+#endif /* EFSYS_OPT_EV_PREFETCH */
+
+ void
+efx_ev_qpoll(
+ __in efx_evq_t *eep,
+ __inout unsigned int *countp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg)
+{
+ EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
+
+ /*
+ * FIXME: Huntington will require support for hardware event batching
+ * and merging, which will need a different ev_qpoll implementation.
+ *
+ * Without those features the Falcon/Siena code can be used unchanged.
+ */
+ 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);
+#if EFSYS_OPT_MCDI
+ EFX_STATIC_ASSERT(ESE_DZ_EV_CODE_MCDI_EV ==
+ FSE_AZ_EV_CODE_MCDI_EVRESPONSE);
+#endif
+ falconsiena_ev_qpoll(eep, countp, eecp, arg);
+}
+
+ void
+efx_ev_qpost(
+ __in efx_evq_t *eep,
+ __in uint16_t data)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ 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 int
+efx_ev_qmoderate(
+ __in efx_evq_t *eep,
+ __in unsigned int us)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ efx_ev_ops_t *eevop = enp->en_eevop;
+ int rc;
+
+ EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
+
+ if ((rc = eevop->eevo_qmoderate(eep, us)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+
+#if EFSYS_OPT_QSTATS
+ void
+efx_ev_qstats_update(
+ __in efx_evq_t *eep,
+ __inout_ecount(EV_NQSTATS) efsys_stat_t *stat)
+
+{ efx_nic_t *enp = eep->ee_enp;
+ efx_ev_ops_t *eevop = enp->en_eevop;
+
+ EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
+
+ eevop->eevo_qstats_update(eep, stat);
+}
+
+#endif /* EFSYS_OPT_QSTATS */
+
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+static __checkReturn int
+falconsiena_ev_init(
+ __in efx_nic_t *enp)
+{
+ efx_oword_t oword;
+
/*
* Program the event queue for receive and transmit queue
* flush events.
@@ -67,17 +462,12 @@ efx_ev_init(
EFX_SET_OWORD_FIELD(oword, FRF_AZ_FLS_EVQ_ID, 0);
EFX_BAR_WRITEO(enp, FR_AZ_DP_CTRL_REG, &oword);
- enp->en_mod_flags |= EFX_MOD_EV;
return (0);
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
}
static __checkReturn boolean_t
-efx_ev_rx_not_ok(
+falconsiena_ev_rx_not_ok(
__in efx_evq_t *eep,
__in efx_qword_t *eqp,
__in uint32_t label,
@@ -167,7 +557,7 @@ efx_ev_rx_not_ok(
}
static __checkReturn boolean_t
-efx_ev_rx(
+falconsiena_ev_rx(
__in efx_evq_t *eep,
__in efx_qword_t *eqp,
__in const efx_ev_callbacks_t *eecp,
@@ -264,7 +654,7 @@ efx_ev_rx(
/* Detect errors included in the FSF_AZ_RX_EV_PKT_OK indication */
if (!ok) {
- ignore = efx_ev_rx_not_ok(eep, eqp, label, id, &flags);
+ ignore = falconsiena_ev_rx_not_ok(eep, eqp, label, id, &flags);
if (ignore) {
EFSYS_PROBE4(rx_complete, uint32_t, label, uint32_t, id,
uint32_t, size, uint16_t, flags);
@@ -323,7 +713,7 @@ efx_ev_rx(
}
static __checkReturn boolean_t
-efx_ev_tx(
+falconsiena_ev_tx(
__in efx_evq_t *eep,
__in efx_qword_t *eqp,
__in const efx_ev_callbacks_t *eecp,
@@ -370,7 +760,7 @@ efx_ev_tx(
}
static __checkReturn boolean_t
-efx_ev_global(
+falconsiena_ev_global(
__in efx_evq_t *eep,
__in efx_qword_t *eqp,
__in const efx_ev_callbacks_t *eecp,
@@ -396,7 +786,7 @@ efx_ev_global(
}
static __checkReturn boolean_t
-efx_ev_driver(
+falconsiena_ev_driver(
__in efx_evq_t *eep,
__in efx_qword_t *eqp,
__in const efx_ev_callbacks_t *eecp,
@@ -437,7 +827,8 @@ efx_ev_driver(
EFSYS_PROBE1(rx_descq_fls_failed, uint32_t, rxq_index);
- should_abort = eecp->eec_rxq_flush_failed(arg, rxq_index);
+ should_abort = eecp->eec_rxq_flush_failed(arg,
+ rxq_index);
} else {
EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DESCQ_FLS_DONE);
@@ -524,7 +915,7 @@ efx_ev_driver(
}
static __checkReturn boolean_t
-efx_ev_drv_gen(
+falconsiena_ev_drv_gen(
__in efx_evq_t *eep,
__in efx_qword_t *eqp,
__in const efx_ev_callbacks_t *eecp,
@@ -552,7 +943,7 @@ efx_ev_drv_gen(
#if EFSYS_OPT_MCDI
static __checkReturn boolean_t
-efx_ev_mcdi(
+falconsiena_ev_mcdi(
__in efx_evq_t *eep,
__in efx_qword_t *eqp,
__in const efx_ev_callbacks_t *eecp,
@@ -583,9 +974,9 @@ efx_ev_mcdi(
case MCDI_EVENT_CODE_CMDDONE:
efx_mcdi_ev_cpl(enp,
- MCDI_EV_FIELD(eqp, CMDDONE_SEQ),
- MCDI_EV_FIELD(eqp, CMDDONE_DATALEN),
- MCDI_EV_FIELD(eqp, CMDDONE_ERRNO));
+ MCDI_EV_FIELD(eqp, CMDDONE_SEQ),
+ MCDI_EV_FIELD(eqp, CMDDONE_DATALEN),
+ MCDI_EV_FIELD(eqp, CMDDONE_ERRNO));
break;
case MCDI_EVENT_CODE_LINKCHANGE: {
@@ -601,7 +992,7 @@ efx_ev_mcdi(
efx_mon_stat_value_t value;
int rc;
- if ((rc = siena_mon_ev(enp, eqp, &id, &value)) == 0)
+ if ((rc = mcdi_mon_ev(enp, eqp, &id, &value)) == 0)
should_abort = eecp->eec_monitor(arg, id, value);
else if (rc == ENOTSUP) {
should_abort = eecp->eec_exception(arg,
@@ -656,22 +1047,14 @@ out:
#endif /* EFSYS_OPT_MCDI */
- __checkReturn int
-efx_ev_qprime(
+static __checkReturn int
+falconsiena_ev_qprime(
__in efx_evq_t *eep,
__in unsigned int count)
{
efx_nic_t *enp = eep->ee_enp;
uint32_t rptr;
efx_dword_t dword;
- int rc;
-
- EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
-
- if (!(enp->en_mod_flags & EFX_MOD_INTR)) {
- rc = EINVAL;
- goto fail1;
- }
rptr = count & eep->ee_mask;
@@ -681,55 +1064,12 @@ efx_ev_qprime(
&dword, B_FALSE);
return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, int, 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_QWORD_FIELD(qword, EFX_DWORD_0) != 0xffffffff &&
- EFX_QWORD_FIELD(qword, EFX_DWORD_1) != 0xffffffff);
-}
-
-#if EFSYS_OPT_EV_PREFETCH
-
- void
-efx_ev_qprefetch(
- __in efx_evq_t *eep,
- __in unsigned int count)
-{
- unsigned int offset;
-
- EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
-
- offset = (count & eep->ee_mask) * sizeof (efx_qword_t);
- EFSYS_MEM_PREFETCH(eep->ee_esmp, offset);
}
-#endif /* EFSYS_OPT_EV_PREFETCH */
-
#define EFX_EV_BATCH 8
-#define EFX_EV_PRESENT(_qword) \
- (EFX_QWORD_FIELD((_qword), EFX_DWORD_0) != 0xffffffff && \
- EFX_QWORD_FIELD((_qword), EFX_DWORD_1) != 0xffffffff)
-
- void
-efx_ev_qpoll(
+static void
+falconsiena_ev_qpoll(
__in efx_evq_t *eep,
__inout unsigned int *countp,
__in const efx_ev_callbacks_t *eecp,
@@ -742,7 +1082,6 @@ efx_ev_qpoll(
unsigned int index;
size_t offset;
- EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
EFSYS_ASSERT(countp != NULL);
EFSYS_ASSERT(eecp != NULL);
@@ -778,7 +1117,6 @@ efx_ev_qpoll(
for (index = 0; index < total; ++index) {
boolean_t should_abort;
uint32_t code;
- efx_ev_handler_t handler;
#if EFSYS_OPT_EV_PREFETCH
/* Prefetch if we've now reached the batch period */
@@ -794,9 +1132,49 @@ efx_ev_qpoll(
EFX_EV_QSTAT_INCR(eep, EV_ALL);
code = EFX_QWORD_FIELD(ev[index], FSF_AZ_EV_CODE);
- handler = eep->ee_handler[code];
- EFSYS_ASSERT(handler != NULL);
- should_abort = handler(eep, &(ev[index]), eecp, arg);
+ 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;
+#if EFSYS_OPT_MCDI
+ case FSE_AZ_EV_CODE_MCDI_EVRESPONSE:
+ should_abort = eep->ee_mcdi(eep,
+ &(ev[index]), eecp, arg);
+ break;
+#endif
+ 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;
@@ -823,8 +1201,8 @@ efx_ev_qpoll(
*countp = count;
}
- void
-efx_ev_qpost(
+static void
+falconsiena_ev_qpost(
__in efx_evq_t *eep,
__in uint16_t data)
{
@@ -832,8 +1210,6 @@ efx_ev_qpost(
efx_qword_t ev;
efx_oword_t oword;
- EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
-
EFX_POPULATE_QWORD_2(ev, FSF_AZ_EV_CODE, FSE_AZ_EV_CODE_DRV_GEN_EV,
FSF_AZ_EV_DATA_DW0, (uint32_t)data);
@@ -844,8 +1220,8 @@ efx_ev_qpost(
EFX_BAR_WRITEO(enp, FR_AZ_DRV_EV_REG, &oword);
}
- __checkReturn int
-efx_ev_qmoderate(
+static __checkReturn int
+falconsiena_ev_qmoderate(
__in efx_evq_t *eep,
__in unsigned int us)
{
@@ -855,8 +1231,6 @@ efx_ev_qmoderate(
efx_dword_t dword;
int rc;
- EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
-
if (us > encp->enc_evq_timer_max_us) {
rc = EINVAL;
goto fail1;
@@ -905,27 +1279,24 @@ fail1:
return (rc);
}
- __checkReturn int
-efx_ev_qcreate(
+static __checkReturn int
+falconsiena_ev_qcreate(
__in efx_nic_t *enp,
__in unsigned int index,
__in efsys_mem_t *esmp,
__in size_t n,
__in uint32_t id,
- __deref_out efx_evq_t **eepp)
+ __in efx_evq_t *eep)
{
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
uint32_t size;
- efx_evq_t *eep;
efx_oword_t oword;
int rc;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_EV);
+ EFX_STATIC_ASSERT(ISP2(EFX_EVQ_MAXNEVS));
+ EFX_STATIC_ASSERT(ISP2(EFX_EVQ_MINNEVS));
- EFSYS_ASSERT3U(enp->en_ev_qcount + 1, <, encp->enc_evq_limit);
-
- if (!ISP2(n) || !(n & EFX_EVQ_NEVS_MASK)) {
+ if (!ISP2(n) || (n < EFX_EVQ_MINNEVS) || (n > EFX_EVQ_MAXNEVS)) {
rc = EINVAL;
goto fail1;
}
@@ -949,46 +1320,29 @@ efx_ev_qcreate(
goto fail4;
}
- /* Allocate an EVQ object */
- EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_evq_t), eep);
- if (eep == NULL) {
- rc = ENOMEM;
- goto fail5;
- }
-
- eep->ee_magic = EFX_EVQ_MAGIC;
- eep->ee_enp = enp;
- eep->ee_index = index;
- eep->ee_mask = n - 1;
- eep->ee_esmp = esmp;
-
/* Set up the handler table */
- eep->ee_handler[FSE_AZ_EV_CODE_RX_EV] = efx_ev_rx;
- eep->ee_handler[FSE_AZ_EV_CODE_TX_EV] = efx_ev_tx;
- eep->ee_handler[FSE_AZ_EV_CODE_DRIVER_EV] = efx_ev_driver;
- eep->ee_handler[FSE_AZ_EV_CODE_GLOBAL_EV] = efx_ev_global;
- eep->ee_handler[FSE_AZ_EV_CODE_DRV_GEN_EV] = efx_ev_drv_gen;
+ eep->ee_rx = falconsiena_ev_rx;
+ eep->ee_tx = falconsiena_ev_tx;
+ eep->ee_driver = falconsiena_ev_driver;
+ eep->ee_global = falconsiena_ev_global;
+ eep->ee_drv_gen = falconsiena_ev_drv_gen;
#if EFSYS_OPT_MCDI
- eep->ee_handler[FSE_AZ_EV_CODE_MCDI_EVRESPONSE] = efx_ev_mcdi;
+ eep->ee_mcdi = falconsiena_ev_mcdi;
#endif /* EFSYS_OPT_MCDI */
/* Set up the new event queue */
if (enp->en_family != EFX_FAMILY_FALCON) {
EFX_POPULATE_OWORD_1(oword, FRF_CZ_TIMER_Q_EN, 1);
- EFX_BAR_TBL_WRITEO(enp, FR_AZ_TIMER_TBL, index, &oword);
+ EFX_BAR_TBL_WRITEO(enp, FR_AZ_TIMER_TBL, index, &oword, B_TRUE);
}
EFX_POPULATE_OWORD_3(oword, FRF_AZ_EVQ_EN, 1, FRF_AZ_EVQ_SIZE, size,
FRF_AZ_EVQ_BUF_BASE_ID, id);
- EFX_BAR_TBL_WRITEO(enp, FR_AZ_EVQ_PTR_TBL, index, &oword);
+ EFX_BAR_TBL_WRITEO(enp, FR_AZ_EVQ_PTR_TBL, index, &oword, B_TRUE);
- enp->en_ev_qcount++;
- *eepp = eep;
return (0);
-fail5:
- EFSYS_PROBE(fail5);
fail4:
EFSYS_PROBE(fail4);
#if EFSYS_OPT_RX_SCALE
@@ -1003,14 +1357,15 @@ fail1:
return (rc);
}
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
+
#if EFSYS_OPT_QSTATS
#if EFSYS_OPT_NAMES
-/* START MKCONFIG GENERATED EfxEventQueueStatNamesBlock 67e9bdcd920059bd */
-static const char __cs * __cs __efx_ev_qstat_name[] = {
+/* START MKCONFIG GENERATED EfxEventQueueStatNamesBlock b693ddf85aee1bfd */
+static const char *__efx_ev_qstat_name[] = {
"all",
"rx",
"rx_ok",
- "rx_recovery",
"rx_frm_trunc",
"rx_tobe_disc",
"rx_pause_frm_err",
@@ -1028,16 +1383,14 @@ static const char __cs * __cs __efx_ev_qstat_name[] = {
"rx_other_ipv4",
"rx_other_ipv6",
"rx_non_ip",
- "rx_overrun",
+ "rx_batch",
"tx",
"tx_wq_ff_full",
"tx_pkt_err",
"tx_pkt_too_big",
"tx_unexpected",
"global",
- "global_phy",
"global_mnt",
- "global_rx_recovery",
"driver",
"driver_srm_upd_done",
"driver_tx_descq_fls_done",
@@ -1050,7 +1403,7 @@ static const char __cs * __cs __efx_ev_qstat_name[] = {
};
/* END MKCONFIG GENERATED EfxEventQueueStatNamesBlock */
- const char __cs *
+ const char *
efx_ev_qstat_name(
__in efx_nic_t *enp,
__in unsigned int id)
@@ -1063,16 +1416,16 @@ efx_ev_qstat_name(
#endif /* EFSYS_OPT_NAMES */
#endif /* EFSYS_OPT_QSTATS */
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
#if EFSYS_OPT_QSTATS
- void
-efx_ev_qstats_update(
+static void
+falconsiena_ev_qstats_update(
__in efx_evq_t *eep,
__inout_ecount(EV_NQSTATS) efsys_stat_t *stat)
{
unsigned int id;
- EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
-
for (id = 0; id < EV_NQSTATS; id++) {
efsys_stat_t *essp = &stat[id];
@@ -1082,44 +1435,31 @@ efx_ev_qstats_update(
}
#endif /* EFSYS_OPT_QSTATS */
- void
-efx_ev_qdestroy(
+static void
+falconsiena_ev_qdestroy(
__in efx_evq_t *eep)
{
efx_nic_t *enp = eep->ee_enp;
efx_oword_t oword;
- EFSYS_ASSERT3U(eep->ee_magic, ==, EFX_EVQ_MAGIC);
-
- EFSYS_ASSERT(enp->en_ev_qcount != 0);
- --enp->en_ev_qcount;
-
/* Purge event queue */
EFX_ZERO_OWORD(oword);
EFX_BAR_TBL_WRITEO(enp, FR_AZ_EVQ_PTR_TBL,
- eep->ee_index, &oword);
+ eep->ee_index, &oword, B_TRUE);
if (enp->en_family != EFX_FAMILY_FALCON) {
EFX_ZERO_OWORD(oword);
EFX_BAR_TBL_WRITEO(enp, FR_AZ_TIMER_TBL,
- eep->ee_index, &oword);
+ eep->ee_index, &oword, B_TRUE);
}
-
- /* Free the EVQ object */
- EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_evq_t), eep);
}
- void
-efx_ev_fini(
+static void
+falconsiena_ev_fini(
__in efx_nic_t *enp)
{
- 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);
-
- enp->en_mod_flags &= ~EFX_MOD_EV;
+ _NOTE(ARGUNUSED(enp))
}
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
diff --git a/sys/dev/sfxge/common/efx_filter.c b/sys/dev/sfxge/common/efx_filter.c
index e8455db..7ae7ea5 100644
--- a/sys/dev/sfxge/common/efx_filter.c
+++ b/sys/dev/sfxge/common/efx_filter.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -35,24 +40,569 @@ __FBSDID("$FreeBSD$");
#if EFSYS_OPT_FILTER
-/* "Fudge factors" - difference between programmed value and actual depth.
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+static __checkReturn int
+falconsiena_filter_init(
+ __in efx_nic_t *enp);
+
+static void
+falconsiena_filter_fini(
+ __in efx_nic_t *enp);
+
+static __checkReturn int
+falconsiena_filter_restore(
+ __in efx_nic_t *enp);
+
+static __checkReturn int
+falconsiena_filter_add(
+ __in efx_nic_t *enp,
+ __inout efx_filter_spec_t *spec,
+ __in boolean_t may_replace);
+
+static __checkReturn int
+falconsiena_filter_delete(
+ __in efx_nic_t *enp,
+ __inout efx_filter_spec_t *spec);
+
+static __checkReturn int
+falconsiena_filter_supported_filters(
+ __in efx_nic_t *enp,
+ __out uint32_t *list,
+ __out size_t *length);
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_FALCON
+static efx_filter_ops_t __efx_filter_falcon_ops = {
+ falconsiena_filter_init, /* efo_init */
+ falconsiena_filter_fini, /* efo_fini */
+ falconsiena_filter_restore, /* efo_restore */
+ falconsiena_filter_add, /* efo_add */
+ falconsiena_filter_delete, /* efo_delete */
+ falconsiena_filter_supported_filters, /* efo_supported_filters */
+ NULL, /* efo_reconfigure */
+};
+#endif /* EFSYS_OPT_FALCON */
+
+#if EFSYS_OPT_SIENA
+static efx_filter_ops_t __efx_filter_siena_ops = {
+ falconsiena_filter_init, /* efo_init */
+ falconsiena_filter_fini, /* efo_fini */
+ falconsiena_filter_restore, /* efo_restore */
+ falconsiena_filter_add, /* efo_add */
+ falconsiena_filter_delete, /* efo_delete */
+ falconsiena_filter_supported_filters, /* efo_supported_filters */
+ NULL, /* efo_reconfigure */
+};
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+static efx_filter_ops_t __efx_filter_hunt_ops = {
+ hunt_filter_init, /* efo_init */
+ hunt_filter_fini, /* efo_fini */
+ hunt_filter_restore, /* efo_restore */
+ hunt_filter_add, /* efo_add */
+ hunt_filter_delete, /* efo_delete */
+ hunt_filter_supported_filters, /* efo_supported_filters */
+ hunt_filter_reconfigure, /* efo_reconfigure */
+};
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+ __checkReturn int
+efx_filter_insert(
+ __in efx_nic_t *enp,
+ __inout efx_filter_spec_t *spec)
+{
+ efx_filter_ops_t *efop = enp->en_efop;
+
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
+ EFSYS_ASSERT3P(spec, !=, NULL);
+ EFSYS_ASSERT3U(spec->efs_flags, &, EFX_FILTER_FLAG_RX);
+
+ return (efop->efo_add(enp, spec, B_FALSE));
+}
+
+ __checkReturn int
+efx_filter_remove(
+ __in efx_nic_t *enp,
+ __inout efx_filter_spec_t *spec)
+{
+ efx_filter_ops_t *efop = enp->en_efop;
+
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
+ EFSYS_ASSERT3P(spec, !=, NULL);
+ EFSYS_ASSERT3U(spec->efs_flags, &, EFX_FILTER_FLAG_RX);
+
+#if EFSYS_OPT_RX_SCALE
+ spec->efs_rss_context = enp->en_rss_context;
+#endif
+
+ return (efop->efo_delete(enp, spec));
+}
+
+ __checkReturn int
+efx_filter_restore(
+ __in efx_nic_t *enp)
+{
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_FILTER);
+
+ if ((rc = enp->en_efop->efo_restore(enp)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_filter_init(
+ __in efx_nic_t *enp)
+{
+ efx_filter_ops_t *efop;
+ int rc;
+
+ /* Check that efx_filter_spec_t is 64 bytes. */
+ EFX_STATIC_ASSERT(sizeof (efx_filter_spec_t) == 64);
+
+ 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_FILTER));
+
+ switch (enp->en_family) {
+#if EFSYS_OPT_FALCON
+ case EFX_FAMILY_FALCON:
+ efop = (efx_filter_ops_t *)&__efx_filter_falcon_ops;
+ break;
+#endif /* EFSYS_OPT_FALCON */
+
+#if EFSYS_OPT_SIENA
+ case EFX_FAMILY_SIENA:
+ efop = (efx_filter_ops_t *)&__efx_filter_siena_ops;
+ break;
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ efop = (efx_filter_ops_t *)&__efx_filter_hunt_ops;
+ break;
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+ default:
+ EFSYS_ASSERT(0);
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+ if ((rc = efop->efo_init(enp)) != 0)
+ goto fail2;
+
+ enp->en_efop = efop;
+ enp->en_mod_flags |= EFX_MOD_FILTER;
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ enp->en_efop = NULL;
+ enp->en_mod_flags &= ~EFX_MOD_FILTER;
+ return (rc);
+}
+
+ void
+efx_filter_fini(
+ __in efx_nic_t *enp)
+{
+ 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_FILTER);
+
+ enp->en_efop->efo_fini(enp);
+
+ enp->en_efop = NULL;
+ enp->en_mod_flags &= ~EFX_MOD_FILTER;
+}
+
+ __checkReturn int
+efx_filter_supported_filters(
+ __in efx_nic_t *enp,
+ __out uint32_t *list,
+ __out size_t *length)
+{
+ int 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_FILTER);
+ EFSYS_ASSERT(enp->en_efop->efo_supported_filters != NULL);
+
+ if ((rc = enp->en_efop->efo_supported_filters(enp, list, length)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_filter_reconfigure(
+ __in efx_nic_t *enp,
+ __in_ecount(6) uint8_t const *mac_addr,
+ __in boolean_t all_unicst,
+ __in boolean_t mulcst,
+ __in boolean_t all_mulcst,
+ __in boolean_t brdcst,
+ __in_ecount(6*count) uint8_t const *addrs,
+ __in int count)
+{
+ int 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_FILTER);
+
+ if (enp->en_efop->efo_reconfigure != NULL) {
+ if ((rc = enp->en_efop->efo_reconfigure(enp, mac_addr,
+ all_unicst, mulcst,
+ all_mulcst, brdcst,
+ addrs, count)) != 0)
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+efx_filter_spec_init_rx(
+ __inout efx_filter_spec_t *spec,
+ __in efx_filter_priority_t priority,
+ __in efx_filter_flag_t flags,
+ __in efx_rxq_t *erp)
+{
+ EFSYS_ASSERT3P(spec, !=, NULL);
+ EFSYS_ASSERT3P(erp, !=, NULL);
+ EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS |
+ EFX_FILTER_FLAG_RX_SCATTER)) == 0);
+
+ memset(spec, 0, sizeof (*spec));
+ spec->efs_priority = priority;
+ spec->efs_flags = EFX_FILTER_FLAG_RX | flags;
+ spec->efs_rss_context = EFX_FILTER_SPEC_RSS_CONTEXT_DEFAULT;
+ spec->efs_dmaq_id = (uint16_t)erp->er_index;
+}
+
+ void
+efx_filter_spec_init_tx(
+ __inout efx_filter_spec_t *spec,
+ __in efx_txq_t *etp)
+{
+ EFSYS_ASSERT3P(spec, !=, NULL);
+ EFSYS_ASSERT3P(etp, !=, NULL);
+
+ memset(spec, 0, sizeof (*spec));
+ spec->efs_priority = EFX_FILTER_PRI_REQUIRED;
+ spec->efs_flags = EFX_FILTER_FLAG_TX;
+ spec->efs_dmaq_id = (uint16_t)etp->et_index;
+}
+
+
+/*
+ * Specify IPv4 host, transport protocol and port in a filter specification
+ */
+__checkReturn int
+efx_filter_spec_set_ipv4_local(
+ __inout efx_filter_spec_t *spec,
+ __in uint8_t proto,
+ __in uint32_t host,
+ __in uint16_t port)
+{
+ EFSYS_ASSERT3P(spec, !=, NULL);
+
+ spec->efs_match_flags |=
+ EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |
+ EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT;
+ spec->efs_ether_type = EFX_ETHER_TYPE_IPV4;
+ spec->efs_ip_proto = proto;
+ spec->efs_loc_host.eo_u32[0] = host;
+ spec->efs_loc_port = port;
+ return (0);
+}
+
+/*
+ * Specify IPv4 hosts, transport protocol and ports in a filter specification
+ */
+__checkReturn int
+efx_filter_spec_set_ipv4_full(
+ __inout efx_filter_spec_t *spec,
+ __in uint8_t proto,
+ __in uint32_t lhost,
+ __in uint16_t lport,
+ __in uint32_t rhost,
+ __in uint16_t rport)
+{
+ EFSYS_ASSERT3P(spec, !=, NULL);
+
+ spec->efs_match_flags |=
+ EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |
+ EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT |
+ EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_REM_PORT;
+ spec->efs_ether_type = EFX_ETHER_TYPE_IPV4;
+ spec->efs_ip_proto = proto;
+ spec->efs_loc_host.eo_u32[0] = lhost;
+ spec->efs_loc_port = lport;
+ spec->efs_rem_host.eo_u32[0] = rhost;
+ spec->efs_rem_port = rport;
+ return (0);
+}
+
+/*
+ * Specify local Ethernet address and/or VID in filter specification
+ */
+__checkReturn int
+efx_filter_spec_set_eth_local(
+ __inout efx_filter_spec_t *spec,
+ __in uint16_t vid,
+ __in const uint8_t *addr)
+{
+ EFSYS_ASSERT3P(spec, !=, NULL);
+ EFSYS_ASSERT3P(addr, !=, NULL);
+
+ if (vid == EFX_FILTER_SPEC_VID_UNSPEC && addr == NULL)
+ return (EINVAL);
+
+ if (vid != EFX_FILTER_SPEC_VID_UNSPEC) {
+ spec->efs_match_flags |= EFX_FILTER_MATCH_OUTER_VID;
+ spec->efs_outer_vid = vid;
+ }
+ if (addr != NULL) {
+ spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_MAC;
+ memcpy(spec->efs_loc_mac, addr, EFX_MAC_ADDR_LEN);
+ }
+ return (0);
+}
+
+/*
+ * Specify matching otherwise-unmatched unicast in a filter specification
+ */
+__checkReturn int
+efx_filter_spec_set_uc_def(
+ __inout efx_filter_spec_t *spec)
+{
+ EFSYS_ASSERT3P(spec, !=, NULL);
+
+ spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_MAC_IG;
+ return (0);
+}
+
+/*
+ * Specify matching otherwise-unmatched multicast in a filter specification
+ */
+__checkReturn int
+efx_filter_spec_set_mc_def(
+ __inout efx_filter_spec_t *spec)
+{
+ EFSYS_ASSERT3P(spec, !=, NULL);
+
+ spec->efs_match_flags |= EFX_FILTER_MATCH_LOC_MAC_IG;
+ spec->efs_loc_mac[0] = 1;
+ return (0);
+}
+
+
+
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+/*
+ * "Fudge factors" - difference between programmed value and actual depth.
* Due to pipelined implementation we need to program H/W with a value that
* is larger than the hop limit we want.
*/
-#define FILTER_CTL_SRCH_FUDGE_WILD 3
-#define FILTER_CTL_SRCH_FUDGE_FULL 1
+#define FILTER_CTL_SRCH_FUDGE_WILD 3
+#define FILTER_CTL_SRCH_FUDGE_FULL 1
-/* Hard maximum hop limit. Hardware will time-out beyond 200-something.
+/*
+ * Hard maximum hop limit. Hardware will time-out beyond 200-something.
* We also need to avoid infinite loops in efx_filter_search() when the
* table is full.
*/
-#define FILTER_CTL_SRCH_MAX 200
+#define FILTER_CTL_SRCH_MAX 200
-/* The filter hash function is LFSR polynomial x^16 + x^3 + 1 of a 32-bit
- * key derived from the n-tuple. */
+static __checkReturn int
+falconsiena_filter_spec_from_gen_spec(
+ __out falconsiena_filter_spec_t *fs_spec,
+ __in efx_filter_spec_t *gen_spec)
+{
+ int rc;
+ boolean_t is_full = B_FALSE;
+
+ if (gen_spec->efs_flags & EFX_FILTER_FLAG_TX)
+ EFSYS_ASSERT3U(gen_spec->efs_flags, ==, EFX_FILTER_FLAG_TX);
+ else
+ EFSYS_ASSERT3U(gen_spec->efs_flags, &, EFX_FILTER_FLAG_RX);
+
+ /* Falconsiena only has one RSS context */
+ if ((gen_spec->efs_flags & EFX_FILTER_FLAG_RX_RSS) &&
+ gen_spec->efs_rss_context != 0) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ fs_spec->fsfs_flags = gen_spec->efs_flags;
+ fs_spec->fsfs_dmaq_id = gen_spec->efs_dmaq_id;
+
+ switch (gen_spec->efs_match_flags) {
+ case EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |
+ EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT |
+ EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_REM_PORT:
+ is_full = B_TRUE;
+ /* Fall through */
+ case EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |
+ EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT: {
+ uint32_t rhost, host1, host2;
+ uint16_t rport, port1, port2;
+
+ if (gen_spec->efs_ether_type != EFX_ETHER_TYPE_IPV4) {
+ rc = ENOTSUP;
+ goto fail2;
+ }
+ if (gen_spec->efs_loc_port == 0 ||
+ (is_full && gen_spec->efs_rem_port == 0)) {
+ rc = EINVAL;
+ goto fail3;
+ }
+ switch (gen_spec->efs_ip_proto) {
+ case EFX_IPPROTO_TCP:
+ if (gen_spec->efs_flags & EFX_FILTER_FLAG_TX) {
+ fs_spec->fsfs_type = (is_full ?
+ EFX_FS_FILTER_TX_TCP_FULL :
+ EFX_FS_FILTER_TX_TCP_WILD);
+ } else {
+ fs_spec->fsfs_type = (is_full ?
+ EFX_FS_FILTER_RX_TCP_FULL :
+ EFX_FS_FILTER_RX_TCP_WILD);
+ }
+ break;
+ case EFX_IPPROTO_UDP:
+ if (gen_spec->efs_flags & EFX_FILTER_FLAG_TX) {
+ fs_spec->fsfs_type = (is_full ?
+ EFX_FS_FILTER_TX_UDP_FULL :
+ EFX_FS_FILTER_TX_UDP_WILD);
+ } else {
+ fs_spec->fsfs_type = (is_full ?
+ EFX_FS_FILTER_RX_UDP_FULL :
+ EFX_FS_FILTER_RX_UDP_WILD);
+ }
+ break;
+ default:
+ rc = ENOTSUP;
+ goto fail4;
+ }
+ /*
+ * The filter is constructed in terms of source and destination,
+ * with the odd wrinkle that the ports are swapped in a UDP
+ * wildcard filter. We need to convert from local and remote
+ * addresses (zero for a wildcard).
+ */
+ rhost = is_full ? gen_spec->efs_rem_host.eo_u32[0] : 0;
+ rport = is_full ? gen_spec->efs_rem_port : 0;
+ if (gen_spec->efs_flags & EFX_FILTER_FLAG_TX) {
+ host1 = gen_spec->efs_loc_host.eo_u32[0];
+ host2 = rhost;
+ } else {
+ host1 = rhost;
+ host2 = gen_spec->efs_loc_host.eo_u32[0];
+ }
+ if (gen_spec->efs_flags & EFX_FILTER_FLAG_TX) {
+ if (fs_spec->fsfs_type == EFX_FS_FILTER_TX_UDP_WILD) {
+ port1 = rport;
+ port2 = gen_spec->efs_loc_port;
+ } else {
+ port1 = gen_spec->efs_loc_port;
+ port2 = rport;
+ }
+ } else {
+ if (fs_spec->fsfs_type == EFX_FS_FILTER_RX_UDP_WILD) {
+ port1 = gen_spec->efs_loc_port;
+ port2 = rport;
+ } else {
+ port1 = rport;
+ port2 = gen_spec->efs_loc_port;
+ }
+ }
+ fs_spec->fsfs_dword[0] = (host1 << 16) | port1;
+ fs_spec->fsfs_dword[1] = (port2 << 16) | (host1 >> 16);
+ fs_spec->fsfs_dword[2] = host2;
+ break;
+ }
+
+ case EFX_FILTER_MATCH_LOC_MAC | EFX_FILTER_MATCH_OUTER_VID:
+ is_full = B_TRUE;
+ /* Fall through */
+ case EFX_FILTER_MATCH_LOC_MAC:
+ if (gen_spec->efs_flags & EFX_FILTER_FLAG_TX) {
+ fs_spec->fsfs_type = (is_full ?
+ EFX_FS_FILTER_TX_MAC_FULL :
+ EFX_FS_FILTER_TX_MAC_WILD);
+ } else {
+ fs_spec->fsfs_type = (is_full ?
+ EFX_FS_FILTER_RX_MAC_FULL :
+ EFX_FS_FILTER_RX_MAC_WILD);
+ }
+ fs_spec->fsfs_dword[0] = is_full ? gen_spec->efs_outer_vid : 0;
+ fs_spec->fsfs_dword[1] =
+ gen_spec->efs_loc_mac[2] << 24 |
+ gen_spec->efs_loc_mac[3] << 16 |
+ gen_spec->efs_loc_mac[4] << 8 |
+ gen_spec->efs_loc_mac[5];
+ fs_spec->fsfs_dword[2] =
+ gen_spec->efs_loc_mac[0] << 8 |
+ gen_spec->efs_loc_mac[1];
+ break;
+
+ default:
+ EFSYS_ASSERT(B_FALSE);
+ rc = ENOTSUP;
+ goto fail5;
+ }
+
+ return (0);
+
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+/*
+ * The filter hash function is LFSR polynomial x^16 + x^3 + 1 of a 32-bit
+ * key derived from the n-tuple.
+ */
static uint16_t
-efx_filter_tbl_hash(
- __in uint32_t key)
+falconsiena_filter_tbl_hash(
+ __in uint32_t key)
{
uint16_t tmp;
@@ -69,119 +619,119 @@ efx_filter_tbl_hash(
return (tmp);
}
-
-/* To allow for hash collisions, filter search continues at these
- * increments from the first possible entry selected by the hash. */
+/*
+ * To allow for hash collisions, filter search continues at these
+ * increments from the first possible entry selected by the hash.
+ */
static uint16_t
-efx_filter_tbl_increment(
+falconsiena_filter_tbl_increment(
__in uint32_t key)
{
return ((uint16_t)(key * 2 - 1));
}
static __checkReturn boolean_t
-efx_filter_test_used(
- __in efx_filter_tbl_t *eftp,
+falconsiena_filter_test_used(
+ __in falconsiena_filter_tbl_t *fsftp,
__in unsigned int index)
{
- EFSYS_ASSERT3P(eftp->eft_bitmap, !=, NULL);
- return ((eftp->eft_bitmap[index / 32] & (1 << (index % 32))) != 0);
+ EFSYS_ASSERT3P(fsftp->fsft_bitmap, !=, NULL);
+ return ((fsftp->fsft_bitmap[index / 32] & (1 << (index % 32))) != 0);
}
static void
-efx_filter_set_used(
- __in efx_filter_tbl_t *eftp,
+falconsiena_filter_set_used(
+ __in falconsiena_filter_tbl_t *fsftp,
__in unsigned int index)
{
- EFSYS_ASSERT3P(eftp->eft_bitmap, !=, NULL);
- eftp->eft_bitmap[index / 32] |= (1 << (index % 32));
- ++eftp->eft_used;
+ EFSYS_ASSERT3P(fsftp->fsft_bitmap, !=, NULL);
+ fsftp->fsft_bitmap[index / 32] |= (1 << (index % 32));
+ ++fsftp->fsft_used;
}
static void
-efx_filter_clear_used(
- __in efx_filter_tbl_t *eftp,
+falconsiena_filter_clear_used(
+ __in falconsiena_filter_tbl_t *fsftp,
__in unsigned int index)
{
- EFSYS_ASSERT3P(eftp->eft_bitmap, !=, NULL);
- eftp->eft_bitmap[index / 32] &= ~(1 << (index % 32));
+ EFSYS_ASSERT3P(fsftp->fsft_bitmap, !=, NULL);
+ fsftp->fsft_bitmap[index / 32] &= ~(1 << (index % 32));
- --eftp->eft_used;
- EFSYS_ASSERT3U(eftp->eft_used, >=, 0);
+ --fsftp->fsft_used;
+ EFSYS_ASSERT3U(fsftp->fsft_used, >=, 0);
}
-static efx_filter_tbl_id_t
-efx_filter_tbl_id(
- __in efx_filter_type_t type)
+static falconsiena_filter_tbl_id_t
+falconsiena_filter_tbl_id(
+ __in falconsiena_filter_type_t type)
{
- efx_filter_tbl_id_t tbl_id;
-
- switch (type)
- {
- case EFX_FILTER_RX_TCP_FULL:
- case EFX_FILTER_RX_TCP_WILD:
- case EFX_FILTER_RX_UDP_FULL:
- case EFX_FILTER_RX_UDP_WILD:
- tbl_id = EFX_FILTER_TBL_RX_IP;
+ falconsiena_filter_tbl_id_t tbl_id;
+
+ switch (type) {
+ case EFX_FS_FILTER_RX_TCP_FULL:
+ case EFX_FS_FILTER_RX_TCP_WILD:
+ case EFX_FS_FILTER_RX_UDP_FULL:
+ case EFX_FS_FILTER_RX_UDP_WILD:
+ tbl_id = EFX_FS_FILTER_TBL_RX_IP;
break;
#if EFSYS_OPT_SIENA
- case EFX_FILTER_RX_MAC_FULL:
- case EFX_FILTER_RX_MAC_WILD:
- tbl_id = EFX_FILTER_TBL_RX_MAC;
+ case EFX_FS_FILTER_RX_MAC_FULL:
+ case EFX_FS_FILTER_RX_MAC_WILD:
+ tbl_id = EFX_FS_FILTER_TBL_RX_MAC;
break;
- case EFX_FILTER_TX_TCP_FULL:
- case EFX_FILTER_TX_TCP_WILD:
- case EFX_FILTER_TX_UDP_FULL:
- case EFX_FILTER_TX_UDP_WILD:
- tbl_id = EFX_FILTER_TBL_TX_IP;
+ case EFX_FS_FILTER_TX_TCP_FULL:
+ case EFX_FS_FILTER_TX_TCP_WILD:
+ case EFX_FS_FILTER_TX_UDP_FULL:
+ case EFX_FS_FILTER_TX_UDP_WILD:
+ tbl_id = EFX_FS_FILTER_TBL_TX_IP;
break;
- case EFX_FILTER_TX_MAC_FULL:
- case EFX_FILTER_TX_MAC_WILD:
- tbl_id = EFX_FILTER_TBL_RX_MAC;
+ case EFX_FS_FILTER_TX_MAC_FULL:
+ case EFX_FS_FILTER_TX_MAC_WILD:
+ tbl_id = EFX_FS_FILTER_TBL_TX_MAC;
break;
#endif /* EFSYS_OPT_SIENA */
default:
EFSYS_ASSERT(B_FALSE);
+ tbl_id = EFX_FS_FILTER_NTBLS;
break;
}
return (tbl_id);
}
static void
-efx_filter_reset_search_depth(
- __inout efx_filter_t *efp,
- __in efx_filter_tbl_id_t tbl_id)
+falconsiena_filter_reset_search_depth(
+ __inout falconsiena_filter_t *fsfp,
+ __in falconsiena_filter_tbl_id_t tbl_id)
{
- switch (tbl_id)
- {
- case EFX_FILTER_TBL_RX_IP:
- efp->ef_depth[EFX_FILTER_RX_TCP_FULL] = 0;
- efp->ef_depth[EFX_FILTER_RX_TCP_WILD] = 0;
- efp->ef_depth[EFX_FILTER_RX_UDP_FULL] = 0;
- efp->ef_depth[EFX_FILTER_RX_UDP_WILD] = 0;
+ switch (tbl_id) {
+ case EFX_FS_FILTER_TBL_RX_IP:
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_TCP_FULL] = 0;
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_TCP_WILD] = 0;
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_UDP_FULL] = 0;
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_UDP_WILD] = 0;
break;
#if EFSYS_OPT_SIENA
- case EFX_FILTER_TBL_RX_MAC:
- efp->ef_depth[EFX_FILTER_RX_MAC_FULL] = 0;
- efp->ef_depth[EFX_FILTER_RX_MAC_WILD] = 0;
+ case EFX_FS_FILTER_TBL_RX_MAC:
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_MAC_FULL] = 0;
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_MAC_WILD] = 0;
break;
- case EFX_FILTER_TBL_TX_IP:
- efp->ef_depth[EFX_FILTER_TX_TCP_FULL] = 0;
- efp->ef_depth[EFX_FILTER_TX_TCP_WILD] = 0;
- efp->ef_depth[EFX_FILTER_TX_UDP_FULL] = 0;
- efp->ef_depth[EFX_FILTER_TX_UDP_WILD] = 0;
+ case EFX_FS_FILTER_TBL_TX_IP:
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_TCP_FULL] = 0;
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_TCP_WILD] = 0;
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_UDP_FULL] = 0;
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_UDP_WILD] = 0;
break;
- case EFX_FILTER_TBL_TX_MAC:
- efp->ef_depth[EFX_FILTER_TX_MAC_FULL] = 0;
- efp->ef_depth[EFX_FILTER_TX_MAC_WILD] = 0;
+ case EFX_FS_FILTER_TBL_TX_MAC:
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_MAC_FULL] = 0;
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_MAC_WILD] = 0;
break;
#endif /* EFSYS_OPT_SIENA */
@@ -192,36 +742,36 @@ efx_filter_reset_search_depth(
}
static void
-efx_filter_push_rx_limits(
+falconsiena_filter_push_rx_limits(
__in efx_nic_t *enp)
{
- efx_filter_t *efp = &enp->en_filter;
+ falconsiena_filter_t *fsfp = enp->en_filter.ef_falconsiena_filter;
efx_oword_t oword;
EFX_BAR_READO(enp, FR_AZ_RX_FILTER_CTL_REG, &oword);
EFX_SET_OWORD_FIELD(oword, FRF_AZ_TCP_FULL_SRCH_LIMIT,
- efp->ef_depth[EFX_FILTER_RX_TCP_FULL] +
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_TCP_FULL] +
FILTER_CTL_SRCH_FUDGE_FULL);
EFX_SET_OWORD_FIELD(oword, FRF_AZ_TCP_WILD_SRCH_LIMIT,
- efp->ef_depth[EFX_FILTER_RX_TCP_WILD] +
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_TCP_WILD] +
FILTER_CTL_SRCH_FUDGE_WILD);
EFX_SET_OWORD_FIELD(oword, FRF_AZ_UDP_FULL_SRCH_LIMIT,
- efp->ef_depth[EFX_FILTER_RX_UDP_FULL] +
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_UDP_FULL] +
FILTER_CTL_SRCH_FUDGE_FULL);
EFX_SET_OWORD_FIELD(oword, FRF_AZ_UDP_WILD_SRCH_LIMIT,
- efp->ef_depth[EFX_FILTER_RX_UDP_WILD] +
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_UDP_WILD] +
FILTER_CTL_SRCH_FUDGE_WILD);
#if EFSYS_OPT_SIENA
- if (efp->ef_tbl[EFX_FILTER_TBL_RX_MAC].eft_size) {
+ if (fsfp->fsf_tbl[EFX_FS_FILTER_TBL_RX_MAC].fsft_size) {
EFX_SET_OWORD_FIELD(oword,
FRF_CZ_ETHERNET_FULL_SEARCH_LIMIT,
- efp->ef_depth[EFX_FILTER_RX_MAC_FULL] +
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_MAC_FULL] +
FILTER_CTL_SRCH_FUDGE_FULL);
EFX_SET_OWORD_FIELD(oword,
FRF_CZ_ETHERNET_WILDCARD_SEARCH_LIMIT,
- efp->ef_depth[EFX_FILTER_RX_MAC_WILD] +
+ fsfp->fsf_depth[EFX_FS_FILTER_RX_MAC_WILD] +
FILTER_CTL_SRCH_FUDGE_WILD);
}
#endif /* EFSYS_OPT_SIENA */
@@ -230,150 +780,177 @@ efx_filter_push_rx_limits(
}
static void
-efx_filter_push_tx_limits(
+falconsiena_filter_push_tx_limits(
__in efx_nic_t *enp)
{
- efx_filter_t *efp = &enp->en_filter;
+ falconsiena_filter_t *fsfp = enp->en_filter.ef_falconsiena_filter;
efx_oword_t oword;
- if (efp->ef_tbl[EFX_FILTER_TBL_TX_IP].eft_size == 0)
- return;
-
EFX_BAR_READO(enp, FR_AZ_TX_CFG_REG, &oword);
- EFX_SET_OWORD_FIELD(oword, FRF_CZ_TX_TCPIP_FILTER_FULL_SEARCH_RANGE,
- efp->ef_depth[EFX_FILTER_TX_TCP_FULL] +
- FILTER_CTL_SRCH_FUDGE_FULL);
- EFX_SET_OWORD_FIELD(oword, FRF_CZ_TX_TCPIP_FILTER_WILD_SEARCH_RANGE,
- efp->ef_depth[EFX_FILTER_TX_TCP_WILD] +
- FILTER_CTL_SRCH_FUDGE_WILD);
- EFX_SET_OWORD_FIELD(oword, FRF_CZ_TX_UDPIP_FILTER_FULL_SEARCH_RANGE,
- efp->ef_depth[EFX_FILTER_TX_UDP_FULL] +
- FILTER_CTL_SRCH_FUDGE_FULL);
- EFX_SET_OWORD_FIELD(oword, FRF_CZ_TX_UDPIP_FILTER_WILD_SEARCH_RANGE,
- efp->ef_depth[EFX_FILTER_TX_UDP_WILD] +
- FILTER_CTL_SRCH_FUDGE_WILD);
+ if (fsfp->fsf_tbl[EFX_FS_FILTER_TBL_TX_IP].fsft_size != 0) {
+ EFX_SET_OWORD_FIELD(oword,
+ FRF_CZ_TX_TCPIP_FILTER_FULL_SEARCH_RANGE,
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_TCP_FULL] +
+ FILTER_CTL_SRCH_FUDGE_FULL);
+ EFX_SET_OWORD_FIELD(oword,
+ FRF_CZ_TX_TCPIP_FILTER_WILD_SEARCH_RANGE,
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_TCP_WILD] +
+ FILTER_CTL_SRCH_FUDGE_WILD);
+ EFX_SET_OWORD_FIELD(oword,
+ FRF_CZ_TX_UDPIP_FILTER_FULL_SEARCH_RANGE,
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_UDP_FULL] +
+ FILTER_CTL_SRCH_FUDGE_FULL);
+ EFX_SET_OWORD_FIELD(oword,
+ FRF_CZ_TX_UDPIP_FILTER_WILD_SEARCH_RANGE,
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_UDP_WILD] +
+ FILTER_CTL_SRCH_FUDGE_WILD);
+ }
+
+ if (fsfp->fsf_tbl[EFX_FS_FILTER_TBL_TX_MAC].fsft_size != 0) {
+ EFX_SET_OWORD_FIELD(
+ oword, FRF_CZ_TX_ETH_FILTER_FULL_SEARCH_RANGE,
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_MAC_FULL] +
+ FILTER_CTL_SRCH_FUDGE_FULL);
+ EFX_SET_OWORD_FIELD(
+ oword, FRF_CZ_TX_ETH_FILTER_WILD_SEARCH_RANGE,
+ fsfp->fsf_depth[EFX_FS_FILTER_TX_MAC_WILD] +
+ FILTER_CTL_SRCH_FUDGE_WILD);
+ }
EFX_BAR_WRITEO(enp, FR_AZ_TX_CFG_REG, &oword);
}
/* Build a filter entry and return its n-tuple key. */
static __checkReturn uint32_t
-efx_filter_build(
+falconsiena_filter_build(
__out efx_oword_t *filter,
- __in efx_filter_spec_t *spec)
+ __in falconsiena_filter_spec_t *spec)
{
uint32_t dword3;
uint32_t key;
- uint8_t type = spec->efs_type;
- uint8_t flags = spec->efs_flags;
+ uint8_t type = spec->fsfs_type;
+ uint32_t flags = spec->fsfs_flags;
- switch (efx_filter_tbl_id(type)) {
- case EFX_FILTER_TBL_RX_IP: {
- boolean_t is_udp = (type == EFX_FILTER_RX_UDP_FULL ||
- type == EFX_FILTER_RX_UDP_WILD);
+ switch (falconsiena_filter_tbl_id(type)) {
+ case EFX_FS_FILTER_TBL_RX_IP: {
+ boolean_t is_udp = (type == EFX_FS_FILTER_RX_UDP_FULL ||
+ type == EFX_FS_FILTER_RX_UDP_WILD);
EFX_POPULATE_OWORD_7(*filter,
- FRF_BZ_RSS_EN, (flags & EFX_FILTER_FLAG_RX_RSS) ? 1 : 0,
- FRF_BZ_SCATTER_EN, (flags & EFX_FILTER_FLAG_RX_SCATTER) ? 1 : 0,
+ FRF_BZ_RSS_EN,
+ (flags & EFX_FILTER_FLAG_RX_RSS) ? 1 : 0,
+ FRF_BZ_SCATTER_EN,
+ (flags & EFX_FILTER_FLAG_RX_SCATTER) ? 1 : 0,
FRF_AZ_TCP_UDP, is_udp,
- FRF_AZ_RXQ_ID, spec->efs_dmaq_id,
- EFX_DWORD_2, spec->efs_dword[2],
- EFX_DWORD_1, spec->efs_dword[1],
- EFX_DWORD_0, spec->efs_dword[0]);
+ FRF_AZ_RXQ_ID, spec->fsfs_dmaq_id,
+ EFX_DWORD_2, spec->fsfs_dword[2],
+ EFX_DWORD_1, spec->fsfs_dword[1],
+ EFX_DWORD_0, spec->fsfs_dword[0]);
dword3 = is_udp;
break;
}
#if EFSYS_OPT_SIENA
- case EFX_FILTER_TBL_RX_MAC: {
- boolean_t is_wild = (type == EFX_FILTER_RX_MAC_WILD);
- EFX_POPULATE_OWORD_8(*filter,
- FRF_CZ_RMFT_RSS_EN, (flags & EFX_FILTER_FLAG_RX_RSS) ? 1 : 0,
- FRF_CZ_RMFT_SCATTER_EN, (flags & EFX_FILTER_FLAG_RX_SCATTER) ? 1 : 0,
- FRF_CZ_RMFT_IP_OVERRIDE, (flags & EFX_FILTER_FLAG_RX_OVERRIDE_IP) ? 1 : 0,
- FRF_CZ_RMFT_RXQ_ID, spec->efs_dmaq_id,
+ case EFX_FS_FILTER_TBL_RX_MAC: {
+ boolean_t is_wild = (type == EFX_FS_FILTER_RX_MAC_WILD);
+ EFX_POPULATE_OWORD_7(*filter,
+ FRF_CZ_RMFT_RSS_EN,
+ (flags & EFX_FILTER_FLAG_RX_RSS) ? 1 : 0,
+ FRF_CZ_RMFT_SCATTER_EN,
+ (flags & EFX_FILTER_FLAG_RX_SCATTER) ? 1 : 0,
+ FRF_CZ_RMFT_RXQ_ID, spec->fsfs_dmaq_id,
FRF_CZ_RMFT_WILDCARD_MATCH, is_wild,
- FRF_CZ_RMFT_DEST_MAC_DW1, spec->efs_dword[2],
- FRF_CZ_RMFT_DEST_MAC_DW0, spec->efs_dword[1],
- FRF_CZ_RMFT_VLAN_ID, spec->efs_dword[0]);
+ FRF_CZ_RMFT_DEST_MAC_DW1, spec->fsfs_dword[2],
+ FRF_CZ_RMFT_DEST_MAC_DW0, spec->fsfs_dword[1],
+ FRF_CZ_RMFT_VLAN_ID, spec->fsfs_dword[0]);
dword3 = is_wild;
break;
}
#endif /* EFSYS_OPT_SIENA */
- case EFX_FILTER_TBL_TX_IP: {
- boolean_t is_udp = (type == EFX_FILTER_TX_UDP_FULL ||
- type == EFX_FILTER_TX_UDP_WILD);
+ case EFX_FS_FILTER_TBL_TX_IP: {
+ boolean_t is_udp = (type == EFX_FS_FILTER_TX_UDP_FULL ||
+ type == EFX_FS_FILTER_TX_UDP_WILD);
EFX_POPULATE_OWORD_5(*filter,
FRF_CZ_TIFT_TCP_UDP, is_udp,
- FRF_CZ_TIFT_TXQ_ID, spec->efs_dmaq_id,
- EFX_DWORD_2, spec->efs_dword[2],
- EFX_DWORD_1, spec->efs_dword[1],
- EFX_DWORD_0, spec->efs_dword[0]);
- dword3 = is_udp | spec->efs_dmaq_id << 1;
+ FRF_CZ_TIFT_TXQ_ID, spec->fsfs_dmaq_id,
+ EFX_DWORD_2, spec->fsfs_dword[2],
+ EFX_DWORD_1, spec->fsfs_dword[1],
+ EFX_DWORD_0, spec->fsfs_dword[0]);
+ dword3 = is_udp | spec->fsfs_dmaq_id << 1;
break;
}
#if EFSYS_OPT_SIENA
- case EFX_FILTER_TBL_TX_MAC: {
- boolean_t is_wild = (type == EFX_FILTER_TX_MAC_WILD);
+ case EFX_FS_FILTER_TBL_TX_MAC: {
+ boolean_t is_wild = (type == EFX_FS_FILTER_TX_MAC_WILD);
EFX_POPULATE_OWORD_5(*filter,
- FRF_CZ_TMFT_TXQ_ID, spec->efs_dmaq_id,
+ FRF_CZ_TMFT_TXQ_ID, spec->fsfs_dmaq_id,
FRF_CZ_TMFT_WILDCARD_MATCH, is_wild,
- FRF_CZ_TMFT_SRC_MAC_DW1, spec->efs_dword[2],
- FRF_CZ_TMFT_SRC_MAC_DW0, spec->efs_dword[1],
- FRF_CZ_TMFT_VLAN_ID, spec->efs_dword[0]);
- dword3 = is_wild | spec->efs_dmaq_id << 1;
+ FRF_CZ_TMFT_SRC_MAC_DW1, spec->fsfs_dword[2],
+ FRF_CZ_TMFT_SRC_MAC_DW0, spec->fsfs_dword[1],
+ FRF_CZ_TMFT_VLAN_ID, spec->fsfs_dword[0]);
+ dword3 = is_wild | spec->fsfs_dmaq_id << 1;
break;
}
#endif /* EFSYS_OPT_SIENA */
default:
EFSYS_ASSERT(B_FALSE);
+ return (0);
}
- key = spec->efs_dword[0] ^ spec->efs_dword[1] ^ spec->efs_dword[2] ^ dword3;
+ key =
+ spec->fsfs_dword[0] ^
+ spec->fsfs_dword[1] ^
+ spec->fsfs_dword[2] ^
+ dword3;
+
return (key);
}
static __checkReturn int
-efx_filter_push_entry(
+falconsiena_filter_push_entry(
__inout efx_nic_t *enp,
- __in efx_filter_type_t type,
+ __in falconsiena_filter_type_t type,
__in int index,
__in efx_oword_t *eop)
{
int rc;
- switch (type)
- {
- case EFX_FILTER_RX_TCP_FULL:
- case EFX_FILTER_RX_TCP_WILD:
- case EFX_FILTER_RX_UDP_FULL:
- case EFX_FILTER_RX_UDP_WILD:
- EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_FILTER_TBL0, index, eop);
+ switch (type) {
+ case EFX_FS_FILTER_RX_TCP_FULL:
+ case EFX_FS_FILTER_RX_TCP_WILD:
+ case EFX_FS_FILTER_RX_UDP_FULL:
+ case EFX_FS_FILTER_RX_UDP_WILD:
+ EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_FILTER_TBL0, index,
+ eop, B_TRUE);
break;
#if EFSYS_OPT_SIENA
- case EFX_FILTER_RX_MAC_FULL:
- case EFX_FILTER_RX_MAC_WILD:
- EFX_BAR_TBL_WRITEO(enp, FR_CZ_RX_MAC_FILTER_TBL0, index, eop);
+ case EFX_FS_FILTER_RX_MAC_FULL:
+ case EFX_FS_FILTER_RX_MAC_WILD:
+ EFX_BAR_TBL_WRITEO(enp, FR_CZ_RX_MAC_FILTER_TBL0, index,
+ eop, B_TRUE);
break;
- case EFX_FILTER_TX_TCP_FULL:
- case EFX_FILTER_TX_TCP_WILD:
- case EFX_FILTER_TX_UDP_FULL:
- case EFX_FILTER_TX_UDP_WILD:
- EFX_BAR_TBL_WRITEO(enp, FR_CZ_TX_FILTER_TBL0, index, eop);
+ case EFX_FS_FILTER_TX_TCP_FULL:
+ case EFX_FS_FILTER_TX_TCP_WILD:
+ case EFX_FS_FILTER_TX_UDP_FULL:
+ case EFX_FS_FILTER_TX_UDP_WILD:
+ EFX_BAR_TBL_WRITEO(enp, FR_CZ_TX_FILTER_TBL0, index,
+ eop, B_TRUE);
break;
- case EFX_FILTER_TX_MAC_FULL:
- case EFX_FILTER_TX_MAC_WILD:
- EFX_BAR_TBL_WRITEO(enp, FR_CZ_TX_MAC_FILTER_TBL0, index, eop);
+ case EFX_FS_FILTER_TX_MAC_FULL:
+ case EFX_FS_FILTER_TX_MAC_WILD:
+ EFX_BAR_TBL_WRITEO(enp, FR_CZ_TX_MAC_FILTER_TBL0, index,
+ eop, B_TRUE);
break;
#endif /* EFSYS_OPT_SIENA */
default:
+ EFSYS_ASSERT(B_FALSE);
rc = ENOTSUP;
goto fail1;
}
@@ -385,30 +962,34 @@ fail1:
static __checkReturn boolean_t
-efx_filter_equal(
- __in const efx_filter_spec_t *left,
- __in const efx_filter_spec_t *right)
+falconsiena_filter_equal(
+ __in const falconsiena_filter_spec_t *left,
+ __in const falconsiena_filter_spec_t *right)
{
- efx_filter_tbl_id_t tbl_id = efx_filter_tbl_id(left->efs_type);
+ falconsiena_filter_tbl_id_t tbl_id;
- if (left->efs_type != right->efs_type)
+ tbl_id = falconsiena_filter_tbl_id(left->fsfs_type);
+
+
+ if (left->fsfs_type != right->fsfs_type)
return (B_FALSE);
- if (memcmp(left->efs_dword, right->efs_dword, sizeof(left->efs_dword)))
+ if (memcmp(left->fsfs_dword, right->fsfs_dword,
+ sizeof (left->fsfs_dword)))
return (B_FALSE);
- if ((tbl_id == EFX_FILTER_TBL_TX_IP ||
- tbl_id == EFX_FILTER_TBL_TX_MAC) &&
- left->efs_dmaq_id != right->efs_dmaq_id)
+ if ((tbl_id == EFX_FS_FILTER_TBL_TX_IP ||
+ tbl_id == EFX_FS_FILTER_TBL_TX_MAC) &&
+ left->fsfs_dmaq_id != right->fsfs_dmaq_id)
return (B_FALSE);
return (B_TRUE);
}
static __checkReturn int
-efx_filter_search(
- __in efx_filter_tbl_t *eftp,
- __in efx_filter_spec_t *spec,
+falconsiena_filter_search(
+ __in falconsiena_filter_tbl_t *fsftp,
+ __in falconsiena_filter_spec_t *spec,
__in uint32_t key,
__in boolean_t for_insert,
__out int *filter_index,
@@ -416,18 +997,20 @@ efx_filter_search(
{
unsigned hash, incr, filter_idx, depth;
- hash = efx_filter_tbl_hash(key);
- incr = efx_filter_tbl_increment(key);
+ hash = falconsiena_filter_tbl_hash(key);
+ incr = falconsiena_filter_tbl_increment(key);
- filter_idx = hash & (eftp->eft_size - 1);
+ filter_idx = hash & (fsftp->fsft_size - 1);
depth = 1;
for (;;) {
- /* Return success if entry is used and matches this spec
+ /*
+ * Return success if entry is used and matches this spec
* or entry is unused and we are trying to insert.
*/
- if (efx_filter_test_used(eftp, filter_idx) ?
- efx_filter_equal(spec, &eftp->eft_spec[filter_idx]) :
+ if (falconsiena_filter_test_used(fsftp, filter_idx) ?
+ falconsiena_filter_equal(spec,
+ &fsftp->fsft_spec[filter_idx]) :
for_insert) {
*filter_index = filter_idx;
*depth_required = depth;
@@ -436,594 +1019,421 @@ efx_filter_search(
/* Return failure if we reached the maximum search depth */
if (depth == FILTER_CTL_SRCH_MAX)
- return for_insert ? EBUSY : ENOENT;
+ return (for_insert ? EBUSY : ENOENT);
- filter_idx = (filter_idx + incr) & (eftp->eft_size - 1);
+ filter_idx = (filter_idx + incr) & (fsftp->fsft_size - 1);
++depth;
}
}
- __checkReturn int
-efx_filter_insert_filter(
- __in efx_nic_t *enp,
- __in efx_filter_spec_t *spec,
- __in boolean_t replace)
-{
- efx_filter_t *efp = &enp->en_filter;
- efx_filter_tbl_id_t tbl_id = efx_filter_tbl_id(spec->efs_type);
- efx_filter_tbl_t *eftp = &efp->ef_tbl[tbl_id];
- efx_filter_spec_t *saved_spec;
- efx_oword_t filter;
- int filter_idx;
- unsigned int depth;
- int state;
- uint32_t key;
- int rc;
-
- if (eftp->eft_size == 0)
- return (EINVAL);
-
- key = efx_filter_build(&filter, spec);
-
- EFSYS_LOCK(enp->en_eslp, state);
-
- rc = efx_filter_search(eftp, spec, key, B_TRUE, &filter_idx, &depth);
- if (rc != 0)
- goto done;
-
- EFSYS_ASSERT3U(filter_idx, <, eftp->eft_size);
- saved_spec = &eftp->eft_spec[filter_idx];
-
- if (efx_filter_test_used(eftp, filter_idx)) {
- if (replace == B_FALSE) {
- rc = EEXIST;
- goto done;
- }
- }
- efx_filter_set_used(eftp, filter_idx);
- *saved_spec = *spec;
-
- if (efp->ef_depth[spec->efs_type] < depth) {
- efp->ef_depth[spec->efs_type] = depth;
- if (tbl_id == EFX_FILTER_TBL_TX_IP ||
- tbl_id == EFX_FILTER_TBL_TX_MAC)
- efx_filter_push_tx_limits(enp);
- else
- efx_filter_push_rx_limits(enp);
- }
-
- efx_filter_push_entry(enp, spec->efs_type, filter_idx, &filter);
-
-done:
- EFSYS_UNLOCK(enp->en_eslp, state);
- return (rc);
-}
-
static void
-efx_filter_clear_entry(
+falconsiena_filter_clear_entry(
__in efx_nic_t *enp,
- __in efx_filter_tbl_t *eftp,
+ __in falconsiena_filter_tbl_t *fsftp,
__in int index)
{
efx_oword_t filter;
- if (efx_filter_test_used(eftp, index)) {
- efx_filter_clear_used(eftp, index);
+ if (falconsiena_filter_test_used(fsftp, index)) {
+ falconsiena_filter_clear_used(fsftp, index);
EFX_ZERO_OWORD(filter);
- efx_filter_push_entry(enp, eftp->eft_spec[index].efs_type,
+ falconsiena_filter_push_entry(enp,
+ fsftp->fsft_spec[index].fsfs_type,
index, &filter);
- memset(&eftp->eft_spec[index], 0, sizeof(eftp->eft_spec[0]));
+ memset(&fsftp->fsft_spec[index],
+ 0, sizeof (fsftp->fsft_spec[0]));
}
}
- __checkReturn int
-efx_filter_remove_filter(
- __in efx_nic_t *enp,
- __in efx_filter_spec_t *spec)
-{
- efx_filter_t *efp = &enp->en_filter;
- efx_filter_tbl_id_t tbl_id = efx_filter_tbl_id(spec->efs_type);
- efx_filter_tbl_t *eftp = &efp->ef_tbl[tbl_id];
- efx_filter_spec_t *saved_spec;
- efx_oword_t filter;
- int filter_idx;
- unsigned int depth;
- int state;
- uint32_t key;
- int rc;
-
- key = efx_filter_build(&filter, spec);
-
- EFSYS_LOCK(enp->en_eslp, state);
-
- rc = efx_filter_search(eftp, spec, key, B_FALSE, &filter_idx, &depth);
- if (rc != 0)
- goto out;
-
- saved_spec = &eftp->eft_spec[filter_idx];
-
- efx_filter_clear_entry(enp, eftp, filter_idx);
- if (eftp->eft_used == 0)
- efx_filter_reset_search_depth(efp, tbl_id);
-
- rc = 0;
-
-out:
- EFSYS_UNLOCK(enp->en_eslp, state);
- return (rc);
-}
-
- void
-efx_filter_remove_index(
- __inout efx_nic_t *enp,
- __in efx_filter_type_t type,
- __in int index)
-{
- efx_filter_t *efp = &enp->en_filter;
- efx_filter_tbl_id_t tbl_id = efx_filter_tbl_id(type);
- efx_filter_tbl_t *eftp = &efp->ef_tbl[tbl_id];
- int state;
-
- if (index < 0)
- return;
-
- EFSYS_LOCK(enp->en_eslp, state);
-
- efx_filter_clear_entry(enp, eftp, index);
- if (eftp->eft_used == 0)
- efx_filter_reset_search_depth(efp, tbl_id);
-
- EFSYS_UNLOCK(enp->en_eslp, state);
-}
-
void
-efx_filter_tbl_clear(
- __inout efx_nic_t *enp,
- __in efx_filter_tbl_id_t tbl_id)
+falconsiena_filter_tbl_clear(
+ __in efx_nic_t *enp,
+ __in falconsiena_filter_tbl_id_t tbl_id)
{
- efx_filter_t *efp = &enp->en_filter;
- efx_filter_tbl_t *eftp = &efp->ef_tbl[tbl_id];
+ falconsiena_filter_t *fsfp = enp->en_filter.ef_falconsiena_filter;
+ falconsiena_filter_tbl_t *fsftp = &fsfp->fsf_tbl[tbl_id];
int index;
int state;
EFSYS_LOCK(enp->en_eslp, state);
- for (index = 0; index < eftp->eft_size; ++index) {
- efx_filter_clear_entry(enp, eftp, index);
+ for (index = 0; index < fsftp->fsft_size; ++index) {
+ falconsiena_filter_clear_entry(enp, fsftp, index);
}
- if (eftp->eft_used == 0)
- efx_filter_reset_search_depth(efp, tbl_id);
+ if (fsftp->fsft_used == 0)
+ falconsiena_filter_reset_search_depth(fsfp, tbl_id);
EFSYS_UNLOCK(enp->en_eslp, state);
}
-/* Restore filter state after a reset */
- void
-efx_filter_restore(
+static __checkReturn int
+falconsiena_filter_init(
__in efx_nic_t *enp)
{
- efx_filter_t *efp = &enp->en_filter;
- efx_filter_tbl_id_t tbl_id;
- efx_filter_tbl_t *eftp;
- efx_filter_spec_t *spec;
- efx_oword_t filter;
- int filter_idx;
- int state;
-
- EFSYS_LOCK(enp->en_eslp, state);
+ falconsiena_filter_t *fsfp;
+ falconsiena_filter_tbl_t *fsftp;
+ int tbl_id;
+ int rc;
- for (tbl_id = 0; tbl_id < EFX_FILTER_NTBLS; tbl_id++) {
- eftp = &efp->ef_tbl[tbl_id];
- for (filter_idx = 0; filter_idx < eftp->eft_size; filter_idx++) {
- if (!efx_filter_test_used(eftp, filter_idx))
- continue;
+ EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (falconsiena_filter_t), fsfp);
- spec = &eftp->eft_spec[filter_idx];
- efx_filter_build(&filter, spec);
- efx_filter_push_entry(enp, spec->efs_type,
- filter_idx, &filter);
- }
+ if (!fsfp) {
+ rc = ENOMEM;
+ goto fail1;
}
- efx_filter_push_rx_limits(enp);
- efx_filter_push_tx_limits(enp);
-
- EFSYS_UNLOCK(enp->en_eslp, state);
-}
-
- void
-efx_filter_redirect_index(
- __inout efx_nic_t *enp,
- __in efx_filter_type_t type,
- __in int filter_index,
- __in int rxq_index)
-{
- efx_filter_t *efp = &enp->en_filter;
- efx_filter_tbl_t *eftp =
- &efp->ef_tbl[efx_filter_tbl_id(type)];
- efx_filter_spec_t *spec;
- efx_oword_t filter;
- int state;
-
- EFSYS_LOCK(enp->en_eslp, state);
+ enp->en_filter.ef_falconsiena_filter = fsfp;
- spec = &eftp->eft_spec[filter_index];
- spec->efs_dmaq_id = (uint16_t)rxq_index;
-
- efx_filter_build(&filter, spec);
- efx_filter_push_entry(enp, spec->efs_type, filter_index, &filter);
-
- EFSYS_UNLOCK(enp->en_eslp, state);
-}
-
- __checkReturn int
-efx_filter_init(
- __in efx_nic_t *enp)
-{
- efx_filter_t *efp = &enp->en_filter;
- efx_filter_tbl_t *eftp;
- int tbl_id;
- int rc;
-
- 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_FILTER));
-
- switch (enp->en_family)
- {
+ switch (enp->en_family) {
#if EFSYS_OPT_FALCON
case EFX_FAMILY_FALCON:
- eftp = &efp->ef_tbl[EFX_FILTER_TBL_RX_IP];
- eftp->eft_size = FR_AZ_RX_FILTER_TBL0_ROWS;
+ fsftp = &fsfp->fsf_tbl[EFX_FS_FILTER_TBL_RX_IP];
+ fsftp->fsft_size = FR_AZ_RX_FILTER_TBL0_ROWS;
break;
#endif /* EFSYS_OPT_FALCON */
#if EFSYS_OPT_SIENA
case EFX_FAMILY_SIENA:
- eftp = &efp->ef_tbl[EFX_FILTER_TBL_RX_IP];
- eftp->eft_size = FR_AZ_RX_FILTER_TBL0_ROWS;
+ fsftp = &fsfp->fsf_tbl[EFX_FS_FILTER_TBL_RX_IP];
+ fsftp->fsft_size = FR_AZ_RX_FILTER_TBL0_ROWS;
- eftp = &efp->ef_tbl[EFX_FILTER_TBL_RX_MAC];
- eftp->eft_size = FR_CZ_RX_MAC_FILTER_TBL0_ROWS;
+ fsftp = &fsfp->fsf_tbl[EFX_FS_FILTER_TBL_RX_MAC];
+ fsftp->fsft_size = FR_CZ_RX_MAC_FILTER_TBL0_ROWS;
- eftp = &efp->ef_tbl[EFX_FILTER_TBL_TX_IP];
- eftp->eft_size = FR_CZ_TX_FILTER_TBL0_ROWS;
+ fsftp = &fsfp->fsf_tbl[EFX_FS_FILTER_TBL_TX_IP];
+ fsftp->fsft_size = FR_CZ_TX_FILTER_TBL0_ROWS;
- eftp = &efp->ef_tbl[EFX_FILTER_TBL_TX_MAC];
- eftp->eft_size = FR_CZ_TX_MAC_FILTER_TBL0_ROWS;
+ fsftp = &fsfp->fsf_tbl[EFX_FS_FILTER_TBL_TX_MAC];
+ fsftp->fsft_size = FR_CZ_TX_MAC_FILTER_TBL0_ROWS;
break;
#endif /* EFSYS_OPT_SIENA */
default:
rc = ENOTSUP;
- goto fail1;
+ goto fail2;
}
- for (tbl_id = 0; tbl_id < EFX_FILTER_NTBLS; tbl_id++) {
+ for (tbl_id = 0; tbl_id < EFX_FS_FILTER_NTBLS; tbl_id++) {
unsigned int bitmap_size;
- eftp = &efp->ef_tbl[tbl_id];
- if (eftp->eft_size == 0)
+ fsftp = &fsfp->fsf_tbl[tbl_id];
+ if (fsftp->fsft_size == 0)
continue;
- EFX_STATIC_ASSERT(sizeof(eftp->eft_bitmap[0]) == sizeof(uint32_t));
- bitmap_size = (eftp->eft_size + (sizeof(uint32_t) * 8) - 1) / 8;
+ EFX_STATIC_ASSERT(sizeof (fsftp->fsft_bitmap[0]) ==
+ sizeof (uint32_t));
+ bitmap_size =
+ (fsftp->fsft_size + (sizeof (uint32_t) * 8) - 1) / 8;
- EFSYS_KMEM_ALLOC(enp->en_esip, bitmap_size, eftp->eft_bitmap);
- if (!eftp->eft_bitmap) {
+ EFSYS_KMEM_ALLOC(enp->en_esip, bitmap_size, fsftp->fsft_bitmap);
+ if (!fsftp->fsft_bitmap) {
rc = ENOMEM;
- goto fail2;
+ goto fail3;
}
- EFSYS_KMEM_ALLOC(enp->en_esip, eftp->eft_size * sizeof(*eftp->eft_spec),
- eftp->eft_spec);
- if (!eftp->eft_spec) {
+ EFSYS_KMEM_ALLOC(enp->en_esip,
+ fsftp->fsft_size * sizeof (*fsftp->fsft_spec),
+ fsftp->fsft_spec);
+ if (!fsftp->fsft_spec) {
rc = ENOMEM;
- goto fail3;
+ goto fail4;
}
- memset(eftp->eft_spec, 0, eftp->eft_size * sizeof(*eftp->eft_spec));
+ memset(fsftp->fsft_spec, 0,
+ fsftp->fsft_size * sizeof (*fsftp->fsft_spec));
}
- enp->en_mod_flags |= EFX_MOD_FILTER;
return (0);
+fail4:
+ EFSYS_PROBE(fail4);
+
fail3:
EFSYS_PROBE(fail3);
fail2:
EFSYS_PROBE(fail2);
- efx_filter_fini(enp);
+ falconsiena_filter_fini(enp);
fail1:
EFSYS_PROBE1(fail1, int, rc);
return (rc);
}
- void
-efx_filter_fini(
+static void
+falconsiena_filter_fini(
__in efx_nic_t *enp)
{
- efx_filter_t *efp = &enp->en_filter;
- efx_filter_tbl_id_t tbl_id;
+ falconsiena_filter_t *fsfp = enp->en_filter.ef_falconsiena_filter;
+ falconsiena_filter_tbl_id_t tbl_id;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
- for (tbl_id = 0; tbl_id < EFX_FILTER_NTBLS; tbl_id++) {
- efx_filter_tbl_t *eftp = &efp->ef_tbl[tbl_id];
+ if (fsfp == NULL)
+ return;
+
+ for (tbl_id = 0; tbl_id < EFX_FS_FILTER_NTBLS; tbl_id++) {
+ falconsiena_filter_tbl_t *fsftp = &fsfp->fsf_tbl[tbl_id];
unsigned int bitmap_size;
- EFX_STATIC_ASSERT(sizeof(eftp->eft_bitmap[0]) == sizeof(uint32_t));
- bitmap_size = (eftp->eft_size + (sizeof(uint32_t) * 8) - 1) / 8;
+ EFX_STATIC_ASSERT(sizeof (fsftp->fsft_bitmap[0]) ==
+ sizeof (uint32_t));
+ bitmap_size =
+ (fsftp->fsft_size + (sizeof (uint32_t) * 8) - 1) / 8;
- if (eftp->eft_bitmap != NULL) {
+ if (fsftp->fsft_bitmap != NULL) {
EFSYS_KMEM_FREE(enp->en_esip, bitmap_size,
- eftp->eft_bitmap);
- eftp->eft_bitmap = NULL;
+ fsftp->fsft_bitmap);
+ fsftp->fsft_bitmap = NULL;
}
- if (eftp->eft_spec != NULL) {
- EFSYS_KMEM_FREE(enp->en_esip, eftp->eft_size *
- sizeof(*eftp->eft_spec), eftp->eft_spec);
- eftp->eft_spec = NULL;
+ if (fsftp->fsft_spec != NULL) {
+ EFSYS_KMEM_FREE(enp->en_esip, fsftp->fsft_size *
+ sizeof (*fsftp->fsft_spec), fsftp->fsft_spec);
+ fsftp->fsft_spec = NULL;
}
}
- enp->en_mod_flags &= ~EFX_MOD_FILTER;
+ EFSYS_KMEM_FREE(enp->en_esip, sizeof (falconsiena_filter_t),
+ enp->en_filter.ef_falconsiena_filter);
}
-extern void
-efx_filter_spec_rx_ipv4_tcp_full(
- __inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint32_t src_ip,
- __in uint16_t src_tcp,
- __in uint32_t dest_ip,
- __in uint16_t dest_tcp)
+/* Restore filter state after a reset */
+static __checkReturn int
+falconsiena_filter_restore(
+ __in efx_nic_t *enp)
{
- EFSYS_ASSERT3P(spec, !=, NULL);
- EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS |
- EFX_FILTER_FLAG_RX_SCATTER)) == 0);
+ falconsiena_filter_t *fsfp = enp->en_filter.ef_falconsiena_filter;
+ falconsiena_filter_tbl_id_t tbl_id;
+ falconsiena_filter_tbl_t *fsftp;
+ falconsiena_filter_spec_t *spec;
+ efx_oword_t filter;
+ int filter_idx;
+ int state;
+ int rc;
- spec->efs_type = EFX_FILTER_RX_TCP_FULL;
- spec->efs_flags = (uint8_t)flags;
- spec->efs_dword[0] = src_tcp | src_ip << 16;
- spec->efs_dword[1] = dest_tcp << 16 | src_ip >> 16;
- spec->efs_dword[2] = dest_ip;
-}
+ EFSYS_LOCK(enp->en_eslp, state);
-extern void
-efx_filter_spec_rx_ipv4_tcp_wild(
- __inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint32_t dest_ip,
- __in uint16_t dest_tcp)
-{
- EFSYS_ASSERT3P(spec, !=, NULL);
- EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS |
- EFX_FILTER_FLAG_RX_SCATTER)) == 0);
+ for (tbl_id = 0; tbl_id < EFX_FS_FILTER_NTBLS; tbl_id++) {
+ fsftp = &fsfp->fsf_tbl[tbl_id];
+ for (filter_idx = 0;
+ filter_idx < fsftp->fsft_size;
+ filter_idx++) {
+ if (!falconsiena_filter_test_used(fsftp, filter_idx))
+ continue;
- spec->efs_type = EFX_FILTER_RX_TCP_WILD;
- spec->efs_flags = (uint8_t)flags;
- spec->efs_dword[0] = 0;
- spec->efs_dword[1] = dest_tcp << 16;
- spec->efs_dword[2] = dest_ip;
-}
+ spec = &fsftp->fsft_spec[filter_idx];
+ if ((rc = falconsiena_filter_build(&filter, spec)) != 0)
+ goto fail1;
+ if ((rc = falconsiena_filter_push_entry(enp,
+ spec->fsfs_type, filter_idx, &filter)) != 0)
+ goto fail2;
+ }
+ }
-extern void
-efx_filter_spec_rx_ipv4_udp_full(
- __inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint32_t src_ip,
- __in uint16_t src_udp,
- __in uint32_t dest_ip,
- __in uint16_t dest_udp)
-{
- EFSYS_ASSERT3P(spec, !=, NULL);
- EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS |
- EFX_FILTER_FLAG_RX_SCATTER)) == 0);
+ falconsiena_filter_push_rx_limits(enp);
+ falconsiena_filter_push_tx_limits(enp);
- spec->efs_type = EFX_FILTER_RX_UDP_FULL;
- spec->efs_flags = (uint8_t)flags;
- spec->efs_dword[0] = src_udp | src_ip << 16;
- spec->efs_dword[1] = dest_udp << 16 | src_ip >> 16;
- spec->efs_dword[2] = dest_ip;
-}
+ EFSYS_UNLOCK(enp->en_eslp, state);
-extern void
-efx_filter_spec_rx_ipv4_udp_wild(
- __inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint32_t dest_ip,
- __in uint16_t dest_udp)
-{
- EFSYS_ASSERT3P(spec, !=, NULL);
- EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS |
- EFX_FILTER_FLAG_RX_SCATTER)) == 0);
+ return (0);
- spec->efs_type = EFX_FILTER_RX_UDP_WILD;
- spec->efs_flags = (uint8_t)flags;
- spec->efs_dword[0] = dest_udp;
- spec->efs_dword[1] = 0;
- spec->efs_dword[2] = dest_ip;
-}
+fail2:
+ EFSYS_PROBE(fail2);
-#if EFSYS_OPT_SIENA
-extern void
-efx_filter_spec_rx_mac_full(
- __inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint16_t vlan_id,
- __in uint8_t *dest_mac)
-{
- EFSYS_ASSERT3P(spec, !=, NULL);
- EFSYS_ASSERT3P(dest_mac, !=, NULL);
- EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS |
- EFX_FILTER_FLAG_RX_SCATTER |
- EFX_FILTER_FLAG_RX_OVERRIDE_IP)) == 0);
-
- spec->efs_type = EFX_FILTER_RX_MAC_FULL;
- spec->efs_flags = (uint8_t)flags;
- spec->efs_dword[0] = vlan_id;
- spec->efs_dword[1] =
- dest_mac[2] << 24 |
- dest_mac[3] << 16 |
- dest_mac[4] << 8 |
- dest_mac[5];
- spec->efs_dword[2] =
- dest_mac[0] << 8 |
- dest_mac[1];
-}
-#endif /* EFSYS_OPT_SIENA */
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
-#if EFSYS_OPT_SIENA
-extern void
-efx_filter_spec_rx_mac_wild(
- __inout efx_filter_spec_t *spec,
- __in unsigned int flags,
- __in uint8_t *dest_mac)
-{
- EFSYS_ASSERT3P(spec, !=, NULL);
- EFSYS_ASSERT3P(dest_mac, !=, NULL);
- EFSYS_ASSERT((flags & ~(EFX_FILTER_FLAG_RX_RSS |
- EFX_FILTER_FLAG_RX_SCATTER |
- EFX_FILTER_FLAG_RX_OVERRIDE_IP)) == 0);
-
- spec->efs_type = EFX_FILTER_RX_MAC_WILD;
- spec->efs_flags = (uint8_t)flags;
- spec->efs_dword[0] = 0;
- spec->efs_dword[1] =
- dest_mac[2] << 24 |
- dest_mac[3] << 16 |
- dest_mac[4] << 8 |
- dest_mac[5];
- spec->efs_dword[2] =
- dest_mac[0] << 8 |
- dest_mac[1];
+ EFSYS_UNLOCK(enp->en_eslp, state);
+
+ return (rc);
}
-#endif /* EFSYS_OPT_SIENA */
-#if EFSYS_OPT_SIENA
-extern void
-efx_filter_spec_tx_ipv4_tcp_full(
+static __checkReturn int
+falconsiena_filter_add(
+ __in efx_nic_t *enp,
__inout efx_filter_spec_t *spec,
- __in uint32_t src_ip,
- __in uint16_t src_tcp,
- __in uint32_t dest_ip,
- __in uint16_t dest_tcp)
+ __in boolean_t may_replace)
{
- EFSYS_ASSERT3P(spec, !=, NULL);
+ int rc;
+ falconsiena_filter_spec_t fs_spec;
+ falconsiena_filter_t *fsfp = enp->en_filter.ef_falconsiena_filter;
+ falconsiena_filter_tbl_id_t tbl_id;
+ falconsiena_filter_tbl_t *fsftp;
+ falconsiena_filter_spec_t *saved_fs_spec;
+ efx_oword_t filter;
+ int filter_idx;
+ unsigned int depth;
+ int state;
+ uint32_t key;
- spec->efs_type = EFX_FILTER_TX_TCP_FULL;
- spec->efs_flags = 0;
- spec->efs_dword[0] = src_tcp | src_ip << 16;
- spec->efs_dword[1] = dest_tcp << 16 | src_ip >> 16;
- spec->efs_dword[2] = dest_ip;
-}
-#endif /* EFSYS_OPT_SIENA */
-#if EFSYS_OPT_SIENA
-extern void
-efx_filter_spec_tx_ipv4_tcp_wild(
- __inout efx_filter_spec_t *spec,
- __in uint32_t src_ip,
- __in uint16_t src_tcp)
-{
EFSYS_ASSERT3P(spec, !=, NULL);
- spec->efs_type = EFX_FILTER_TX_TCP_WILD;
- spec->efs_flags = 0;
- spec->efs_dword[0] = 0;
- spec->efs_dword[1] = src_tcp << 16;
- spec->efs_dword[2] = src_ip;
-}
-#endif /* EFSYS_OPT_SIENA */
+ if ((rc = falconsiena_filter_spec_from_gen_spec(&fs_spec, spec)) != 0)
+ goto fail1;
-#if EFSYS_OPT_SIENA
-extern void
-efx_filter_spec_tx_ipv4_udp_full(
- __inout efx_filter_spec_t *spec,
- __in uint32_t src_ip,
- __in uint16_t src_udp,
- __in uint32_t dest_ip,
- __in uint16_t dest_udp)
-{
- EFSYS_ASSERT3P(spec, !=, NULL);
+ tbl_id = falconsiena_filter_tbl_id(fs_spec.fsfs_type);
+ fsftp = &fsfp->fsf_tbl[tbl_id];
- spec->efs_type = EFX_FILTER_TX_UDP_FULL;
- spec->efs_flags = 0;
- spec->efs_dword[0] = src_udp | src_ip << 16;
- spec->efs_dword[1] = dest_udp << 16 | src_ip >> 16;
- spec->efs_dword[2] = dest_ip;
-}
-#endif /* EFSYS_OPT_SIENA */
+ if (fsftp->fsft_size == 0) {
+ rc = EINVAL;
+ goto fail2;
+ }
-#if EFSYS_OPT_SIENA
-extern void
-efx_filter_spec_tx_ipv4_udp_wild(
- __inout efx_filter_spec_t *spec,
- __in uint32_t src_ip,
- __in uint16_t src_udp)
-{
- EFSYS_ASSERT3P(spec, !=, NULL);
+ key = falconsiena_filter_build(&filter, &fs_spec);
+
+ EFSYS_LOCK(enp->en_eslp, state);
+
+ rc = falconsiena_filter_search(fsftp, &fs_spec, key, B_TRUE,
+ &filter_idx, &depth);
+ if (rc != 0)
+ goto fail3;
+
+ EFSYS_ASSERT3U(filter_idx, <, fsftp->fsft_size);
+ saved_fs_spec = &fsftp->fsft_spec[filter_idx];
+
+ if (falconsiena_filter_test_used(fsftp, filter_idx)) {
+ if (may_replace == B_FALSE) {
+ rc = EEXIST;
+ goto fail4;
+ }
+ }
+ falconsiena_filter_set_used(fsftp, filter_idx);
+ *saved_fs_spec = fs_spec;
+
+ if (fsfp->fsf_depth[fs_spec.fsfs_type] < depth) {
+ fsfp->fsf_depth[fs_spec.fsfs_type] = depth;
+ if (tbl_id == EFX_FS_FILTER_TBL_TX_IP ||
+ tbl_id == EFX_FS_FILTER_TBL_TX_MAC)
+ falconsiena_filter_push_tx_limits(enp);
+ else
+ falconsiena_filter_push_rx_limits(enp);
+ }
+
+ falconsiena_filter_push_entry(enp, fs_spec.fsfs_type,
+ filter_idx, &filter);
+
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ return (0);
+
+fail4:
+ EFSYS_PROBE(fail4);
- spec->efs_type = EFX_FILTER_TX_UDP_WILD;
- spec->efs_flags = 0;
- spec->efs_dword[0] = src_udp;
- spec->efs_dword[1] = 0;
- spec->efs_dword[2] = src_ip;
+fail3:
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ EFSYS_PROBE(fail3);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
}
-#endif /* EFSYS_OPT_SIENA */
-#if EFSYS_OPT_SIENA
-extern void
-efx_filter_spec_tx_mac_full(
- __inout efx_filter_spec_t *spec,
- __in uint16_t vlan_id,
- __in uint8_t *src_mac)
+static __checkReturn int
+falconsiena_filter_delete(
+ __in efx_nic_t *enp,
+ __inout efx_filter_spec_t *spec)
{
+ int rc;
+ falconsiena_filter_spec_t fs_spec;
+ falconsiena_filter_t *fsfp = enp->en_filter.ef_falconsiena_filter;
+ falconsiena_filter_tbl_id_t tbl_id;
+ falconsiena_filter_tbl_t *fsftp;
+ falconsiena_filter_spec_t *saved_spec;
+ efx_oword_t filter;
+ int filter_idx;
+ unsigned int depth;
+ int state;
+ uint32_t key;
+
EFSYS_ASSERT3P(spec, !=, NULL);
- EFSYS_ASSERT3P(src_mac, !=, NULL);
-
- spec->efs_type = EFX_FILTER_TX_MAC_FULL;
- spec->efs_flags = 0;
- spec->efs_dword[0] = vlan_id;
- spec->efs_dword[1] =
- src_mac[2] << 24 |
- src_mac[3] << 16 |
- src_mac[4] << 8 |
- src_mac[5];
- spec->efs_dword[2] =
- src_mac[0] << 8 |
- src_mac[1];
+
+ if ((rc = falconsiena_filter_spec_from_gen_spec(&fs_spec, spec)) != 0)
+ goto fail1;
+
+ tbl_id = falconsiena_filter_tbl_id(fs_spec.fsfs_type);
+ fsftp = &fsfp->fsf_tbl[tbl_id];
+
+ key = falconsiena_filter_build(&filter, &fs_spec);
+
+ EFSYS_LOCK(enp->en_eslp, state);
+
+ rc = falconsiena_filter_search(fsftp, &fs_spec, key, B_FALSE,
+ &filter_idx, &depth);
+ if (rc != 0)
+ goto fail2;
+
+ saved_spec = &fsftp->fsft_spec[filter_idx];
+
+ falconsiena_filter_clear_entry(enp, fsftp, filter_idx);
+ if (fsftp->fsft_used == 0)
+ falconsiena_filter_reset_search_depth(fsfp, tbl_id);
+
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ return (0);
+
+fail2:
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
}
-#endif /* EFSYS_OPT_SIENA */
-#if EFSYS_OPT_SIENA
-extern void
-efx_filter_spec_tx_mac_wild(
- __inout efx_filter_spec_t *spec,
- __in uint8_t *src_mac)
+#define MAX_SUPPORTED 4
+
+static __checkReturn int
+falconsiena_filter_supported_filters(
+ __in efx_nic_t *enp,
+ __out uint32_t *list,
+ __out size_t *length)
{
- EFSYS_ASSERT3P(spec, !=, NULL);
- EFSYS_ASSERT3P(src_mac, !=, NULL);
-
- spec->efs_type = EFX_FILTER_TX_MAC_WILD;
- spec->efs_flags = 0;
- spec->efs_dword[0] = 0;
- spec->efs_dword[1] =
- src_mac[2] << 24 |
- src_mac[3] << 16 |
- src_mac[4] << 8 |
- src_mac[5];
- spec->efs_dword[2] =
- src_mac[0] << 8 |
- src_mac[1];
+ int index = 0;
+ uint32_t rx_matches[MAX_SUPPORTED];
+ int rc;
+
+ if (list == NULL) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ rx_matches[index++] =
+ EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |
+ EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT |
+ EFX_FILTER_MATCH_REM_HOST | EFX_FILTER_MATCH_REM_PORT;
+
+ rx_matches[index++] =
+ EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_IP_PROTO |
+ EFX_FILTER_MATCH_LOC_HOST | EFX_FILTER_MATCH_LOC_PORT;
+
+ if (enp->en_features & EFX_FEATURE_MAC_HEADER_FILTERS) {
+ rx_matches[index++] =
+ EFX_FILTER_MATCH_OUTER_VID | EFX_FILTER_MATCH_LOC_MAC;
+
+ rx_matches[index++] = EFX_FILTER_MATCH_LOC_MAC;
+ }
+
+ EFSYS_ASSERT3U(index, <=, MAX_SUPPORTED);
+
+ *length = index;
+ memcpy(list, rx_matches, *length);
+
+ return (0);
+
+fail1:
+
+ return (rc);
}
-#endif /* EFSYS_OPT_SIENA */
+#undef MAX_SUPPORTED
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
#endif /* EFSYS_OPT_FILTER */
diff --git a/sys/dev/sfxge/common/efx_hash.c b/sys/dev/sfxge/common/efx_hash.c
new file mode 100644
index 0000000..3005c1b
--- /dev/null
+++ b/sys/dev/sfxge/common/efx_hash.c
@@ -0,0 +1,333 @@
+/*-
+ * 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-2015 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_types.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/sys/dev/sfxge/common/efx_impl.h b/sys/dev/sfxge/common/efx_impl.h
index e7c2231..6f72d5f 100644
--- a/sys/dev/sfxge/common/efx_impl.h
+++ b/sys/dev/sfxge/common/efx_impl.h
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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.
*
* $FreeBSD$
*/
@@ -31,6 +36,15 @@
#include "efsys.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
+
+#include "efx_check.h"
+
#if EFSYS_OPT_FALCON
#include "falcon_impl.h"
@@ -40,40 +54,138 @@
#include "siena_impl.h"
#endif /* EFSYS_OPT_SIENA */
+#if EFSYS_OPT_HUNTINGTON
+#include "hunt_impl.h"
+#endif /* EFSYS_OPT_HUNTINGTON */
+
#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_WOL 0x00000800
-#define EFX_MOD_FILTER 0x00001000
-
-#define EFX_RESET_MAC 0x00000001
-#define EFX_RESET_PHY 0x00000002
+#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_WOL 0x00000800
+#define EFX_MOD_FILTER 0x00001000
+#define EFX_MOD_PKTFILTER 0x00002000
+
+#define EFX_RESET_MAC 0x00000001
+#define EFX_RESET_PHY 0x00000002
+#define EFX_RESET_RXQ_ERR 0x00000004
+#define EFX_RESET_TXQ_ERR 0x00000008
typedef enum efx_mac_type_e {
EFX_MAC_INVALID = 0,
EFX_MAC_FALCON_GMAC,
EFX_MAC_FALCON_XMAC,
EFX_MAC_SIENA,
+ EFX_MAC_HUNTINGTON,
EFX_MAC_NTYPES
} efx_mac_type_t;
+typedef struct efx_ev_ops_s {
+ int (*eevo_init)(efx_nic_t *);
+ void (*eevo_fini)(efx_nic_t *);
+ int (*eevo_qcreate)(efx_nic_t *, unsigned int,
+ efsys_mem_t *, size_t, uint32_t,
+ efx_evq_t *);
+ void (*eevo_qdestroy)(efx_evq_t *);
+ int (*eevo_qprime)(efx_evq_t *, unsigned int);
+ void (*eevo_qpost)(efx_evq_t *, uint16_t);
+ int (*eevo_qmoderate)(efx_evq_t *, unsigned int);
+#if EFSYS_OPT_QSTATS
+ void (*eevo_qstats_update)(efx_evq_t *, efsys_stat_t *);
+#endif
+} efx_ev_ops_t;
+
+typedef struct efx_tx_ops_s {
+ int (*etxo_init)(efx_nic_t *);
+ void (*etxo_fini)(efx_nic_t *);
+ int (*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 *);
+ int (*etxo_qpost)(efx_txq_t *, efx_buffer_t *,
+ unsigned int, unsigned int,
+ unsigned int *);
+ void (*etxo_qpush)(efx_txq_t *, unsigned int, unsigned int);
+ int (*etxo_qpace)(efx_txq_t *, unsigned int);
+ int (*etxo_qflush)(efx_txq_t *);
+ void (*etxo_qenable)(efx_txq_t *);
+ int (*etxo_qpio_enable)(efx_txq_t *);
+ void (*etxo_qpio_disable)(efx_txq_t *);
+ int (*etxo_qpio_write)(efx_txq_t *,uint8_t *, size_t,
+ size_t);
+ int (*etxo_qpio_post)(efx_txq_t *, size_t, unsigned int,
+ unsigned int *);
+ int (*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_vlantci_create)(efx_txq_t *, uint16_t,
+ efx_desc_t *);
+#if EFSYS_OPT_QSTATS
+ void (*etxo_qstats_update)(efx_txq_t *,
+ efsys_stat_t *);
+#endif
+} efx_tx_ops_t;
+
+typedef struct efx_rx_ops_s {
+ int (*erxo_init)(efx_nic_t *);
+ void (*erxo_fini)(efx_nic_t *);
+#if EFSYS_OPT_RX_HDR_SPLIT
+ int (*erxo_hdr_split_enable)(efx_nic_t *, unsigned int,
+ unsigned int);
+#endif
+#if EFSYS_OPT_RX_SCATTER
+ int (*erxo_scatter_enable)(efx_nic_t *, unsigned int);
+#endif
+#if EFSYS_OPT_RX_SCALE
+ int (*erxo_scale_mode_set)(efx_nic_t *, efx_rx_hash_alg_t,
+ efx_rx_hash_type_t, boolean_t);
+ int (*erxo_scale_key_set)(efx_nic_t *, uint8_t *, size_t);
+ int (*erxo_scale_tbl_set)(efx_nic_t *, unsigned int *,
+ size_t);
+#endif
+ 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 *);
+ int (*erxo_qflush)(efx_rxq_t *);
+ void (*erxo_qenable)(efx_rxq_t *);
+ int (*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 {
int (*emo_reset)(efx_nic_t *); /* optional */
int (*emo_poll)(efx_nic_t *, efx_link_mode_t *);
int (*emo_up)(efx_nic_t *, boolean_t *);
+ int (*emo_addr_set)(efx_nic_t *);
int (*emo_reconfigure)(efx_nic_t *);
+ int (*emo_multicast_list_set)(efx_nic_t *);
+ int (*emo_filter_default_rxq_set)(efx_nic_t *,
+ efx_rxq_t *, boolean_t);
+ void (*emo_filter_default_rxq_clear)(efx_nic_t *);
#if EFSYS_OPT_LOOPBACK
int (*emo_loopback_set)(efx_nic_t *, efx_link_mode_t,
efx_loopback_type_t);
@@ -103,21 +215,59 @@ typedef struct efx_phy_ops_s {
#endif /* EFSYS_OPT_PHY_STATS */
#if EFSYS_OPT_PHY_PROPS
#if EFSYS_OPT_NAMES
- const char __cs *(*epo_prop_name)(efx_nic_t *, unsigned int);
+ const char *(*epo_prop_name)(efx_nic_t *, unsigned int);
#endif /* EFSYS_OPT_PHY_PROPS */
int (*epo_prop_get)(efx_nic_t *, unsigned int, uint32_t,
uint32_t *);
int (*epo_prop_set)(efx_nic_t *, unsigned int, uint32_t);
#endif /* EFSYS_OPT_PHY_PROPS */
-#if EFSYS_OPT_PHY_BIST
- int (*epo_bist_start)(efx_nic_t *, efx_phy_bist_type_t);
- int (*epo_bist_poll)(efx_nic_t *, efx_phy_bist_type_t,
- efx_phy_bist_result_t *, uint32_t *,
+#if EFSYS_OPT_BIST
+ int (*epo_bist_enable_offline)(efx_nic_t *);
+ int (*epo_bist_start)(efx_nic_t *, efx_bist_type_t);
+ int (*epo_bist_poll)(efx_nic_t *, efx_bist_type_t,
+ efx_bist_result_t *, uint32_t *,
unsigned long *, size_t);
- void (*epo_bist_stop)(efx_nic_t *, efx_phy_bist_type_t);
-#endif /* EFSYS_OPT_PHY_BIST */
+ void (*epo_bist_stop)(efx_nic_t *, efx_bist_type_t);
+#endif /* EFSYS_OPT_BIST */
} efx_phy_ops_t;
+#if EFSYS_OPT_FILTER
+typedef struct efx_filter_ops_s {
+ int (*efo_init)(efx_nic_t *);
+ void (*efo_fini)(efx_nic_t *);
+ int (*efo_restore)(efx_nic_t *);
+ int (*efo_add)(efx_nic_t *, efx_filter_spec_t *,
+ boolean_t may_replace);
+ int (*efo_delete)(efx_nic_t *, efx_filter_spec_t *);
+ int (*efo_supported_filters)(efx_nic_t *, uint32_t *, size_t *);
+ int (*efo_reconfigure)(efx_nic_t *, uint8_t const *, boolean_t,
+ boolean_t, boolean_t, boolean_t,
+ uint8_t const *, int);
+} efx_filter_ops_t;
+
+extern __checkReturn int
+efx_filter_reconfigure(
+ __in efx_nic_t *enp,
+ __in_ecount(6) uint8_t const *mac_addr,
+ __in boolean_t all_unicst,
+ __in boolean_t mulcst,
+ __in boolean_t all_mulcst,
+ __in boolean_t brdcst,
+ __in_ecount(6*count) uint8_t const *addrs,
+ __in int count);
+
+#endif /* EFSYS_OPT_FILTER */
+
+typedef struct efx_pktfilter_ops_s {
+ int (*epfo_set)(efx_nic_t *,
+ boolean_t unicst,
+ boolean_t brdcast);
+#if EFSYS_OPT_MCAST_FILTER_LIST
+ int (*epfo_mcast_list_set)(efx_nic_t *, uint8_t const *addrs, int count);
+#endif /* EFSYS_OPT_MCAST_FILTER_LIST */
+ int (*epfo_mcast_all)(efx_nic_t *);
+} efx_pktfilter_ops_t;
+
typedef struct efx_port_s {
efx_mac_type_t ep_mac_type;
uint32_t ep_phy_type;
@@ -125,11 +275,16 @@ typedef struct efx_port_s {
uint32_t ep_mac_pdu;
uint8_t ep_mac_addr[6];
efx_link_mode_t ep_link_mode;
- boolean_t ep_unicst;
+ 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;
#if EFSYS_OPT_LOOPBACK
efx_loopback_type_t ep_loopback_type;
efx_link_mode_t ep_loopback_link_mode;
@@ -161,8 +316,8 @@ typedef struct efx_port_s {
uint32_t ep_fwver; /* falcon only */
boolean_t ep_mac_drain;
boolean_t ep_mac_stats_pending;
-#if EFSYS_OPT_PHY_BIST
- efx_phy_bist_type_t ep_current_bist;
+#if EFSYS_OPT_BIST
+ efx_bist_type_t ep_current_bist;
#endif
efx_mac_ops_t *ep_emop;
efx_phy_ops_t *ep_epop;
@@ -182,16 +337,30 @@ typedef struct efx_mon_s {
efx_mon_ops_t *em_emop;
} efx_mon_t;
+typedef struct efx_intr_ops_s {
+ int (*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 *);
+ int (*eio_trigger)(efx_nic_t *, unsigned int);
+ void (*eio_fini)(efx_nic_t *);
+} efx_intr_ops_t;
+
typedef struct efx_intr_s {
- efx_intr_type_t ei_type;
+ 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 {
int (*eno_probe)(efx_nic_t *);
+ int (*eno_set_drv_limits)(efx_nic_t *, efx_drv_limits_t*);
int (*eno_reset)(efx_nic_t *);
int (*eno_init)(efx_nic_t *);
+ int (*eno_get_vi_pool)(efx_nic_t *, uint32_t *);
+ int (*eno_get_bar_region)(efx_nic_t *, efx_nic_region_t,
+ uint32_t *, size_t *);
#if EFSYS_OPT_DIAG
int (*eno_sram_test)(efx_nic_t *, efx_sram_pattern_fn_t);
int (*eno_register_test)(efx_nic_t *);
@@ -201,94 +370,107 @@ typedef struct efx_nic_ops_s {
} efx_nic_ops_t;
#ifndef EFX_TXQ_LIMIT_TARGET
-# define EFX_TXQ_LIMIT_TARGET 259
+#define EFX_TXQ_LIMIT_TARGET 259
#endif
#ifndef EFX_RXQ_LIMIT_TARGET
-# define EFX_RXQ_LIMIT_TARGET 512
+#define EFX_RXQ_LIMIT_TARGET 512
#endif
#ifndef EFX_TXQ_DC_SIZE
-#define EFX_TXQ_DC_SIZE 1 /* 16 descriptors */
+#define EFX_TXQ_DC_SIZE 1 /* 16 descriptors */
#endif
#ifndef EFX_RXQ_DC_SIZE
-#define EFX_RXQ_DC_SIZE 3 /* 64 descriptors */
+#define EFX_RXQ_DC_SIZE 3 /* 64 descriptors */
#endif
#if EFSYS_OPT_FILTER
-typedef enum efx_filter_type_e {
- EFX_FILTER_RX_TCP_FULL, /* TCP/IPv4 4-tuple {dIP,dTCP,sIP,sTCP} */
- EFX_FILTER_RX_TCP_WILD, /* TCP/IPv4 dest {dIP,dTCP, -, -} */
- EFX_FILTER_RX_UDP_FULL, /* UDP/IPv4 4-tuple {dIP,dUDP,sIP,sUDP} */
- EFX_FILTER_RX_UDP_WILD, /* UDP/IPv4 dest {dIP,dUDP, -, -} */
+typedef struct falconsiena_filter_spec_s {
+ uint8_t fsfs_type;
+ uint32_t fsfs_flags;
+ uint32_t fsfs_dmaq_id;
+ uint32_t fsfs_dword[3];
+} falconsiena_filter_spec_t;
+
+typedef enum falconsiena_filter_type_e {
+ EFX_FS_FILTER_RX_TCP_FULL, /* TCP/IPv4 4-tuple {dIP,dTCP,sIP,sTCP} */
+ EFX_FS_FILTER_RX_TCP_WILD, /* TCP/IPv4 dest {dIP,dTCP, -, -} */
+ EFX_FS_FILTER_RX_UDP_FULL, /* UDP/IPv4 4-tuple {dIP,dUDP,sIP,sUDP} */
+ EFX_FS_FILTER_RX_UDP_WILD, /* UDP/IPv4 dest {dIP,dUDP, -, -} */
#if EFSYS_OPT_SIENA
- EFX_FILTER_RX_MAC_FULL, /* Ethernet {dMAC,VLAN} */
- EFX_FILTER_RX_MAC_WILD, /* Ethernet {dMAC, -} */
+ EFX_FS_FILTER_RX_MAC_FULL, /* Ethernet {dMAC,VLAN} */
+ EFX_FS_FILTER_RX_MAC_WILD, /* Ethernet {dMAC, -} */
- EFX_FILTER_TX_TCP_FULL, /* TCP/IPv4 {dIP,dTCP,sIP,sTCP} */
- EFX_FILTER_TX_TCP_WILD, /* TCP/IPv4 { -, -,sIP,sTCP} */
- EFX_FILTER_TX_UDP_FULL, /* UDP/IPv4 {dIP,dTCP,sIP,sTCP} */
- EFX_FILTER_TX_UDP_WILD, /* UDP/IPv4 source (host, port) */
+ EFX_FS_FILTER_TX_TCP_FULL, /* TCP/IPv4 {dIP,dTCP,sIP,sTCP} */
+ EFX_FS_FILTER_TX_TCP_WILD, /* TCP/IPv4 { -, -,sIP,sTCP} */
+ EFX_FS_FILTER_TX_UDP_FULL, /* UDP/IPv4 {dIP,dTCP,sIP,sTCP} */
+ EFX_FS_FILTER_TX_UDP_WILD, /* UDP/IPv4 source (host, port) */
- EFX_FILTER_TX_MAC_FULL, /* Ethernet source (MAC address, VLAN ID) */
- EFX_FILTER_TX_MAC_WILD, /* Ethernet source (MAC address) */
+ EFX_FS_FILTER_TX_MAC_FULL, /* Ethernet source (MAC address, VLAN ID) */
+ EFX_FS_FILTER_TX_MAC_WILD, /* Ethernet source (MAC address) */
#endif /* EFSYS_OPT_SIENA */
- EFX_FILTER_NTYPES
-} efx_filter_type_t;
-
-typedef enum efx_filter_tbl_id_e {
- EFX_FILTER_TBL_RX_IP = 0,
- EFX_FILTER_TBL_RX_MAC,
- EFX_FILTER_TBL_TX_IP,
- EFX_FILTER_TBL_TX_MAC,
- EFX_FILTER_NTBLS
-} efx_filter_tbl_id_t;
-
-typedef struct efx_filter_tbl_s {
- int eft_size; /* number of entries */
- int eft_used; /* active count */
- uint32_t *eft_bitmap; /* active bitmap */
- efx_filter_spec_t *eft_spec; /* array of saved specs */
-} efx_filter_tbl_t;
+ EFX_FS_FILTER_NTYPES
+} falconsiena_filter_type_t;
+
+typedef enum falconsiena_filter_tbl_id_e {
+ EFX_FS_FILTER_TBL_RX_IP = 0,
+ EFX_FS_FILTER_TBL_RX_MAC,
+ EFX_FS_FILTER_TBL_TX_IP,
+ EFX_FS_FILTER_TBL_TX_MAC,
+ EFX_FS_FILTER_NTBLS
+} falconsiena_filter_tbl_id_t;
+
+typedef struct falconsiena_filter_tbl_s {
+ int fsft_size; /* number of entries */
+ int fsft_used; /* active count */
+ uint32_t *fsft_bitmap; /* active bitmap */
+ falconsiena_filter_spec_t *fsft_spec; /* array of saved specs */
+} falconsiena_filter_tbl_t;
+
+typedef struct falconsiena_filter_s {
+ falconsiena_filter_tbl_t fsf_tbl[EFX_FS_FILTER_NTBLS];
+ unsigned int fsf_depth[EFX_FS_FILTER_NTYPES];
+} falconsiena_filter_t;
typedef struct efx_filter_s {
- efx_filter_tbl_t ef_tbl[EFX_FILTER_NTBLS];
- unsigned int ef_depth[EFX_FILTER_NTYPES];
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+ falconsiena_filter_t *ef_falconsiena_filter;
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
+#if EFSYS_OPT_HUNTINGTON
+ hunt_filter_table_t *ef_hunt_filter_table;
+#endif /* EFSYS_OPT_HUNTINGTON */
} efx_filter_t;
-
-extern __checkReturn int
-efx_filter_insert_filter(
- __in efx_nic_t *enp,
- __in efx_filter_spec_t *spec,
- __in boolean_t replace);
-
-extern __checkReturn int
-efx_filter_remove_filter(
- __in efx_nic_t *enp,
- __in efx_filter_spec_t *spec);
-
-extern void
-efx_filter_remove_index(
- __inout efx_nic_t *enp,
- __in efx_filter_type_t type,
- __in int filter_idx);
-
extern void
-efx_filter_redirect_index(
- __inout efx_nic_t *enp,
- __in efx_filter_type_t type,
- __in int filter_index,
- __in int rxq_index);
-
-extern __checkReturn int
-efx_filter_clear_tbl(
+falconsiena_filter_tbl_clear(
__in efx_nic_t *enp,
- __in efx_filter_tbl_id_t tbl);
+ __in falconsiena_filter_tbl_id_t tbl);
#endif /* EFSYS_OPT_FILTER */
+#if EFSYS_OPT_MCDI
+
+typedef struct efx_mcdi_ops_s {
+ int (*emco_init)(efx_nic_t *, const efx_mcdi_transport_t *);
+ void (*emco_request_copyin)(efx_nic_t *, efx_mcdi_req_t *,
+ unsigned int, boolean_t, boolean_t);
+ boolean_t (*emco_request_poll)(efx_nic_t *);
+ void (*emco_request_copyout)(efx_nic_t *, efx_mcdi_req_t *);
+ int (*emco_poll_reboot)(efx_nic_t *);
+ void (*emco_fini)(efx_nic_t *);
+ int (*emco_fw_update_supported)(efx_nic_t *, boolean_t *);
+ int (*emco_macaddr_change_supported)(efx_nic_t *, boolean_t *);
+} efx_mcdi_ops_t;
+
+typedef struct efx_mcdi_s {
+ efx_mcdi_ops_t *em_emcop;
+ const efx_mcdi_transport_t *em_emtp;
+ efx_mcdi_iface_t em_emip;
+} efx_mcdi_t;
+
+#endif /* EFSYS_OPT_MCDI */
+
#if EFSYS_OPT_NVRAM
typedef struct efx_nvram_ops_s {
#if EFSYS_OPT_DIAG
@@ -325,6 +507,85 @@ typedef struct efx_vpd_ops_s {
} efx_vpd_ops_t;
#endif /* EFSYS_OPT_VPD */
+#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
+
+ __checkReturn int
+efx_mcdi_nvram_partitions(
+ __in efx_nic_t *enp,
+ __out_bcount(size) caddr_t data,
+ __in size_t size,
+ __out unsigned int *npartnp);
+
+ __checkReturn int
+efx_mcdi_nvram_metadata(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __out uint32_t *subtypep,
+ __out_ecount(4) uint16_t version[4],
+ __out_bcount_opt(size) char *descp,
+ __in size_t size);
+
+ __checkReturn int
+efx_mcdi_nvram_info(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __out_opt size_t *sizep,
+ __out_opt uint32_t *addressp,
+ __out_opt uint32_t *erase_sizep);
+
+ __checkReturn int
+efx_mcdi_nvram_update_start(
+ __in efx_nic_t *enp,
+ __in uint32_t partn);
+
+ __checkReturn int
+efx_mcdi_nvram_read(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in uint32_t offset,
+ __out_bcount(size) caddr_t data,
+ __in size_t size);
+
+ __checkReturn int
+efx_mcdi_nvram_erase(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in uint32_t offset,
+ __in size_t size);
+
+ __checkReturn int
+efx_mcdi_nvram_write(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in uint32_t offset,
+ __out_bcount(size) caddr_t data,
+ __in size_t size);
+
+ __checkReturn int
+efx_mcdi_nvram_update_finish(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in boolean_t reboot);
+
+#if EFSYS_OPT_DIAG
+
+ __checkReturn int
+efx_mcdi_nvram_test(
+ __in efx_nic_t *enp,
+ __in uint32_t partn);
+
+#endif /* EFSYS_OPT_DIAG */
+
+#endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */
+
+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;
@@ -335,6 +596,7 @@ struct efx_nic_s {
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;
@@ -342,9 +604,17 @@ struct efx_nic_s {
uint32_t en_rx_qcount;
uint32_t en_tx_qcount;
efx_nic_ops_t *en_enop;
+ efx_ev_ops_t *en_eevop;
+ efx_tx_ops_t *en_etxop;
+ efx_rx_ops_t *en_erxop;
#if EFSYS_OPT_FILTER
efx_filter_t en_filter;
+ efx_filter_ops_t *en_efop;
#endif /* EFSYS_OPT_FILTER */
+ efx_pktfilter_ops_t *en_epfop;
+#if EFSYS_OPT_MCDI
+ efx_mcdi_t en_mcdi;
+#endif /* EFSYS_OPT_MCDI */
#if EFSYS_OPT_NVRAM
efx_nvram_type_t en_nvram_locked;
efx_nvram_ops_t *en_envop;
@@ -352,6 +622,12 @@ struct efx_nic_s {
#if EFSYS_OPT_VPD
efx_vpd_ops_t *en_evpdop;
#endif /* EFSYS_OPT_VPD */
+#if EFSYS_OPT_RX_SCALE
+ efx_rx_hash_support_t en_hash_support;
+ efx_rx_scale_support_t en_rss_support;
+ uint32_t en_rss_context;
+#endif /* EFSYS_OPT_RX_SCALE */
+ uint32_t en_vport_id;
union {
#if EFSYS_OPT_FALCON
struct {
@@ -373,9 +649,6 @@ struct efx_nic_s {
#endif /* EFSYS_OPT_FALCON */
#if EFSYS_OPT_SIENA
struct {
-#if EFSYS_OPT_MCDI
- efx_mcdi_iface_t enu_mip;
-#endif /* EFSYS_OPT_MCDI */
#if EFSYS_OPT_NVRAM || EFSYS_OPT_VPD
unsigned int enu_partn_mask;
#endif /* EFSYS_OPT_NVRAM || EFSYS_OPT_VPD */
@@ -383,8 +656,28 @@ struct efx_nic_s {
caddr_t enu_svpd;
size_t enu_svpd_length;
#endif /* EFSYS_OPT_VPD */
+ int enu_unused;
} siena;
#endif /* EFSYS_OPT_SIENA */
+#if EFSYS_OPT_HUNTINGTON
+ struct {
+ int enu_vi_base;
+ int enu_vi_count;
+#if EFSYS_OPT_VPD
+ caddr_t enu_svpd;
+ size_t enu_svpd_length;
+#endif /* EFSYS_OPT_VPD */
+ efx_piobuf_handle_t enu_piobuf_handle[HUNT_PIOBUF_NBUFS];
+ uint32_t enu_piobuf_count;
+ uint32_t enu_pio_alloc_map[HUNT_PIOBUF_NBUFS];
+ uint32_t enu_pio_write_vi_base;
+ /* Memory BAR mapping regions */
+ uint32_t enu_uc_mem_map_offset;
+ size_t enu_uc_mem_map_size;
+ uint32_t enu_wc_mem_map_offset;
+ size_t enu_wc_mem_map_size;
+ } hunt;
+#endif /* EFSYS_OPT_HUNTINGTON */
} en_u;
};
@@ -394,6 +687,11 @@ struct efx_nic_s {
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;
@@ -403,7 +701,17 @@ struct efx_evq_s {
#if EFSYS_OPT_QSTATS
uint32_t ee_stat[EV_NQSTATS];
#endif /* EFSYS_OPT_QSTATS */
- efx_ev_handler_t ee_handler[1 << FSF_AZ_EV_CODE_WIDTH];
+
+ 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;
+#if EFSYS_OPT_MCDI
+ efx_ev_handler_t ee_mcdi;
+#endif /* EFSYS_OPT_MCDI */
+
+ efx_evq_rxq_state_t ee_rxq_state[EFX_EV_RX_NLABELS];
};
#define EFX_EVQ_MAGIC 0x08081997
@@ -414,7 +722,9 @@ struct efx_evq_s {
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;
};
@@ -427,6 +737,13 @@ struct efx_txq_s {
unsigned int et_index;
unsigned int et_mask;
efsys_mem_t *et_esmp;
+#if EFSYS_OPT_HUNTINGTON
+ uint32_t et_pio_bufnum;
+ uint32_t et_pio_blknum;
+ uint32_t et_pio_write_offset;
+ uint32_t et_pio_offset;
+ size_t et_pio_size;
+#endif
#if EFSYS_OPT_QSTATS
uint32_t et_stat[TX_NQSTATS];
#endif /* EFSYS_OPT_QSTATS */
@@ -445,10 +762,19 @@ struct efx_txq_s {
_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 __cs *name = #_reg; \
+ const char *name = #_reg; \
char min = name[4]; \
char max = name[5]; \
char rev; \
@@ -462,6 +788,10 @@ struct efx_txq_s {
rev = 'C'; \
break; \
\
+ case EFX_FAMILY_HUNTINGTON: \
+ rev = 'D'; \
+ break; \
+ \
default: \
rev = '?'; \
break; \
@@ -578,6 +908,21 @@ struct efx_txq_s {
_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)); \
@@ -621,12 +966,12 @@ struct efx_txq_s {
_NOTE(CONSTANTCONDITION) \
} while (B_FALSE)
-#define EFX_BAR_TBL_READO(_enp, _reg, _index, _eop) \
+#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), B_TRUE); \
+ (_eop), (_lock)); \
EFSYS_PROBE7(efx_bar_tbl_reado, const char *, #_reg, \
uint32_t, (_index), \
uint32_t, _reg ## _OFST, \
@@ -637,7 +982,7 @@ struct efx_txq_s {
_NOTE(CONSTANTCONDITION) \
} while (B_FALSE)
-#define EFX_BAR_TBL_WRITEO(_enp, _reg, _index, _eop) \
+#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, \
@@ -649,14 +994,71 @@ struct efx_txq_s {
uint32_t, (_eop)->eo_u32[0]); \
EFSYS_BAR_WRITEO((_enp)->en_esbp, \
(_reg ## _OFST + ((_index) * _reg ## _STEP)), \
- (_eop), B_TRUE); \
+ (_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 int
+efx_nic_biu_test(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
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 int
efx_phy_probe(
__in efx_nic_t *enp);
@@ -683,7 +1085,7 @@ efx_vpd_hunk_verify(
extern __checkReturn int
efx_vpd_hunk_reinit(
- __in caddr_t data,
+ __in_bcount(size) caddr_t data,
__in size_t size,
__in boolean_t wantpid);
@@ -716,7 +1118,7 @@ efx_vpd_hunk_set(
#if EFSYS_OPT_DIAG
-extern efx_sram_pattern_fn_t __cs __efx_sram_pattern_fns[];
+extern efx_sram_pattern_fn_t __efx_sram_pattern_fns[];
typedef struct efx_register_set_s {
unsigned int address;
@@ -740,6 +1142,23 @@ efx_nic_test_tables(
#endif /* EFSYS_OPT_DIAG */
+#if EFSYS_OPT_MCDI
+
+extern __checkReturn int
+efx_mcdi_set_workaround(
+ __in efx_nic_t *enp,
+ __in uint32_t type,
+ __in boolean_t enabled,
+ __out_opt uint32_t *flagsp);
+
+extern __checkReturn int
+efx_mcdi_get_workarounds(
+ __in efx_nic_t *enp,
+ __out_opt uint32_t *implementedp,
+ __out_opt uint32_t *enabledp);
+
+#endif /* EFSYS_OPT_MCDI */
+
#ifdef __cplusplus
}
#endif
diff --git a/sys/dev/sfxge/common/efx_intr.c b/sys/dev/sfxge/common/efx_intr.c
index 556728d..d40f57f 100644
--- a/sys/dev/sfxge/common/efx_intr.c
+++ b/sys/dev/sfxge/common/efx_intr.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -32,6 +37,82 @@ __FBSDID("$FreeBSD$");
#include "efx_regs.h"
#include "efx_impl.h"
+
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+static __checkReturn int
+falconsiena_intr_init(
+ __in efx_nic_t *enp,
+ __in efx_intr_type_t type,
+ __in efsys_mem_t *esmp);
+
+static void
+falconsiena_intr_enable(
+ __in efx_nic_t *enp);
+
+static void
+falconsiena_intr_disable(
+ __in efx_nic_t *enp);
+
+static void
+falconsiena_intr_disable_unlocked(
+ __in efx_nic_t *enp);
+
+static __checkReturn int
+falconsiena_intr_trigger(
+ __in efx_nic_t *enp,
+ __in unsigned int level);
+
+static void
+falconsiena_intr_fini(
+ __in efx_nic_t *enp);
+
+
+static __checkReturn boolean_t
+falconsiena_intr_check_fatal(
+ __in efx_nic_t *enp);
+
+static void
+falconsiena_intr_fatal(
+ __in efx_nic_t *enp);
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
+
+
+#if EFSYS_OPT_FALCON
+static efx_intr_ops_t __efx_intr_falcon_ops = {
+ falconsiena_intr_init, /* eio_init */
+ falconsiena_intr_enable, /* eio_enable */
+ falconsiena_intr_disable, /* eio_disable */
+ falconsiena_intr_disable_unlocked, /* eio_disable_unlocked */
+ falconsiena_intr_trigger, /* eio_trigger */
+ falconsiena_intr_fini, /* eio_fini */
+};
+#endif /* EFSYS_OPT_FALCON */
+
+#if EFSYS_OPT_SIENA
+static efx_intr_ops_t __efx_intr_siena_ops = {
+ falconsiena_intr_init, /* eio_init */
+ falconsiena_intr_enable, /* eio_enable */
+ falconsiena_intr_disable, /* eio_disable */
+ falconsiena_intr_disable_unlocked, /* eio_disable_unlocked */
+ falconsiena_intr_trigger, /* eio_trigger */
+ falconsiena_intr_fini, /* eio_fini */
+};
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+static efx_intr_ops_t __efx_intr_hunt_ops = {
+ hunt_intr_init, /* eio_init */
+ hunt_intr_enable, /* eio_enable */
+ hunt_intr_disable, /* eio_disable */
+ hunt_intr_disable_unlocked, /* eio_disable_unlocked */
+ hunt_intr_trigger, /* eio_trigger */
+ hunt_intr_fini, /* eio_fini */
+};
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+
__checkReturn int
efx_intr_init(
__in efx_nic_t *enp,
@@ -39,7 +120,7 @@ efx_intr_init(
__in efsys_mem_t *esmp)
{
efx_intr_t *eip = &(enp->en_intr);
- efx_oword_t oword;
+ efx_intr_ops_t *eiop;
int rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
@@ -50,10 +131,219 @@ efx_intr_init(
goto fail1;
}
+ eip->ei_esmp = esmp;
+ eip->ei_type = type;
+ eip->ei_level = 0;
+
enp->en_mod_flags |= EFX_MOD_INTR;
- eip->ei_type = type;
- eip->ei_esmp = esmp;
+ switch (enp->en_family) {
+#if EFSYS_OPT_FALCON
+ case EFX_FAMILY_FALCON:
+ eiop = (efx_intr_ops_t *)&__efx_intr_falcon_ops;
+ break;
+#endif /* EFSYS_OPT_FALCON */
+
+#if EFSYS_OPT_SIENA
+ case EFX_FAMILY_SIENA:
+ eiop = (efx_intr_ops_t *)&__efx_intr_siena_ops;
+ break;
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ eiop = (efx_intr_ops_t *)&__efx_intr_hunt_ops;
+ break;
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+ 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, int, rc);
+
+ return (rc);
+}
+
+ void
+efx_intr_fini(
+ __in efx_nic_t *enp)
+{
+ efx_intr_t *eip = &(enp->en_intr);
+ 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);
+ 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);
+ 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);
+ 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 int
+efx_intr_trigger(
+ __in efx_nic_t *enp,
+ __in unsigned int level)
+{
+ efx_intr_t *eip = &(enp->en_intr);
+ 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);
+ efx_dword_t dword;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
+
+ /* Ensure Huntington and Falcon/Siena ISR at same location */
+ EFX_STATIC_ASSERT(FR_BZ_INT_ISR0_REG_OFST ==
+ ER_DZ_BIU_INT_ISR_REG_OFST);
+
+ /*
+ * Read the queue mask and implicitly acknowledge the
+ * interrupt.
+ */
+ EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE);
+ *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
+
+ EFSYS_PROBE1(qmask, uint32_t, *qmaskp);
+
+#if EFSYS_OPT_HUNTINGTON
+ if (enp->en_family == EFX_FAMILY_HUNTINGTON) {
+ /* Huntington reports fatal errors via events */
+ *fatalp = B_FALSE;
+ return;
+ }
+#endif
+ if (*qmaskp & (1U << eip->ei_level))
+ *fatalp = falconsiena_intr_check_fatal(enp);
+ else
+ *fatalp = B_FALSE;
+}
+
+ 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);
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
+
+#if EFSYS_OPT_HUNTINGTON
+ if (enp->en_family == EFX_FAMILY_HUNTINGTON) {
+ /* Huntington reports fatal errors via events */
+ *fatalp = B_FALSE;
+ return;
+ }
+#endif
+ if (message == eip->ei_level)
+ *fatalp = falconsiena_intr_check_fatal(enp);
+ else
+ *fatalp = B_FALSE;
+}
+
+ void
+efx_intr_fatal(
+ __in efx_nic_t *enp)
+{
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
+
+#if EFSYS_OPT_HUNTINGTON
+ if (enp->en_family == EFX_FAMILY_HUNTINGTON) {
+ /* Huntington reports fatal errors via events */
+ return;
+ }
+#endif
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+ falconsiena_intr_fatal(enp);
+#endif
+}
+
+
+/* ************************************************************************* */
+/* ************************************************************************* */
+/* ************************************************************************* */
+
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+static __checkReturn int
+falconsiena_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);
+ efx_oword_t oword;
/*
* bug17213 workaround.
@@ -85,23 +375,15 @@ efx_intr_init(
EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
}
- void
-efx_intr_enable(
+static void
+falconsiena_intr_enable(
__in efx_nic_t *enp)
{
efx_intr_t *eip = &(enp->en_intr);
efx_oword_t oword;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
-
EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
EFX_SET_OWORD_FIELD(oword, FRF_AZ_KER_INT_LEVE_SEL, eip->ei_level);
@@ -109,15 +391,12 @@ efx_intr_enable(
EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
}
- void
-efx_intr_disable(
+static void
+falconsiena_intr_disable(
__in efx_nic_t *enp)
{
efx_oword_t oword;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
-
EFX_BAR_READO(enp, FR_AZ_INT_EN_REG_KER, &oword);
EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
EFX_BAR_WRITEO(enp, FR_AZ_INT_EN_REG_KER, &oword);
@@ -125,15 +404,12 @@ efx_intr_disable(
EFSYS_SPIN(10);
}
- void
-efx_intr_disable_unlocked(
+static void
+falconsiena_intr_disable_unlocked(
__in efx_nic_t *enp)
{
efx_oword_t oword;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
-
EFSYS_BAR_READO(enp->en_esbp, FR_AZ_INT_EN_REG_KER_OFST,
&oword, B_FALSE);
EFX_SET_OWORD_FIELD(oword, FRF_AZ_DRV_INT_EN_KER, 0);
@@ -141,8 +417,8 @@ efx_intr_disable_unlocked(
&oword, B_FALSE);
}
- __checkReturn int
-efx_intr_trigger(
+static __checkReturn int
+falconsiena_intr_trigger(
__in efx_nic_t *enp,
__in unsigned int level)
{
@@ -152,22 +428,19 @@ efx_intr_trigger(
uint32_t sel;
int rc;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
-
/* bug16757: No event queues can be initialized */
EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_EV));
switch (enp->en_family) {
case EFX_FAMILY_FALCON:
- if (level > EFX_NINTR_FALCON) {
+ if (level >= EFX_NINTR_FALCON) {
rc = EINVAL;
goto fail1;
}
break;
case EFX_FAMILY_SIENA:
- if (level > EFX_NINTR_SIENA) {
+ if (level >= EFX_NINTR_SIENA) {
rc = EINVAL;
goto fail1;
}
@@ -213,7 +486,7 @@ fail1:
}
static __checkReturn boolean_t
-efx_intr_check_fatal(
+falconsiena_intr_check_fatal(
__in efx_nic_t *enp)
{
efx_intr_t *eip = &(enp->en_intr);
@@ -236,61 +509,14 @@ efx_intr_check_fatal(
return (B_FALSE);
}
- 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);
- efx_dword_t dword;
-
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
-
- /*
- * Read the queue mask and implicitly acknowledge the
- * interrupt.
- */
- EFX_BAR_READD(enp, FR_BZ_INT_ISR0_REG, &dword, B_FALSE);
- *qmaskp = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
-
- EFSYS_PROBE1(qmask, uint32_t, *qmaskp);
-
- if (*qmaskp & (1U << eip->ei_level))
- *fatalp = efx_intr_check_fatal(enp);
- else
- *fatalp = B_FALSE;
-}
-
- 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);
-
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
-
- if (message == eip->ei_level)
- *fatalp = efx_intr_check_fatal(enp);
- else
- *fatalp = B_FALSE;
-}
-
- void
-efx_intr_fatal(
+static void
+falconsiena_intr_fatal(
__in efx_nic_t *enp)
{
#if EFSYS_OPT_DECODE_INTR_FATAL
efx_oword_t fatal;
efx_oword_t mem_per;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_INTR);
-
EFX_BAR_READO(enp, FR_AZ_FATAL_INTR_REG_KER, &fatal);
EFX_ZERO_OWORD(mem_per);
@@ -339,19 +565,15 @@ efx_intr_fatal(
#endif
}
- void
-efx_intr_fini(
+static void
+falconsiena_intr_fini(
__in efx_nic_t *enp)
{
efx_oword_t oword;
- 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);
-
/* Clear the interrupt address register */
EFX_ZERO_OWORD(oword);
EFX_BAR_WRITEO(enp, FR_AZ_INT_ADR_REG_KER, &oword);
-
- enp->en_mod_flags &= ~EFX_MOD_INTR;
}
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
diff --git a/sys/dev/sfxge/common/efx_mac.c b/sys/dev/sfxge/common/efx_mac.c
index 3e9449a..a701797 100644
--- a/sys/dev/sfxge/common/efx_mac.c
+++ b/sys/dev/sfxge/common/efx_mac.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -39,74 +44,126 @@ __FBSDID("$FreeBSD$");
#include "falcon_xmac.h"
#endif
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+static __checkReturn int
+falconsiena_mac_multicast_list_set(
+ __in efx_nic_t *enp);
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
+
#if EFSYS_OPT_MAC_FALCON_GMAC
-static efx_mac_ops_t __cs __efx_falcon_gmac_ops = {
- falcon_gmac_reset, /* emo_reset */
- falcon_mac_poll, /* emo_poll */
- falcon_mac_up, /* emo_up */
- falcon_gmac_reconfigure, /* emo_reconfigure */
+static efx_mac_ops_t __efx_falcon_gmac_ops = {
+ falcon_gmac_reset, /* emo_reset */
+ falcon_mac_poll, /* emo_poll */
+ falcon_mac_up, /* emo_up */
+ falcon_gmac_reconfigure, /* emo_addr_set */
+ falcon_gmac_reconfigure, /* emo_reconfigure */
+ falconsiena_mac_multicast_list_set, /* emo_multicast_list_set */
+ NULL, /* emo_filter_set_default_rxq */
+ NULL, /* emo_filter_default_rxq_clear */
#if EFSYS_OPT_LOOPBACK
- falcon_mac_loopback_set, /* emo_loopback_set */
+ falcon_mac_loopback_set, /* emo_loopback_set */
#endif /* EFSYS_OPT_LOOPBACK */
#if EFSYS_OPT_MAC_STATS
- falcon_mac_stats_upload, /* emo_stats_upload */
- NULL, /* emo_stats_periodic */
- falcon_gmac_stats_update /* emo_stats_update */
+ falcon_mac_stats_upload, /* emo_stats_upload */
+ NULL, /* emo_stats_periodic */
+ falcon_gmac_stats_update /* emo_stats_update */
#endif /* EFSYS_OPT_MAC_STATS */
};
#endif /* EFSYS_OPT_MAC_FALCON_GMAC */
#if EFSYS_OPT_MAC_FALCON_XMAC
-static efx_mac_ops_t __cs __efx_falcon_xmac_ops = {
- falcon_xmac_reset, /* emo_reset */
- falcon_mac_poll, /* emo_poll */
- falcon_mac_up, /* emo_up */
- falcon_xmac_reconfigure, /* emo_reconfigure */
+static efx_mac_ops_t __efx_falcon_xmac_ops = {
+ falcon_xmac_reset, /* emo_reset */
+ falcon_mac_poll, /* emo_poll */
+ falcon_mac_up, /* emo_up */
+ falcon_xmac_reconfigure, /* emo_addr_set */
+ falcon_xmac_reconfigure, /* emo_reconfigure */
+ falconsiena_mac_multicast_list_set, /* emo_multicast_list_set */
+ NULL, /* emo_filter_set_default_rxq */
+ NULL, /* emo_filter_default_rxq_clear */
#if EFSYS_OPT_LOOPBACK
- falcon_mac_loopback_set, /* emo_loopback_set */
+ falcon_mac_loopback_set, /* emo_loopback_set */
#endif /* EFSYS_OPT_LOOPBACK */
#if EFSYS_OPT_MAC_STATS
- falcon_mac_stats_upload, /* emo_stats_upload */
- NULL, /* emo_stats_periodic */
- falcon_xmac_stats_update /* emo_stats_update */
+ falcon_mac_stats_upload, /* emo_stats_upload */
+ NULL, /* emo_stats_periodic */
+ falcon_xmac_stats_update /* emo_stats_update */
#endif /* EFSYS_OPT_MAC_STATS */
};
#endif /* EFSYS_OPT_MAC_FALCON_XMAC */
#if EFSYS_OPT_SIENA
-static efx_mac_ops_t __cs __efx_siena_mac_ops = {
- NULL, /* emo_reset */
- siena_mac_poll, /* emo_poll */
- siena_mac_up, /* emo_up */
- siena_mac_reconfigure, /* emo_reconfigure */
+static efx_mac_ops_t __efx_siena_mac_ops = {
+ NULL, /* emo_reset */
+ siena_mac_poll, /* emo_poll */
+ siena_mac_up, /* emo_up */
+ siena_mac_reconfigure, /* emo_addr_set */
+ siena_mac_reconfigure, /* emo_reconfigure */
+ falconsiena_mac_multicast_list_set, /* emo_multicast_list_set */
+ NULL, /* emo_filter_set_default_rxq */
+ NULL, /* emo_filter_default_rxq_clear */
#if EFSYS_OPT_LOOPBACK
- siena_mac_loopback_set, /* emo_loopback_set */
+ siena_mac_loopback_set, /* emo_loopback_set */
#endif /* EFSYS_OPT_LOOPBACK */
#if EFSYS_OPT_MAC_STATS
- siena_mac_stats_upload, /* emo_stats_upload */
- siena_mac_stats_periodic, /* emo_stats_periodic */
- siena_mac_stats_update /* emo_stats_update */
+ efx_mcdi_mac_stats_upload, /* emo_stats_upload */
+ efx_mcdi_mac_stats_periodic, /* emo_stats_periodic */
+ siena_mac_stats_update /* emo_stats_update */
#endif /* EFSYS_OPT_MAC_STATS */
};
#endif /* EFSYS_OPT_SIENA */
-static efx_mac_ops_t __cs * __cs __efx_mac_ops[] = {
+#if EFSYS_OPT_HUNTINGTON
+static efx_mac_ops_t __efx_hunt_mac_ops = {
+ NULL, /* emo_reset */
+ hunt_mac_poll, /* emo_poll */
+ hunt_mac_up, /* emo_up */
+ hunt_mac_addr_set, /* emo_addr_set */
+ hunt_mac_reconfigure, /* emo_reconfigure */
+ hunt_mac_multicast_list_set, /* emo_multicast_list_set */
+ hunt_mac_filter_default_rxq_set, /* emo_filter_default_rxq_set */
+ hunt_mac_filter_default_rxq_clear,
+ /* emo_filter_default_rxq_clear */
+#if EFSYS_OPT_LOOPBACK
+ hunt_mac_loopback_set, /* emo_loopback_set */
+#endif /* EFSYS_OPT_LOOPBACK */
+#if EFSYS_OPT_MAC_STATS
+ efx_mcdi_mac_stats_upload, /* emo_stats_upload */
+ efx_mcdi_mac_stats_periodic, /* emo_stats_periodic */
+ hunt_mac_stats_update /* emo_stats_update */
+#endif /* EFSYS_OPT_MAC_STATS */
+};
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+static efx_mac_ops_t *__efx_mac_ops[] = {
+ /* [EFX_MAC_INVALID] */
NULL,
+ /* [EFX_MAC_FALCON_GMAC] */
#if EFSYS_OPT_MAC_FALCON_GMAC
&__efx_falcon_gmac_ops,
#else
NULL,
-#endif /* EFSYS_OPT_MAC_FALCON_GMAC */
+#endif
+ /* [EFX_MAC_FALCON_XMAC] */
#if EFSYS_OPT_MAC_FALCON_XMAC
&__efx_falcon_xmac_ops,
#else
NULL,
-#endif /* EFSYS_OPT_MAC_FALCON_XMAC */
+#endif
+ /* [EFX_MAC_SIENA] */
#if EFSYS_OPT_SIENA
&__efx_siena_mac_ops,
#else
NULL,
-#endif /* EFSYS_OPT_SIENA */
+#endif
+ /* [EFX_MAC_HUNTINGTON] */
+#if EFSYS_OPT_HUNTINGTON
+ &__efx_hunt_mac_ops,
+#else
+ NULL,
+#endif
};
__checkReturn int
@@ -167,7 +224,7 @@ efx_mac_addr_set(
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
- if (addr[0] & 0x01) {
+ if (EFX_MAC_ADDR_IS_MULTICAST(addr)) {
rc = EINVAL;
goto fail1;
}
@@ -180,7 +237,7 @@ efx_mac_addr_set(
EFX_MAC_ADDR_COPY(old_addr, epp->ep_mac_addr);
EFX_MAC_ADDR_COPY(epp->ep_mac_addr, addr);
- if ((rc = emop->emo_reconfigure(enp)) != 0)
+ if ((rc = emop->emo_addr_set(enp)) != 0)
goto fail3;
return (0);
@@ -201,22 +258,30 @@ fail1:
__checkReturn int
efx_mac_filter_set(
__in efx_nic_t *enp,
- __in boolean_t unicst,
+ __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);
efx_mac_ops_t *emop = epp->ep_emop;
- boolean_t old_unicst;
+ boolean_t old_all_unicst;
+ boolean_t old_mulcst;
+ boolean_t old_all_mulcst;
boolean_t old_brdcst;
int rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
- old_unicst = unicst;
- old_brdcst = brdcst;
+ 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_unicst = unicst;
+ 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)
@@ -227,7 +292,9 @@ efx_mac_filter_set(
fail1:
EFSYS_PROBE1(fail1, int, rc);
- epp->ep_unicst = old_unicst;
+ 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);
@@ -318,45 +385,45 @@ efx_mac_fcntl_set(
}
/*
- * Ignore a request to set flow control autonegotiation
+ * 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 = autoneg;
+ old_autoneg = epp->ep_fcntl_autoneg;
old_adv_cap = epp->ep_adv_cap_mask;
epp->ep_fcntl = fcntl;
epp->ep_fcntl_autoneg = autoneg;
/*
- * If the PHY supports autonegotiation, then encode the flow control
- * settings in the advertised capabilities, and restart AN. Otherwise,
- * just push the new settings directly to the MAC.
+ * 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 (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN)) {
- 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_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 (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 = epop->epo_reconfigure(enp)) != 0)
+ goto fail2;
- } else {
- if ((rc = emop->emo_reconfigure(enp)) != 0)
- goto fail2;
- }
+ if ((rc = emop->emo_reconfigure(enp)) != 0)
+ goto fail3;
return (0);
+fail3:
+ EFSYS_PROBE(fail3);
+
fail2:
EFSYS_PROBE(fail2);
@@ -377,29 +444,30 @@ efx_mac_fcntl_get(
__out unsigned int *fcntl_linkp)
{
efx_port_t *epp = &(enp->en_port);
- unsigned int wanted;
+ unsigned int wanted = 0;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
/*
- * If the PHY supports auto negotiation, then the requested flow
- * control settings are encoded in the advertised capabilities.
+ * Decode the requested flow control settings from the PHY
+ * advertised capabilities.
*/
- if (epp->ep_phy_cap_mask & (1 << EFX_PHY_CAP_AN)) {
- wanted = 0;
-
- 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;
- } else
- wanted = epp->ep_fcntl;
+ 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;
}
+/*
+ * FIXME: efx_mac_hash_set() should be deleted once all its callers have been
+ * updated to use efx_mac_multicast_list_set().
+ * Then efx_port_t.ep_multicst_hash could be made Falcon/Siena specific as
+ * well.
+ */
__checkReturn int
efx_mac_hash_set(
__in efx_nic_t *enp,
@@ -443,12 +511,130 @@ fail1:
return (rc);
}
+ __checkReturn int
+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);
+ efx_mac_ops_t *emop = epp->ep_emop;
+ uint8_t *old_mulcst_addr_list = NULL;
+ uint32_t old_mulcst_addr_count;
+ int 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, int, rc);
+
+ return (rc);
+
+}
+
+ __checkReturn int
+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);
+ efx_mac_ops_t *emop = epp->ep_emop;
+ int 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, int, rc);
+
+ return (rc);
+}
+
+ void
+efx_mac_filter_default_rxq_clear(
+ __in efx_nic_t *enp)
+{
+ efx_port_t *epp = &(enp->en_port);
+ 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);
+}
+
+
#if EFSYS_OPT_MAC_STATS
#if EFSYS_OPT_NAMES
-/* START MKCONFIG GENERATED EfxMacStatNamesBlock adf707adba80813e */
-static const char __cs * __cs __efx_mac_stat_name[] = {
+/* START MKCONFIG GENERATED EfxMacStatNamesBlock 054d43a31d2d7a45 */
+static const char *__efx_mac_stat_name[] = {
"rx_octets",
"rx_pkts",
"rx_unicst_pkts",
@@ -500,10 +686,40 @@ static const char __cs * __cs __efx_mac_stat_name[] = {
"tx_late_col_pkts",
"tx_def_pkts",
"tx_ex_def_pkts",
+ "pm_trunc_bb_overflow",
+ "pm_discard_bb_overflow",
+ "pm_trunc_vfifo_full",
+ "pm_discard_vfifo_full",
+ "pm_trunc_qbb",
+ "pm_discard_qbb",
+ "pm_discard_mapping",
+ "rxdp_q_disabled_pkts",
+ "rxdp_di_dropped_pkts",
+ "rxdp_streaming_pkts",
+ "rxdp_hlb_fetch",
+ "rxdp_hlb_wait",
+ "vadapter_rx_unicast_packets",
+ "vadapter_rx_unicast_bytes",
+ "vadapter_rx_multicast_packets",
+ "vadapter_rx_multicast_bytes",
+ "vadapter_rx_broadcast_packets",
+ "vadapter_rx_broadcast_bytes",
+ "vadapter_rx_bad_packets",
+ "vadapter_rx_bad_bytes",
+ "vadapter_rx_overflow",
+ "vadapter_tx_unicast_packets",
+ "vadapter_tx_unicast_bytes",
+ "vadapter_tx_multicast_packets",
+ "vadapter_tx_multicast_bytes",
+ "vadapter_tx_broadcast_packets",
+ "vadapter_tx_broadcast_bytes",
+ "vadapter_tx_bad_packets",
+ "vadapter_tx_bad_bytes",
+ "vadapter_tx_overflow",
};
/* END MKCONFIG GENERATED EfxMacStatNamesBlock */
- __checkReturn const char __cs *
+ __checkReturn const char *
efx_mac_stat_name(
__in efx_nic_t *enp,
__in unsigned int id)
@@ -515,7 +731,7 @@ efx_mac_stat_name(
return (__efx_mac_stat_name[id]);
}
-#endif /* EFSYS_OPT_STAT_NAME */
+#endif /* EFSYS_OPT_NAMES */
__checkReturn int
efx_mac_stats_upload(
@@ -588,7 +804,7 @@ efx_mac_stats_update(
__in efx_nic_t *enp,
__in efsys_mem_t *esmp,
__inout_ecount(EFX_MAC_NSTATS) efsys_stat_t *essp,
- __in uint32_t *generationp)
+ __out_opt uint32_t *generationp)
{
efx_port_t *epp = &(enp->en_port);
efx_mac_ops_t *emop = epp->ep_emop;
@@ -616,6 +832,13 @@ efx_mac_select(
efx_mac_ops_t *emop;
int rc = EINVAL;
+#if EFSYS_OPT_HUNTINGTON
+ if (enp->en_family == EFX_FAMILY_HUNTINGTON) {
+ type = EFX_MAC_HUNTINGTON;
+ goto chosen;
+ }
+#endif
+
#if EFSYS_OPT_SIENA
if (enp->en_family == EFX_FAMILY_SIENA) {
type = EFX_MAC_SIENA;
@@ -685,3 +908,71 @@ fail1:
return (rc);
}
+
+
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+/* Compute the multicast hash as used on Falcon and Siena. */
+static void
+falconsiena_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)
+{
+ uint32_t crc, index;
+ int i;
+
+ EFSYS_ASSERT(hash_low != NULL);
+ EFSYS_ASSERT(hash_high != NULL);
+
+ EFX_ZERO_OWORD(*hash_low);
+ EFX_ZERO_OWORD(*hash_high);
+
+ for (i = 0; i < count; i++) {
+ /* Calculate hash bucket (IEEE 802.3 CRC32 of the MAC addr) */
+ crc = efx_crc32_calculate(0xffffffff, addrs, EFX_MAC_ADDR_LEN);
+ index = crc % EFX_MAC_HASH_BITS;
+ if (index < 128) {
+ EFX_SET_OWORD_BIT(*hash_low, index);
+ } else {
+ EFX_SET_OWORD_BIT(*hash_high, index - 128);
+ }
+
+ addrs += EFX_MAC_ADDR_LEN;
+ }
+}
+
+static __checkReturn int
+falconsiena_mac_multicast_list_set(
+ __in efx_nic_t *enp)
+{
+ efx_port_t *epp = &(enp->en_port);
+ efx_mac_ops_t *emop = epp->ep_emop;
+ efx_oword_t old_hash[2];
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
+
+ memcpy(old_hash, epp->ep_multicst_hash, sizeof (old_hash));
+
+ falconsiena_mac_multicast_hash_compute(epp->ep_mulcst_addr_list,
+ epp->ep_mulcst_addr_count,
+ &epp->ep_multicst_hash[0],
+ &epp->ep_multicst_hash[1]);
+
+ if ((rc = emop->emo_reconfigure(enp)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ memcpy(epp->ep_multicst_hash, old_hash, sizeof (old_hash));
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
diff --git a/sys/dev/sfxge/common/efx_mcdi.c b/sys/dev/sfxge/common/efx_mcdi.c
index f389d57..e1c4b45 100644
--- a/sys/dev/sfxge/common/efx_mcdi.c
+++ b/sys/dev/sfxge/common/efx_mcdi.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2008-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2008-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -35,12 +40,144 @@ __FBSDID("$FreeBSD$");
#if EFSYS_OPT_MCDI
-/*
- * A reboot/assertion causes the MCDI status word to be set after the
- * command word is set or a REBOOT event is sent. If we notice a reboot
- * via these mechanisms then wait 10ms for the status word to be set.
- */
-#define MCDI_STATUS_SLEEP_US 10000
+
+#if EFSYS_OPT_SIENA
+
+static efx_mcdi_ops_t __efx_mcdi_siena_ops = {
+ siena_mcdi_init, /* emco_init */
+ siena_mcdi_request_copyin, /* emco_request_copyin */
+ siena_mcdi_request_poll, /* emco_request_poll */
+ siena_mcdi_request_copyout, /* emco_request_copyout */
+ siena_mcdi_poll_reboot, /* emco_poll_reboot */
+ siena_mcdi_fini, /* emco_fini */
+ siena_mcdi_fw_update_supported, /* emco_fw_update_supported */
+ siena_mcdi_macaddr_change_supported,
+ /* emco_macaddr_change_supported */
+};
+
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+
+static efx_mcdi_ops_t __efx_mcdi_hunt_ops = {
+ hunt_mcdi_init, /* emco_init */
+ hunt_mcdi_request_copyin, /* emco_request_copyin */
+ hunt_mcdi_request_poll, /* emco_request_poll */
+ hunt_mcdi_request_copyout, /* emco_request_copyout */
+ hunt_mcdi_poll_reboot, /* emco_poll_reboot */
+ hunt_mcdi_fini, /* emco_fini */
+ hunt_mcdi_fw_update_supported, /* emco_fw_update_supported */
+ hunt_mcdi_macaddr_change_supported,
+ /* emco_macaddr_change_supported */
+};
+
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+
+
+ __checkReturn int
+efx_mcdi_init(
+ __in efx_nic_t *enp,
+ __in const efx_mcdi_transport_t *emtp)
+{
+ efx_mcdi_ops_t *emcop;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0);
+
+ switch (enp->en_family) {
+#if EFSYS_OPT_FALCON
+ case EFX_FAMILY_FALCON:
+ emcop = NULL;
+ emtp = NULL;
+ break;
+#endif /* EFSYS_OPT_FALCON */
+
+#if EFSYS_OPT_SIENA
+ case EFX_FAMILY_SIENA:
+ emcop = (efx_mcdi_ops_t *)&__efx_mcdi_siena_ops;
+ break;
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ emcop = (efx_mcdi_ops_t *)&__efx_mcdi_hunt_ops;
+ break;
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+ default:
+ EFSYS_ASSERT(0);
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+ if (enp->en_features & EFX_FEATURE_MCDI_DMA) {
+ /* MCDI requires a DMA buffer in host memory */
+ if ((emtp == NULL) || (emtp->emt_dma_mem) == NULL) {
+ rc = EINVAL;
+ goto fail2;
+ }
+ }
+ enp->en_mcdi.em_emtp = emtp;
+
+ if (emcop != NULL && emcop->emco_init != NULL) {
+ if ((rc = emcop->emco_init(enp, emtp)) != 0)
+ goto fail3;
+ }
+
+ enp->en_mcdi.em_emcop = emcop;
+ enp->en_mod_flags |= EFX_MOD_MCDI;
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ enp->en_mcdi.em_emcop = NULL;
+ enp->en_mcdi.em_emtp = NULL;
+ enp->en_mod_flags &= ~EFX_MOD_MCDI;
+
+ return (rc);
+}
+
+ void
+efx_mcdi_fini(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, ==, EFX_MOD_MCDI);
+
+ if (emcop != NULL && emcop->emco_fini != NULL)
+ emcop->emco_fini(enp);
+
+ emip->emi_port = 0;
+ emip->emi_aborted = 0;
+
+ enp->en_mcdi.em_emcop = NULL;
+ enp->en_mod_flags &= ~EFX_MOD_MCDI;
+}
+
+ void
+efx_mcdi_new_epoch(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ int state;
+
+ /* Start a new epoch (allow fresh MCDI requests to succeed) */
+ EFSYS_LOCK(enp->en_eslp, state);
+ emip->emi_new_epoch = B_TRUE;
+ EFSYS_UNLOCK(enp->en_eslp, state);
+}
+
void
efx_mcdi_request_start(
@@ -48,32 +185,18 @@ efx_mcdi_request_start(
__in efx_mcdi_req_t *emrp,
__in boolean_t ev_cpl)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- efx_dword_t dword;
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
unsigned int seq;
- unsigned int xflags;
- unsigned int pdur;
- unsigned int dbr;
- unsigned int pos;
+ boolean_t new_epoch;
int state;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
- switch (emip->emi_port) {
- case 1:
- pdur = MC_SMEM_P0_PDU_OFST >> 2;
- dbr = MC_SMEM_P0_DOORBELL_OFST >> 2;
- break;
- case 2:
- pdur = MC_SMEM_P1_PDU_OFST >> 2;
- dbr = MC_SMEM_P1_DOORBELL_OFST >> 2;
- break;
- default:
- EFSYS_ASSERT(0);
- pdur = dbr = 0;
- };
+ if (emcop == NULL || emcop->emco_request_copyin == NULL)
+ return;
/*
* efx_mcdi_request_start() is naturally serialised against both
@@ -92,68 +215,85 @@ efx_mcdi_request_start(
emip->emi_pending_req = emrp;
emip->emi_ev_cpl = ev_cpl;
emip->emi_poll_cnt = 0;
- seq = emip->emi_seq++ & 0xf;
+ seq = emip->emi_seq++ & EFX_MASK32(MCDI_HEADER_SEQ);
+ new_epoch = emip->emi_new_epoch;
EFSYS_UNLOCK(enp->en_eslp, state);
- xflags = 0;
- if (ev_cpl)
- xflags |= MCDI_HEADER_XFLAGS_EVREQ;
+ emcop->emco_request_copyin(enp, emrp, seq, ev_cpl, new_epoch);
+}
+
+ __checkReturn boolean_t
+efx_mcdi_request_poll(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+ boolean_t completed;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
+ EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
- /* Construct the header in shared memory */
- EFX_POPULATE_DWORD_6(dword,
- MCDI_HEADER_CODE, emrp->emr_cmd,
- MCDI_HEADER_RESYNC, 1,
- MCDI_HEADER_DATALEN, emrp->emr_in_length,
- MCDI_HEADER_SEQ, seq,
- MCDI_HEADER_RESPONSE, 0,
- MCDI_HEADER_XFLAGS, xflags);
- EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, pdur, &dword, B_TRUE);
+ completed = B_FALSE;
- for (pos = 0; pos < emrp->emr_in_length; pos += sizeof (efx_dword_t)) {
- memcpy(&dword, MCDI_IN(*emrp, efx_dword_t, pos),
- MIN(sizeof (dword), emrp->emr_in_length - pos));
- EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM,
- pdur + 1 + (pos >> 2), &dword, B_FALSE);
- }
+ if (emcop != NULL && emcop->emco_request_poll != NULL)
+ completed = emcop->emco_request_poll(enp);
- /* Ring the doorbell */
- EFX_POPULATE_DWORD_1(dword, EFX_DWORD_0, 0xd004be11);
- EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, dbr, &dword, B_FALSE);
+ return (completed);
}
-static void
-efx_mcdi_request_copyout(
- __in efx_nic_t *enp,
- __in efx_mcdi_req_t *emrp)
-{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- unsigned int pos;
- unsigned int pdur;
- efx_dword_t data;
-
- pdur = (emip->emi_port == 1)
- ? MC_SMEM_P0_PDU_OFST >> 2
- : MC_SMEM_P1_PDU_OFST >> 2;
-
- /* Copy payload out if caller supplied buffer */
- if (emrp->emr_out_buf != NULL) {
- size_t bytes = MIN(emrp->emr_out_length_used,
- emrp->emr_out_length);
- for (pos = 0; pos < bytes; pos += sizeof (efx_dword_t)) {
- EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM,
- pdur + 1 + (pos >> 2), &data, B_FALSE);
- memcpy(MCDI_OUT(*emrp, efx_dword_t, pos), &data,
- MIN(sizeof (data), bytes - pos));
- }
+ __checkReturn boolean_t
+efx_mcdi_request_abort(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_mcdi_req_t *emrp;
+ boolean_t aborted;
+ int state;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
+ EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
+
+ /*
+ * efx_mcdi_ev_* may have already completed this event, and be
+ * spinning/blocked on the upper layer lock. So it *is* legitimate
+ * to for emi_pending_req to be NULL. If there is a pending event
+ * completed request, then provide a "credit" to allow
+ * efx_mcdi_ev_cpl() to accept a single spurious completion.
+ */
+ EFSYS_LOCK(enp->en_eslp, state);
+ emrp = emip->emi_pending_req;
+ aborted = (emrp != NULL);
+ if (aborted) {
+ emip->emi_pending_req = NULL;
+
+ /* Error the request */
+ emrp->emr_out_length_used = 0;
+ emrp->emr_rc = ETIMEDOUT;
+
+ /* Provide a credit for seqno/emr_pending_req mismatches */
+ if (emip->emi_ev_cpl)
+ ++emip->emi_aborted;
+
+ /*
+ * The upper layer has called us, so we don't
+ * need to complete the request.
+ */
}
+ EFSYS_UNLOCK(enp->en_eslp, state);
+
+ return (aborted);
}
-static int
+ __checkReturn int
efx_mcdi_request_errcode(
__in unsigned int err)
{
switch (err) {
+ /* MCDI v1 */
+ case MC_CMD_ERR_EPERM:
+ return (EACCES);
case MC_CMD_ERR_ENOENT:
return (ENOENT);
case MC_CMD_ERR_EINTR:
@@ -170,26 +310,55 @@ efx_mcdi_request_errcode(
return (ENOTSUP);
case MC_CMD_ERR_ETIME:
return (ETIMEDOUT);
-#ifdef WITH_MCDI_V2
+ case MC_CMD_ERR_ENOTSUP:
+ return (ENOTSUP);
+ case MC_CMD_ERR_EALREADY:
+ return (EALREADY);
+
+ /* MCDI v2 */
+#ifdef MC_CMD_ERR_EAGAIN
case MC_CMD_ERR_EAGAIN:
return (EAGAIN);
+#endif
+#ifdef MC_CMD_ERR_ENOSPC
case MC_CMD_ERR_ENOSPC:
return (ENOSPC);
#endif
+
+ case MC_CMD_ERR_ALLOC_FAIL:
+ return (ENOMEM);
+ case MC_CMD_ERR_NO_VADAPTOR:
+ return (ENOENT);
+ case MC_CMD_ERR_NO_EVB_PORT:
+ return (ENOENT);
+ case MC_CMD_ERR_NO_VSWITCH:
+ return (ENODEV);
+ case MC_CMD_ERR_VLAN_LIMIT:
+ return (EINVAL);
+ case MC_CMD_ERR_BAD_PCI_FUNC:
+ return (ENODEV);
+ case MC_CMD_ERR_BAD_VLAN_MODE:
+ return (EINVAL);
+ case MC_CMD_ERR_BAD_VSWITCH_TYPE:
+ return (EINVAL);
+ case MC_CMD_ERR_BAD_VPORT_TYPE:
+ return (EINVAL);
+ case MC_CMD_ERR_MAC_EXIST:
+ return (EEXIST);
+
default:
EFSYS_PROBE1(mc_pcol_error, int, err);
return (EIO);
}
}
-static void
+ void
efx_mcdi_raise_exception(
__in efx_nic_t *enp,
__in_opt efx_mcdi_req_t *emrp,
__in int rc)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- const efx_mcdi_transport_t *emtp = emip->emi_mtp;
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
efx_mcdi_exception_t exception;
/* Reboot or Assertion failure only */
@@ -213,167 +382,37 @@ static int
efx_mcdi_poll_reboot(
__in efx_nic_t *enp)
{
-#ifndef EFX_GRACEFUL_MC_REBOOT
- /*
- * This function is not being used properly.
- * Until its callers are fixed, it should always return 0.
- */
- _NOTE(ARGUNUSED(enp))
- return (0);
-#else
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- unsigned int rebootr;
- efx_dword_t dword;
- uint32_t value;
-
- EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2);
- rebootr = ((emip->emi_port == 1)
- ? MC_SMEM_P0_STATUS_OFST >> 2
- : MC_SMEM_P1_STATUS_OFST >> 2);
-
- EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, rebootr, &dword, B_FALSE);
- value = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
-
- if (value == 0)
- return (0);
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
- EFX_ZERO_DWORD(dword);
- EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, rebootr, &dword, B_FALSE);
-
- if (value == MC_STATUS_DWORD_ASSERT)
- return (EINTR);
- else
- return (EIO);
-#endif
+ return (emcop->emco_poll_reboot(enp));
}
- __checkReturn boolean_t
-efx_mcdi_request_poll(
- __in efx_nic_t *enp)
+
+ void
+efx_mcdi_execute(
+ __in efx_nic_t *enp,
+ __inout efx_mcdi_req_t *emrp)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- efx_mcdi_req_t *emrp;
- efx_dword_t dword;
- unsigned int pdur;
- unsigned int seq;
- unsigned int length;
- int state;
- int rc;
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
- EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
- /* Serialise against post-watchdog efx_mcdi_ev* */
- EFSYS_LOCK(enp->en_eslp, state);
-
- EFSYS_ASSERT(emip->emi_pending_req != NULL);
- EFSYS_ASSERT(!emip->emi_ev_cpl);
- emrp = emip->emi_pending_req;
-
- /* Check for reboot atomically w.r.t efx_mcdi_request_start */
- if (emip->emi_poll_cnt++ == 0) {
- if ((rc = efx_mcdi_poll_reboot(enp)) != 0) {
- emip->emi_pending_req = NULL;
- EFSYS_UNLOCK(enp->en_eslp, state);
-
- goto fail1;
- }
- }
-
- EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2);
- pdur = (emip->emi_port == 1)
- ? MC_SMEM_P0_PDU_OFST >> 2
- : MC_SMEM_P1_PDU_OFST >> 2;
-
- /* Read the command header */
- EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, pdur, &dword, B_FALSE);
- if (EFX_DWORD_FIELD(dword, MCDI_HEADER_RESPONSE) == 0) {
- EFSYS_UNLOCK(enp->en_eslp, state);
- return (B_FALSE);
- }
-
- /* Request complete */
- emip->emi_pending_req = NULL;
- seq = (emip->emi_seq - 1) & 0xf;
-
- /* Check for synchronous reboot */
- if (EFX_DWORD_FIELD(dword, MCDI_HEADER_ERROR) != 0 &&
- EFX_DWORD_FIELD(dword, MCDI_HEADER_DATALEN) == 0) {
- /* Consume status word */
- EFSYS_SPIN(MCDI_STATUS_SLEEP_US);
- efx_mcdi_poll_reboot(enp);
- EFSYS_UNLOCK(enp->en_eslp, state);
- rc = EIO;
- goto fail2;
- }
-
- EFSYS_UNLOCK(enp->en_eslp, state);
-
- /* Check that the returned data is consistent */
- if (EFX_DWORD_FIELD(dword, MCDI_HEADER_CODE) != emrp->emr_cmd ||
- EFX_DWORD_FIELD(dword, MCDI_HEADER_SEQ) != seq) {
- /* Response is for a different request */
- rc = EIO;
- goto fail3;
- }
-
- length = EFX_DWORD_FIELD(dword, MCDI_HEADER_DATALEN);
- if (EFX_DWORD_FIELD(dword, MCDI_HEADER_ERROR)) {
- efx_dword_t errdword;
- int errcode;
-
- EFSYS_ASSERT3U(length, ==, 4);
- EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM,
- pdur + 1 + (MC_CMD_ERR_CODE_OFST >> 2),
- &errdword, B_FALSE);
- errcode = EFX_DWORD_FIELD(errdword, EFX_DWORD_0);
- rc = efx_mcdi_request_errcode(errcode);
- EFSYS_PROBE2(mcdi_err, int, emrp->emr_cmd, int, errcode);
- goto fail4;
-
- } else {
- emrp->emr_out_length_used = length;
- emrp->emr_rc = 0;
- efx_mcdi_request_copyout(enp, emrp);
- }
-
- goto out;
-
-fail4:
- EFSYS_PROBE(fail4);
-fail3:
- EFSYS_PROBE(fail3);
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- /* Fill out error state */
- emrp->emr_rc = rc;
- emrp->emr_out_length_used = 0;
-
- /* Reboot/Assertion */
- if (rc == EIO || rc == EINTR)
- efx_mcdi_raise_exception(enp, emrp, rc);
-
-out:
- return (B_TRUE);
+ emrp->emr_quiet = B_FALSE;
+ emtp->emt_execute(emtp->emt_context, emrp);
}
void
-efx_mcdi_execute(
+efx_mcdi_execute_quiet(
__in efx_nic_t *enp,
- __in efx_mcdi_req_t *emrp)
+ __inout efx_mcdi_req_t *emrp)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- const efx_mcdi_transport_t *emtp = emip->emi_mtp;
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
- EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
+ emrp->emr_quiet = B_TRUE;
emtp->emt_execute(emtp->emt_context, emrp);
}
@@ -384,13 +423,13 @@ efx_mcdi_ev_cpl(
__in unsigned int outlen,
__in int errcode)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- const efx_mcdi_transport_t *emtp = emip->emi_mtp;
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
efx_mcdi_req_t *emrp;
int state;
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MCDI);
- EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
/*
@@ -399,7 +438,7 @@ efx_mcdi_ev_cpl(
*/
EFSYS_LOCK(enp->en_eslp, state);
if (emip->emi_pending_req == NULL || !emip->emi_ev_cpl ||
- (seq != ((emip->emi_seq - 1) & 0xf))) {
+ (seq != ((emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ)))) {
EFSYS_ASSERT(emip->emi_aborted > 0);
if (emip->emi_aborted > 0)
--emip->emi_aborted;
@@ -416,14 +455,17 @@ efx_mcdi_ev_cpl(
* if the user supplied an output buffer.
*/
if (errcode != 0) {
- EFSYS_PROBE2(mcdi_err, int, emrp->emr_cmd,
- int, errcode);
+ if (!emrp->emr_quiet) {
+ EFSYS_PROBE2(mcdi_err, int, emrp->emr_cmd,
+ int, errcode);
+ }
emrp->emr_out_length_used = 0;
emrp->emr_rc = efx_mcdi_request_errcode(errcode);
} else {
emrp->emr_out_length_used = outlen;
emrp->emr_rc = 0;
- efx_mcdi_request_copyout(enp, emrp);
+
+ emcop->emco_request_copyout(enp, emrp);
}
emtp->emt_ev_cpl(emtp->emt_context);
@@ -434,8 +476,8 @@ efx_mcdi_ev_death(
__in efx_nic_t *enp,
__in int rc)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- const efx_mcdi_transport_t *emtp = emip->emi_mtp;
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
efx_mcdi_req_t *emrp = NULL;
boolean_t ev_cpl;
int state;
@@ -469,8 +511,9 @@ efx_mcdi_ev_death(
* status word before dropping the lock.
*/
if (rc == EIO || rc == EINTR) {
- EFSYS_SPIN(MCDI_STATUS_SLEEP_US);
+ EFSYS_SPIN(EFX_MCDI_STATUS_SLEEP_US);
(void) efx_mcdi_poll_reboot(enp);
+ emip->emi_new_epoch = B_TRUE;
}
EFSYS_UNLOCK(enp->en_eslp, state);
@@ -488,23 +531,24 @@ efx_mcdi_version(
__out_opt uint32_t *buildp,
__out_opt efx_mcdi_boot_t *statusp)
{
- uint8_t outbuf[MAX(MC_CMD_GET_VERSION_OUT_LEN,
- MC_CMD_GET_BOOT_STATUS_OUT_LEN)];
efx_mcdi_req_t req;
+ uint8_t payload[MAX(MAX(MC_CMD_GET_VERSION_IN_LEN,
+ MC_CMD_GET_VERSION_OUT_LEN),
+ MAX(MC_CMD_GET_BOOT_STATUS_IN_LEN,
+ MC_CMD_GET_BOOT_STATUS_OUT_LEN))];
efx_word_t *ver_words;
uint16_t version[4];
uint32_t build;
efx_mcdi_boot_t status;
int rc;
- EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
- EFX_STATIC_ASSERT(MC_CMD_GET_VERSION_IN_LEN == 0);
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_VERSION;
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = outbuf;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_VERSION_IN_LEN;
+ req.emr_out_buf = payload;
req.emr_out_length = MC_CMD_GET_VERSION_OUT_LEN;
efx_mcdi_execute(enp, &req);
@@ -536,19 +580,27 @@ efx_mcdi_version(
version:
/* The bootrom doesn't understand BOOT_STATUS */
- if (build == MC_CMD_GET_VERSION_OUT_FIRMWARE_SIENA_BOOTROM) {
+ if (MC_FW_VERSION_IS_BOOTLOADER(build)) {
status = EFX_MCDI_BOOT_ROM;
goto out;
}
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_BOOT_STATUS;
- EFX_STATIC_ASSERT(MC_CMD_GET_BOOT_STATUS_IN_LEN == 0);
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = outbuf;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_BOOT_STATUS_IN_LEN;
+ req.emr_out_buf = payload;
req.emr_out_length = MC_CMD_GET_BOOT_STATUS_OUT_LEN;
- efx_mcdi_execute(enp, &req);
+ efx_mcdi_execute_quiet(enp, &req);
+
+ if (req.emr_rc == EACCES) {
+ /* Unprivileged functions cannot access BOOT_STATUS */
+ status = EFX_MCDI_BOOT_PRIMARY;
+ version[0] = version[1] = version[2] = version[3] = 0;
+ build = 0;
+ goto out;
+ }
if (req.emr_rc != 0) {
rc = req.emr_rc;
@@ -588,86 +640,624 @@ fail1:
return (rc);
}
- __checkReturn int
-efx_mcdi_init(
+static __checkReturn int
+efx_mcdi_do_reboot(
__in efx_nic_t *enp,
- __in const efx_mcdi_transport_t *mtp)
+ __in boolean_t after_assertion)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- efx_oword_t oword;
- unsigned int portnum;
+ uint8_t payload[MAX(MC_CMD_REBOOT_IN_LEN, MC_CMD_REBOOT_OUT_LEN)];
+ efx_mcdi_req_t req;
int rc;
- EFSYS_ASSERT3U(enp->en_mod_flags, ==, 0);
- enp->en_mod_flags |= EFX_MOD_MCDI;
+ /*
+ * We could require the caller to have caused en_mod_flags=0 to
+ * call this function. This doesn't help the other port though,
+ * who's about to get the MC ripped out from underneath them.
+ * Since they have to cope with the subsequent fallout of MCDI
+ * failures, we should as well.
+ */
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- if (enp->en_family == EFX_FAMILY_FALCON)
- return (0);
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_REBOOT;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_REBOOT_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_REBOOT_OUT_LEN;
- emip->emi_mtp = mtp;
+ MCDI_IN_SET_DWORD(req, REBOOT_IN_FLAGS,
+ (after_assertion ? MC_CMD_REBOOT_FLAGS_AFTER_ASSERTION : 0));
- /* Determine the port number to use for MCDI */
- EFX_BAR_READO(enp, FR_AZ_CS_DEBUG_REG, &oword);
- portnum = EFX_OWORD_FIELD(oword, FRF_CZ_CS_PORT_NUM);
+ efx_mcdi_execute_quiet(enp, &req);
- if (portnum == 0) {
- /* Presumably booted from ROM; only MCDI port 1 will work */
- emip->emi_port = 1;
- } else if (portnum <= 2) {
- emip->emi_port = portnum;
- } else {
- rc = EINVAL;
+ if (req.emr_rc == EACCES) {
+ /* Unprivileged functions cannot reboot the MC. */
+ goto out;
+ }
+
+ /* A successful reboot request returns EIO. */
+ if (req.emr_rc != 0 && req.emr_rc != EIO) {
+ rc = req.emr_rc;
goto fail1;
}
+out:
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_reboot(
+ __in efx_nic_t *enp)
+{
+ return (efx_mcdi_do_reboot(enp, B_FALSE));
+}
+
+ __checkReturn int
+efx_mcdi_exit_assertion_handler(
+ __in efx_nic_t *enp)
+{
+ return (efx_mcdi_do_reboot(enp, B_TRUE));
+}
+
+ __checkReturn int
+efx_mcdi_read_assertion(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_ASSERTS_IN_LEN,
+ MC_CMD_GET_ASSERTS_OUT_LEN)];
+ const char *reason;
+ unsigned int flags;
+ unsigned int index;
+ unsigned int ofst;
+ int retry;
+ int rc;
+
/*
- * Wipe the atomic reboot status so subsequent MCDI requests succeed.
- * BOOT_STATUS is preserved so eno_nic_probe() can boot out of the
- * assertion handler.
+ * Before we attempt to chat to the MC, we should verify that the MC
+ * isn't in it's assertion handler, either due to a previous reboot,
+ * or because we're reinitializing due to an eec_exception().
+ *
+ * Use GET_ASSERTS to read any assertion state that may be present.
+ * Retry this command twice. Once because a boot-time assertion failure
+ * might cause the 1st MCDI request to fail. And once again because
+ * we might race with efx_mcdi_exit_assertion_handler() running on
+ * partner port(s) on the same NIC.
*/
- (void) efx_mcdi_poll_reboot(enp);
+ retry = 2;
+ do {
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_ASSERTS;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_ASSERTS_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_ASSERTS_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, GET_ASSERTS_IN_CLEAR, 1);
+ efx_mcdi_execute_quiet(enp, &req);
+
+ } while ((req.emr_rc == EINTR || req.emr_rc == EIO) && retry-- > 0);
+
+ if (req.emr_rc != 0) {
+ if (req.emr_rc == EACCES) {
+ /* Unprivileged functions cannot clear assertions. */
+ goto out;
+ }
+ rc = req.emr_rc;
+ goto fail1;
+ }
+ if (req.emr_out_length_used < MC_CMD_GET_ASSERTS_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ /* Print out any assertion state recorded */
+ flags = MCDI_OUT_DWORD(req, GET_ASSERTS_OUT_GLOBAL_FLAGS);
+ if (flags == MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS)
+ return (0);
+
+ reason = (flags == MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL)
+ ? "system-level assertion"
+ : (flags == MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL)
+ ? "thread-level assertion"
+ : (flags == MC_CMD_GET_ASSERTS_FLAGS_WDOG_FIRED)
+ ? "watchdog reset"
+ : (flags == MC_CMD_GET_ASSERTS_FLAGS_ADDR_TRAP)
+ ? "illegal address trap"
+ : "unknown assertion";
+ EFSYS_PROBE3(mcpu_assertion,
+ const char *, reason, unsigned int,
+ MCDI_OUT_DWORD(req, GET_ASSERTS_OUT_SAVED_PC_OFFS),
+ unsigned int,
+ MCDI_OUT_DWORD(req, GET_ASSERTS_OUT_THREAD_OFFS));
+
+ /* Print out the registers (r1 ... r31) */
+ ofst = MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST;
+ for (index = 1;
+ index < 1 + MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_NUM;
+ index++) {
+ EFSYS_PROBE2(mcpu_register, unsigned int, index, unsigned int,
+ EFX_DWORD_FIELD(*MCDI_OUT(req, efx_dword_t, ofst),
+ EFX_DWORD_0));
+ ofst += sizeof (efx_dword_t);
+ }
+ EFSYS_ASSERT(ofst <= MC_CMD_GET_ASSERTS_OUT_LEN);
+
+out:
return (0);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, int, rc);
- enp->en_mod_flags &= ~EFX_MOD_MCDI;
-
return (rc);
}
+/*
+ * Internal routines for for specific MCDI requests.
+ */
+
__checkReturn int
-efx_mcdi_reboot(
- __in efx_nic_t *enp)
+efx_mcdi_drv_attach(
+ __in efx_nic_t *enp,
+ __in boolean_t attach)
{
- uint8_t payload[MC_CMD_REBOOT_IN_LEN];
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_DRV_ATTACH_IN_LEN,
+ MC_CMD_DRV_ATTACH_EXT_OUT_LEN)];
+ uint32_t flags;
int rc;
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_DRV_ATTACH;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_DRV_ATTACH_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_DRV_ATTACH_EXT_OUT_LEN;
+
/*
- * We could require the caller to have caused en_mod_flags=0 to
- * call this function. This doesn't help the other port though,
- * who's about to get the MC ripped out from underneath them.
- * Since they have to cope with the subsequent fallout of MCDI
- * failures, we should as well.
+ * Use DONT_CARE for the datapath firmware type to ensure that the
+ * driver can attach to an unprivileged function. The datapath firmware
+ * type to use is controlled by the 'sfboot' utility.
*/
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ MCDI_IN_SET_DWORD(req, DRV_ATTACH_IN_NEW_STATE, attach ? 1 : 0);
+ MCDI_IN_SET_DWORD(req, DRV_ATTACH_IN_UPDATE, 1);
+ MCDI_IN_SET_DWORD(req, DRV_ATTACH_IN_FIRMWARE_ID, MC_CMD_FW_DONT_CARE);
- req.emr_cmd = MC_CMD_REBOOT;
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_DRV_ATTACH_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ if (attach == B_FALSE) {
+ flags = 0;
+ } else if (enp->en_family == EFX_FAMILY_SIENA) {
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+
+ /* Create synthetic privileges for Siena functions */
+ flags = EFX_NIC_FUNC_LINKCTRL | EFX_NIC_FUNC_TRUSTED;
+ if (emip->emi_port == 1)
+ flags |= EFX_NIC_FUNC_PRIMARY;
+ } else {
+ EFX_STATIC_ASSERT(EFX_NIC_FUNC_PRIMARY ==
+ (1u << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_PRIMARY));
+ EFX_STATIC_ASSERT(EFX_NIC_FUNC_LINKCTRL ==
+ (1u << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_LINKCTRL));
+ EFX_STATIC_ASSERT(EFX_NIC_FUNC_TRUSTED ==
+ (1u << MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_TRUSTED));
+
+ /* Save function privilege flags (EF10 and later) */
+ if (req.emr_out_length_used < MC_CMD_DRV_ATTACH_EXT_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail3;
+ }
+ flags = MCDI_OUT_DWORD(req, DRV_ATTACH_EXT_OUT_FUNC_FLAGS);
+ }
+ encp->enc_func_flags = flags;
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_get_board_cfg(
+ __in efx_nic_t *enp,
+ __out_opt uint32_t *board_typep,
+ __out_opt efx_dword_t *capabilitiesp,
+ __out_ecount_opt(6) uint8_t mac_addrp[6])
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_BOARD_CFG_IN_LEN,
+ MC_CMD_GET_BOARD_CFG_OUT_LENMIN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_BOARD_CFG;
req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_REBOOT_IN_LEN;
+ req.emr_in_length = MC_CMD_GET_BOARD_CFG_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_BOARD_CFG_OUT_LENMIN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_BOARD_CFG_OUT_LENMIN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ if (mac_addrp != NULL) {
+ uint8_t *addrp;
+
+ if (emip->emi_port == 1) {
+ addrp = MCDI_OUT2(req, uint8_t,
+ GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0);
+ } else if (emip->emi_port == 2) {
+ addrp = MCDI_OUT2(req, uint8_t,
+ GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1);
+ } else {
+ rc = EINVAL;
+ goto fail3;
+ }
+
+ EFX_MAC_ADDR_COPY(mac_addrp, addrp);
+ }
+
+ if (capabilitiesp != NULL) {
+ if (emip->emi_port == 1) {
+ *capabilitiesp = *MCDI_OUT2(req, efx_dword_t,
+ GET_BOARD_CFG_OUT_CAPABILITIES_PORT0);
+ } else if (emip->emi_port == 2) {
+ *capabilitiesp = *MCDI_OUT2(req, efx_dword_t,
+ GET_BOARD_CFG_OUT_CAPABILITIES_PORT1);
+ } else {
+ rc = EINVAL;
+ goto fail4;
+ }
+ }
+
+ if (board_typep != NULL) {
+ *board_typep = MCDI_OUT_DWORD(req,
+ GET_BOARD_CFG_OUT_BOARD_TYPE);
+ }
+
+ return (0);
+
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_get_resource_limits(
+ __in efx_nic_t *enp,
+ __out_opt uint32_t *nevqp,
+ __out_opt uint32_t *nrxqp,
+ __out_opt uint32_t *ntxqp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_RESOURCE_LIMITS_IN_LEN,
+ MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_RESOURCE_LIMITS;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_RESOURCE_LIMITS_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ if (nevqp != NULL)
+ *nevqp = MCDI_OUT_DWORD(req, GET_RESOURCE_LIMITS_OUT_EVQ);
+ if (nrxqp != NULL)
+ *nrxqp = MCDI_OUT_DWORD(req, GET_RESOURCE_LIMITS_OUT_RXQ);
+ if (ntxqp != NULL)
+ *ntxqp = MCDI_OUT_DWORD(req, GET_RESOURCE_LIMITS_OUT_TXQ);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_get_phy_cfg(
+ __in efx_nic_t *enp)
+{
+ efx_port_t *epp = &(enp->en_port);
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_PHY_CFG_IN_LEN,
+ MC_CMD_GET_PHY_CFG_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_PHY_CFG;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_PHY_CFG_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_PHY_CFG_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_PHY_CFG_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ encp->enc_phy_type = MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_TYPE);
+#if EFSYS_OPT_NAMES
+ (void) strncpy(encp->enc_phy_name,
+ MCDI_OUT2(req, char, GET_PHY_CFG_OUT_NAME),
+ MIN(sizeof (encp->enc_phy_name) - 1,
+ MC_CMD_GET_PHY_CFG_OUT_NAME_LEN));
+#endif /* EFSYS_OPT_NAMES */
+ (void) memset(encp->enc_phy_revision, 0,
+ sizeof (encp->enc_phy_revision));
+ memcpy(encp->enc_phy_revision,
+ MCDI_OUT2(req, char, GET_PHY_CFG_OUT_REVISION),
+ MIN(sizeof (encp->enc_phy_revision) - 1,
+ MC_CMD_GET_PHY_CFG_OUT_REVISION_LEN));
+#if EFSYS_OPT_PHY_LED_CONTROL
+ encp->enc_led_mask = ((1 << EFX_PHY_LED_DEFAULT) |
+ (1 << EFX_PHY_LED_OFF) |
+ (1 << EFX_PHY_LED_ON));
+#endif /* EFSYS_OPT_PHY_LED_CONTROL */
+
+#if EFSYS_OPT_PHY_PROPS
+ encp->enc_phy_nprops = 0;
+#endif /* EFSYS_OPT_PHY_PROPS */
+
+ /* Get the media type of the fixed port, if recognised. */
+ EFX_STATIC_ASSERT(MC_CMD_MEDIA_XAUI == EFX_PHY_MEDIA_XAUI);
+ EFX_STATIC_ASSERT(MC_CMD_MEDIA_CX4 == EFX_PHY_MEDIA_CX4);
+ EFX_STATIC_ASSERT(MC_CMD_MEDIA_KX4 == EFX_PHY_MEDIA_KX4);
+ EFX_STATIC_ASSERT(MC_CMD_MEDIA_XFP == EFX_PHY_MEDIA_XFP);
+ EFX_STATIC_ASSERT(MC_CMD_MEDIA_SFP_PLUS == EFX_PHY_MEDIA_SFP_PLUS);
+ EFX_STATIC_ASSERT(MC_CMD_MEDIA_BASE_T == EFX_PHY_MEDIA_BASE_T);
+ EFX_STATIC_ASSERT(MC_CMD_MEDIA_QSFP_PLUS == EFX_PHY_MEDIA_QSFP_PLUS);
+ epp->ep_fixed_port_type =
+ MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_MEDIA_TYPE);
+ if (epp->ep_fixed_port_type >= EFX_PHY_MEDIA_NTYPES)
+ epp->ep_fixed_port_type = EFX_PHY_MEDIA_INVALID;
+
+ epp->ep_phy_cap_mask =
+ MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_SUPPORTED_CAP);
+#if EFSYS_OPT_PHY_FLAGS
+ encp->enc_phy_flags_mask = MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_FLAGS);
+#endif /* EFSYS_OPT_PHY_FLAGS */
+
+ encp->enc_port = (uint8_t)MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_PRT);
+
+ /* Populate internal state */
+ encp->enc_mcdi_mdio_channel =
+ (uint8_t)MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_CHANNEL);
+
+#if EFSYS_OPT_PHY_STATS
+ encp->enc_mcdi_phy_stat_mask =
+ MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_STATS_MASK);
+#endif /* EFSYS_OPT_PHY_STATS */
+
+#if EFSYS_OPT_BIST
+ encp->enc_bist_mask = 0;
+ if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS,
+ GET_PHY_CFG_OUT_BIST_CABLE_SHORT))
+ encp->enc_bist_mask |= (1 << EFX_BIST_TYPE_PHY_CABLE_SHORT);
+ if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS,
+ GET_PHY_CFG_OUT_BIST_CABLE_LONG))
+ encp->enc_bist_mask |= (1 << EFX_BIST_TYPE_PHY_CABLE_LONG);
+ if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS,
+ GET_PHY_CFG_OUT_BIST))
+ encp->enc_bist_mask |= (1 << EFX_BIST_TYPE_PHY_NORMAL);
+#endif /* EFSYS_OPT_BIST */
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+ __checkReturn int
+efx_mcdi_firmware_update_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp)
+{
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+ int rc;
+
+ if (emcop != NULL && emcop->emco_fw_update_supported != NULL) {
+ if ((rc = emcop->emco_fw_update_supported(enp, supportedp))
+ != 0)
+ goto fail1;
+ } else {
+ /* Earlier devices always supported updates */
+ *supportedp = B_TRUE;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_macaddr_change_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp)
+{
+ efx_mcdi_ops_t *emcop = enp->en_mcdi.em_emcop;
+ int rc;
+
+ if (emcop != NULL && emcop->emco_macaddr_change_supported != NULL) {
+ if ((rc = emcop->emco_macaddr_change_supported(enp, supportedp))
+ != 0)
+ goto fail1;
+ } else {
+ /* Earlier devices always supported MAC changes */
+ *supportedp = B_TRUE;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+#if EFSYS_OPT_BIST
+
+#if EFSYS_OPT_HUNTINGTON
+/*
+ * Enter bist offline mode. This is a fw mode which puts the NIC into a state
+ * where memory BIST tests can be run and not much else can interfere or happen.
+ * A reboot is required to exit this mode.
+ */
+ __checkReturn int
+efx_mcdi_bist_enable_offline(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_req_t req;
+ int rc;
+
+ EFX_STATIC_ASSERT(MC_CMD_ENABLE_OFFLINE_BIST_IN_LEN == 0);
+ EFX_STATIC_ASSERT(MC_CMD_ENABLE_OFFLINE_BIST_OUT_LEN == 0);
+
+ req.emr_cmd = MC_CMD_ENABLE_OFFLINE_BIST;
+ req.emr_in_buf = NULL;
+ req.emr_in_length = 0;
req.emr_out_buf = NULL;
req.emr_out_length = 0;
- MCDI_IN_SET_DWORD(req, REBOOT_IN_FLAGS, 0);
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+ __checkReturn int
+efx_mcdi_bist_start(
+ __in efx_nic_t *enp,
+ __in efx_bist_type_t type)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_START_BIST_IN_LEN,
+ MC_CMD_START_BIST_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_START_BIST;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_START_BIST_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_START_BIST_OUT_LEN;
+
+ switch (type) {
+ case EFX_BIST_TYPE_PHY_NORMAL:
+ MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE, MC_CMD_PHY_BIST);
+ break;
+ case EFX_BIST_TYPE_PHY_CABLE_SHORT:
+ MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE,
+ MC_CMD_PHY_BIST_CABLE_SHORT);
+ break;
+ case EFX_BIST_TYPE_PHY_CABLE_LONG:
+ MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE,
+ MC_CMD_PHY_BIST_CABLE_LONG);
+ break;
+ case EFX_BIST_TYPE_MC_MEM:
+ MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE,
+ MC_CMD_MC_MEM_BIST);
+ break;
+ case EFX_BIST_TYPE_SAT_MEM:
+ MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE,
+ MC_CMD_PORT_MEM_BIST);
+ break;
+ case EFX_BIST_TYPE_REG:
+ MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE,
+ MC_CMD_REG_BIST);
+ break;
+ default:
+ EFSYS_ASSERT(0);
+ }
efx_mcdi_execute(enp, &req);
- /* Invert EIO */
- if (req.emr_rc != EIO) {
- rc = EIO;
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
goto fail1;
}
@@ -679,64 +1269,391 @@ fail1:
return (rc);
}
- __checkReturn boolean_t
-efx_mcdi_request_abort(
+#endif /* EFSYS_OPT_BIST */
+
+
+/* Enable logging of some events (e.g. link state changes) */
+ __checkReturn int
+efx_mcdi_log_ctrl(
__in efx_nic_t *enp)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- efx_mcdi_req_t *emrp;
- boolean_t aborted;
- int state;
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_LOG_CTRL_IN_LEN,
+ MC_CMD_LOG_CTRL_OUT_LEN)];
+ int rc;
- EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
- EFSYS_ASSERT3U(enp->en_features, &, EFX_FEATURE_MCDI);
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_LOG_CTRL;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_LOG_CTRL_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_LOG_CTRL_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, LOG_CTRL_IN_LOG_DEST,
+ MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ);
+ MCDI_IN_SET_DWORD(req, LOG_CTRL_IN_LOG_DEST_EVQ, 0);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+#if EFSYS_OPT_MAC_STATS
+
+typedef enum efx_stats_action_e
+{
+ EFX_STATS_CLEAR,
+ EFX_STATS_UPLOAD,
+ EFX_STATS_ENABLE_NOEVENTS,
+ EFX_STATS_ENABLE_EVENTS,
+ EFX_STATS_DISABLE,
+} efx_stats_action_t;
+
+static __checkReturn int
+efx_mcdi_mac_stats(
+ __in efx_nic_t *enp,
+ __in_opt efsys_mem_t *esmp,
+ __in efx_stats_action_t action)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_MAC_STATS_IN_LEN,
+ MC_CMD_MAC_STATS_OUT_DMA_LEN)];
+ int clear = (action == EFX_STATS_CLEAR);
+ int upload = (action == EFX_STATS_UPLOAD);
+ int enable = (action == EFX_STATS_ENABLE_NOEVENTS);
+ int events = (action == EFX_STATS_ENABLE_EVENTS);
+ int disable = (action == EFX_STATS_DISABLE);
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_MAC_STATS;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_MAC_STATS_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_MAC_STATS_OUT_DMA_LEN;
+
+ MCDI_IN_POPULATE_DWORD_6(req, MAC_STATS_IN_CMD,
+ MAC_STATS_IN_DMA, upload,
+ MAC_STATS_IN_CLEAR, clear,
+ MAC_STATS_IN_PERIODIC_CHANGE, enable | events | disable,
+ MAC_STATS_IN_PERIODIC_ENABLE, enable | events,
+ MAC_STATS_IN_PERIODIC_NOEVENT, !events,
+ MAC_STATS_IN_PERIOD_MS, (enable | events) ? 1000: 0);
+
+ if (esmp != NULL) {
+ int bytes = MC_CMD_MAC_NSTATS * sizeof (uint64_t);
+
+ EFX_STATIC_ASSERT(MC_CMD_MAC_NSTATS * sizeof (uint64_t) <=
+ EFX_MAC_STATS_SIZE);
+
+ MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_LO,
+ EFSYS_MEM_ADDR(esmp) & 0xffffffff);
+ MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_HI,
+ EFSYS_MEM_ADDR(esmp) >> 32);
+ MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_LEN, bytes);
+ } else {
+ EFSYS_ASSERT(!upload && !enable && !events);
+ }
/*
- * efx_mcdi_ev_* may have already completed this event, and be
- * spinning/blocked on the upper layer lock. So it *is* legitimate
- * to for emi_pending_req to be NULL. If there is a pending event
- * completed request, then provide a "credit" to allow
- * efx_mcdi_ev_cpl() to accept a single spurious completion.
+ * NOTE: Do not use EVB_PORT_ID_ASSIGNED when disabling periodic stats,
+ * as this may fail (and leave periodic DMA enabled) if the
+ * vadapter has already been deleted.
*/
- EFSYS_LOCK(enp->en_eslp, state);
- emrp = emip->emi_pending_req;
- aborted = (emrp != NULL);
- if (aborted) {
- emip->emi_pending_req = NULL;
+ MCDI_IN_SET_DWORD(req, MAC_STATS_IN_PORT_ID,
+ (disable ? EVB_PORT_ID_NULL : enp->en_vport_id));
- /* Error the request */
- emrp->emr_out_length_used = 0;
- emrp->emr_rc = ETIMEDOUT;
-
- /* Provide a credit for seqno/emr_pending_req mismatches */
- if (emip->emi_ev_cpl)
- ++emip->emi_aborted;
+ efx_mcdi_execute(enp, &req);
- /*
- * The upper layer has called us, so we don't
- * need to complete the request.
- */
+ if (req.emr_rc != 0) {
+ /* EF10: Expect ENOENT if no DMA queues are initialised */
+ if ((req.emr_rc != ENOENT) ||
+ (enp->en_rx_qcount + enp->en_tx_qcount != 0)) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
}
- EFSYS_UNLOCK(enp->en_eslp, state);
- return (aborted);
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
}
- void
-efx_mcdi_fini(
+ __checkReturn int
+efx_mcdi_mac_stats_clear(
__in efx_nic_t *enp)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
+ int rc;
- EFSYS_ASSERT3U(enp->en_mod_flags, ==, EFX_MOD_MCDI);
- enp->en_mod_flags &= ~EFX_MOD_MCDI;
+ if ((rc = efx_mcdi_mac_stats(enp, NULL, EFX_STATS_CLEAR)) != 0)
+ goto fail1;
- if (~(enp->en_features) & EFX_FEATURE_MCDI)
- return;
+ return (0);
- emip->emi_mtp = NULL;
- emip->emi_port = 0;
- emip->emi_aborted = 0;
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
}
+ __checkReturn int
+efx_mcdi_mac_stats_upload(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp)
+{
+ int rc;
+
+ /*
+ * The MC DMAs aggregate statistics for our convenience, so we can
+ * avoid having to pull the statistics buffer into the cache to
+ * maintain cumulative statistics.
+ */
+ if ((rc = efx_mcdi_mac_stats(enp, esmp, EFX_STATS_UPLOAD)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_mac_stats_periodic(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp,
+ __in uint16_t period,
+ __in boolean_t events)
+{
+ int rc;
+
+ /*
+ * The MC DMAs aggregate statistics for our convenience, so we can
+ * avoid having to pull the statistics buffer into the cache to
+ * maintain cumulative statistics.
+ * Huntington uses a fixed 1sec period, so use that on Siena too.
+ */
+ if (period == 0)
+ rc = efx_mcdi_mac_stats(enp, NULL, EFX_STATS_DISABLE);
+ else if (events)
+ rc = efx_mcdi_mac_stats(enp, esmp, EFX_STATS_ENABLE_EVENTS);
+ else
+ rc = efx_mcdi_mac_stats(enp, esmp, EFX_STATS_ENABLE_NOEVENTS);
+
+ if (rc != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_MAC_STATS */
+
+#if EFSYS_OPT_HUNTINGTON
+
+/*
+ * This function returns the pf and vf number of a function. If it is a pf the
+ * vf number is 0xffff. The vf number is the index of the vf on that
+ * function. So if you have 3 vfs on pf 0 the 3 vfs will return (pf=0,vf=0),
+ * (pf=0,vf=1), (pf=0,vf=2) aand the pf will return (pf=0, vf=0xffff).
+ */
+ __checkReturn int
+efx_mcdi_get_function_info(
+ __in efx_nic_t *enp,
+ __out uint32_t *pfp,
+ __out_opt uint32_t *vfp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_FUNCTION_INFO_IN_LEN,
+ MC_CMD_GET_FUNCTION_INFO_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_FUNCTION_INFO;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_FUNCTION_INFO_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_FUNCTION_INFO_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_FUNCTION_INFO_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ *pfp = MCDI_OUT_DWORD(req, GET_FUNCTION_INFO_OUT_PF);
+ if (vfp != NULL)
+ *vfp = MCDI_OUT_DWORD(req, GET_FUNCTION_INFO_OUT_VF);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_privilege_mask(
+ __in efx_nic_t *enp,
+ __in uint32_t pf,
+ __in uint32_t vf,
+ __out uint32_t *maskp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_PRIVILEGE_MASK_IN_LEN,
+ MC_CMD_PRIVILEGE_MASK_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_PRIVILEGE_MASK;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_PRIVILEGE_MASK_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_PRIVILEGE_MASK_OUT_LEN;
+
+ MCDI_IN_POPULATE_DWORD_2(req, PRIVILEGE_MASK_IN_FUNCTION,
+ PRIVILEGE_MASK_IN_FUNCTION_PF, pf,
+ PRIVILEGE_MASK_IN_FUNCTION_VF, vf);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_PRIVILEGE_MASK_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ *maskp = MCDI_OUT_DWORD(req, PRIVILEGE_MASK_OUT_OLD_MASK);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+ __checkReturn int
+efx_mcdi_set_workaround(
+ __in efx_nic_t *enp,
+ __in uint32_t type,
+ __in boolean_t enabled,
+ __out_opt uint32_t *flagsp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_WORKAROUND_IN_LEN,
+ MC_CMD_WORKAROUND_EXT_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_WORKAROUND;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_WORKAROUND_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_WORKAROUND_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, WORKAROUND_IN_TYPE, type);
+ MCDI_IN_SET_DWORD(req, WORKAROUND_IN_ENABLED, enabled ? 1 : 0);
+
+ efx_mcdi_execute_quiet(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (flagsp != NULL) {
+ if (req.emr_out_length_used >= MC_CMD_WORKAROUND_EXT_OUT_LEN)
+ *flagsp = MCDI_OUT_DWORD(req, WORKAROUND_EXT_OUT_FLAGS);
+ else
+ *flagsp = 0;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+ __checkReturn int
+efx_mcdi_get_workarounds(
+ __in efx_nic_t *enp,
+ __out_opt uint32_t *implementedp,
+ __out_opt uint32_t *enabledp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MC_CMD_GET_WORKAROUNDS_OUT_LEN];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_WORKAROUNDS;
+ req.emr_in_buf = NULL;
+ req.emr_in_length = 0;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_WORKAROUNDS_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (implementedp != NULL) {
+ *implementedp =
+ MCDI_OUT_DWORD(req, GET_WORKAROUNDS_OUT_IMPLEMENTED);
+ }
+
+ if (enabledp != NULL) {
+ *enabledp = MCDI_OUT_DWORD(req, GET_WORKAROUNDS_OUT_ENABLED);
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
#endif /* EFSYS_OPT_MCDI */
diff --git a/sys/dev/sfxge/common/efx_mcdi.h b/sys/dev/sfxge/common/efx_mcdi.h
index b115746..ea02248 100644
--- a/sys/dev/sfxge/common/efx_mcdi.h
+++ b/sys/dev/sfxge/common/efx_mcdi.h
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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.
*
* $FreeBSD$
*/
@@ -36,10 +41,15 @@
extern "C" {
#endif
-/* Number of retries attempted for init code */
-#define EFX_MCDI_REQ_RETRY_INIT 2
+/*
+ * A reboot/assertion causes the MCDI status word to be set after the
+ * command word is set or a REBOOT event is sent. If we notice a reboot
+ * via these mechanisms then wait 10ms for the status word to be set.
+ */
+#define EFX_MCDI_STATUS_SLEEP_US 10000
struct efx_mcdi_req_s {
+ boolean_t emr_quiet;
/* Inputs: Command #, input buffer and length */
unsigned int emr_cmd;
uint8_t *emr_in_buf;
@@ -52,19 +62,25 @@ struct efx_mcdi_req_s {
};
typedef struct efx_mcdi_iface_s {
- const efx_mcdi_transport_t *emi_mtp;
unsigned int emi_port;
unsigned int emi_seq;
efx_mcdi_req_t *emi_pending_req;
boolean_t emi_ev_cpl;
+ boolean_t emi_new_epoch;
int emi_aborted;
uint32_t emi_poll_cnt;
+ uint32_t emi_mc_reboot_status;
} efx_mcdi_iface_t;
extern void
efx_mcdi_execute(
__in efx_nic_t *enp,
- __in efx_mcdi_req_t *emrp);
+ __inout efx_mcdi_req_t *emrp);
+
+extern void
+efx_mcdi_execute_quiet(
+ __in efx_nic_t *enp,
+ __inout efx_mcdi_req_t *emrp);
extern void
efx_mcdi_ev_cpl(
@@ -78,6 +94,16 @@ efx_mcdi_ev_death(
__in efx_nic_t *enp,
__in int rc);
+extern __checkReturn int
+efx_mcdi_request_errcode(
+ __in unsigned int err);
+
+extern void
+efx_mcdi_raise_exception(
+ __in efx_nic_t *enp,
+ __in_opt efx_mcdi_req_t *emrp,
+ __in int rc);
+
typedef enum efx_mcdi_boot_e {
EFX_MCDI_BOOT_PRIMARY,
EFX_MCDI_BOOT_SECONDARY,
@@ -91,6 +117,86 @@ efx_mcdi_version(
__out_opt uint32_t *buildp,
__out_opt efx_mcdi_boot_t *statusp);
+extern __checkReturn int
+efx_mcdi_read_assertion(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+efx_mcdi_exit_assertion_handler(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+efx_mcdi_drv_attach(
+ __in efx_nic_t *enp,
+ __in boolean_t attach);
+
+extern __checkReturn int
+efx_mcdi_get_board_cfg(
+ __in efx_nic_t *enp,
+ __out_opt uint32_t *board_typep,
+ __out_opt efx_dword_t *capabilitiesp,
+ __out_ecount_opt(6) uint8_t mac_addrp[6]);
+
+extern __checkReturn int
+efx_mcdi_get_phy_cfg(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+efx_mcdi_firmware_update_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp);
+
+extern __checkReturn int
+efx_mcdi_macaddr_change_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp);
+
+#if EFSYS_OPT_BIST
+#if EFSYS_OPT_HUNTINGTON
+extern __checkReturn int
+efx_mcdi_bist_enable_offline(
+ __in efx_nic_t *enp);
+#endif /* EFSYS_OPT_HUNTINGTON */
+extern __checkReturn int
+efx_mcdi_bist_start(
+ __in efx_nic_t *enp,
+ __in efx_bist_type_t type);
+#endif /* EFSYS_OPT_BIST */
+
+extern __checkReturn int
+efx_mcdi_get_resource_limits(
+ __in efx_nic_t *enp,
+ __out_opt uint32_t *nevqp,
+ __out_opt uint32_t *nrxqp,
+ __out_opt uint32_t *ntxqp);
+
+extern __checkReturn int
+efx_mcdi_log_ctrl(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+efx_mcdi_mac_stats_clear(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+efx_mcdi_mac_stats_upload(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp);
+
+extern __checkReturn int
+efx_mcdi_mac_stats_periodic(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp,
+ __in uint16_t period,
+ __in boolean_t events);
+
+
+#if EFSYS_OPT_LOOPBACK
+extern __checkReturn int
+efx_mcdi_get_loopback_modes(
+ __in efx_nic_t *enp);
+#endif /* EFSYS_OPT_LOOPBACK */
+
#define MCDI_IN(_emr, _type, _ofst) \
((_type *)((_emr).emr_in_buf + (_ofst)))
@@ -101,10 +207,18 @@ efx_mcdi_version(
EFX_POPULATE_BYTE_1(*MCDI_IN2(_emr, efx_byte_t, _ofst), \
EFX_BYTE_0, _value)
+#define MCDI_IN_SET_WORD(_emr, _ofst, _value) \
+ EFX_POPULATE_WORD_1(*MCDI_IN2(_emr, efx_word_t, _ofst), \
+ EFX_WORD_0, _value)
+
#define MCDI_IN_SET_DWORD(_emr, _ofst, _value) \
EFX_POPULATE_DWORD_1(*MCDI_IN2(_emr, efx_dword_t, _ofst), \
EFX_DWORD_0, _value)
+#define MCDI_IN_SET_DWORD_FIELD(_emr, _ofst, _field, _value) \
+ EFX_SET_DWORD_FIELD(*MCDI_IN2(_emr, efx_dword_t, _ofst), \
+ MC_CMD_ ## _field, _value)
+
#define MCDI_IN_POPULATE_DWORD_1(_emr, _ofst, _field1, _value1) \
EFX_POPULATE_DWORD_1(*MCDI_IN2(_emr, efx_dword_t, _ofst), \
MC_CMD_ ## _field1, _value1)
@@ -154,7 +268,7 @@ efx_mcdi_version(
#define MCDI_IN_POPULATE_DWORD_7(_emr, _ofst, _field1, _value1, \
_field2, _value2, _field3, _value3, _field4, _value4, \
_field5, _value5, _field6, _value6, _field7, _value7) \
- EFX_POPULATE_DWORD_7(MCDI_IN2(_emr, efx_dword_t, _ofst), \
+ EFX_POPULATE_DWORD_7(*MCDI_IN2(_emr, efx_dword_t, _ofst), \
MC_CMD_ ## _field1, _value1, \
MC_CMD_ ## _field2, _value2, \
MC_CMD_ ## _field3, _value3, \
@@ -233,7 +347,7 @@ efx_mcdi_version(
#define MCDI_EV_FIELD(_eqp, _field) \
EFX_QWORD_FIELD(*_eqp, MCDI_EVENT_ ## _field)
-#define MCDI_CMD_DWORD_FIELD(_edp, _field) \
+#define MCDI_CMD_DWORD_FIELD(_edp, _field) \
EFX_DWORD_FIELD(*_edp, MC_CMD_ ## _field)
#ifdef __cplusplus
diff --git a/sys/dev/sfxge/common/efx_mon.c b/sys/dev/sfxge/common/efx_mon.c
index dc2e256..c5b356d 100644
--- a/sys/dev/sfxge/common/efx_mon.c
+++ b/sys/dev/sfxge/common/efx_mon.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -44,17 +49,22 @@ __FBSDID("$FreeBSD$");
#include "max6647.h"
#endif
+#if EFSYS_OPT_MON_MCDI
+#include "mcdi_mon.h"
+#endif
+
#if EFSYS_OPT_NAMES
-static const char __cs * __cs __efx_mon_name[] = {
+static const char *__efx_mon_name[] = {
"",
"nullmon",
"lm87",
"max6647",
- "sfx90x0"
+ "sfx90x0",
+ "sfx91x0"
};
- const char __cs *
+ const char *
efx_mon_name(
__in efx_nic_t *enp)
{
@@ -70,47 +80,46 @@ efx_mon_name(
#endif /* EFSYS_OPT_NAMES */
#if EFSYS_OPT_MON_NULL
-static efx_mon_ops_t __cs __efx_mon_null_ops = {
+static efx_mon_ops_t __efx_mon_null_ops = {
nullmon_reset, /* emo_reset */
nullmon_reconfigure, /* emo_reconfigure */
#if EFSYS_OPT_MON_STATS
- nullmon_stats_update /* emo_stat_update */
+ nullmon_stats_update /* emo_stats_update */
#endif /* EFSYS_OPT_MON_STATS */
};
#endif
#if EFSYS_OPT_MON_LM87
-static efx_mon_ops_t __cs __efx_mon_lm87_ops = {
+static efx_mon_ops_t __efx_mon_lm87_ops = {
lm87_reset, /* emo_reset */
lm87_reconfigure, /* emo_reconfigure */
#if EFSYS_OPT_MON_STATS
- lm87_stats_update /* emo_stat_update */
+ lm87_stats_update /* emo_stats_update */
#endif /* EFSYS_OPT_MON_STATS */
};
#endif
#if EFSYS_OPT_MON_MAX6647
-static efx_mon_ops_t __cs __efx_mon_max6647_ops = {
+static efx_mon_ops_t __efx_mon_max6647_ops = {
max6647_reset, /* emo_reset */
max6647_reconfigure, /* emo_reconfigure */
#if EFSYS_OPT_MON_STATS
- max6647_stats_update /* emo_stat_update */
+ max6647_stats_update /* emo_stats_update */
#endif /* EFSYS_OPT_MON_STATS */
};
#endif
-#if EFSYS_OPT_MON_SIENA
-static efx_mon_ops_t __cs __efx_mon_siena_ops = {
- siena_mon_reset, /* emo_reset */
- siena_mon_reconfigure, /* emo_reconfigure */
+#if EFSYS_OPT_MON_MCDI
+static efx_mon_ops_t __efx_mon_mcdi_ops = {
+ NULL, /* emo_reset */
+ NULL, /* emo_reconfigure */
#if EFSYS_OPT_MON_STATS
- siena_mon_stats_update /* emo_stat_update */
+ mcdi_mon_stats_update /* emo_stats_update */
#endif /* EFSYS_OPT_MON_STATS */
};
#endif
-
-static efx_mon_ops_t __cs * __cs __efx_mon_ops[] = {
+static efx_mon_ops_t *__efx_mon_ops[] = {
NULL,
#if EFSYS_OPT_MON_NULL
&__efx_mon_null_ops,
@@ -127,8 +136,13 @@ static efx_mon_ops_t __cs * __cs __efx_mon_ops[] = {
#else
NULL,
#endif
-#if EFSYS_OPT_MON_SIENA
- &__efx_mon_siena_ops
+#if EFSYS_OPT_MON_MCDI
+ &__efx_mon_mcdi_ops,
+#else
+ NULL,
+#endif
+#if EFSYS_OPT_MON_MCDI
+ &__efx_mon_mcdi_ops
#else
NULL
#endif
@@ -162,11 +176,15 @@ efx_mon_init(
goto fail2;
}
- if ((rc = emop->emo_reset(enp)) != 0)
- goto fail3;
+ if (emop->emo_reset != NULL) {
+ if ((rc = emop->emo_reset(enp)) != 0)
+ goto fail3;
+ }
- if ((rc = emop->emo_reconfigure(enp)) != 0)
- goto fail4;
+ if (emop->emo_reconfigure != NULL) {
+ if ((rc = emop->emo_reconfigure(enp)) != 0)
+ goto fail4;
+ }
emp->em_emop = emop;
return (0);
@@ -174,7 +192,8 @@ efx_mon_init(
fail4:
EFSYS_PROBE(fail5);
- (void) emop->emo_reset(enp);
+ if (emop->emo_reset != NULL)
+ (void) emop->emo_reset(enp);
fail3:
EFSYS_PROBE(fail4);
@@ -195,8 +214,8 @@ fail1:
#if EFSYS_OPT_NAMES
-/* START MKCONFIG GENERATED MonitorStatNamesBlock 89ff37f1d74ad8b3 */
-static const char __cs * __cs __mon_stat_name[] = {
+/* START MKCONFIG GENERATED MonitorStatNamesBlock b9328f15438c4d01 */
+static const char *__mon_stat_name[] = {
"value_2_5v",
"value_vccp1",
"value_vcc",
@@ -227,11 +246,50 @@ static const char __cs * __cs __mon_stat_name[] = {
"vaoe_in",
"iaoe",
"iaoe_in",
+ "nic_power",
+ "0_9v",
+ "i0_9v",
+ "i1_2v",
+ "0_9v_adc",
+ "controller_temperature2",
+ "vreg_temperature",
+ "vreg_0_9v_temperature",
+ "vreg_1_2v_temperature",
+ "int_vptat",
+ "controller_internal_adc_temperature",
+ "ext_vptat",
+ "controller_external_adc_temperature",
+ "ambient_temperature",
+ "airflow",
+ "vdd08d_vss08d_csr",
+ "vdd08d_vss08d_csr_extadc",
+ "hotpoint_temperature",
+ "phy_power_switch_port0",
+ "phy_power_switch_port1",
+ "mum_vcc",
+ "0v9_a",
+ "i0v9_a",
+ "0v9_a_temp",
+ "0v9_b",
+ "i0v9_b",
+ "0v9_b_temp",
+ "ccom_avreg_1v2_supply",
+ "ccom_avreg_1v2_supply_ext_adc",
+ "ccom_avreg_1v8_supply",
+ "ccom_avreg_1v8_supply_ext_adc",
+ "controller_master_vptat",
+ "controller_master_internal_temp",
+ "controller_master_vptat_ext_adc",
+ "controller_master_internal_temp_ext_adc",
+ "controller_slave_vptat",
+ "controller_slave_internal_temp",
+ "controller_slave_vptat_ext_adc",
+ "controller_slave_internal_temp_ext_adc",
};
/* END MKCONFIG GENERATED MonitorStatNamesBlock */
-extern const char __cs *
+extern const char *
efx_mon_stat_name(
__in efx_nic_t *enp,
__in efx_mon_stat_t id)
@@ -276,9 +334,11 @@ efx_mon_fini(
emp->em_emop = NULL;
- rc = emop->emo_reset(enp);
- if (rc != 0)
- EFSYS_PROBE1(fail1, int, rc);
+ if (emop->emo_reset != NULL) {
+ rc = emop->emo_reset(enp);
+ if (rc != 0)
+ EFSYS_PROBE1(fail1, int, rc);
+ }
emp->em_type = EFX_MON_INVALID;
diff --git a/sys/dev/sfxge/common/efx_nic.c b/sys/dev/sfxge/common/efx_nic.c
index b0ba58c..b5ad65e 100644
--- a/sys/dev/sfxge/common/efx_nic.c
+++ b/sys/dev/sfxge/common/efx_nic.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -38,27 +43,55 @@ efx_family(
__in uint16_t devid,
__out efx_family_t *efp)
{
+ if (venid == EFX_PCI_VENID_SFC) {
+ switch (devid) {
#if EFSYS_OPT_FALCON
- if (venid == EFX_PCI_VENID_SFC && devid == EFX_PCI_DEVID_FALCON) {
- *efp = EFX_FAMILY_FALCON;
- return (0);
- }
+ case EFX_PCI_DEVID_FALCON:
+ *efp = EFX_FAMILY_FALCON;
+ return (0);
#endif
#if EFSYS_OPT_SIENA
- if (venid == EFX_PCI_VENID_SFC && devid == EFX_PCI_DEVID_BETHPAGE) {
- *efp = EFX_FAMILY_SIENA;
- return (0);
- }
- if (venid == EFX_PCI_VENID_SFC && devid == EFX_PCI_DEVID_SIENA) {
- *efp = EFX_FAMILY_SIENA;
- return (0);
- }
- if (venid == EFX_PCI_VENID_SFC &&
- devid == EFX_PCI_DEVID_SIENA_F1_UNINIT) {
- *efp = EFX_FAMILY_SIENA;
- return (0);
- }
+ case EFX_PCI_DEVID_SIENA_F1_UNINIT:
+ /*
+ * Hardware default for PF0 of uninitialised Siena.
+ * manftest must be able to cope with this device id.
+ */
+ *efp = EFX_FAMILY_SIENA;
+ return (0);
+
+ case EFX_PCI_DEVID_BETHPAGE:
+ case EFX_PCI_DEVID_SIENA:
+ *efp = EFX_FAMILY_SIENA;
+ return (0);
+#endif
+
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_PCI_DEVID_HUNTINGTON_PF_UNINIT:
+ /*
+ * Hardware default for PF0 of uninitialised Huntington.
+ * manftest must be able to cope with this device id.
+ */
+ *efp = EFX_FAMILY_HUNTINGTON;
+ return (0);
+
+ case EFX_PCI_DEVID_FARMINGDALE:
+ case EFX_PCI_DEVID_GREENPORT:
+ case EFX_PCI_DEVID_HUNTINGTON:
+ *efp = EFX_FAMILY_HUNTINGTON;
+ return (0);
+
+ case EFX_PCI_DEVID_FARMINGDALE_VF:
+ case EFX_PCI_DEVID_GREENPORT_VF:
+ case EFX_PCI_DEVID_HUNTINGTON_VF:
+ *efp = EFX_FAMILY_HUNTINGTON;
+ return (0);
#endif
+ default:
+ break;
+ }
+ }
+
+ *efp = EFX_FAMILY_INVALID;
return (ENOTSUP);
}
@@ -80,11 +113,28 @@ efx_infer_family(
EFSYS_BAR_READO(esbp, FR_AZ_CS_DEBUG_REG_OFST, &oword, B_TRUE);
portnum = EFX_OWORD_FIELD(oword, FRF_CZ_CS_PORT_NUM);
switch (portnum) {
+ case 0: {
+ efx_dword_t dword;
+ uint32_t hw_rev;
+
+ EFSYS_BAR_READD(esbp, ER_DZ_BIU_HW_REV_ID_REG_OFST, &dword,
+ B_TRUE);
+ hw_rev = EFX_DWORD_FIELD(dword, ERF_DZ_HW_REV_ID);
+ if (hw_rev == ER_DZ_BIU_HW_REV_ID_REG_RESET) {
+#if EFSYS_OPT_HUNTINGTON
+ family = EFX_FAMILY_HUNTINGTON;
+ break;
+#endif
+ } else {
#if EFSYS_OPT_FALCON
- case 0:
- family = EFX_FAMILY_FALCON;
- break;
+ family = EFX_FAMILY_FALCON;
+ break;
#endif
+ }
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
#if EFSYS_OPT_SIENA
case 1:
case 2:
@@ -106,15 +156,10 @@ fail1:
return (rc);
}
-/*
- * The built-in default value device id for port 1 of Siena is 0x0810.
- * manftest needs to be able to cope with that.
- */
-
#define EFX_BIU_MAGIC0 0x01234567
#define EFX_BIU_MAGIC1 0xfedcba98
-static __checkReturn int
+ __checkReturn int
efx_nic_biu_test(
__in efx_nic_t *enp)
{
@@ -128,18 +173,18 @@ efx_nic_biu_test(
* 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);
+ 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);
+ EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
- EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword);
+ 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);
+ 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;
@@ -151,18 +196,18 @@ efx_nic_biu_test(
* 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);
+ 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);
+ EFX_BAR_TBL_WRITEO(enp, FR_AZ_DRIVER_REG, 1, &oword, B_TRUE);
- EFX_BAR_TBL_READO(enp, FR_AZ_DRIVER_REG, 0, &oword);
+ 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);
+ 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;
@@ -184,10 +229,13 @@ fail1:
#if EFSYS_OPT_FALCON
-static efx_nic_ops_t __cs __efx_nic_falcon_ops = {
+static efx_nic_ops_t __efx_nic_falcon_ops = {
falcon_nic_probe, /* eno_probe */
+ NULL, /* eno_set_drv_limits */
falcon_nic_reset, /* eno_reset */
falcon_nic_init, /* eno_init */
+ NULL, /* eno_get_vi_pool */
+ NULL, /* eno_get_bar_region */
#if EFSYS_OPT_DIAG
falcon_sram_test, /* eno_sram_test */
falcon_nic_register_test, /* eno_register_test */
@@ -200,10 +248,13 @@ static efx_nic_ops_t __cs __efx_nic_falcon_ops = {
#if EFSYS_OPT_SIENA
-static efx_nic_ops_t __cs __efx_nic_siena_ops = {
+static efx_nic_ops_t __efx_nic_siena_ops = {
siena_nic_probe, /* eno_probe */
+ NULL, /* eno_set_drv_limits */
siena_nic_reset, /* eno_reset */
siena_nic_init, /* eno_init */
+ NULL, /* eno_get_vi_pool */
+ NULL, /* eno_get_bar_region */
#if EFSYS_OPT_DIAG
siena_sram_test, /* eno_sram_test */
siena_nic_register_test, /* eno_register_test */
@@ -214,6 +265,25 @@ static efx_nic_ops_t __cs __efx_nic_siena_ops = {
#endif /* EFSYS_OPT_SIENA */
+#if EFSYS_OPT_HUNTINGTON
+
+static efx_nic_ops_t __efx_nic_hunt_ops = {
+ hunt_nic_probe, /* eno_probe */
+ hunt_nic_set_drv_limits, /* eno_set_drv_limits */
+ hunt_nic_reset, /* eno_reset */
+ hunt_nic_init, /* eno_init */
+ hunt_nic_get_vi_pool, /* eno_get_vi_pool */
+ hunt_nic_get_bar_region, /* eno_get_bar_region */
+#if EFSYS_OPT_DIAG
+ hunt_sram_test, /* eno_sram_test */
+ hunt_nic_register_test, /* eno_register_test */
+#endif /* EFSYS_OPT_DIAG */
+ hunt_nic_fini, /* eno_fini */
+ hunt_nic_unprobe, /* eno_unprobe */
+};
+
+#endif /* EFSYS_OPT_HUNTINGTON */
+
__checkReturn int
efx_nic_create(
__in efx_family_t family,
@@ -257,10 +327,27 @@ efx_nic_create(
EFX_FEATURE_WOL |
EFX_FEATURE_MCDI |
EFX_FEATURE_LOOKAHEAD_SPLIT |
- EFX_FEATURE_MAC_HEADER_FILTERS;
+ EFX_FEATURE_MAC_HEADER_FILTERS |
+ EFX_FEATURE_TX_SRC_FILTERS;
break;
#endif /* EFSYS_OPT_SIENA */
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ enp->en_enop = (efx_nic_ops_t *)&__efx_nic_hunt_ops;
+ /* FIXME: Add WOL support */
+ enp->en_features =
+ EFX_FEATURE_IPV6 |
+ EFX_FEATURE_LINK_EVENTS |
+ EFX_FEATURE_PERIODIC_MAC_STATS |
+ EFX_FEATURE_MCDI |
+ EFX_FEATURE_MAC_HEADER_FILTERS |
+ EFX_FEATURE_MCDI_DMA |
+ EFX_FEATURE_PIO_BUFFERS |
+ EFX_FEATURE_FW_ASSISTED_TSO;
+ break;
+#endif /* EFSYS_OPT_HUNTINGTON */
+
default:
rc = ENOTSUP;
goto fail2;
@@ -276,7 +363,7 @@ efx_nic_create(
return (0);
fail2:
- EFSYS_PROBE(fail3);
+ EFSYS_PROBE(fail2);
enp->en_magic = 0;
@@ -294,7 +381,6 @@ efx_nic_probe(
__in efx_nic_t *enp)
{
efx_nic_ops_t *enop;
- efx_oword_t oword;
int rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
@@ -303,36 +389,22 @@ efx_nic_probe(
#endif /* EFSYS_OPT_MCDI */
EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROBE));
- /* Test BIU */
- if ((rc = efx_nic_biu_test(enp)) != 0)
- goto fail1;
-
- /* Clear the region register */
- EFX_POPULATE_OWORD_4(oword,
- FRF_AZ_ADR_REGION0, 0,
- FRF_AZ_ADR_REGION1, (1 << 16),
- FRF_AZ_ADR_REGION2, (2 << 16),
- FRF_AZ_ADR_REGION3, (3 << 16));
- EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
-
enop = enp->en_enop;
if ((rc = enop->eno_probe(enp)) != 0)
- goto fail2;
+ goto fail1;
if ((rc = efx_phy_probe(enp)) != 0)
- goto fail3;
+ goto fail2;
enp->en_mod_flags |= EFX_MOD_PROBE;
return (0);
-fail3:
- EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
enop->eno_unprobe(enp);
-fail2:
- EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, int, rc);
@@ -376,6 +448,105 @@ efx_nic_pcie_extended_sync(
#endif /* EFSYS_OPT_PCIE_TUNE */
__checkReturn int
+efx_nic_set_drv_limits(
+ __inout efx_nic_t *enp,
+ __in efx_drv_limits_t *edlp)
+{
+ efx_nic_ops_t *enop = enp->en_enop;
+ int 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, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_nic_get_bar_region(
+ __in efx_nic_t *enp,
+ __in efx_nic_region_t region,
+ __out uint32_t *offsetp,
+ __out size_t *sizep)
+{
+ efx_nic_ops_t *enop = enp->en_enop;
+ int 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, int, rc);
+
+ return (rc);
+}
+
+
+ __checkReturn int
+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)
+{
+ efx_nic_ops_t *enop = enp->en_enop;
+ efx_nic_cfg_t *encp = &enp->en_nic_cfg;
+ int 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, int, rc);
+
+ return (rc);
+}
+
+
+ __checkReturn int
efx_nic_init(
__in efx_nic_t *enp)
{
@@ -679,3 +850,191 @@ fail1:
}
#endif /* EFSYS_OPT_DIAG */
+
+#if EFSYS_OPT_LOOPBACK
+
+extern void
+efx_loopback_mask(
+ __in efx_loopback_kind_t loopback_kind,
+ __out efx_qword_t *maskp)
+{
+ efx_qword_t mask;
+
+ EFSYS_ASSERT3U(loopback_kind, <, EFX_LOOPBACK_NKINDS);
+ EFSYS_ASSERT(maskp != NULL);
+
+ /* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_NONE == EFX_LOOPBACK_OFF);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_DATA == EFX_LOOPBACK_DATA);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMAC == EFX_LOOPBACK_GMAC);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII == EFX_LOOPBACK_XGMII);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGXS == EFX_LOOPBACK_XGXS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI == EFX_LOOPBACK_XAUI);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII == EFX_LOOPBACK_GMII);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII == EFX_LOOPBACK_SGMII);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGBR == EFX_LOOPBACK_XGBR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI == EFX_LOOPBACK_XFI);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_FAR == EFX_LOOPBACK_XAUI_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_FAR == EFX_LOOPBACK_GMII_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII_FAR == EFX_LOOPBACK_SGMII_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_FAR == EFX_LOOPBACK_XFI_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GPHY == EFX_LOOPBACK_GPHY);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS == EFX_LOOPBACK_PHY_XS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PCS == EFX_LOOPBACK_PCS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMAPMD == EFX_LOOPBACK_PMA_PMD);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XPORT == EFX_LOOPBACK_XPORT);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII_WS == EFX_LOOPBACK_XGMII_WS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS == EFX_LOOPBACK_XAUI_WS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_FAR ==
+ EFX_LOOPBACK_XAUI_WS_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_WS_NEAR ==
+ EFX_LOOPBACK_XAUI_WS_NEAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_WS == EFX_LOOPBACK_GMII_WS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS == EFX_LOOPBACK_XFI_WS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_WS_FAR ==
+ EFX_LOOPBACK_XFI_WS_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS_WS == EFX_LOOPBACK_PHYXS_WS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT == EFX_LOOPBACK_PMA_INT);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_NEAR == EFX_LOOPBACK_SD_NEAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FAR == EFX_LOOPBACK_SD_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMA_INT_WS ==
+ EFX_LOOPBACK_PMA_INT_WS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP2_WS ==
+ EFX_LOOPBACK_SD_FEP2_WS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP1_5_WS ==
+ EFX_LOOPBACK_SD_FEP1_5_WS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FEP_WS == EFX_LOOPBACK_SD_FEP_WS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SD_FES_WS == EFX_LOOPBACK_SD_FES_WS);
+
+ /* Build bitmask of possible loopback types */
+ EFX_ZERO_QWORD(mask);
+
+ if ((loopback_kind == EFX_LOOPBACK_KIND_OFF) ||
+ (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_OFF);
+ }
+
+ if ((loopback_kind == EFX_LOOPBACK_KIND_MAC) ||
+ (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
+ /*
+ * The "MAC" grouping has historically been used by drivers to
+ * mean loopbacks supported by on-chip hardware. Keep that
+ * meaning here, and include on-chip PHY layer loopbacks.
+ */
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_DATA);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMAC);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGMII);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGXS);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XGBR);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XAUI_FAR);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GMII_FAR);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SGMII_FAR);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_XFI_FAR);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_INT);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_NEAR);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_SD_FAR);
+ }
+
+ if ((loopback_kind == EFX_LOOPBACK_KIND_PHY) ||
+ (loopback_kind == EFX_LOOPBACK_KIND_ALL)) {
+ /*
+ * The "PHY" grouping has historically been used by drivers to
+ * mean loopbacks supported by off-chip hardware. Keep that
+ * meaning here.
+ */
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_GPHY);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PHY_XS);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PCS);
+ EFX_SET_QWORD_BIT(mask, EFX_LOOPBACK_PMA_PMD);
+ }
+
+ *maskp = mask;
+}
+
+__checkReturn int
+efx_mcdi_get_loopback_modes(
+ __in efx_nic_t *enp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_LOOPBACK_MODES_IN_LEN,
+ MC_CMD_GET_LOOPBACK_MODES_OUT_LEN)];
+ efx_qword_t mask;
+ efx_qword_t modes;
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_LOOPBACK_MODES_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_LOOPBACK_MODES_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used <
+ MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST +
+ MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ /*
+ * We assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespaces agree
+ * in efx_loopback_mask() and in siena_phy.c:siena_phy_get_link().
+ */
+ efx_loopback_mask(EFX_LOOPBACK_KIND_ALL, &mask);
+
+ EFX_AND_QWORD(mask,
+ *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_SUGGESTED));
+
+ modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_100M);
+ EFX_AND_QWORD(modes, mask);
+ encp->enc_loopback_types[EFX_LINK_100FDX] = modes;
+
+ modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_1G);
+ EFX_AND_QWORD(modes, mask);
+ encp->enc_loopback_types[EFX_LINK_1000FDX] = modes;
+
+ modes = *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_10G);
+ EFX_AND_QWORD(modes, mask);
+ encp->enc_loopback_types[EFX_LINK_10000FDX] = modes;
+
+ if (req.emr_out_length_used >=
+ MC_CMD_GET_LOOPBACK_MODES_OUT_40G_OFST +
+ MC_CMD_GET_LOOPBACK_MODES_OUT_40G_LEN) {
+ /* Response includes 40G loopback modes */
+ modes =
+ *MCDI_OUT2(req, efx_qword_t, GET_LOOPBACK_MODES_OUT_40G);
+ EFX_AND_QWORD(modes, mask);
+ encp->enc_loopback_types[EFX_LINK_40000FDX] = modes;
+ }
+
+ EFX_ZERO_QWORD(modes);
+ EFX_SET_QWORD_BIT(modes, EFX_LOOPBACK_OFF);
+ EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_100FDX]);
+ EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_1000FDX]);
+ EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_10000FDX]);
+ EFX_OR_QWORD(modes, encp->enc_loopback_types[EFX_LINK_40000FDX]);
+ encp->enc_loopback_types[EFX_LINK_UNKNOWN] = modes;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_LOOPBACK */
diff --git a/sys/dev/sfxge/common/efx_nvram.c b/sys/dev/sfxge/common/efx_nvram.c
index 2df9bb9..82bb1d9 100644
--- a/sys/dev/sfxge/common/efx_nvram.c
+++ b/sys/dev/sfxge/common/efx_nvram.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -36,7 +41,7 @@ __FBSDID("$FreeBSD$");
#if EFSYS_OPT_FALCON
-static efx_nvram_ops_t __cs __efx_nvram_falcon_ops = {
+static efx_nvram_ops_t __efx_nvram_falcon_ops = {
#if EFSYS_OPT_DIAG
falcon_nvram_test, /* envo_test */
#endif /* EFSYS_OPT_DIAG */
@@ -54,7 +59,7 @@ static efx_nvram_ops_t __cs __efx_nvram_falcon_ops = {
#if EFSYS_OPT_SIENA
-static efx_nvram_ops_t __cs __efx_nvram_siena_ops = {
+static efx_nvram_ops_t __efx_nvram_siena_ops = {
#if EFSYS_OPT_DIAG
siena_nvram_test, /* envo_test */
#endif /* EFSYS_OPT_DIAG */
@@ -70,6 +75,24 @@ static efx_nvram_ops_t __cs __efx_nvram_siena_ops = {
#endif /* EFSYS_OPT_SIENA */
+#if EFSYS_OPT_HUNTINGTON
+
+static efx_nvram_ops_t __efx_nvram_hunt_ops = {
+#if EFSYS_OPT_DIAG
+ hunt_nvram_test, /* envo_test */
+#endif /* EFSYS_OPT_DIAG */
+ hunt_nvram_size, /* envo_size */
+ hunt_nvram_get_version, /* envo_get_version */
+ hunt_nvram_rw_start, /* envo_rw_start */
+ hunt_nvram_read_chunk, /* envo_read_chunk */
+ hunt_nvram_erase, /* envo_erase */
+ hunt_nvram_write_chunk, /* envo_write_chunk */
+ hunt_nvram_rw_finish, /* envo_rw_finish */
+ hunt_nvram_set_version, /* envo_set_version */
+};
+
+#endif /* EFSYS_OPT_HUNTINGTON */
+
__checkReturn int
efx_nvram_init(
__in efx_nic_t *enp)
@@ -94,6 +117,12 @@ efx_nvram_init(
break;
#endif /* EFSYS_OPT_SIENA */
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ envop = (efx_nvram_ops_t *)&__efx_nvram_hunt_ops;
+ break;
+#endif /* EFSYS_OPT_HUNTINGTON */
+
default:
EFSYS_ASSERT(0);
rc = ENOTSUP;
@@ -329,7 +358,7 @@ efx_nvram_rw_finish(
efx_nvram_set_version(
__in efx_nic_t *enp,
__in efx_nvram_type_t type,
- __out uint16_t version[4])
+ __in_ecount(4) uint16_t version[4])
{
efx_nvram_ops_t *envop = enp->en_envop;
int rc;
@@ -373,3 +402,486 @@ efx_nvram_fini(
}
#endif /* EFSYS_OPT_NVRAM */
+
+#if EFSYS_OPT_NVRAM || EFSYS_OPT_VPD
+
+/*
+ * Internal MCDI request handling
+ */
+
+ __checkReturn int
+efx_mcdi_nvram_partitions(
+ __in efx_nic_t *enp,
+ __out_bcount(size) caddr_t data,
+ __in size_t size,
+ __out unsigned int *npartnp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_NVRAM_PARTITIONS_IN_LEN,
+ MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX)];
+ unsigned int npartn;
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_NVRAM_PARTITIONS;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_NVRAM_PARTITIONS_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_NVRAM_PARTITIONS_OUT_LENMIN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+ npartn = MCDI_OUT_DWORD(req, NVRAM_PARTITIONS_OUT_NUM_PARTITIONS);
+
+ if (req.emr_out_length_used < MC_CMD_NVRAM_PARTITIONS_OUT_LEN(npartn)) {
+ rc = ENOENT;
+ goto fail3;
+ }
+
+ if (size < npartn * sizeof (uint32_t)) {
+ rc = ENOSPC;
+ goto fail3;
+ }
+
+ *npartnp = npartn;
+
+ memcpy(data,
+ MCDI_OUT2(req, uint32_t, NVRAM_PARTITIONS_OUT_TYPE_ID),
+ (npartn * sizeof (uint32_t)));
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_nvram_metadata(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __out uint32_t *subtypep,
+ __out_ecount(4) uint16_t version[4],
+ __out_bcount_opt(size) char *descp,
+ __in size_t size)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_NVRAM_METADATA_IN_LEN,
+ MC_CMD_NVRAM_METADATA_OUT_LENMAX)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_NVRAM_METADATA;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_NVRAM_METADATA_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_NVRAM_METADATA_OUT_LENMAX;
+
+ MCDI_IN_SET_DWORD(req, NVRAM_METADATA_IN_TYPE, partn);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_NVRAM_METADATA_OUT_LENMIN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
+ NVRAM_METADATA_OUT_SUBTYPE_VALID)) {
+ *subtypep = MCDI_OUT_DWORD(req, NVRAM_METADATA_OUT_SUBTYPE);
+ } else {
+ *subtypep = 0;
+ }
+
+ if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
+ NVRAM_METADATA_OUT_VERSION_VALID)) {
+ version[0] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_W);
+ version[1] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_X);
+ version[2] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_Y);
+ version[3] = MCDI_OUT_WORD(req, NVRAM_METADATA_OUT_VERSION_Z);
+ } else {
+ version[0] = version[1] = version[2] = version[3] = 0;
+ }
+
+ if (MCDI_OUT_DWORD_FIELD(req, NVRAM_METADATA_OUT_FLAGS,
+ NVRAM_METADATA_OUT_DESCRIPTION_VALID)) {
+ /* Return optional descrition string */
+ if ((descp != NULL) && (size > 0)) {
+ size_t desclen;
+
+ descp[0] = '\0';
+ desclen = (req.emr_out_length_used
+ - MC_CMD_NVRAM_METADATA_OUT_LEN(0));
+
+ EFSYS_ASSERT3U(desclen, <=,
+ MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_MAXNUM);
+
+ if (size < desclen) {
+ rc = ENOSPC;
+ goto fail3;
+ }
+
+ memcpy(descp, MCDI_OUT2(req, char,
+ NVRAM_METADATA_OUT_DESCRIPTION),
+ desclen);
+
+ /* Ensure string is NUL terminated */
+ descp[desclen] = '\0';
+ }
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_nvram_info(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __out_opt size_t *sizep,
+ __out_opt uint32_t *addressp,
+ __out_opt uint32_t *erase_sizep)
+{
+ uint8_t payload[MAX(MC_CMD_NVRAM_INFO_IN_LEN,
+ MC_CMD_NVRAM_INFO_OUT_LEN)];
+ efx_mcdi_req_t req;
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_NVRAM_INFO;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_NVRAM_INFO_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_NVRAM_INFO_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, NVRAM_INFO_IN_TYPE, partn);
+
+ efx_mcdi_execute_quiet(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_NVRAM_INFO_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ if (sizep)
+ *sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_SIZE);
+
+ if (addressp)
+ *addressp = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_PHYSADDR);
+
+ if (erase_sizep)
+ *erase_sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_ERASESIZE);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_nvram_update_start(
+ __in efx_nic_t *enp,
+ __in uint32_t partn)
+{
+ uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_START_IN_LEN,
+ MC_CMD_NVRAM_UPDATE_START_OUT_LEN)];
+ efx_mcdi_req_t req;
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_NVRAM_UPDATE_START;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_NVRAM_UPDATE_START_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_NVRAM_UPDATE_START_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_START_IN_TYPE, partn);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_nvram_read(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in uint32_t offset,
+ __out_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_NVRAM_READ_IN_LEN,
+ MC_CMD_NVRAM_READ_OUT_LENMAX)];
+ int rc;
+
+ if (size > MC_CMD_NVRAM_READ_OUT_LENMAX) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_NVRAM_READ;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_NVRAM_READ_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_NVRAM_READ_OUT_LENMAX;
+
+ MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_TYPE, partn);
+ MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_OFFSET, offset);
+ MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_LENGTH, size);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_NVRAM_READ_OUT_LEN(size)) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ memcpy(data,
+ MCDI_OUT2(req, uint8_t, NVRAM_READ_OUT_READ_BUFFER),
+ size);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_nvram_erase(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in uint32_t offset,
+ __in size_t size)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_NVRAM_ERASE_IN_LEN,
+ MC_CMD_NVRAM_ERASE_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_NVRAM_ERASE;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_NVRAM_ERASE_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_NVRAM_ERASE_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_TYPE, partn);
+ MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_OFFSET, offset);
+ MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_LENGTH, size);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_nvram_write(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in uint32_t offset,
+ __out_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_NVRAM_WRITE_IN_LENMAX,
+ MC_CMD_NVRAM_WRITE_OUT_LEN)];
+ int rc;
+
+ if (size > MC_CMD_NVRAM_WRITE_IN_LENMAX) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_NVRAM_WRITE;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_NVRAM_WRITE_IN_LEN(size);
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_NVRAM_WRITE_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_TYPE, partn);
+ MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_OFFSET, offset);
+ MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_LENGTH, size);
+
+ memcpy(MCDI_IN2(req, uint8_t, NVRAM_WRITE_IN_WRITE_BUFFER),
+ data, size);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_mcdi_nvram_update_finish(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in boolean_t reboot)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN,
+ MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_NVRAM_UPDATE_FINISH;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_IN_TYPE, partn);
+ MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_IN_REBOOT, reboot);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+#if EFSYS_OPT_DIAG
+
+ __checkReturn int
+efx_mcdi_nvram_test(
+ __in efx_nic_t *enp,
+ __in uint32_t partn)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_NVRAM_TEST_IN_LEN,
+ MC_CMD_NVRAM_TEST_OUT_LEN)];
+ int result;
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_NVRAM_TEST;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_NVRAM_TEST_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_NVRAM_TEST_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, NVRAM_TEST_IN_TYPE, partn);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_NVRAM_TEST_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ result = MCDI_OUT_DWORD(req, NVRAM_TEST_OUT_RESULT);
+ if (result == MC_CMD_NVRAM_TEST_FAIL) {
+
+ EFSYS_PROBE1(nvram_test_failure, int, partn);
+
+ rc = (EINVAL);
+ goto fail3;
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_DIAG */
+
+
+#endif /* EFSYS_OPT_NVRAM || EFSYS_OPT_VPD */
diff --git a/sys/dev/sfxge/common/efx_phy.c b/sys/dev/sfxge/common/efx_phy.c
index bb34ea7..5d18dc7 100644
--- a/sys/dev/sfxge/common/efx_phy.c
+++ b/sys/dev/sfxge/common/efx_phy.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -68,7 +73,7 @@ __FBSDID("$FreeBSD$");
#endif
#if EFSYS_OPT_PHY_NULL
-static efx_phy_ops_t __cs __efx_phy_null_ops = {
+static efx_phy_ops_t __efx_phy_null_ops = {
NULL, /* epo_power */
nullphy_reset, /* epo_reset */
nullphy_reconfigure, /* epo_reconfigure */
@@ -86,16 +91,17 @@ static efx_phy_ops_t __cs __efx_phy_null_ops = {
nullphy_prop_get, /* epo_prop_get */
nullphy_prop_set, /* epo_prop_set */
#endif /* EFSYS_OPT_PHY_PROPS */
-#if EFSYS_OPT_PHY_BIST
+#if EFSYS_OPT_BIST
+ NULL, /* epo_bist_enable_offline */
NULL, /* epo_bist_start */
NULL, /* epo_bist_poll */
NULL, /* epo_bist_stop */
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
};
#endif /* EFSYS_OPT_PHY_NULL */
#if EFSYS_OPT_PHY_QT2022C2
-static efx_phy_ops_t __cs __efx_phy_qt2022c2_ops = {
+static efx_phy_ops_t __efx_phy_qt2022c2_ops = {
NULL, /* epo_power */
qt2022c2_reset, /* epo_reset */
qt2022c2_reconfigure, /* epo_reconfigure */
@@ -113,16 +119,17 @@ static efx_phy_ops_t __cs __efx_phy_qt2022c2_ops = {
qt2022c2_prop_get, /* epo_prop_get */
qt2022c2_prop_set, /* epo_prop_set */
#endif /* EFSYS_OPT_PHY_PROPS */
-#if EFSYS_OPT_PHY_BIST
+#if EFSYS_OPT_BIST
+ NULL, /* epo_bist_enable_offline */
NULL, /* epo_bist_start */
NULL, /* epo_bist_poll */
NULL, /* epo_bist_stop */
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
};
#endif /* EFSYS_OPT_PHY_QT2022C2 */
#if EFSYS_OPT_PHY_SFX7101
-static efx_phy_ops_t __cs __efx_phy_sfx7101_ops = {
+static efx_phy_ops_t __efx_phy_sfx7101_ops = {
sfx7101_power, /* epo_power */
sfx7101_reset, /* epo_reset */
sfx7101_reconfigure, /* epo_reconfigure */
@@ -140,16 +147,17 @@ static efx_phy_ops_t __cs __efx_phy_sfx7101_ops = {
sfx7101_prop_get, /* epo_prop_get */
sfx7101_prop_set, /* epo_prop_set */
#endif /* EFSYS_OPT_PHY_PROPS */
-#if EFSYS_OPT_PHY_BIST
+#if EFSYS_OPT_BIST
+ NULL, /* epo_bist_enable_offline */
NULL, /* epo_bist_start */
NULL, /* epo_bist_poll */
NULL, /* epo_bist_stop */
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
};
#endif /* EFSYS_OPT_PHY_SFX7101 */
#if EFSYS_OPT_PHY_TXC43128
-static efx_phy_ops_t __cs __efx_phy_txc43128_ops = {
+static efx_phy_ops_t __efx_phy_txc43128_ops = {
NULL, /* epo_power */
txc43128_reset, /* epo_reset */
txc43128_reconfigure, /* epo_reconfigure */
@@ -167,16 +175,17 @@ static efx_phy_ops_t __cs __efx_phy_txc43128_ops = {
txc43128_prop_get, /* epo_prop_get */
txc43128_prop_set, /* epo_prop_set */
#endif /* EFSYS_OPT_PHY_PROPS */
-#if EFSYS_OPT_PHY_BIST
+#if EFSYS_OPT_BIST
+ NULL, /* epo_bist_enable_offline */
NULL, /* epo_bist_start */
NULL, /* epo_bist_poll */
NULL, /* epo_bist_stop */
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
};
#endif /* EFSYS_OPT_PHY_TXC43128 */
#if EFSYS_OPT_PHY_SFT9001
-static efx_phy_ops_t __cs __efx_phy_sft9001_ops = {
+static efx_phy_ops_t __efx_phy_sft9001_ops = {
NULL, /* epo_power */
sft9001_reset, /* epo_reset */
sft9001_reconfigure, /* epo_reconfigure */
@@ -194,16 +203,17 @@ static efx_phy_ops_t __cs __efx_phy_sft9001_ops = {
sft9001_prop_get, /* epo_prop_get */
sft9001_prop_set, /* epo_prop_set */
#endif /* EFSYS_OPT_PHY_PROPS */
-#if EFSYS_OPT_PHY_BIST
+#if EFSYS_OPT_BIST
+ NULL, /* epo_bist_enable_offline */
sft9001_bist_start, /* epo_bist_start */
sft9001_bist_poll, /* epo_bist_poll */
sft9001_bist_stop, /* epo_bist_stop */
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
};
#endif /* EFSYS_OPT_PHY_SFT9001 */
#if EFSYS_OPT_PHY_QT2025C
-static efx_phy_ops_t __cs __efx_phy_qt2025c_ops = {
+static efx_phy_ops_t __efx_phy_qt2025c_ops = {
NULL, /* epo_power */
qt2025c_reset, /* epo_reset */
qt2025c_reconfigure, /* epo_reconfigure */
@@ -221,16 +231,17 @@ static efx_phy_ops_t __cs __efx_phy_qt2025c_ops = {
qt2025c_prop_get, /* epo_prop_get */
qt2025c_prop_set, /* epo_prop_set */
#endif /* EFSYS_OPT_PHY_PROPS */
-#if EFSYS_OPT_PHY_BIST
+#if EFSYS_OPT_BIST
+ NULL, /* epo_bist_enable_offline */
NULL, /* epo_bist_start */
NULL, /* epo_bist_poll */
NULL, /* epo_bist_stop */
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
};
#endif /* EFSYS_OPT_PHY_QT2025C */
#if EFSYS_OPT_SIENA
-static efx_phy_ops_t __cs __efx_phy_siena_ops = {
+static efx_phy_ops_t __efx_phy_siena_ops = {
siena_phy_power, /* epo_power */
NULL, /* epo_reset */
siena_phy_reconfigure, /* epo_reconfigure */
@@ -248,14 +259,43 @@ static efx_phy_ops_t __cs __efx_phy_siena_ops = {
siena_phy_prop_get, /* epo_prop_get */
siena_phy_prop_set, /* epo_prop_set */
#endif /* EFSYS_OPT_PHY_PROPS */
-#if EFSYS_OPT_PHY_BIST
+#if EFSYS_OPT_BIST
+ NULL, /* epo_bist_enable_offline */
siena_phy_bist_start, /* epo_bist_start */
siena_phy_bist_poll, /* epo_bist_poll */
siena_phy_bist_stop, /* epo_bist_stop */
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
};
#endif /* EFSYS_OPT_SIENA */
+#if EFSYS_OPT_HUNTINGTON
+static efx_phy_ops_t __efx_phy_hunt_ops = {
+ hunt_phy_power, /* epo_power */
+ NULL, /* epo_reset */
+ hunt_phy_reconfigure, /* epo_reconfigure */
+ hunt_phy_verify, /* epo_verify */
+ NULL, /* epo_uplink_check */
+ NULL, /* epo_downlink_check */
+ hunt_phy_oui_get, /* epo_oui_get */
+#if EFSYS_OPT_PHY_STATS
+ hunt_phy_stats_update, /* epo_stats_update */
+#endif /* EFSYS_OPT_PHY_STATS */
+#if EFSYS_OPT_PHY_PROPS
+#if EFSYS_OPT_NAMES
+ hunt_phy_prop_name, /* epo_prop_name */
+#endif
+ hunt_phy_prop_get, /* epo_prop_get */
+ hunt_phy_prop_set, /* epo_prop_set */
+#endif /* EFSYS_OPT_PHY_PROPS */
+#if EFSYS_OPT_BIST
+ hunt_bist_enable_offline, /* epo_bist_enable_offline */
+ hunt_bist_start, /* epo_bist_start */
+ hunt_bist_poll, /* epo_bist_poll */
+ hunt_bist_stop, /* epo_bist_stop */
+#endif /* EFSYS_OPT_BIST */
+};
+#endif /* EFSYS_OPT_HUNTINGTON */
+
__checkReturn int
efx_phy_probe(
__in efx_nic_t *enp)
@@ -317,6 +357,11 @@ efx_phy_probe(
epop = (efx_phy_ops_t *)&__efx_phy_siena_ops;
break;
#endif /* EFSYS_OPT_SIENA */
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ epop = (efx_phy_ops_t *)&__efx_phy_hunt_ops;
+ break;
+#endif /* EFSYS_OPT_HUNTINGTON */
default:
rc = ENOTSUP;
goto fail1;
@@ -516,8 +561,8 @@ efx_phy_media_type_get(
#if EFSYS_OPT_NAMES
-/* START MKCONFIG GENERATED PhyStatNamesBlock 271268f3da0e804f */
-static const char __cs * __cs __efx_phy_stat_name[] = {
+/* START MKCONFIG GENERATED PhyStatNamesBlock d5f79b4bc2c050fe */
+static const char *__efx_phy_stat_name[] = {
"oui",
"pma_pmd_link_up",
"pma_pmd_rx_fault",
@@ -568,7 +613,7 @@ static const char __cs * __cs __efx_phy_stat_name[] = {
/* END MKCONFIG GENERATED PhyStatNamesBlock */
- const char __cs *
+ const char *
efx_phy_stat_name(
__in efx_nic_t *enp,
__in efx_phy_stat_t type)
@@ -602,7 +647,7 @@ efx_phy_stats_update(
#if EFSYS_OPT_PHY_PROPS
#if EFSYS_OPT_NAMES
- const char __cs *
+ const char *
efx_phy_prop_name(
__in efx_nic_t *enp,
__in unsigned int id)
@@ -649,23 +694,51 @@ efx_phy_prop_set(
}
#endif /* EFSYS_OPT_PHY_STATS */
-#if EFSYS_OPT_PHY_BIST
+#if EFSYS_OPT_BIST
+
+ __checkReturn int
+efx_bist_enable_offline(
+ __in efx_nic_t *enp)
+{
+ efx_port_t *epp = &(enp->en_port);
+ efx_phy_ops_t *epop = epp->ep_epop;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+
+ if (epop->epo_bist_enable_offline == NULL) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+ if ((rc = epop->epo_bist_enable_offline(enp)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+
+}
__checkReturn int
-efx_phy_bist_start(
+efx_bist_start(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type)
+ __in efx_bist_type_t type)
{
efx_port_t *epp = &(enp->en_port);
efx_phy_ops_t *epop = epp->ep_epop;
int rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
- EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN);
- EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES);
- EFSYS_ASSERT3U(epp->ep_current_bist, ==, EFX_PHY_BIST_TYPE_UNKNOWN);
+ EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
+ EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
+ EFSYS_ASSERT3U(epp->ep_current_bist, ==, EFX_BIST_TYPE_UNKNOWN);
if (epop->epo_bist_start == NULL) {
rc = ENOTSUP;
@@ -688,10 +761,10 @@ fail1:
}
__checkReturn int
-efx_phy_bist_poll(
+efx_bist_poll(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type,
- __out efx_phy_bist_result_t *resultp,
+ __in efx_bist_type_t type,
+ __out efx_bist_result_t *resultp,
__out_opt uint32_t *value_maskp,
__out_ecount_opt(count) unsigned long *valuesp,
__in size_t count)
@@ -701,10 +774,9 @@ efx_phy_bist_poll(
int rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PORT);
- EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN);
- EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES);
+ EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
+ EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
EFSYS_ASSERT(epop->epo_bist_poll != NULL);
@@ -728,18 +800,17 @@ fail1:
}
void
-efx_phy_bist_stop(
+efx_bist_stop(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type)
+ __in efx_bist_type_t type)
{
efx_port_t *epp = &(enp->en_port);
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);
- EFSYS_ASSERT3U(type, !=, EFX_PHY_BIST_TYPE_UNKNOWN);
- EFSYS_ASSERT3U(type, <, EFX_PHY_BIST_TYPE_NTYPES);
+ EFSYS_ASSERT3U(type, !=, EFX_BIST_TYPE_UNKNOWN);
+ EFSYS_ASSERT3U(type, <, EFX_BIST_TYPE_NTYPES);
EFSYS_ASSERT3U(epp->ep_current_bist, ==, type);
EFSYS_ASSERT(epop->epo_bist_stop != NULL);
@@ -747,10 +818,10 @@ efx_phy_bist_stop(
if (epop->epo_bist_stop != NULL)
epop->epo_bist_stop(enp, type);
- epp->ep_current_bist = EFX_PHY_BIST_TYPE_UNKNOWN;
+ epp->ep_current_bist = EFX_BIST_TYPE_UNKNOWN;
}
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
void
efx_phy_unprobe(
__in efx_nic_t *enp)
diff --git a/sys/dev/sfxge/common/efx_phy_ids.h b/sys/dev/sfxge/common/efx_phy_ids.h
new file mode 100644
index 0000000..e062519
--- /dev/null
+++ b/sys/dev/sfxge/common/efx_phy_ids.h
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 2013-2015 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.
+ *
+ * $FreeBSD$
+ */
+
+#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/sys/dev/sfxge/common/efx_port.c b/sys/dev/sfxge/common/efx_port.c
index 0b67d06..a750c15 100644
--- a/sys/dev/sfxge/common/efx_port.c
+++ b/sys/dev/sfxge/common/efx_port.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -61,6 +66,9 @@ efx_port_init(
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.
@@ -96,7 +104,7 @@ fail1:
__checkReturn int
efx_port_poll(
__in efx_nic_t *enp,
- __out efx_link_mode_t *link_modep)
+ __out_opt efx_link_mode_t *link_modep)
{
efx_port_t *epp = &(enp->en_port);
efx_mac_ops_t *emop = epp->ep_emop;
@@ -141,7 +149,9 @@ efx_port_loopback_set(
EFSYS_ASSERT(emop != NULL);
EFSYS_ASSERT(link_mode < EFX_LINK_NMODES);
- if ((1 << loopback_type) & ~encp->enc_loopback_types[link_mode]) {
+
+ if (EFX_TEST_QWORD_BIT(encp->enc_loopback_types[link_mode],
+ loopback_type) == 0) {
rc = ENOTSUP;
goto fail1;
}
@@ -165,7 +175,7 @@ fail1:
#if EFSYS_OPT_NAMES
-static const char __cs * __cs __efx_loopback_type_name[] = {
+static const char *__efx_loopback_type_name[] = {
"OFF",
"DATA",
"GMAC",
@@ -184,13 +194,33 @@ static const char __cs * __cs __efx_loopback_type_name[] = {
"PHY_XS",
"PCS",
"PMA_PMD",
+ "XPORT",
+ "XGMII_WS",
+ "XAUI_WS",
+ "XAUI_WS_FAR",
+ "XAUI_WS_NEAR",
+ "GMII_WS",
+ "XFI_WS",
+ "XFI_WS_FAR",
+ "PHYXS_WS",
+ "PMA_INT",
+ "SD_NEAR",
+ "SD_FAR",
+ "PMA_INT_WS",
+ "SD_FEP2_WS",
+ "SD_FEP1_5_WS",
+ "SD_FEP_WS",
+ "SD_FES_WS",
};
- __checkReturn const char __cs *
+ __checkReturn const char *
efx_loopback_type_name(
__in efx_nic_t *enp,
__in efx_loopback_type_t type)
{
+ EFX_STATIC_ASSERT(EFX_ARRAY_SIZE(__efx_loopback_type_name) ==
+ EFX_LOOPBACK_NTYPES);
+
_NOTE(ARGUNUSED(enp))
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(type, <, EFX_LOOPBACK_NTYPES);
diff --git a/sys/dev/sfxge/common/efx_regs.h b/sys/dev/sfxge/common/efx_regs.h
index 4019663..5ece431 100644
--- a/sys/dev/sfxge/common/efx_regs.h
+++ b/sys/dev/sfxge/common/efx_regs.h
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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.
*
* $FreeBSD$
*/
@@ -3854,7 +3859,7 @@ extern "C" {
*/
-#define FR_AZ_TX_PACE_TBL_OFST FR_BZ_TX_PACE_TBL_OFST
+#define FR_AZ_TX_PACE_TBL_OFST FR_BZ_TX_PACE_TBL_OFST
#ifdef __cplusplus
diff --git a/sys/dev/sfxge/common/efx_regs_ef10.h b/sys/dev/sfxge/common/efx_regs_ef10.h
index c4a6d0e..8401726 100644
--- a/sys/dev/sfxge/common/efx_regs_ef10.h
+++ b/sys/dev/sfxge/common/efx_regs_ef10.h
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2010 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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.
*
* $FreeBSD$
*/
@@ -34,11 +39,13 @@ extern "C" {
/*
* BIU_HW_REV_ID_REG(32bit):
- *
+ *
*/
-#define ER_DZ_BIU_HW_REV_ID_REG 0x00000000
+#define ER_DZ_BIU_HW_REV_ID_REG_OFST 0x00000000
/* hunta0=pcie_pf_bar2 */
+#define ER_DZ_BIU_HW_REV_ID_REG_RESET 0xeb14face
+
#define ERF_DZ_HW_REV_ID_LBN 0
#define ERF_DZ_HW_REV_ID_WIDTH 32
@@ -46,13 +53,15 @@ extern "C" {
/*
* BIU_MC_SFT_STATUS_REG(32bit):
- *
+ *
*/
-#define ER_DZ_BIU_MC_SFT_STATUS_REG 0x00000010
+#define ER_DZ_BIU_MC_SFT_STATUS_REG_OFST 0x00000010
/* hunta0=pcie_pf_bar2 */
#define ER_DZ_BIU_MC_SFT_STATUS_REG_STEP 4
#define ER_DZ_BIU_MC_SFT_STATUS_REG_ROWS 8
+#define ER_DZ_BIU_MC_SFT_STATUS_REG_RESET 0x1111face
+
#define ERF_DZ_MC_SFT_STATUS_LBN 0
#define ERF_DZ_MC_SFT_STATUS_WIDTH 32
@@ -60,11 +69,13 @@ extern "C" {
/*
* BIU_INT_ISR_REG(32bit):
- *
+ *
*/
-#define ER_DZ_BIU_INT_ISR_REG 0x00000090
+#define ER_DZ_BIU_INT_ISR_REG_OFST 0x00000090
/* hunta0=pcie_pf_bar2 */
+#define ER_DZ_BIU_INT_ISR_REG_RESET 0x0
+
#define ERF_DZ_ISR_REG_LBN 0
#define ERF_DZ_ISR_REG_WIDTH 32
@@ -72,11 +83,13 @@ extern "C" {
/*
* MC_DB_LWRD_REG(32bit):
- *
+ *
*/
-#define ER_DZ_MC_DB_LWRD_REG 0x00000200
+#define ER_DZ_MC_DB_LWRD_REG_OFST 0x00000200
/* hunta0=pcie_pf_bar2 */
+#define ER_DZ_MC_DB_LWRD_REG_RESET 0x0
+
#define ERF_DZ_MC_DOORBELL_L_LBN 0
#define ERF_DZ_MC_DOORBELL_L_WIDTH 32
@@ -84,11 +97,13 @@ extern "C" {
/*
* MC_DB_HWRD_REG(32bit):
- *
+ *
*/
-#define ER_DZ_MC_DB_HWRD_REG 0x00000204
+#define ER_DZ_MC_DB_HWRD_REG_OFST 0x00000204
/* hunta0=pcie_pf_bar2 */
+#define ER_DZ_MC_DB_HWRD_REG_RESET 0x0
+
#define ERF_DZ_MC_DOORBELL_H_LBN 0
#define ERF_DZ_MC_DOORBELL_H_WIDTH 32
@@ -96,13 +111,15 @@ extern "C" {
/*
* EVQ_RPTR_REG(32bit):
- *
+ *
*/
-#define ER_DZ_EVQ_RPTR_REG 0x00000400
+#define ER_DZ_EVQ_RPTR_REG_OFST 0x00000400
/* hunta0=pcie_pf_bar2 */
-#define ER_DZ_EVQ_RPTR_REG_STEP 4096
+#define ER_DZ_EVQ_RPTR_REG_STEP 8192
#define ER_DZ_EVQ_RPTR_REG_ROWS 2048
+#define ER_DZ_EVQ_RPTR_REG_RESET 0x0
+
#define ERF_DZ_EVQ_RPTR_VLD_LBN 15
#define ERF_DZ_EVQ_RPTR_VLD_WIDTH 1
@@ -112,13 +129,15 @@ extern "C" {
/*
* EVQ_TMR_REG(32bit):
- *
+ *
*/
-#define ER_DZ_EVQ_TMR_REG 0x00000420
+#define ER_DZ_EVQ_TMR_REG_OFST 0x00000420
/* hunta0=pcie_pf_bar2 */
-#define ER_DZ_EVQ_TMR_REG_STEP 4096
+#define ER_DZ_EVQ_TMR_REG_STEP 8192
#define ER_DZ_EVQ_TMR_REG_ROWS 2048
+#define ER_DZ_EVQ_TMR_REG_RESET 0x0
+
#define ERF_DZ_TC_TIMER_MODE_LBN 14
#define ERF_DZ_TC_TIMER_MODE_WIDTH 2
@@ -128,28 +147,34 @@ extern "C" {
/*
* RX_DESC_UPD_REG(32bit):
- *
+ *
*/
-#define ER_DZ_RX_DESC_UPD_REG 0x00000830
+#define ER_DZ_RX_DESC_UPD_REG_OFST 0x00000830
/* hunta0=pcie_pf_bar2 */
-#define ER_DZ_RX_DESC_UPD_REG_STEP 4096
+#define ER_DZ_RX_DESC_UPD_REG_STEP 8192
#define ER_DZ_RX_DESC_UPD_REG_ROWS 2048
+#define ER_DZ_RX_DESC_UPD_REG_RESET 0x0
+
#define ERF_DZ_RX_DESC_WPTR_LBN 0
#define ERF_DZ_RX_DESC_WPTR_WIDTH 12
/*
- * TX_DESC_UPD_REG(76bit):
- *
+ * TX_DESC_UPD_REG(96bit):
+ *
*/
-#define ER_DZ_TX_DESC_UPD_REG 0x00000a10
+#define ER_DZ_TX_DESC_UPD_REG_OFST 0x00000a10
/* hunta0=pcie_pf_bar2 */
-#define ER_DZ_TX_DESC_UPD_REG_STEP 4096
+#define ER_DZ_TX_DESC_UPD_REG_STEP 8192
#define ER_DZ_TX_DESC_UPD_REG_ROWS 2048
+#define ER_DZ_TX_DESC_UPD_REG_RESET 0x0
+
+#define ERF_DZ_RSVD_LBN 76
+#define ERF_DZ_RSVD_WIDTH 20
#define ERF_DZ_TX_DESC_WPTR_LBN 64
#define ERF_DZ_TX_DESC_WPTR_WIDTH 12
#define ERF_DZ_TX_DESC_HWORD_LBN 32
@@ -157,14 +182,38 @@ extern "C" {
#define ERF_DZ_TX_DESC_LWORD_LBN 0
#define ERF_DZ_TX_DESC_LWORD_WIDTH 32
+/*
+ * The workaround for bug 35388 requires multiplexing writes through
+ * the ERF_DZ_TX_DESC_WPTR address.
+ * TX_DESC_UPD: 0ppppppppppp (bit 11 lost)
+ * EVQ_RPTR: 1000hhhhhhhh, 1001llllllll (split into high and low bits)
+ * EVQ_TMR: 11mmvvvvvvvv (bits 8:13 of value lost)
+ */
+#define ER_DD_EVQ_INDIRECT_OFST (ER_DZ_TX_DESC_UPD_REG_OFST + 2 * 4)
+#define ER_DD_EVQ_INDIRECT_STEP ER_DZ_TX_DESC_UPD_REG_STEP
+#define ERF_DD_EVQ_IND_RPTR_FLAGS_LBN 8
+#define ERF_DD_EVQ_IND_RPTR_FLAGS_WIDTH 4
+#define EFE_DD_EVQ_IND_RPTR_FLAGS_HIGH 8
+#define EFE_DD_EVQ_IND_RPTR_FLAGS_LOW 9
+#define ERF_DD_EVQ_IND_RPTR_LBN 0
+#define ERF_DD_EVQ_IND_RPTR_WIDTH 8
+#define ERF_DD_EVQ_IND_TIMER_FLAGS_LBN 10
+#define ERF_DD_EVQ_IND_TIMER_FLAGS_WIDTH 2
+#define EFE_DD_EVQ_IND_TIMER_FLAGS 3
+#define ERF_DD_EVQ_IND_TIMER_MODE_LBN 8
+#define ERF_DD_EVQ_IND_TIMER_MODE_WIDTH 2
+#define ERF_DD_EVQ_IND_TIMER_VAL_LBN 0
+#define ERF_DD_EVQ_IND_TIMER_VAL_WIDTH 8
+
/* ES_DRIVER_EV */
#define ESF_DZ_DRV_CODE_LBN 60
#define ESF_DZ_DRV_CODE_WIDTH 4
#define ESF_DZ_DRV_SUB_CODE_LBN 56
#define ESF_DZ_DRV_SUB_CODE_WIDTH 4
-#define ESE_DZ_DRV_TIMER_EV 10
-#define ESE_DZ_DRV_WAKE_UP_EV 6
+#define ESE_DZ_DRV_TIMER_EV 3
+#define ESE_DZ_DRV_START_UP_EV 2
+#define ESE_DZ_DRV_WAKE_UP_EV 1
#define ESF_DZ_DRV_SUB_DATA_DW0_LBN 0
#define ESF_DZ_DRV_SUB_DATA_DW0_WIDTH 32
#define ESF_DZ_DRV_SUB_DATA_DW1_LBN 32
@@ -194,9 +243,9 @@ extern "C" {
/* ES_FF_UMSG_CPU2DL_DESC_FETCH */
-#define ESF_DZ_C2DDF_DSCR_CACHE_RPTR_LBN 112
+#define ESF_DZ_C2DDF_DSCR_CACHE_RPTR_LBN 208
#define ESF_DZ_C2DDF_DSCR_CACHE_RPTR_WIDTH 6
-#define ESF_DZ_C2DDF_QID_LBN 96
+#define ESF_DZ_C2DDF_QID_LBN 160
#define ESF_DZ_C2DDF_QID_WIDTH 11
#define ESF_DZ_C2DDF_DSCR_BASE_PAGE_ID_LBN 64
#define ESF_DZ_C2DDF_DSCR_BASE_PAGE_ID_WIDTH 18
@@ -217,16 +266,16 @@ extern "C" {
/* ES_FF_UMSG_CPU2DL_DESC_PUSH */
+#define ESF_DZ_C2DDP_DSCR_HW_RPTR_LBN 224
+#define ESF_DZ_C2DDP_DSCR_HW_RPTR_WIDTH 12
#define ESF_DZ_C2DDP_DESC_DW0_LBN 128
#define ESF_DZ_C2DDP_DESC_DW0_WIDTH 32
#define ESF_DZ_C2DDP_DESC_DW1_LBN 160
#define ESF_DZ_C2DDP_DESC_DW1_WIDTH 32
#define ESF_DZ_C2DDP_DESC_LBN 128
#define ESF_DZ_C2DDP_DESC_WIDTH 64
-#define ESF_DZ_C2DDP_QID_LBN 96
+#define ESF_DZ_C2DDP_QID_LBN 64
#define ESF_DZ_C2DDP_QID_WIDTH 11
-#define ESF_DZ_C2DDP_DSCR_HW_RPTR_LBN 48
-#define ESF_DZ_C2DDP_DSCR_HW_RPTR_WIDTH 12
#define ESF_DZ_C2DDP_DSCR_HW_WPTR_LBN 32
#define ESF_DZ_C2DDP_DSCR_HW_WPTR_WIDTH 12
#define ESF_DZ_C2DDP_OID_LBN 16
@@ -258,8 +307,18 @@ extern "C" {
/* ES_FF_UMSG_CPU2EV_TXCMPLT */
-#define ESF_DZ_C2ET_EV_SOFT0_LBN 32
-#define ESF_DZ_C2ET_EV_SOFT0_WIDTH 16
+#define ESF_DZ_C2ET_EV_SOFT2_LBN 48
+#define ESF_DZ_C2ET_EV_SOFT2_WIDTH 16
+#define ESF_DZ_C2ET_EV_CODE_LBN 42
+#define ESF_DZ_C2ET_EV_CODE_WIDTH 4
+#define ESF_DZ_C2ET_EV_OVERRIDE_HOLDOFF_LBN 41
+#define ESF_DZ_C2ET_EV_OVERRIDE_HOLDOFF_WIDTH 1
+#define ESF_DZ_C2ET_EV_DROP_EVENT_LBN 40
+#define ESF_DZ_C2ET_EV_DROP_EVENT_WIDTH 1
+#define ESF_DZ_C2ET_EV_CAN_MERGE_LBN 39
+#define ESF_DZ_C2ET_EV_CAN_MERGE_WIDTH 1
+#define ESF_DZ_C2ET_EV_SOFT1_LBN 32
+#define ESF_DZ_C2ET_EV_SOFT1_WIDTH 7
#define ESF_DZ_C2ET_DSCR_IDX_LBN 16
#define ESF_DZ_C2ET_DSCR_IDX_WIDTH 16
#define ESF_DZ_C2ET_EV_QID_LBN 5
@@ -310,7 +369,6 @@ extern "C" {
#define ESF_DZ_C2RIP_EV_ARG1_WIDTH 16
#define ESF_DZ_C2RIP_UPD_CRC_MODE_LBN 157
#define ESF_DZ_C2RIP_UPD_CRC_MODE_WIDTH 3
-#define ESE_DZ_C2RIP_FCOIP_MPA 5
#define ESE_DZ_C2RIP_FCOIP_FCOE 4
#define ESE_DZ_C2RIP_ISCSI_HDR_AND_PYLD 3
#define ESE_DZ_C2RIP_ISCSI_HDR 2
@@ -379,7 +437,7 @@ extern "C" {
#define ESF_DZ_C2SD_ENCODED_HOST_ADDR_DW1_WIDTH 16
#define ESF_DZ_C2SD_ENCODED_HOST_ADDR_LBN 64
#define ESF_DZ_C2SD_ENCODED_HOST_ADDR_WIDTH 48
-#define ESF_DZ_C2SD_OFFSET_LBN 48
+#define ESF_DZ_C2SD_OFFSET_LBN 80
#define ESF_DZ_C2SD_OFFSET_WIDTH 8
#define ESF_DZ_C2SD_QID_LBN 32
#define ESF_DZ_C2SD_QID_WIDTH 11
@@ -419,7 +477,6 @@ extern "C" {
#define ESF_DZ_C2TDB_DESC_IDX_WIDTH 16
#define ESF_DZ_C2TDB_UPD_CRC_MODE_LBN 93
#define ESF_DZ_C2TDB_UPD_CRC_MODE_WIDTH 3
-#define ESE_DZ_C2RIP_FCOIP_MPA 5
#define ESE_DZ_C2RIP_FCOIP_FCOE 4
#define ESE_DZ_C2RIP_ISCSI_HDR_AND_PYLD 3
#define ESE_DZ_C2RIP_ISCSI_HDR 2
@@ -460,6 +517,14 @@ extern "C" {
/* ES_FF_UMSG_CPU2TXDP_EGR */
+#define ESF_DZ_C2TE_RMON_SOFT_LBN 240
+#define ESF_DZ_C2TE_RMON_SOFT_WIDTH 1
+#define ESF_DZ_C2TE_VLAN_PRIO_LBN 224
+#define ESF_DZ_C2TE_VLAN_PRIO_WIDTH 3
+#define ESF_DZ_C2TE_VLAN_LBN 208
+#define ESF_DZ_C2TE_VLAN_WIDTH 1
+#define ESF_DZ_C2TE_QID_LBN 192
+#define ESF_DZ_C2TE_QID_WIDTH 11
#define ESF_DZ_C2TE_PEDIT_DELTA_LBN 168
#define ESF_DZ_C2TE_PEDIT_DELTA_WIDTH 8
#define ESF_DZ_C2TE_PYLOAD_OFST_LBN 160
@@ -480,20 +545,19 @@ extern "C" {
#define ESF_DZ_C2TE_IS_FCOE_WIDTH 1
#define ESF_DZ_C2TE_PARSE_INCOMP_LBN 128
#define ESF_DZ_C2TE_PARSE_INCOMP_WIDTH 1
-#define ESF_DZ_C2TE_PKT_LEN_LBN 112
-#define ESF_DZ_C2TE_PKT_LEN_WIDTH 16
-#define ESF_DZ_C2TE_UPD_TCPUDPCSUM_MODE_LBN 97
-#define ESF_DZ_C2TE_UPD_TCPUDPCSUM_MODE_WIDTH 1
-#define ESF_DZ_C2TE_UPD_IPCSUM_MODE_LBN 96
-#define ESF_DZ_C2TE_UPD_IPCSUM_MODE_WIDTH 1
-#define ESF_DZ_C2TE_UPD_CRC_MODE_LBN 93
+#define ESF_DZ_C2TE_UPD_CRC_MODE_LBN 98
#define ESF_DZ_C2TE_UPD_CRC_MODE_WIDTH 3
-#define ESE_DZ_C2RIP_FCOIP_MPA 5
#define ESE_DZ_C2RIP_FCOIP_FCOE 4
#define ESE_DZ_C2RIP_ISCSI_HDR_AND_PYLD 3
#define ESE_DZ_C2RIP_ISCSI_HDR 2
#define ESE_DZ_C2RIP_FCOE 1
#define ESE_DZ_C2RIP_OFF 0
+#define ESF_DZ_C2TE_UPD_TCPUDPCSUM_MODE_LBN 97
+#define ESF_DZ_C2TE_UPD_TCPUDPCSUM_MODE_WIDTH 1
+#define ESF_DZ_C2TE_UPD_IPCSUM_MODE_LBN 96
+#define ESF_DZ_C2TE_UPD_IPCSUM_MODE_WIDTH 1
+#define ESF_DZ_C2TE_PKT_LEN_LBN 64
+#define ESF_DZ_C2TE_PKT_LEN_WIDTH 16
#define ESF_DZ_C2TE_FINFO_WRD3_LBN 48
#define ESF_DZ_C2TE_FINFO_WRD3_WIDTH 16
#define ESF_DZ_C2TE_FINFO_WRD2_LBN 32
@@ -542,7 +606,7 @@ extern "C" {
/* ES_FF_UMSG_PACER_BKT_TBL_RD_REQ */
#define ESF_DZ_BKT_ID_LBN 0
-#define ESF_DZ_BKT_ID_WIDTH 9
+#define ESF_DZ_BKT_ID_WIDTH 10
/* ES_FF_UMSG_PACER_BKT_TBL_RD_RSP */
@@ -563,7 +627,7 @@ extern "C" {
#define ESF_DZ_MAX_FILL_REG_LBN 12
#define ESF_DZ_MAX_FILL_REG_WIDTH 2
#define ESF_DZ_BKT_ID_LBN 0
-#define ESF_DZ_BKT_ID_WIDTH 9
+#define ESF_DZ_BKT_ID_WIDTH 10
/* ES_FF_UMSG_PACER_BKT_TBL_WR_REQ */
@@ -580,7 +644,7 @@ extern "C" {
#define ESF_DZ_MAX_FILL_REG_LBN 12
#define ESF_DZ_MAX_FILL_REG_WIDTH 2
#define ESF_DZ_BKT_ID_LBN 0
-#define ESF_DZ_BKT_ID_WIDTH 9
+#define ESF_DZ_BKT_ID_WIDTH 10
/* ES_FF_UMSG_PACER_TXQ_TBL_RD_REQ */
@@ -590,13 +654,13 @@ extern "C" {
/* ES_FF_UMSG_PACER_TXQ_TBL_RD_RSP */
#define ESF_DZ_MAX_BKT2_LBN 112
-#define ESF_DZ_MAX_BKT2_WIDTH 9
+#define ESF_DZ_MAX_BKT2_WIDTH 10
#define ESF_DZ_MAX_BKT1_LBN 96
-#define ESF_DZ_MAX_BKT1_WIDTH 9
+#define ESF_DZ_MAX_BKT1_WIDTH 10
#define ESF_DZ_MAX_BKT0_LBN 80
-#define ESF_DZ_MAX_BKT0_WIDTH 9
+#define ESF_DZ_MAX_BKT0_WIDTH 10
#define ESF_DZ_MIN_BKT_LBN 64
-#define ESF_DZ_MIN_BKT_WIDTH 9
+#define ESF_DZ_MIN_BKT_WIDTH 10
#define ESF_DZ_LABEL_LBN 48
#define ESF_DZ_LABEL_WIDTH 4
#define ESF_DZ_PQ_FLAGS_LBN 32
@@ -609,13 +673,13 @@ extern "C" {
/* ES_FF_UMSG_PACER_TXQ_TBL_WR_REQ */
#define ESF_DZ_MAX_BKT2_LBN 112
-#define ESF_DZ_MAX_BKT2_WIDTH 9
+#define ESF_DZ_MAX_BKT2_WIDTH 10
#define ESF_DZ_MAX_BKT1_LBN 96
-#define ESF_DZ_MAX_BKT1_WIDTH 9
+#define ESF_DZ_MAX_BKT1_WIDTH 10
#define ESF_DZ_MAX_BKT0_LBN 80
-#define ESF_DZ_MAX_BKT0_WIDTH 9
+#define ESF_DZ_MAX_BKT0_WIDTH 10
#define ESF_DZ_MIN_BKT_LBN 64
-#define ESF_DZ_MIN_BKT_WIDTH 9
+#define ESF_DZ_MIN_BKT_WIDTH 10
#define ESF_DZ_LABEL_LBN 48
#define ESF_DZ_LABEL_WIDTH 4
#define ESF_DZ_PQ_FLAGS_LBN 32
@@ -663,17 +727,19 @@ extern "C" {
/* ES_FF_UMSG_RXDP_INGR2CPU */
+#define ESF_DZ_RI2C_QUEUE_ID_LBN 224
+#define ESF_DZ_RI2C_QUEUE_ID_WIDTH 11
#define ESF_DZ_RI2C_LEN_LBN 208
#define ESF_DZ_RI2C_LEN_WIDTH 16
-#define ESF_DZ_RI2C_L4_CLASS_LBN 202
+#define ESF_DZ_RI2C_L4_CLASS_LBN 205
#define ESF_DZ_RI2C_L4_CLASS_WIDTH 3
-#define ESF_DZ_RI2C_L3_CLASS_LBN 199
+#define ESF_DZ_RI2C_L3_CLASS_LBN 202
#define ESF_DZ_RI2C_L3_CLASS_WIDTH 3
-#define ESF_DZ_RI2C_ETHTAG_CLASS_LBN 196
+#define ESF_DZ_RI2C_ETHTAG_CLASS_LBN 199
#define ESF_DZ_RI2C_ETHTAG_CLASS_WIDTH 3
-#define ESF_DZ_RI2C_ETHBASE_CLASS_LBN 193
+#define ESF_DZ_RI2C_ETHBASE_CLASS_LBN 196
#define ESF_DZ_RI2C_ETHBASE_CLASS_WIDTH 3
-#define ESF_DZ_RI2C_MAC_CLASS_LBN 192
+#define ESF_DZ_RI2C_MAC_CLASS_LBN 195
#define ESF_DZ_RI2C_MAC_CLASS_WIDTH 1
#define ESF_DZ_RI2C_PKT_OFST_LBN 176
#define ESF_DZ_RI2C_PKT_OFST_WIDTH 16
@@ -765,12 +831,12 @@ extern "C" {
#define ESF_DZ_TD2CP_ETHBASE_CLASS_WIDTH 3
#define ESF_DZ_TD2CP_MAC_CLASS_LBN 240
#define ESF_DZ_TD2CP_MAC_CLASS_WIDTH 1
-#define ESF_DZ_TD2CP_SOFT_LBN 226
-#define ESF_DZ_TD2CP_SOFT_WIDTH 14
-#define ESF_DZ_TD2CP_PKT_ABORT_LBN 225
+#define ESF_DZ_TD2CP_PCIE_ERR_OR_ABORT_LBN 239
+#define ESF_DZ_TD2CP_PCIE_ERR_OR_ABORT_WIDTH 1
+#define ESF_DZ_TD2CP_PKT_ABORT_LBN 238
#define ESF_DZ_TD2CP_PKT_ABORT_WIDTH 1
-#define ESF_DZ_TD2CP_PCIE_ERR_LBN 224
-#define ESF_DZ_TD2CP_PCIE_ERR_WIDTH 1
+#define ESF_DZ_TD2CP_SOFT_LBN 224
+#define ESF_DZ_TD2CP_SOFT_WIDTH 14
#define ESF_DZ_TD2CP_DESC_IDX_LBN 208
#define ESF_DZ_TD2CP_DESC_IDX_WIDTH 16
#define ESF_DZ_TD2CP_PKT_LEN_LBN 192
@@ -854,7 +920,7 @@ extern "C" {
/* ES_LUE_DB_MATCH_ENTRY */
#define ESF_DZ_LUE_DSCRMNTR_LBN 140
-#define ESF_DZ_LUE_DSCRMNTR_WIDTH 4
+#define ESF_DZ_LUE_DSCRMNTR_WIDTH 6
#define ESF_DZ_LUE_MATCH_VAL_DW0_LBN 44
#define ESF_DZ_LUE_MATCH_VAL_DW0_WIDTH 32
#define ESF_DZ_LUE_MATCH_VAL_DW1_LBN 76
@@ -875,13 +941,11 @@ extern "C" {
#define ESE_DZ_LUE_SINGLE 0
#define ESF_DZ_LUE_RCPNTR_LBN 0
#define ESF_DZ_LUE_RCPNTR_WIDTH 24
-#define ESF_DZ_LUE_RCPNTR_ME_PTR_LBN 0
-#define ESF_DZ_LUE_RCPNTR_ME_PTR_WIDTH 14
/* ES_LUE_DB_NONMATCH_ENTRY */
#define ESF_DZ_LUE_DSCRMNTR_LBN 140
-#define ESF_DZ_LUE_DSCRMNTR_WIDTH 4
+#define ESF_DZ_LUE_DSCRMNTR_WIDTH 6
#define ESF_DZ_LUE_TERMINAL_LBN 139
#define ESF_DZ_LUE_TERMINAL_WIDTH 1
#define ESF_DZ_LUE_LAST_LBN 138
@@ -914,9 +978,9 @@ extern "C" {
#define ESF_DZ_MC2L_DR_PAD_DW3_LBN 118
#define ESF_DZ_MC2L_DR_PAD_DW3_WIDTH 32
#define ESF_DZ_MC2L_DR_PAD_DW4_LBN 150
-#define ESF_DZ_MC2L_DR_PAD_DW4_WIDTH 16
+#define ESF_DZ_MC2L_DR_PAD_DW4_WIDTH 18
#define ESF_DZ_MC2L_DR_PAD_LBN 22
-#define ESF_DZ_MC2L_DR_PAD_WIDTH 144
+#define ESF_DZ_MC2L_DR_PAD_WIDTH 146
#define ESF_DZ_MC2L_DR_ADDR_LBN 8
#define ESF_DZ_MC2L_DR_ADDR_WIDTH 14
#define ESF_DZ_MC2L_DR_THREAD_ID_LBN 5
@@ -933,7 +997,7 @@ extern "C" {
/* ES_LUE_MC_DIRECT_RESPONSE_MSG */
#define ESF_DZ_L2MC_DR_PAD_LBN 146
-#define ESF_DZ_L2MC_DR_PAD_WIDTH 6
+#define ESF_DZ_L2MC_DR_PAD_WIDTH 8
#define ESF_DZ_L2MC_DR_RCPNT_PTR_LBN 132
#define ESF_DZ_L2MC_DR_RCPNT_PTR_WIDTH 14
#define ESF_DZ_L2MC_DR_RCPNT4_LBN 108
@@ -972,9 +1036,9 @@ extern "C" {
#define ESF_DZ_MC2L_GPR_PAD_DW3_LBN 118
#define ESF_DZ_MC2L_GPR_PAD_DW3_WIDTH 32
#define ESF_DZ_MC2L_GPR_PAD_DW4_LBN 150
-#define ESF_DZ_MC2L_GPR_PAD_DW4_WIDTH 16
+#define ESF_DZ_MC2L_GPR_PAD_DW4_WIDTH 18
#define ESF_DZ_MC2L_GPR_PAD_LBN 22
-#define ESF_DZ_MC2L_GPR_PAD_WIDTH 144
+#define ESF_DZ_MC2L_GPR_PAD_WIDTH 146
#define ESF_DZ_MC2L_GPR_ADDR_LBN 8
#define ESF_DZ_MC2L_GPR_ADDR_WIDTH 14
#define ESF_DZ_MC2L_GPR_THREAD_ID_LBN 5
@@ -999,9 +1063,9 @@ extern "C" {
#define ESF_DZ_L2MC_GPR_DATA_DW3_LBN 104
#define ESF_DZ_L2MC_GPR_DATA_DW3_WIDTH 32
#define ESF_DZ_L2MC_GPR_DATA_DW4_LBN 136
-#define ESF_DZ_L2MC_GPR_DATA_DW4_WIDTH 16
+#define ESF_DZ_L2MC_GPR_DATA_DW4_WIDTH 18
#define ESF_DZ_L2MC_GPR_DATA_LBN 8
-#define ESF_DZ_L2MC_GPR_DATA_WIDTH 144
+#define ESF_DZ_L2MC_GPR_DATA_WIDTH 146
#define ESF_DZ_L2MC_GPR_THREAD_ID_LBN 5
#define ESF_DZ_L2MC_GPR_THREAD_ID_WIDTH 3
#define ESF_DZ_L2MC_GPR_CLIENT_ID_LBN 2
@@ -1024,9 +1088,9 @@ extern "C" {
#define ESF_DZ_MC2L_GPW_DATA_DW3_LBN 118
#define ESF_DZ_MC2L_GPW_DATA_DW3_WIDTH 32
#define ESF_DZ_MC2L_GPW_DATA_DW4_LBN 150
-#define ESF_DZ_MC2L_GPW_DATA_DW4_WIDTH 16
+#define ESF_DZ_MC2L_GPW_DATA_DW4_WIDTH 18
#define ESF_DZ_MC2L_GPW_DATA_LBN 22
-#define ESF_DZ_MC2L_GPW_DATA_WIDTH 144
+#define ESF_DZ_MC2L_GPW_DATA_WIDTH 146
#define ESF_DZ_MC2L_GPW_ADDR_LBN 8
#define ESF_DZ_MC2L_GPW_ADDR_WIDTH 14
#define ESF_DZ_MC2L_GPW_THREAD_ID_LBN 5
@@ -1042,22 +1106,22 @@ extern "C" {
/* ES_LUE_MC_MATCH_REQUEST_MSG */
-#define ESF_DZ_MC2L_MR_PAD_LBN 135
+#define ESF_DZ_MC2L_MR_PAD_LBN 137
#define ESF_DZ_MC2L_MR_PAD_WIDTH 31
-#define ESF_DZ_MC2L_MR_HASH2_LBN 122
+#define ESF_DZ_MC2L_MR_HASH2_LBN 124
#define ESF_DZ_MC2L_MR_HASH2_WIDTH 13
-#define ESF_DZ_MC2L_MR_HASH1_LBN 108
+#define ESF_DZ_MC2L_MR_HASH1_LBN 110
#define ESF_DZ_MC2L_MR_HASH1_WIDTH 14
-#define ESF_DZ_MC2L_MR_MATCH_BITS_DW0_LBN 12
+#define ESF_DZ_MC2L_MR_MATCH_BITS_DW0_LBN 14
#define ESF_DZ_MC2L_MR_MATCH_BITS_DW0_WIDTH 32
-#define ESF_DZ_MC2L_MR_MATCH_BITS_DW1_LBN 44
+#define ESF_DZ_MC2L_MR_MATCH_BITS_DW1_LBN 46
#define ESF_DZ_MC2L_MR_MATCH_BITS_DW1_WIDTH 32
-#define ESF_DZ_MC2L_MR_MATCH_BITS_DW2_LBN 76
+#define ESF_DZ_MC2L_MR_MATCH_BITS_DW2_LBN 78
#define ESF_DZ_MC2L_MR_MATCH_BITS_DW2_WIDTH 32
-#define ESF_DZ_MC2L_MR_MATCH_BITS_LBN 12
+#define ESF_DZ_MC2L_MR_MATCH_BITS_LBN 14
#define ESF_DZ_MC2L_MR_MATCH_BITS_WIDTH 96
#define ESF_DZ_MC2L_MR_DSCRMNTR_LBN 8
-#define ESF_DZ_MC2L_MR_DSCRMNTR_WIDTH 4
+#define ESF_DZ_MC2L_MR_DSCRMNTR_WIDTH 6
#define ESF_DZ_MC2L_MR_THREAD_ID_LBN 5
#define ESF_DZ_MC2L_MR_THREAD_ID_WIDTH 3
#define ESF_DZ_MC2L_MR_CLIENT_ID_LBN 2
@@ -1078,9 +1142,9 @@ extern "C" {
#define ESF_DZ_L2MC_MR_PAD_DW2_LBN 117
#define ESF_DZ_L2MC_MR_PAD_DW2_WIDTH 32
#define ESF_DZ_L2MC_MR_PAD_DW3_LBN 149
-#define ESF_DZ_L2MC_MR_PAD_DW3_WIDTH 3
+#define ESF_DZ_L2MC_MR_PAD_DW3_WIDTH 5
#define ESF_DZ_L2MC_MR_PAD_LBN 53
-#define ESF_DZ_L2MC_MR_PAD_WIDTH 99
+#define ESF_DZ_L2MC_MR_PAD_WIDTH 101
#define ESF_DZ_L2MC_MR_LUE_RCPNT_LBN 29
#define ESF_DZ_L2MC_MR_LUE_RCPNT_WIDTH 24
#define ESF_DZ_L2MC_MR_RX_MCAST_LBN 28
@@ -1115,9 +1179,9 @@ extern "C" {
#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_DW3_LBN 104
#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_DW3_WIDTH 32
#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_DW4_LBN 136
-#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_DW4_WIDTH 30
+#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_DW4_WIDTH 32
#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_LBN 8
-#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_WIDTH 158
+#define ESF_DZ_LUE_HW_REQ_BASE_REQ_MSG_DATA_WIDTH 160
#define ESF_DZ_LUE_HW_REQ_BASE_THREAD_ID_LBN 5
#define ESF_DZ_LUE_HW_REQ_BASE_THREAD_ID_WIDTH 3
#define ESF_DZ_LUE_HW_REQ_BASE_CLIENT_ID_LBN 2
@@ -1144,9 +1208,9 @@ extern "C" {
#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_DW3_LBN 104
#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_DW3_WIDTH 32
#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_DW4_LBN 136
-#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_DW4_WIDTH 16
+#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_DW4_WIDTH 18
#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_LBN 8
-#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_WIDTH 144
+#define ESF_DZ_LUE_HW_RSP_BASE_RSP_DATA_WIDTH 146
#define ESF_DZ_LUE_HW_RSP_BASE_THREAD_ID_LBN 5
#define ESF_DZ_LUE_HW_RSP_BASE_THREAD_ID_WIDTH 3
#define ESF_DZ_LUE_HW_RSP_BASE_CLIENT_ID_LBN 2
@@ -1244,9 +1308,9 @@ extern "C" {
#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_DW3_LBN 104
#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_DW3_WIDTH 32
#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_DW4_LBN 136
-#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_DW4_WIDTH 16
+#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_DW4_WIDTH 18
#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_LBN 8
-#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_WIDTH 144
+#define ESF_DZ_LUE_HW_RSP_GPRD_LUE_DATA_WIDTH 146
#define ESF_DZ_LUE_HW_RSP_GPRD_THREAD_ID_LBN 5
#define ESF_DZ_LUE_HW_RSP_GPRD_THREAD_ID_WIDTH 3
#define ESF_DZ_LUE_HW_RSP_GPRD_CLIENT_ID_LBN 2
@@ -1273,9 +1337,9 @@ extern "C" {
#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_DW3_LBN 118
#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_DW3_WIDTH 32
#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_DW4_LBN 150
-#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_DW4_WIDTH 16
+#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_DW4_WIDTH 18
#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_LBN 22
-#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_WIDTH 144
+#define ESF_DZ_LUE_HW_REQ_GPWR_LUE_DATA_WIDTH 146
#define ESF_DZ_LUE_HW_REQ_GPWR_ADDR_LBN 8
#define ESF_DZ_LUE_HW_REQ_GPWR_ADDR_WIDTH 14
#define ESF_DZ_LUE_HW_REQ_GPWR_THREAD_ID_LBN 5
@@ -1295,22 +1359,22 @@ extern "C" {
/* ES_LUE_MSG_MATCH_REQ */
-#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_REQ_COUNT_LBN 135
-#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_REQ_COUNT_WIDTH 6
-#define ESF_DZ_LUE_HW_REQ_MATCH_HASH2_LBN 122
+#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_REQ_COUNT_LBN 137
+#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_REQ_COUNT_WIDTH 8
+#define ESF_DZ_LUE_HW_REQ_MATCH_HASH2_LBN 124
#define ESF_DZ_LUE_HW_REQ_MATCH_HASH2_WIDTH 13
-#define ESF_DZ_LUE_HW_REQ_MATCH_HASH1_LBN 108
+#define ESF_DZ_LUE_HW_REQ_MATCH_HASH1_LBN 110
#define ESF_DZ_LUE_HW_REQ_MATCH_HASH1_WIDTH 14
-#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW0_LBN 12
+#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW0_LBN 14
#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW0_WIDTH 32
-#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW1_LBN 44
+#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW1_LBN 46
#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW1_WIDTH 32
-#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW2_LBN 76
+#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW2_LBN 78
#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_DW2_WIDTH 32
-#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_LBN 12
+#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_LBN 14
#define ESF_DZ_LUE_HW_REQ_MATCH_MATCH_BITS_WIDTH 96
#define ESF_DZ_LUE_HW_REQ_MATCH_DSCRMNTR_LBN 8
-#define ESF_DZ_LUE_HW_REQ_MATCH_DSCRMNTR_WIDTH 4
+#define ESF_DZ_LUE_HW_REQ_MATCH_DSCRMNTR_WIDTH 6
#define ESF_DZ_LUE_HW_REQ_MATCH_THREAD_ID_LBN 5
#define ESF_DZ_LUE_HW_REQ_MATCH_THREAD_ID_WIDTH 3
#define ESF_DZ_LUE_HW_REQ_MATCH_CLIENT_ID_LBN 2
@@ -1543,10 +1607,10 @@ extern "C" {
#define ESF_DZ_RX_OVERRIDE_HOLDOFF_WIDTH 1
#define ESF_DZ_RX_DROP_EVENT_LBN 58
#define ESF_DZ_RX_DROP_EVENT_WIDTH 1
-#define ESF_DZ_RX_EV_RSVD2_LBN 55
-#define ESF_DZ_RX_EV_RSVD2_WIDTH 3
+#define ESF_DZ_RX_EV_RSVD2_LBN 54
+#define ESF_DZ_RX_EV_RSVD2_WIDTH 4
#define ESF_DZ_RX_EV_SOFT2_LBN 52
-#define ESF_DZ_RX_EV_SOFT2_WIDTH 3
+#define ESF_DZ_RX_EV_SOFT2_WIDTH 2
#define ESF_DZ_RX_DSC_PTR_LBITS_LBN 48
#define ESF_DZ_RX_DSC_PTR_LBITS_WIDTH 4
#define ESF_DZ_RX_L4_CLASS_LBN 45
@@ -1590,8 +1654,10 @@ extern "C" {
#define ESE_DZ_MAC_CLASS_UCAST 0
#define ESF_DZ_RX_EV_SOFT1_LBN 32
#define ESF_DZ_RX_EV_SOFT1_WIDTH 3
-#define ESF_DZ_RX_EV_RSVD1_LBN 30
-#define ESF_DZ_RX_EV_RSVD1_WIDTH 2
+#define ESF_DZ_RX_EV_RSVD1_LBN 31
+#define ESF_DZ_RX_EV_RSVD1_WIDTH 1
+#define ESF_DZ_RX_ABORT_LBN 30
+#define ESF_DZ_RX_ABORT_WIDTH 1
#define ESF_DZ_RX_ECC_ERR_LBN 29
#define ESF_DZ_RX_ECC_ERR_WIDTH 1
#define ESF_DZ_RX_CRC1_ERR_LBN 28
@@ -1605,7 +1671,7 @@ extern "C" {
#define ESF_DZ_RX_ECRC_ERR_LBN 24
#define ESF_DZ_RX_ECRC_ERR_WIDTH 1
#define ESF_DZ_RX_QLABEL_LBN 16
-#define ESF_DZ_RX_QLABEL_WIDTH 8
+#define ESF_DZ_RX_QLABEL_WIDTH 5
#define ESF_DZ_RX_PARSE_INCOMPLETE_LBN 15
#define ESF_DZ_RX_PARSE_INCOMPLETE_WIDTH 1
#define ESF_DZ_RX_CONT_LBN 14
@@ -1687,16 +1753,16 @@ extern "C" {
#define ESF_DZ_RX_U_FAST_PATH_WIDTH 1
#define ESF_DZ_RX_U_SOFT1_B1R0_4_LBN 68
#define ESF_DZ_RX_U_SOFT1_B1R0_4_WIDTH 1
-#define ESF_DZ_RX_U_NO_FLUSH_LBN 67
-#define ESF_DZ_RX_U_NO_FLUSH_WIDTH 1
+#define ESF_DZ_RX_U_CHAIN_LBN 67
+#define ESF_DZ_RX_U_CHAIN_WIDTH 1
#define ESF_DZ_RX_U_SOFT1_B1R0_3_LBN 67
#define ESF_DZ_RX_U_SOFT1_B1R0_3_WIDTH 1
#define ESF_DZ_RX_U_DESC_ACTIVE_LBN 66
#define ESF_DZ_RX_U_DESC_ACTIVE_WIDTH 1
#define ESF_DZ_RX_U_SOFT1_B1R0_2_LBN 66
#define ESF_DZ_RX_U_SOFT1_B1R0_2_WIDTH 1
-#define ESF_DZ_RX_U_HDR_SPLIT_LBN 65
-#define ESF_DZ_RX_U_HDR_SPLIT_WIDTH 1
+#define ESF_DZ_RX_U_TIMESTAMP_LBN 65
+#define ESF_DZ_RX_U_TIMESTAMP_WIDTH 1
#define ESF_DZ_RX_U_SOFT1_B1R0_1_LBN 65
#define ESF_DZ_RX_U_SOFT1_B1R0_1_WIDTH 1
#define ESF_DZ_RX_U_Q_ENABLE_LBN 64
@@ -1728,12 +1794,14 @@ extern "C" {
#define ESF_DZ_RX_U_DSCR_BASE_PAGE_ID_WIDTH 18
#define ESF_DZ_RX_U_SOFT18_B1R0_0_LBN 64
#define ESF_DZ_RX_U_SOFT18_B1R0_0_WIDTH 18
-#define ESF_DZ_RX_U_QST1_SPARE_LBN 52
-#define ESF_DZ_RX_U_QST1_SPARE_WIDTH 12
+#define ESF_DZ_RX_U_QST1_SPARE_LBN 53
+#define ESF_DZ_RX_U_QST1_SPARE_WIDTH 11
#define ESF_DZ_RX_U_SOFT16_B0R3_0_LBN 48
#define ESF_DZ_RX_U_SOFT16_B0R3_0_WIDTH 16
-#define ESF_DZ_RX_U_TIMESTAMP_LBN 51
-#define ESF_DZ_RX_U_TIMESTAMP_WIDTH 1
+#define ESF_DZ_RX_U_NO_FLUSH_LBN 52
+#define ESF_DZ_RX_U_NO_FLUSH_WIDTH 1
+#define ESF_DZ_RX_U_HDR_SPLIT_LBN 51
+#define ESF_DZ_RX_U_HDR_SPLIT_WIDTH 1
#define ESF_DZ_RX_U_DOORBELL_ENABLED_LBN 50
#define ESF_DZ_RX_U_DOORBELL_ENABLED_WIDTH 1
#define ESF_DZ_RX_U_WORK_PENDING_LBN 49
@@ -1758,6 +1826,39 @@ extern "C" {
#define ESF_DZ_RX_U_SOFT3_B0R0_0_WIDTH 3
+/* ES_SGMII_DEV_PTNR_ABILITY_1000BX_MD */
+#define ESF_DZ_SGMII_DPA_NXT_PG_LBN 15
+#define ESF_DZ_SGMII_DPA_NXT_PG_WIDTH 1
+#define ESF_DZ_SGMII_DPA_ACK_LBN 14
+#define ESF_DZ_SGMII_DPA_ACK_WIDTH 1
+#define ESF_DZ_SGMII_DPA_REMOTE_FLT_LBN 12
+#define ESF_DZ_SGMII_DPA_REMOTE_FLT_WIDTH 2
+#define ESE_DZ_SGMII_DPA_RF_AN_ERR 3
+#define ESE_DZ_SGMII_DPA_RF_OFFLINE 2
+#define ESE_DZ_SGMII_DPA_RF_LINK_FAIL 1
+#define ESE_DZ_SGMII_DPA_RF_NONE 0
+#define ESF_DZ_SGMII_DPA_PS_LBN 7
+#define ESF_DZ_SGMII_DPA_PS_WIDTH 2
+#define ESF_DZ_SGMII_DPA_HD_LBN 6
+#define ESF_DZ_SGMII_DPA_HD_WIDTH 1
+#define ESF_DZ_SGMII_DPA_FD_LBN 5
+#define ESF_DZ_SGMII_DPA_FD_WIDTH 1
+
+
+/* ES_SGMII_DEV_PTNR_ABILITY_SGMII_MD */
+#define ESF_DZ_SGMII_DPA_CPR_LINK_STATE_LBN 15
+#define ESF_DZ_SGMII_DPA_CPR_LINK_STATE_WIDTH 1
+#define ESF_DZ_SGMII_DPA_ACK_LBN 14
+#define ESF_DZ_SGMII_DPA_ACK_WIDTH 1
+#define ESF_DZ_SGMII_CPR_BPLX_STS_LBN 12
+#define ESF_DZ_SGMII_CPR_BPLX_STS_WIDTH 1
+#define ESF_DZ_SGMII_DPA_COPPER_SPEED_LBN 10
+#define ESF_DZ_SGMII_DPA_COPPER_SPEED_WIDTH 2
+#define ESE_DZ_SGMII_DPA_CPR_1GBS 2
+#define ESE_DZ_SGMII_DPA_CPR_100MBS 1
+#define ESE_DZ_SGMII_DPA_CPR_10MBS 0
+
+
/* ES_SMC_BUFTBL_CNTRL_ENTRY */
#define ESF_DZ_SMC_SW_CNTXT_DW0_LBN 16
#define ESF_DZ_SMC_SW_CNTXT_DW0_WIDTH 32
@@ -2187,6 +2288,30 @@ extern "C" {
#define ESE_DZ_SMC_REQ_BUFTBL_LOOKUP 0
+/* ES_TX_CSUM_TSTAMP_DESC */
+#define ESF_DZ_TX_DESC_IS_OPT_LBN 63
+#define ESF_DZ_TX_DESC_IS_OPT_WIDTH 1
+#define ESF_DZ_TX_OPTION_TYPE_LBN 60
+#define ESF_DZ_TX_OPTION_TYPE_WIDTH 3
+#define ESE_DZ_TX_OPTION_DESC_TSO 7
+#define ESE_DZ_TX_OPTION_DESC_VLAN 6
+#define ESE_DZ_TX_OPTION_DESC_CRC_CSUM 0
+#define ESF_DZ_TX_TIMESTAMP_LBN 5
+#define ESF_DZ_TX_TIMESTAMP_WIDTH 1
+#define ESF_DZ_TX_OPTION_CRC_MODE_LBN 2
+#define ESF_DZ_TX_OPTION_CRC_MODE_WIDTH 3
+#define ESE_DZ_TX_OPTION_CRC_FCOIP_MPA 5
+#define ESE_DZ_TX_OPTION_CRC_FCOIP_FCOE 4
+#define ESE_DZ_TX_OPTION_CRC_ISCSI_HDR_AND_PYLD 3
+#define ESE_DZ_TX_OPTION_CRC_ISCSI_HDR 2
+#define ESE_DZ_TX_OPTION_CRC_FCOE 1
+#define ESE_DZ_TX_OPTION_CRC_OFF 0
+#define ESF_DZ_TX_OPTION_UDP_TCP_CSUM_LBN 1
+#define ESF_DZ_TX_OPTION_UDP_TCP_CSUM_WIDTH 1
+#define ESF_DZ_TX_OPTION_IP_CSUM_LBN 0
+#define ESF_DZ_TX_OPTION_IP_CSUM_WIDTH 1
+
+
/* ES_TX_EVENT */
#define ESF_DZ_TX_CODE_LBN 60
#define ESF_DZ_TX_CODE_WIDTH 4
@@ -2198,10 +2323,12 @@ extern "C" {
#define ESF_DZ_TX_EV_RSVD_WIDTH 10
#define ESF_DZ_TX_SOFT2_LBN 32
#define ESF_DZ_TX_SOFT2_WIDTH 16
+#define ESF_DZ_TX_CAN_MERGE_LBN 31
+#define ESF_DZ_TX_CAN_MERGE_WIDTH 1
#define ESF_DZ_TX_SOFT1_LBN 24
-#define ESF_DZ_TX_SOFT1_WIDTH 8
+#define ESF_DZ_TX_SOFT1_WIDTH 7
#define ESF_DZ_TX_QLABEL_LBN 16
-#define ESF_DZ_TX_QLABEL_WIDTH 8
+#define ESF_DZ_TX_QLABEL_WIDTH 5
#define ESF_DZ_TX_DESCR_INDX_LBN 0
#define ESF_DZ_TX_DESCR_INDX_WIDTH 16
@@ -2221,305 +2348,33 @@ extern "C" {
#define ESF_DZ_TX_KER_BUF_ADDR_WIDTH 48
-/* ES_TX_OPTION_DESC */
+/* ES_TX_PIO_DESC */
+#define ESF_DZ_TX_PIO_TYPE_LBN 63
+#define ESF_DZ_TX_PIO_TYPE_WIDTH 1
+#define ESF_DZ_TX_PIO_OPT_LBN 60
+#define ESF_DZ_TX_PIO_OPT_WIDTH 3
+#define ESF_DZ_TX_PIO_CONT_LBN 59
+#define ESF_DZ_TX_PIO_CONT_WIDTH 1
+#define ESF_DZ_TX_PIO_BYTE_CNT_LBN 32
+#define ESF_DZ_TX_PIO_BYTE_CNT_WIDTH 12
+#define ESF_DZ_TX_PIO_BUF_ADDR_LBN 0
+#define ESF_DZ_TX_PIO_BUF_ADDR_WIDTH 12
+
+
+/* ES_TX_TSO_DESC */
#define ESF_DZ_TX_DESC_IS_OPT_LBN 63
#define ESF_DZ_TX_DESC_IS_OPT_WIDTH 1
#define ESF_DZ_TX_OPTION_TYPE_LBN 60
#define ESF_DZ_TX_OPTION_TYPE_WIDTH 3
-#define ESE_DZ_TX_OPTION_DESC_TSO 4
+#define ESE_DZ_TX_OPTION_DESC_TSO 7
+#define ESE_DZ_TX_OPTION_DESC_VLAN 6
#define ESE_DZ_TX_OPTION_DESC_CRC_CSUM 0
#define ESF_DZ_TX_TSO_TCP_FLAGS_LBN 48
#define ESF_DZ_TX_TSO_TCP_FLAGS_WIDTH 8
-#define ESF_DZ_TX_TSO_TCP_MSS_LBN 32
-#define ESF_DZ_TX_TSO_TCP_MSS_WIDTH 16
+#define ESF_DZ_TX_TSO_IP_ID_LBN 32
+#define ESF_DZ_TX_TSO_IP_ID_WIDTH 16
#define ESF_DZ_TX_TSO_TCP_SEQNO_LBN 0
#define ESF_DZ_TX_TSO_TCP_SEQNO_WIDTH 32
-#define ESF_DZ_TX_OPTION_CRC_MODE_LBN 2
-#define ESF_DZ_TX_OPTION_CRC_MODE_WIDTH 3
-#define ESE_DZ_TX_OPTION_CRC_FCOIP_MPA 5
-#define ESE_DZ_TX_OPTION_CRC_FCOIP_FCOE 4
-#define ESE_DZ_TX_OPTION_CRC_ISCSI_HDR_AND_PYLD 3
-#define ESE_DZ_TX_OPTION_CRC_ISCSI_HDR 2
-#define ESE_DZ_TX_OPTION_CRC_FCOE 1
-#define ESE_DZ_TX_OPTION_CRC_OFF 0
-#define ESF_DZ_TX_OPTION_UDP_TCP_CSUM_LBN 1
-#define ESF_DZ_TX_OPTION_UDP_TCP_CSUM_WIDTH 1
-#define ESF_DZ_TX_OPTION_IP_CSUM_LBN 0
-#define ESF_DZ_TX_OPTION_IP_CSUM_WIDTH 1
-
-
-/* ES_TX_PACER_BASE_MSG */
-#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_DW0_LBN 11
-#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_DW0_WIDTH 32
-#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_DW1_LBN 43
-#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_DW1_WIDTH 32
-#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_DW2_LBN 75
-#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_DW2_WIDTH 23
-#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_LBN 11
-#define ESF_DZ_TXP_BASE_REQ_MSG_DATA_WIDTH 87
-#define ESF_DZ_TXP_BASE_OP_LBN 2
-#define ESF_DZ_TXP_BASE_OP_WIDTH 3
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2
-#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1
-#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0
-#define ESF_DZ_TXP_BASE_CLIENT_ID_LBN 0
-#define ESF_DZ_TXP_BASE_CLIENT_ID_WIDTH 2
-#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2
-#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1
-#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0
-
-
-/* ES_TX_PACER_BKT_D_R_REQ */
-#define ESF_DZ_TXP_BKT_D_R_REQ_FRM_LEN_LBN 45
-#define ESF_DZ_TXP_BKT_D_R_REQ_FRM_LEN_WIDTH 14
-#define ESF_DZ_TXP_BKT_D_R_REQ_MAX_BKT2_LBN 35
-#define ESF_DZ_TXP_BKT_D_R_REQ_MAX_BKT2_WIDTH 10
-#define ESF_DZ_TXP_BKT_D_R_REQ_MAX_BKT1_LBN 25
-#define ESF_DZ_TXP_BKT_D_R_REQ_MAX_BKT1_WIDTH 10
-#define ESF_DZ_TXP_BKT_D_R_REQ_MAX_BKT0_LBN 15
-#define ESF_DZ_TXP_BKT_D_R_REQ_MAX_BKT0_WIDTH 10
-#define ESF_DZ_TXP_BKT_D_R_REQ_MIN_BKT_LBN 5
-#define ESF_DZ_TXP_BKT_D_R_REQ_MIN_BKT_WIDTH 10
-#define ESF_DZ_TXP_BKT_D_R_REQ_OP_LBN 2
-#define ESF_DZ_TXP_BKT_D_R_REQ_OP_WIDTH 3
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2
-#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1
-#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0
-#define ESF_DZ_TXP_BKT_D_R_REQ_CLIENT_ID_LBN 0
-#define ESF_DZ_TXP_BKT_D_R_REQ_CLIENT_ID_WIDTH 2
-#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2
-#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1
-#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0
-
-
-/* ES_TX_PACER_BKT_TBL_D_R_RSP */
-#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_DUE_TIME_WITH_MIN_BKT_LBN 21
-#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_DUE_TIME_WITH_MIN_BKT_WIDTH 26
-#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_DUE_TIME_LBN 5
-#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_DUE_TIME_WIDTH 16
-#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_OP_LBN 2
-#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_OP_WIDTH 3
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2
-#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1
-#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0
-#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_CLIENT_ID_LBN 0
-#define ESF_DZ_TXP_BKT_TBL_D_R_RSP_CLIENT_ID_WIDTH 2
-#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2
-#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1
-#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0
-
-
-/* ES_TX_PACER_BKT_TBL_RD_REQ */
-#define ESF_DZ_TXP_BKT_TBL_RD_REQ_BKT_ID_LBN 5
-#define ESF_DZ_TXP_BKT_TBL_RD_REQ_BKT_ID_WIDTH 10
-#define ESF_DZ_TXP_BKT_TBL_RD_REQ_OP_LBN 2
-#define ESF_DZ_TXP_BKT_TBL_RD_REQ_OP_WIDTH 3
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2
-#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1
-#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0
-#define ESF_DZ_TXP_BKT_TBL_RD_REQ_CLIENT_ID_LBN 0
-#define ESF_DZ_TXP_BKT_TBL_RD_REQ_CLIENT_ID_WIDTH 2
-#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2
-#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1
-#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0
-
-
-/* ES_TX_PACER_BKT_TBL_RD_RSP */
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_IDLE_LBN 97
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_IDLE_WIDTH 1
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_USED_LBN 96
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_USED_WIDTH 1
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_MAX_FILL_REG_LBN 94
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_MAX_FILL_REG_WIDTH 2
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_RATE_REC_LBN 78
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_RATE_REC_WIDTH 16
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_RATE_LBN 62
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_RATE_WIDTH 16
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_FILL_LEVEL_LBN 47
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_FILL_LEVEL_WIDTH 15
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_DUE_TIME_LBN 31
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_DUE_TIME_WIDTH 16
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_LAST_FILL_TIME_LBN 15
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_LAST_FILL_TIME_WIDTH 16
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_BKT_ID_LBN 5
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_BKT_ID_WIDTH 10
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_OP_LBN 2
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_OP_WIDTH 3
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2
-#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1
-#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_CLIENT_ID_LBN 0
-#define ESF_DZ_TXP_BKT_TBL_RD_RSP_CLIENT_ID_WIDTH 2
-#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2
-#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1
-#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0
-
-
-/* ES_TX_PACER_BKT_TBL_WR_REQ */
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_IDLE_LBN 65
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_IDLE_WIDTH 1
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_USED_LBN 64
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_USED_WIDTH 1
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_MAX_FILL_REG_LBN 62
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_MAX_FILL_REG_WIDTH 2
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_RATE_REC_LBN 46
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_RATE_REC_WIDTH 16
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_RATE_LBN 30
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_RATE_WIDTH 16
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_FILL_LEVEL_LBN 15
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_FILL_LEVEL_WIDTH 15
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_BKT_ID_LBN 5
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_BKT_ID_WIDTH 10
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_OP_LBN 2
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_OP_WIDTH 3
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2
-#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1
-#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_CLIENT_ID_LBN 0
-#define ESF_DZ_TXP_BKT_TBL_WR_REQ_CLIENT_ID_WIDTH 2
-#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2
-#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1
-#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0
-
-
-/* ES_TX_PACER_TXQ_D_R_I_REQ */
-#define ESF_DZ_TXP_TXQ_D_R_I_REQ_FRM_LEN_LBN 15
-#define ESF_DZ_TXP_TXQ_D_R_I_REQ_FRM_LEN_WIDTH 14
-#define ESF_DZ_TXP_TXQ_D_R_I_REQ_TXQ_ID_LBN 5
-#define ESF_DZ_TXP_TXQ_D_R_I_REQ_TXQ_ID_WIDTH 10
-#define ESF_DZ_TXP_TXQ_D_R_I_REQ_OP_LBN 2
-#define ESF_DZ_TXP_TXQ_D_R_I_REQ_OP_WIDTH 3
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2
-#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1
-#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0
-#define ESF_DZ_TXP_TXQ_D_R_I_REQ_CLIENT_ID_LBN 0
-#define ESF_DZ_TXP_TXQ_D_R_I_REQ_CLIENT_ID_WIDTH 2
-#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2
-#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1
-#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0
-
-
-/* ES_TX_PACER_TXQ_TBL_RD_REQ */
-#define ESF_DZ_TXP_TXQ_TBL_RD_REQ_TXQ_ID_LBN 5
-#define ESF_DZ_TXP_TXQ_TBL_RD_REQ_TXQ_ID_WIDTH 10
-#define ESF_DZ_TXP_TXQ_TBL_RD_REQ_OP_LBN 2
-#define ESF_DZ_TXP_TXQ_TBL_RD_REQ_OP_WIDTH 3
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2
-#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1
-#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0
-#define ESF_DZ_TXP_TXQ_TBL_RD_REQ_CLIENT_ID_LBN 0
-#define ESF_DZ_TXP_TXQ_TBL_RD_REQ_CLIENT_ID_WIDTH 2
-#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2
-#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1
-#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0
-
-
-/* ES_TX_PACER_TXQ_TBL_RD_RSP */
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MAX_BKT2_LBN 53
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MAX_BKT2_WIDTH 10
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MAX_BKT1_LBN 43
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MAX_BKT1_WIDTH 10
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MAX_BKT0_LBN 33
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MAX_BKT0_WIDTH 10
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MIN_BKT_LBN 23
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_MIN_BKT_WIDTH 10
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_LABEL_LBN 19
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_LABEL_WIDTH 4
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_PQ_FLAGS_LBN 16
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_PQ_FLAGS_WIDTH 3
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_DSBL_LBN 15
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_DSBL_WIDTH 1
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_TXQ_ID_LBN 5
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_TXQ_ID_WIDTH 10
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_OP_LBN 2
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_OP_WIDTH 3
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2
-#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1
-#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_CLIENT_ID_LBN 0
-#define ESF_DZ_TXP_TXQ_TBL_RD_RSP_CLIENT_ID_WIDTH 2
-#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2
-#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1
-#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0
-
-
-/* ES_TX_PACER_TXQ_TBL_WR_REQ */
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MAX_BKT2_LBN 53
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MAX_BKT2_WIDTH 10
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MAX_BKT1_LBN 43
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MAX_BKT1_WIDTH 10
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MAX_BKT0_LBN 33
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MAX_BKT0_WIDTH 10
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MIN_BKT_LBN 23
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_MIN_BKT_WIDTH 10
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_LABEL_LBN 19
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_LABEL_WIDTH 4
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_PQ_FLAGS_LBN 16
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_PQ_FLAGS_WIDTH 3
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_DSBL_LBN 15
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_DSBL_WIDTH 1
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_TXQ_ID_LBN 5
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_TXQ_ID_WIDTH 10
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_OP_LBN 2
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_OP_WIDTH 3
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_RD 7
-#define ESE_DZ_DPCPU_PACER_BKT_TBL_WR 6
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_RD 5
-#define ESE_DZ_DPCPU_PACER_TXQ_TBL_WR 4
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_NI 3
-#define ESE_DZ_DPCPU_PACER_TXQ_D_R_I 2
-#define ESE_DZ_DPCPU_PACER_BKT_D_R_RD 1
-#define ESE_DZ_DPCPU_PACER_BKT_D_RD 0
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_CLIENT_ID_LBN 0
-#define ESF_DZ_TXP_TXQ_TBL_WR_REQ_CLIENT_ID_WIDTH 2
-#define ESE_DZ_DPCPU_PACER_CPU_CLIENT 2
-#define ESE_DZ_DPCPU_PACER_CMD_CTL_CLIENT 1
-#define ESE_DZ_DPCPU_PACER_ALRT_CTL_CLIENT 0
/* ES_TX_USER_DESC */
@@ -2572,8 +2427,12 @@ extern "C" {
#define ESF_DZ_TX_U_DC_RPTR_WIDTH 6
#define ESF_DZ_TX_U_SOFT6_B1R1_LBN 80
#define ESF_DZ_TX_U_SOFT6_B1R1_WIDTH 6
+#define ESF_DZ_TX_U_CNTAG_LBN 68
+#define ESF_DZ_TX_U_CNTAG_WIDTH 1
#define ESF_DZ_TX_U_SOFT5_B1R0_LBN 64
#define ESF_DZ_TX_U_SOFT5_B1R0_WIDTH 5
+#define ESF_DZ_TX_U_TIMESTAMP_LBN 67
+#define ESF_DZ_TX_U_TIMESTAMP_WIDTH 1
#define ESF_DZ_TX_U_PREFETCH_ACTIVE_LBN 66
#define ESF_DZ_TX_U_PREFETCH_ACTIVE_WIDTH 1
#define ESF_DZ_TX_U_PREFETCH_PENDING_LBN 65
@@ -2613,6 +2472,18 @@ extern "C" {
#define ESF_DZ_TX_U_SOFT18_B1R0_WIDTH 18
#define ESF_DZ_TX_U_SOFT16_B0R3_LBN 48
#define ESF_DZ_TX_U_SOFT16_B0R3_WIDTH 16
+#define ESF_DZ_TX_U_EMERGENCY_FETCH_FAILED_LBN 56
+#define ESF_DZ_TX_U_EMERGENCY_FETCH_FAILED_WIDTH 1
+#define ESF_DZ_TX_U_PACER_BYPASS_OK_LBN 55
+#define ESF_DZ_TX_U_PACER_BYPASS_OK_WIDTH 1
+#define ESF_DZ_TX_U_STALE_DL_FETCH_LBN 54
+#define ESF_DZ_TX_U_STALE_DL_FETCH_WIDTH 1
+#define ESF_DZ_TX_U_ROLLBACK_IDX_REACHED_LBN 52
+#define ESF_DZ_TX_U_ROLLBACK_IDX_REACHED_WIDTH 1
+#define ESF_DZ_TX_U_ROLLBACK_ACTIVE_LBN 51
+#define ESF_DZ_TX_U_ROLLBACK_ACTIVE_WIDTH 1
+#define ESF_DZ_TX_U_QUEUE_PAUSED_LBN 50
+#define ESF_DZ_TX_U_QUEUE_PAUSED_WIDTH 1
#define ESF_DZ_TX_U_QUEUE_ENABLED_LBN 49
#define ESF_DZ_TX_U_QUEUE_ENABLED_WIDTH 1
#define ESF_DZ_TX_U_FLUSH_PENDING_LBN 48
@@ -2625,7 +2496,7 @@ extern "C" {
#define ESF_DZ_TX_U_OWNER_ID_WIDTH 12
#define ESF_DZ_TX_U_SOFT12_B0R1_LBN 16
#define ESF_DZ_TX_U_SOFT12_B0R1_WIDTH 12
-#define ESF_DZ_TX_U_DSCR_SIZE_LBN 0
+#define ESF_DZ_TX_U_DSCR_SIZE_LBN 13
#define ESF_DZ_TX_U_DSCR_SIZE_WIDTH 3
#define ESF_DZ_TX_U_SOFT3_B0R0_LBN 0
#define ESF_DZ_TX_U_SOFT3_B0R0_WIDTH 3
@@ -2642,9 +2513,27 @@ extern "C" {
#define ESF_DZ_TX_FINFO_SRCDST_WIDTH 16
+/* ES_TX_VLAN_DESC */
+#define ESF_DZ_TX_DESC_IS_OPT_LBN 63
+#define ESF_DZ_TX_DESC_IS_OPT_WIDTH 1
+#define ESF_DZ_TX_OPTION_TYPE_LBN 60
+#define ESF_DZ_TX_OPTION_TYPE_WIDTH 3
+#define ESE_DZ_TX_OPTION_DESC_TSO 7
+#define ESE_DZ_TX_OPTION_DESC_VLAN 6
+#define ESE_DZ_TX_OPTION_DESC_CRC_CSUM 0
+#define ESF_DZ_TX_VLAN_OP_LBN 32
+#define ESF_DZ_TX_VLAN_OP_WIDTH 2
+#define ESF_DZ_TX_VLAN_TAG2_LBN 16
+#define ESF_DZ_TX_VLAN_TAG2_WIDTH 16
+#define ESF_DZ_TX_VLAN_TAG1_LBN 0
+#define ESF_DZ_TX_VLAN_TAG1_WIDTH 16
+
+
/* ES_b2t_cpl_rsp */
-#define ESF_DZ_B2T_CPL_RSP_CPL_ECC_LBN 268
+#define ESF_DZ_B2T_CPL_RSP_CPL_ECC_LBN 284
#define ESF_DZ_B2T_CPL_RSP_CPL_ECC_WIDTH 32
+#define ESF_DZ_B2T_CPL_RSP_CPL_EOT_LBN 283
+#define ESF_DZ_B2T_CPL_RSP_CPL_EOT_WIDTH 1
#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW0_LBN 27
#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW0_WIDTH 32
#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW1_LBN 59
@@ -2663,8 +2552,6 @@ extern "C" {
#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_DW7_WIDTH 32
#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_LBN 27
#define ESF_DZ_B2T_CPL_RSP_CPL_DATA_WIDTH 256
-#define ESF_DZ_B2T_CPL_RSP_CPL_EOT_LBN 283
-#define ESF_DZ_B2T_CPL_RSP_CPL_EOT_WIDTH -15
#define ESF_DZ_B2T_CPL_RSP_CPL_ERROR_LBN 26
#define ESF_DZ_B2T_CPL_RSP_CPL_ERROR_WIDTH 1
#define ESF_DZ_B2T_CPL_RSP_CPL_LAST_LBN 25
@@ -2677,95 +2564,321 @@ extern "C" {
#define ESF_DZ_B2T_CPL_RSP_CPL_ADRS_WIDTH 7
+/* ES_fltr_info_wrd_mac_to_rx */
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_RESERVED2_LBN 112
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_RESERVED2_WIDTH 16
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_TIMESTAMP2_LBN 96
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_TIMESTAMP2_WIDTH 16
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_TIMESTAMP1_LBN 80
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_TIMESTAMP1_WIDTH 16
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_TIMESTAMP0_LBN 64
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_TIMESTAMP0_WIDTH 16
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_RESERVED1_LBN 48
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_RESERVED1_WIDTH 16
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_IPSEC_SA_LBN 32
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_IPSEC_SA_WIDTH 16
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_RESERVED0_LBN 8
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_RESERVED0_WIDTH 24
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_IPSEC_LBN 7
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_IPSEC_WIDTH 1
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_PRIORITY_LBN 4
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_PRIORITY_WIDTH 3
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_SRC_LBN 0
+#define ESF_DZ_FLTR_INFO_MAC_TO_RX_SRC_WIDTH 4
+
+
+/* ES_fltr_info_wrd_mc_pdma */
+#define ESF_DZ_FLTR_INFO_MC_PDMA_FLTR_OUT_LBN 64
+#define ESF_DZ_FLTR_INFO_MC_PDMA_FLTR_OUT_WIDTH 16
+#define ESE_DZ_FLTR_MULTICAST_VLAN 512
+#define ESE_DZ_FLTR_MAC_VLAN 256
+#define ESE_DZ_FLTR_STRUCTURED7 128
+#define ESE_DZ_FLTR_STRUCTURED6 64
+#define ESE_DZ_FLTR_STRUCTURED5 32
+#define ESE_DZ_FLTR_STRUCTURED4 16
+#define ESE_DZ_FLTR_STRUCTURED3 8
+#define ESE_DZ_FLTR_STRUCTURED2 4
+#define ESE_DZ_FLTR_STRUCTURED1 2
+#define ESE_DZ_FLTR_STRUCTURED0 1
+#define ESF_DZ_FLTR_INFO_MC_PDMA_TIMESTAMP_DW0_LBN 16
+#define ESF_DZ_FLTR_INFO_MC_PDMA_TIMESTAMP_DW0_WIDTH 32
+#define ESF_DZ_FLTR_INFO_MC_PDMA_TIMESTAMP_DW1_LBN 48
+#define ESF_DZ_FLTR_INFO_MC_PDMA_TIMESTAMP_DW1_WIDTH 16
+#define ESF_DZ_FLTR_INFO_MC_PDMA_TIMESTAMP_LBN 16
+#define ESF_DZ_FLTR_INFO_MC_PDMA_TIMESTAMP_WIDTH 48
+#define ESF_DZ_FLTR_INFO_MC_PDMA_DST_LBN 8
+#define ESF_DZ_FLTR_INFO_MC_PDMA_DST_WIDTH 8
+#define ESE_DZ_DST_NCSI 64
+#define ESE_DZ_DST_PORT0 32
+#define ESE_DZ_DST_PORT1 16
+#define ESE_DZ_DST_PORT0_IPSEC 8
+#define ESE_DZ_DST_PORT1_IPSEC 4
+#define ESE_DZ_DST_PM 2
+#define ESE_DZ_DST_TIMESTAMP 1
+#define ESF_DZ_FLTR_INFO_MC_PDMA_PRIORITY_LBN 4
+#define ESF_DZ_FLTR_INFO_MC_PDMA_PRIORITY_WIDTH 4
+#define ESF_DZ_FLTR_INFO_MC_PDMA_SRC_LBN 0
+#define ESF_DZ_FLTR_INFO_MC_PDMA_SRC_WIDTH 4
+
+
+/* ES_fltr_info_wrd_rxdi_to_rxdp */
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_INNER_VLAN_LBN 112
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_INNER_VLAN_WIDTH 16
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_OUTER_VLAN_LBN 96
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_OUTER_VLAN_WIDTH 16
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_THASH1_LBN 80
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_THASH1_WIDTH 16
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_THASH0_LBN 64
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_THASH0_WIDTH 16
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_TIMESTAMP1_LBN 48
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_TIMESTAMP1_WIDTH 16
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_TIMESTAMP0_LBN 32
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_TIMESTAMP0_WIDTH 16
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_CNP_LBN 31
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_CNP_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_IVP_LBN 30
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_IVP_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_OVP_LBN 29
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_OVP_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_ST2_LBN 28
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_ST2_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_ST1_LBN 27
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_ST1_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_ST0_LBN 26
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_ST0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_RX_QID_LBN 16
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_RX_QID_WIDTH 10
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_DST_HOST_LBN 15
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_DST_HOST_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_DST_MC_LBN 14
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_DST_MC_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_DST_P0_LBN 13
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_DST_P0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_DST_P1_LBN 12
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_DST_P1_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_RESERVED1_LBN 11
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_RESERVED1_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_DST_CRF_LBN 10
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_DST_CRF_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_RESERVED0_LBN 9
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_RESERVED0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_REPLAY_LBN 8
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_REPLAY_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_IPSEC_LBN 7
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_IPSEC_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_PRIORITY_LBN 4
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_PRIORITY_WIDTH 3
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_SRC_LBN 0
+#define ESF_DZ_FLTR_INFO_RXDI_TO_RXDP_SRC_WIDTH 4
+
+
+/* ES_fltr_info_wrd_rxdp_to_host */
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RESERVED3_LBN 33
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RESERVED3_WIDTH 31
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RMON_SOFT_LBN 32
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RMON_SOFT_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RESERVED2_LBN 27
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RESERVED2_WIDTH 5
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RX_QID_LBN 16
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RX_QID_WIDTH 11
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_DST_HOST_LBN 15
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_DST_HOST_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_DST_MC_LBN 14
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_DST_MC_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_DST_P0_LBN 13
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_DST_P0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_DST_P1_LBN 12
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_DST_P1_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RESERVED1_LBN 11
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RESERVED1_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_DST_CRF_LBN 10
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_DST_CRF_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RESERVED0_LBN 9
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_RESERVED0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_REPLAY_LBN 8
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_REPLAY_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_IPSEC_LBN 7
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_IPSEC_WIDTH 1
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_PRIORITY_LBN 4
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_PRIORITY_WIDTH 3
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_SRC_LBN 0
+#define ESF_DZ_FLTR_INFO_RXDP_TO_HOST_SRC_WIDTH 4
+
+
+/* ES_fltr_info_wrd_tx_to_mac */
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_PRV_LBN 63
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_PRV_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_LB_LBN 62
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_LB_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_MS0_LBN 61
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_MS0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_MS1_LBN 60
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_MS1_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_NDI_LBN 59
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_NDI_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_RESERVED2_LBN 48
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_RESERVED2_WIDTH 11
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_IPSEC_SA_LBN 32
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_IPSEC_SA_WIDTH 16
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_TX_STACK_ID_LBN 24
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_TX_STACK_ID_WIDTH 8
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_TX_DOMAIN_LBN 16
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_TX_DOMAIN_WIDTH 8
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_RESERVED1_LBN 14
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_RESERVED1_WIDTH 2
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_DST_P0_LBN 13
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_DST_P0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_DST_P1_LBN 12
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_DST_P1_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_DST_IP0_LBN 11
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_DST_IP0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_DST_IP1_LBN 10
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_DST_IP1_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_DST_PM_LBN 9
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_DST_PM_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_RESERVED0_LBN 8
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_RESERVED0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_IPSEC_LBN 7
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_IPSEC_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_PRIORITY_LBN 4
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_PRIORITY_WIDTH 3
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_SRC_LBN 0
+#define ESF_DZ_FLTR_INFO_TX_TO_MAC_SRC_WIDTH 4
+
+
+/* ES_fltr_info_wrd_txdi_to_txdp */
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_INNER_VLAN_LBN 112
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_INNER_VLAN_WIDTH 16
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_OUTER_VLAN_LBN 96
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_OUTER_VLAN_WIDTH 16
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_CNP_LBN 95
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_CNP_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_IVP_LBN 94
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_IVP_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_OVP_LBN 93
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_OVP_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_RESERVED4_LBN 90
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_RESERVED4_WIDTH 3
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_QID_LBN 80
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_QID_WIDTH 10
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_VRI_LBN 79
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_VRI_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_RESERVED3_LBN 78
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_RESERVED3_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_MTU_DIV4_LBN 66
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_MTU_DIV4_WIDTH 12
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_VRI_OP_LBN 64
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_VRI_OP_WIDTH 2
+#define ESE_DZ_VRI_OP_INSERT_REPLACE 3
+#define ESE_DZ_VRI_OP_INSERT_INSERT 2
+#define ESE_DZ_VRI_OP_REPLACE 1
+#define ESE_DZ_VRI_OP_INSERT 0
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_PRV_LBN 63
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_PRV_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_LB_LBN 62
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_LB_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_MS0_LBN 61
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_MS0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_MS1_LBN 60
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_MS1_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_NDI_LBN 59
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_NDI_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_TXDP_CONTEXT_OUT_LBN 48
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_TXDP_CONTEXT_OUT_WIDTH 11
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_IPSEC_SA_LBN 32
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_IPSEC_SA_WIDTH 16
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_TX_STACK_ID_LBN 24
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_TX_STACK_ID_WIDTH 8
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_TX_DOMAIN_LBN 16
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_TX_DOMAIN_WIDTH 8
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_RESERVED1_LBN 14
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_RESERVED1_WIDTH 2
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_DST_P0_LBN 13
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_DST_P0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_DST_P1_LBN 12
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_DST_P1_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_DST_IP0_LBN 11
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_DST_IP0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_DST_IP1_LBN 10
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_DST_IP1_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_DST_PM_LBN 9
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_DST_PM_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_RESERVED0_LBN 8
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_RESERVED0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_IPSEC_LBN 7
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_IPSEC_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_PRIORITY_LBN 4
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_PRIORITY_WIDTH 3
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_SRC_LBN 0
+#define ESF_DZ_FLTR_INFO_TXDI_TO_TXDP_SRC_WIDTH 4
+
+
+/* ES_fltr_info_wrd_txdp_to_txdi */
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_VLAN_OP_LBN 62
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_VLAN_OP_WIDTH 2
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_RESERVED1_LBN 58
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_RESERVED1_WIDTH 4
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_TX_QID_LBN 48
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_TX_QID_WIDTH 10
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_INNER_VLAN_LBN 32
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_INNER_VLAN_WIDTH 16
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_OUTER_VLAN_LBN 16
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_OUTER_VLAN_WIDTH 16
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_TXDP_CONTEXT_IN_LBN 5
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_TXDP_CONTEXT_IN_WIDTH 11
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_RESERVED0_LBN 4
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_RESERVED0_WIDTH 1
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_SRC_LBN 0
+#define ESF_DZ_FLTR_INFO_TXDP_TO_TXDI_SRC_WIDTH 4
+
+
+/* ES_nwk_ev_merge_blk_cmd */
+#define ESF_DZ_EV_MERGE_BLK_COMMAND_OP_LBN 28
+#define ESF_DZ_EV_MERGE_BLK_COMMAND_OP_WIDTH 4
+#define ESE_DZ_EV_MERGE_BLK_COMMAND_OP_FLUSH 2
+#define ESE_DZ_EV_MERGE_BLK_COMMAND_OP_ENABLE 1
+#define ESE_DZ_EV_MERGE_BLK_COMMAND_OP_DISABLE 0
+#define ESF_DZ_EV_MERGE_BLK_COMMAND_BUSY_LBN 31
+#define ESF_DZ_EV_MERGE_BLK_COMMAND_BUSY_WIDTH 1
+#define ESF_DZ_EV_MERGE_BLK_COMMAND_EVQ_IDX_LBN 0
+#define ESF_DZ_EV_MERGE_BLK_COMMAND_EVQ_IDX_WIDTH 11
+
+
+/* ES_txpm2ini_cpl_rsp */
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_ECC_LBN 284
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_ECC_WIDTH 32
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_EOT_LBN 283
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_EOT_WIDTH 1
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW0_LBN 27
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW0_WIDTH 32
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW1_LBN 59
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW1_WIDTH 32
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW2_LBN 91
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW2_WIDTH 32
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW3_LBN 123
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW3_WIDTH 32
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW4_LBN 155
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW4_WIDTH 32
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW5_LBN 187
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW5_WIDTH 32
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW6_LBN 219
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW6_WIDTH 32
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW7_LBN 251
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_DW7_WIDTH 32
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_LBN 27
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_DATA_WIDTH 256
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_ERROR_LBN 26
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_ERROR_WIDTH 1
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_LAST_LBN 25
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_LAST_WIDTH 1
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_TAG_LBN 19
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_TAG_WIDTH 6
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_LEN_LBN 7
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_LEN_WIDTH 12
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_ADRS_LBN 0
+#define ESF_DZ_TXPM2INI_CPL_RSP_CPL_ADRS_WIDTH 7
+
-/* Enum DPCPU_INSTR_BRTYPE */
-#define ESE_DZ_BNEZAL 19
-#define ESE_DZ_BEQZAL 18
-#define ESE_DZ_BGEZAL 17
-#define ESE_DZ_BLTZAL 16
-#define ESE_DZ_BNEZ 3
-#define ESE_DZ_BEQZ 2
-#define ESE_DZ_BGEZ 1
-#define ESE_DZ_BLTZ 0
-
-/* Enum DPCPU_INSTR_FUNCT */
-#define ESE_DZ_MASKMOD 44
-#define ESE_DZ_SLTU 43
-#define ESE_DZ_SLT 42
-#define ESE_DZ_INCMOD 40
-#define ESE_DZ_NOR 39
-#define ESE_DZ_XOR 38
-#define ESE_DZ_OR 37
-#define ESE_DZ_AND 36
-#define ESE_DZ_SUBU 35
-#define ESE_DZ_SUB 34
-#define ESE_DZ_ADDU 33
-#define ESE_DZ_ADD 32
-#define ESE_DZ_MULT 25
-#define ESE_DZ_MFLO 18
-#define ESE_DZ_MFHI 16
-#define ESE_DZ_JALR 9
-#define ESE_DZ_JR 8
-#define ESE_DZ_SRAV 7
-#define ESE_DZ_SRLV 6
-#define ESE_DZ_SLLV 4
-#define ESE_DZ_SRA 3
-#define ESE_DZ_SRL 2
-#define ESE_DZ_SLL 0
-
-/* Enum DPCPU_INSTR_OP */
-#define ESE_DZ_LM_MSG 49
-#define ESE_DZ_MSG 48
-#define ESE_DZ_SHA 43
-#define ESE_DZ_SBA 42
-#define ESE_DZ_SH 41
-#define ESE_DZ_SB 40
-#define ESE_DZ_LHUA 39
-#define ESE_DZ_LBUA 38
-#define ESE_DZ_LHU 37
-#define ESE_DZ_LBU 36
-#define ESE_DZ_LHA 35
-#define ESE_DZ_LBA 34
-#define ESE_DZ_LH 33
-#define ESE_DZ_LB 32
-#define ESE_DZ_BGTU 31
-#define ESE_DZ_BLEU 30
-#define ESE_DZ_MODI 28
-#define ESE_DZ_NEGU 27
-#define ESE_DZ_NEG 26
-#define ESE_DZ_LI 25
-#define ESE_DZ_INCMODI 24
-#define ESE_DZ_BGT 23
-#define ESE_DZ_BLE 22
-#define ESE_DZ_BBS 21
-#define ESE_DZ_BBC 20
-#define ESE_DZ_JAL_EVT 19
-#define ESE_DZ_J_EVT 18
-#define ESE_DZ_HALT 16
-#define ESE_DZ_NORI 15
-#define ESE_DZ_XORI 14
-#define ESE_DZ_ORI 13
-#define ESE_DZ_ANDI 12
-#define ESE_DZ_SLTIU 11
-#define ESE_DZ_SLTI 10
-#define ESE_DZ_ADDIU 9
-#define ESE_DZ_ADDI 8
-#define ESE_DZ_BGTZ 7
-#define ESE_DZ_BLEZ 6
-#define ESE_DZ_BNE 5
-#define ESE_DZ_BEQ 4
-#define ESE_DZ_JAL 3
-#define ESE_DZ_J 2
-#define ESE_DZ_BRANCH 1
-#define ESE_DZ_REG2REG 0
-
-/* Enum DPCPU_MSG_DIR */
-#define ESE_DPCPU_MSG_DZ_OUTB 0x1
-#define ESE_DPCPU_MSG_DZ_INB 0x0
-
-/* Enum DPCPU_PDBUS_OP */
-#define ESE_DPCPU_PDBUS_DZ_RD 0x1
-#define ESE_DPCPU_PDBUS_DZ_WR 0x0
/* Enum INI_OP */
#define ESE_DZ_RD_COMPL 0x3
@@ -2778,6 +2891,19 @@ extern "C" {
#define ESE_DZ_MSI 0x1
#define ESE_DZ_MSIX 0x0
+/* Enum MC_PDMA_BUFFER_ID */
+#define ESE_DZ_MC_PDMA_BUFFER_ALL 4
+#define ESE_DZ_MC_PDMA_BUFFER_RXDP 3
+#define ESE_DZ_MC_PDMA_BUFFER_NCSI 2
+#define ESE_DZ_MC_PDMA_BUFFER_NWPORT1 1
+#define ESE_DZ_MC_PDMA_BUFFER_NWPORT0 0
+
+/* Enum MC_PDMA_INTERFACE_ID */
+#define ESE_DZ_MC_PDMA_INTERFACE_RXDP 3
+#define ESE_DZ_MC_PDMA_INTERFACE_NCSI 2
+#define ESE_DZ_MC_PDMA_INTERFACE_NWPORT1 1
+#define ESE_DZ_MC_PDMA_INTERFACE_NWPORT0 0
+
/* Enum PKT_STRM_CTL */
#define ESE_DZ_EOP_TRUNC 0x3
#define ESE_DZ_EOP_CRC_ERR 0x2
diff --git a/sys/dev/sfxge/common/efx_regs_mcdi.h b/sys/dev/sfxge/common/efx_regs_mcdi.h
index 9016ca9..bd35970 100644
--- a/sys/dev/sfxge/common/efx_regs_mcdi.h
+++ b/sys/dev/sfxge/common/efx_regs_mcdi.h
@@ -1,5 +1,5 @@
/*-
- * Copyright 2008-2011 Solarflare Communications Inc. All rights reserved.
+ * Copyright 2008-2013 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
@@ -39,6 +39,17 @@
#define MC_FW_STATE_BOOTING (4)
/* The Scheduler has started. */
#define MC_FW_STATE_SCHED (8)
+/* If this is set in MC_RESET_STATE_REG then it should be
+ * possible to jump into IMEM without loading code from flash.
+ * Unlike a warm boot, assume DMEM has been reloaded, so that
+ * the MC persistent data must be reinitialised. */
+#define MC_FW_TEPID_BOOT_OK (16)
+/* We have entered the main firmware via recovery mode. This
+ * means that MC persistent data must be reinitialised, but that
+ * we shouldn't touch PCIe config. */
+#define MC_FW_RECOVERY_MODE_PCIE_INIT_OK (32)
+/* BIST state has been initialized */
+#define MC_FW_BIST_INIT_OK (128)
/* Siena MC shared memmory offsets */
/* The 'doorbell' addresses are hard-wired to alert the MC when written */
@@ -57,6 +68,9 @@
#define MC_STATUS_DWORD_REBOOT (0xb007b007)
#define MC_STATUS_DWORD_ASSERT (0xdeaddead)
+/* Check whether an mcfw version (in host order) belongs to a bootloader */
+#define MC_FW_VERSION_IS_BOOTLOADER(_v) (((_v) >> 16) == 0xb007)
+
/* The current version of the MCDI protocol.
*
* Note that the ROM burnt into the card only talks V0, so at the very
@@ -72,7 +86,7 @@
/* MCDI version 1
*
- * Each MCDI request starts with an MCDI_HEADER, which is a 32byte
+ * Each MCDI request starts with an MCDI_HEADER, which is a 32bit
* structure, filled in by the client.
*
* 0 7 8 16 20 22 23 24 31
@@ -109,9 +123,11 @@
#define MCDI_HEADER_DATALEN_LBN 8
#define MCDI_HEADER_DATALEN_WIDTH 8
#define MCDI_HEADER_SEQ_LBN 16
-#define MCDI_HEADER_RSVD_LBN 20
-#define MCDI_HEADER_RSVD_WIDTH 2
#define MCDI_HEADER_SEQ_WIDTH 4
+#define MCDI_HEADER_RSVD_LBN 20
+#define MCDI_HEADER_RSVD_WIDTH 1
+#define MCDI_HEADER_NOT_EPOCH_LBN 21
+#define MCDI_HEADER_NOT_EPOCH_WIDTH 1
#define MCDI_HEADER_ERROR_LBN 22
#define MCDI_HEADER_ERROR_WIDTH 1
#define MCDI_HEADER_RESPONSE_LBN 23
@@ -122,12 +138,16 @@
#define MCDI_HEADER_XFLAGS_EVREQ 0x01
/* Maximum number of payload bytes */
+#define MCDI_CTL_SDU_LEN_MAX_V1 0xfc
+#define MCDI_CTL_SDU_LEN_MAX_V2 0x400
+
#ifdef WITH_MCDI_V2
-#define MCDI_CTL_SDU_LEN_MAX 0x400
+#define MCDI_CTL_SDU_LEN_MAX MCDI_CTL_SDU_LEN_MAX_V2
#else
-#define MCDI_CTL_SDU_LEN_MAX 0xfc
+#define MCDI_CTL_SDU_LEN_MAX MCDI_CTL_SDU_LEN_MAX_V1
#endif
+
/* The MC can generate events for two reasons:
* - To complete a shared memory request if XFLAGS_EVREQ was set
* - As a notification (link state, i2c event), controlled
@@ -171,22 +191,114 @@
#define FSE_AZ_EV_CODE_MCDI_EVRESPONSE 0xc
+/* Operation not permitted. */
+#define MC_CMD_ERR_EPERM 1
/* Non-existent command target */
#define MC_CMD_ERR_ENOENT 2
/* assert() has killed the MC */
#define MC_CMD_ERR_EINTR 4
+/* I/O failure */
+#define MC_CMD_ERR_EIO 5
+/* Already exists */
+#define MC_CMD_ERR_EEXIST 6
+/* Try again */
+#define MC_CMD_ERR_EAGAIN 11
+/* Out of memory */
+#define MC_CMD_ERR_ENOMEM 12
/* Caller does not hold required locks */
#define MC_CMD_ERR_EACCES 13
/* Resource is currently unavailable (e.g. lock contention) */
#define MC_CMD_ERR_EBUSY 16
+/* No such device */
+#define MC_CMD_ERR_ENODEV 19
/* Invalid argument to target */
#define MC_CMD_ERR_EINVAL 22
+/* Broken pipe */
+#define MC_CMD_ERR_EPIPE 32
+/* Read-only */
+#define MC_CMD_ERR_EROFS 30
+/* Out of range */
+#define MC_CMD_ERR_ERANGE 34
/* Non-recursive resource is already acquired */
#define MC_CMD_ERR_EDEADLK 35
/* Operation not implemented */
#define MC_CMD_ERR_ENOSYS 38
/* Operation timed out */
#define MC_CMD_ERR_ETIME 62
+/* Link has been severed */
+#define MC_CMD_ERR_ENOLINK 67
+/* Protocol error */
+#define MC_CMD_ERR_EPROTO 71
+/* Operation not supported */
+#define MC_CMD_ERR_ENOTSUP 95
+/* Address not available */
+#define MC_CMD_ERR_EADDRNOTAVAIL 99
+/* Not connected */
+#define MC_CMD_ERR_ENOTCONN 107
+/* Operation already in progress */
+#define MC_CMD_ERR_EALREADY 114
+
+/* Resource allocation failed. */
+#define MC_CMD_ERR_ALLOC_FAIL 0x1000
+/* V-adaptor not found. */
+#define MC_CMD_ERR_NO_VADAPTOR 0x1001
+/* EVB port not found. */
+#define MC_CMD_ERR_NO_EVB_PORT 0x1002
+/* V-switch not found. */
+#define MC_CMD_ERR_NO_VSWITCH 0x1003
+/* Too many VLAN tags. */
+#define MC_CMD_ERR_VLAN_LIMIT 0x1004
+/* Bad PCI function number. */
+#define MC_CMD_ERR_BAD_PCI_FUNC 0x1005
+/* Invalid VLAN mode. */
+#define MC_CMD_ERR_BAD_VLAN_MODE 0x1006
+/* Invalid v-switch type. */
+#define MC_CMD_ERR_BAD_VSWITCH_TYPE 0x1007
+/* Invalid v-port type. */
+#define MC_CMD_ERR_BAD_VPORT_TYPE 0x1008
+/* MAC address exists. */
+#define MC_CMD_ERR_MAC_EXIST 0x1009
+/* Slave core not present */
+#define MC_CMD_ERR_SLAVE_NOT_PRESENT 0x100a
+/* The datapath is disabled. */
+#define MC_CMD_ERR_DATAPATH_DISABLED 0x100b
+/* The requesting client is not a function */
+#define MC_CMD_ERR_CLIENT_NOT_FN 0x100c
+/* The requested operation might require the
+ command to be passed between MCs, and the
+ transport doesn't support that. Should
+ only ever been seen over the UART. */
+#define MC_CMD_ERR_TRANSPORT_NOPROXY 0x100d
+/* VLAN tag(s) exists */
+#define MC_CMD_ERR_VLAN_EXIST 0x100e
+/* No MAC address assigned to an EVB port */
+#define MC_CMD_ERR_NO_MAC_ADDR 0x100f
+/* Notifies the driver that the request has been relayed
+ * to an admin function for authorization. The driver should
+ * wait for a PROXY_RESPONSE event and then resend its request.
+ * This error code is followed by a 32-bit handle that
+ * helps matching it with the respective PROXY_RESPONSE event. */
+#define MC_CMD_ERR_PROXY_PENDING 0x1010
+#define MC_CMD_ERR_PROXY_PENDING_HANDLE_OFST 4
+/* The request cannot be passed for authorization because
+ * another request from the same function is currently being
+ * authorized. The drvier should try again later. */
+#define MC_CMD_ERR_PROXY_INPROGRESS 0x1011
+/* Returned by MC_CMD_PROXY_COMPLETE if the caller is not the function
+ * that has enabled proxying or BLOCK_INDEX points to a function that
+ * doesn't await an authorization. */
+#define MC_CMD_ERR_PROXY_UNEXPECTED 0x1012
+/* This code is currently only used internally in FW. Its meaning is that
+ * an operation failed due to lack of SR-IOV privilege.
+ * Normally it is translated to EPERM by send_cmd_err(),
+ * but it may also be used to trigger some special mechanism
+ * for handling such case, e.g. to relay the failed request
+ * to a designated admin function for authorization. */
+#define MC_CMD_ERR_NO_PRIVILEGE 0x1013
+/* Workaround 26807 could not be turned on/off because some functions
+ * have already installed filters. See the comment at
+ * MC_CMD_WORKAROUND_BUG26807. */
+#define MC_CMD_ERR_FILTERS_PRESENT 0x1014
#define MC_CMD_ERR_CODE_OFST 0
@@ -204,9 +316,11 @@
/* Vectors in the boot ROM */
/* Point to the copycode entry point. */
-#define MC_BOOTROM_COPYCODE_VEC (0x7f4)
+#define SIENA_MC_BOOTROM_COPYCODE_VEC (0x800 - 3 * 0x4)
+#define HUNT_MC_BOOTROM_COPYCODE_VEC (0x8000 - 3 * 0x4)
/* Points to the recovery mode entry point. */
-#define MC_BOOTROM_NOFLASH_VEC (0x7f8)
+#define SIENA_MC_BOOTROM_NOFLASH_VEC (0x800 - 2 * 0x4)
+#define HUNT_MC_BOOTROM_NOFLASH_VEC (0x8000 - 2 * 0x4)
/* The command set exported by the boot ROM (MCDI v0) */
#define MC_CMD_GET_VERSION_V0_SUPPORTED_FUNCS { \
@@ -216,23 +330,28 @@
(1 << MC_CMD_GET_VERSION), \
0, 0, 0 }
-#define MC_CMD_SENSOR_INFO_OUT_OFFSET_OFST(_x) \
+#define MC_CMD_SENSOR_INFO_OUT_OFFSET_OFST(_x) \
(MC_CMD_SENSOR_ENTRY_OFST + (_x))
-#define MC_CMD_DBI_WRITE_IN_ADDRESS_OFST(n) ( \
- (MC_CMD_DBI_WRITE_IN_DBIWROP_OFST+ \
- MC_CMD_DBIWROP_TYPEDEF_ADDRESS_OFST)+ \
- ((n)*MC_CMD_DBIWROP_TYPEDEF_LEN))
+#define MC_CMD_DBI_WRITE_IN_ADDRESS_OFST(n) \
+ (MC_CMD_DBI_WRITE_IN_DBIWROP_OFST + \
+ MC_CMD_DBIWROP_TYPEDEF_ADDRESS_OFST + \
+ (n) * MC_CMD_DBIWROP_TYPEDEF_LEN)
-#define MC_CMD_DBI_WRITE_IN_BYTE_MASK_OFST(n) ( \
- (MC_CMD_DBI_WRITE_IN_DBIWROP_OFST+ \
- MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_OFST)+ \
- ((n)*MC_CMD_DBIWROP_TYPEDEF_LEN))
+#define MC_CMD_DBI_WRITE_IN_BYTE_MASK_OFST(n) \
+ (MC_CMD_DBI_WRITE_IN_DBIWROP_OFST + \
+ MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_OFST + \
+ (n) * MC_CMD_DBIWROP_TYPEDEF_LEN)
-#define MC_CMD_DBI_WRITE_IN_VALUE_OFST(n) ( \
- (MC_CMD_DBI_WRITE_IN_DBIWROP_OFST+ \
- MC_CMD_DBIWROP_TYPEDEF_VALUE_OFST)+ \
- ((n)*MC_CMD_DBIWROP_TYPEDEF_LEN))
+#define MC_CMD_DBI_WRITE_IN_VALUE_OFST(n) \
+ (MC_CMD_DBI_WRITE_IN_DBIWROP_OFST + \
+ MC_CMD_DBIWROP_TYPEDEF_VALUE_OFST + \
+ (n) * MC_CMD_DBIWROP_TYPEDEF_LEN)
+
+/* This may be ORed with an EVB_PORT_ID_xxx constant to pass a non-default
+ * stack ID (which must be in the range 1-255) along with an EVB port ID.
+ */
+#define EVB_STACK_ID(n) (((n) & 0xff) << 16)
#ifdef WITH_MCDI_V2
@@ -243,8 +362,6 @@
*/
#define MC_CMD_ERR_ARG_OFST 4
-/* Try again */
-#define MC_CMD_ERR_EAGAIN 11
/* No space */
#define MC_CMD_ERR_ENOSPC 28
@@ -256,10 +373,14 @@
#define MCDI_EVENT_CONT_WIDTH 1
#define MCDI_EVENT_LEVEL_LBN 33
#define MCDI_EVENT_LEVEL_WIDTH 3
-#define MCDI_EVENT_LEVEL_INFO 0x0 /* enum */
-#define MCDI_EVENT_LEVEL_WARN 0x1 /* enum */
-#define MCDI_EVENT_LEVEL_ERR 0x2 /* enum */
-#define MCDI_EVENT_LEVEL_FATAL 0x3 /* enum */
+/* enum: Info. */
+#define MCDI_EVENT_LEVEL_INFO 0x0
+/* enum: Warning. */
+#define MCDI_EVENT_LEVEL_WARN 0x1
+/* enum: Error. */
+#define MCDI_EVENT_LEVEL_ERR 0x2
+/* enum: Fatal. */
+#define MCDI_EVENT_LEVEL_FATAL 0x3
#define MCDI_EVENT_DATA_OFST 0
#define MCDI_EVENT_CMDDONE_SEQ_LBN 0
#define MCDI_EVENT_CMDDONE_SEQ_WIDTH 8
@@ -271,9 +392,14 @@
#define MCDI_EVENT_LINKCHANGE_LP_CAP_WIDTH 16
#define MCDI_EVENT_LINKCHANGE_SPEED_LBN 16
#define MCDI_EVENT_LINKCHANGE_SPEED_WIDTH 4
-#define MCDI_EVENT_LINKCHANGE_SPEED_100M 0x1 /* enum */
-#define MCDI_EVENT_LINKCHANGE_SPEED_1G 0x2 /* enum */
-#define MCDI_EVENT_LINKCHANGE_SPEED_10G 0x3 /* enum */
+/* enum: 100Mbs */
+#define MCDI_EVENT_LINKCHANGE_SPEED_100M 0x1
+/* enum: 1Gbs */
+#define MCDI_EVENT_LINKCHANGE_SPEED_1G 0x2
+/* enum: 10Gbs */
+#define MCDI_EVENT_LINKCHANGE_SPEED_10G 0x3
+/* enum: 40Gbs */
+#define MCDI_EVENT_LINKCHANGE_SPEED_40G 0x4
#define MCDI_EVENT_LINKCHANGE_FCNTL_LBN 20
#define MCDI_EVENT_LINKCHANGE_FCNTL_WIDTH 4
#define MCDI_EVENT_LINKCHANGE_LINK_FLAGS_LBN 24
@@ -288,41 +414,94 @@
#define MCDI_EVENT_FWALERT_DATA_WIDTH 24
#define MCDI_EVENT_FWALERT_REASON_LBN 0
#define MCDI_EVENT_FWALERT_REASON_WIDTH 8
-#define MCDI_EVENT_FWALERT_REASON_SRAM_ACCESS 0x1 /* enum */
+/* enum: SRAM Access. */
+#define MCDI_EVENT_FWALERT_REASON_SRAM_ACCESS 0x1
#define MCDI_EVENT_FLR_VF_LBN 0
#define MCDI_EVENT_FLR_VF_WIDTH 8
#define MCDI_EVENT_TX_ERR_TXQ_LBN 0
#define MCDI_EVENT_TX_ERR_TXQ_WIDTH 12
#define MCDI_EVENT_TX_ERR_TYPE_LBN 12
#define MCDI_EVENT_TX_ERR_TYPE_WIDTH 4
-#define MCDI_EVENT_TX_ERR_DL_FAIL 0x1 /* enum */
-#define MCDI_EVENT_TX_ERR_NO_EOP 0x2 /* enum */
-#define MCDI_EVENT_TX_ERR_2BIG 0x3 /* enum */
+/* enum: Descriptor loader reported failure */
+#define MCDI_EVENT_TX_ERR_DL_FAIL 0x1
+/* enum: Descriptor ring empty and no EOP seen for packet */
+#define MCDI_EVENT_TX_ERR_NO_EOP 0x2
+/* enum: Overlength packet */
+#define MCDI_EVENT_TX_ERR_2BIG 0x3
+/* enum: Malformed option descriptor */
+#define MCDI_EVENT_TX_BAD_OPTDESC 0x5
+/* enum: Option descriptor part way through a packet */
+#define MCDI_EVENT_TX_OPT_IN_PKT 0x8
+/* enum: DMA or PIO data access error */
+#define MCDI_EVENT_TX_ERR_BAD_DMA_OR_PIO 0x9
#define MCDI_EVENT_TX_ERR_INFO_LBN 16
#define MCDI_EVENT_TX_ERR_INFO_WIDTH 16
+#define MCDI_EVENT_TX_FLUSH_TO_DRIVER_LBN 12
+#define MCDI_EVENT_TX_FLUSH_TO_DRIVER_WIDTH 1
#define MCDI_EVENT_TX_FLUSH_TXQ_LBN 0
#define MCDI_EVENT_TX_FLUSH_TXQ_WIDTH 12
#define MCDI_EVENT_PTP_ERR_TYPE_LBN 0
#define MCDI_EVENT_PTP_ERR_TYPE_WIDTH 8
-#define MCDI_EVENT_PTP_ERR_PLL_LOST 0x1 /* enum */
-#define MCDI_EVENT_PTP_ERR_FILTER 0x2 /* enum */
-#define MCDI_EVENT_PTP_ERR_FIFO 0x3 /* enum */
-#define MCDI_EVENT_PTP_ERR_QUEUE 0x4 /* enum */
+/* enum: PLL lost lock */
+#define MCDI_EVENT_PTP_ERR_PLL_LOST 0x1
+/* enum: Filter overflow (PDMA) */
+#define MCDI_EVENT_PTP_ERR_FILTER 0x2
+/* enum: FIFO overflow (FPGA) */
+#define MCDI_EVENT_PTP_ERR_FIFO 0x3
+/* enum: Merge queue overflow */
+#define MCDI_EVENT_PTP_ERR_QUEUE 0x4
#define MCDI_EVENT_AOE_ERR_TYPE_LBN 0
#define MCDI_EVENT_AOE_ERR_TYPE_WIDTH 8
-#define MCDI_EVENT_AOE_NO_LOAD 0x1 /* enum */
-#define MCDI_EVENT_AOE_FC_ASSERT 0x2 /* enum */
-#define MCDI_EVENT_AOE_FC_WATCHDOG 0x3 /* enum */
-#define MCDI_EVENT_AOE_FC_NO_START 0x4 /* enum */
-#define MCDI_EVENT_AOE_FAULT 0x5 /* enum */
-#define MCDI_EVENT_AOE_CPLD_REPROGRAMMED 0x6 /* enum */
-#define MCDI_EVENT_AOE_LOAD 0x7 /* enum */
-#define MCDI_EVENT_AOE_DMA 0x8 /* enum */
-#define MCDI_EVENT_AOE_BYTEBLASTER 0x9 /* enum */
-#define MCDI_EVENT_AOE_DDR_ECC_STATUS 0xa /* enum */
-#define MCDI_EVENT_AOE_PTP_STATUS 0xb /* enum */
+/* enum: AOE failed to load - no valid image? */
+#define MCDI_EVENT_AOE_NO_LOAD 0x1
+/* enum: AOE FC reported an exception */
+#define MCDI_EVENT_AOE_FC_ASSERT 0x2
+/* enum: AOE FC watchdogged */
+#define MCDI_EVENT_AOE_FC_WATCHDOG 0x3
+/* enum: AOE FC failed to start */
+#define MCDI_EVENT_AOE_FC_NO_START 0x4
+/* enum: Generic AOE fault - likely to have been reported via other means too
+ * but intended for use by aoex driver.
+ */
+#define MCDI_EVENT_AOE_FAULT 0x5
+/* enum: Results of reprogramming the CPLD (status in AOE_ERR_DATA) */
+#define MCDI_EVENT_AOE_CPLD_REPROGRAMMED 0x6
+/* enum: AOE loaded successfully */
+#define MCDI_EVENT_AOE_LOAD 0x7
+/* enum: AOE DMA operation completed (LSB of HOST_HANDLE in AOE_ERR_DATA) */
+#define MCDI_EVENT_AOE_DMA 0x8
+/* enum: AOE byteblaster connected/disconnected (Connection status in
+ * AOE_ERR_DATA)
+ */
+#define MCDI_EVENT_AOE_BYTEBLASTER 0x9
+/* enum: DDR ECC status update */
+#define MCDI_EVENT_AOE_DDR_ECC_STATUS 0xa
+/* enum: PTP status update */
+#define MCDI_EVENT_AOE_PTP_STATUS 0xb
#define MCDI_EVENT_AOE_ERR_DATA_LBN 8
#define MCDI_EVENT_AOE_ERR_DATA_WIDTH 8
+#define MCDI_EVENT_RX_ERR_RXQ_LBN 0
+#define MCDI_EVENT_RX_ERR_RXQ_WIDTH 12
+#define MCDI_EVENT_RX_ERR_TYPE_LBN 12
+#define MCDI_EVENT_RX_ERR_TYPE_WIDTH 4
+#define MCDI_EVENT_RX_ERR_INFO_LBN 16
+#define MCDI_EVENT_RX_ERR_INFO_WIDTH 16
+#define MCDI_EVENT_RX_FLUSH_TO_DRIVER_LBN 12
+#define MCDI_EVENT_RX_FLUSH_TO_DRIVER_WIDTH 1
+#define MCDI_EVENT_RX_FLUSH_RXQ_LBN 0
+#define MCDI_EVENT_RX_FLUSH_RXQ_WIDTH 12
+#define MCDI_EVENT_MC_REBOOT_COUNT_LBN 0
+#define MCDI_EVENT_MC_REBOOT_COUNT_WIDTH 16
+#define MCDI_EVENT_MUM_ERR_TYPE_LBN 0
+#define MCDI_EVENT_MUM_ERR_TYPE_WIDTH 8
+/* enum: MUM failed to load - no valid image? */
+#define MCDI_EVENT_MUM_NO_LOAD 0x1
+/* enum: MUM f/w reported an exception */
+#define MCDI_EVENT_MUM_ASSERT 0x2
+/* enum: MUM not kicking watchdog */
+#define MCDI_EVENT_MUM_WATCHDOG 0x3
+#define MCDI_EVENT_MUM_ERR_DATA_LBN 8
+#define MCDI_EVENT_MUM_ERR_DATA_WIDTH 8
#define MCDI_EVENT_DATA_LBN 0
#define MCDI_EVENT_DATA_WIDTH 32
#define MCDI_EVENT_SRC_LBN 36
@@ -331,24 +510,74 @@
#define MCDI_EVENT_EV_CODE_WIDTH 4
#define MCDI_EVENT_CODE_LBN 44
#define MCDI_EVENT_CODE_WIDTH 8
-#define MCDI_EVENT_CODE_BADSSERT 0x1 /* enum */
-#define MCDI_EVENT_CODE_PMNOTICE 0x2 /* enum */
-#define MCDI_EVENT_CODE_CMDDONE 0x3 /* enum */
-#define MCDI_EVENT_CODE_LINKCHANGE 0x4 /* enum */
-#define MCDI_EVENT_CODE_SENSOREVT 0x5 /* enum */
-#define MCDI_EVENT_CODE_SCHEDERR 0x6 /* enum */
-#define MCDI_EVENT_CODE_REBOOT 0x7 /* enum */
-#define MCDI_EVENT_CODE_MAC_STATS_DMA 0x8 /* enum */
-#define MCDI_EVENT_CODE_FWALERT 0x9 /* enum */
-#define MCDI_EVENT_CODE_FLR 0xa /* enum */
-#define MCDI_EVENT_CODE_TX_ERR 0xb /* enum */
-#define MCDI_EVENT_CODE_TX_FLUSH 0xc /* enum */
-#define MCDI_EVENT_CODE_PTP_RX 0xd /* enum */
-#define MCDI_EVENT_CODE_PTP_FAULT 0xe /* enum */
-#define MCDI_EVENT_CODE_PTP_PPS 0xf /* enum */
-#define MCDI_EVENT_CODE_AOE 0x12 /* enum */
-#define MCDI_EVENT_CODE_VCAL_FAIL 0x13 /* enum */
-#define MCDI_EVENT_CODE_HW_PPS 0x14 /* enum */
+/* enum: Event generated by host software */
+#define MCDI_EVENT_SW_EVENT 0x0
+/* enum: Bad assert. */
+#define MCDI_EVENT_CODE_BADSSERT 0x1
+/* enum: PM Notice. */
+#define MCDI_EVENT_CODE_PMNOTICE 0x2
+/* enum: Command done. */
+#define MCDI_EVENT_CODE_CMDDONE 0x3
+/* enum: Link change. */
+#define MCDI_EVENT_CODE_LINKCHANGE 0x4
+/* enum: Sensor Event. */
+#define MCDI_EVENT_CODE_SENSOREVT 0x5
+/* enum: Schedule error. */
+#define MCDI_EVENT_CODE_SCHEDERR 0x6
+/* enum: Reboot. */
+#define MCDI_EVENT_CODE_REBOOT 0x7
+/* enum: Mac stats DMA. */
+#define MCDI_EVENT_CODE_MAC_STATS_DMA 0x8
+/* enum: Firmware alert. */
+#define MCDI_EVENT_CODE_FWALERT 0x9
+/* enum: Function level reset. */
+#define MCDI_EVENT_CODE_FLR 0xa
+/* enum: Transmit error */
+#define MCDI_EVENT_CODE_TX_ERR 0xb
+/* enum: Tx flush has completed */
+#define MCDI_EVENT_CODE_TX_FLUSH 0xc
+/* enum: PTP packet received timestamp */
+#define MCDI_EVENT_CODE_PTP_RX 0xd
+/* enum: PTP NIC failure */
+#define MCDI_EVENT_CODE_PTP_FAULT 0xe
+/* enum: PTP PPS event */
+#define MCDI_EVENT_CODE_PTP_PPS 0xf
+/* enum: Rx flush has completed */
+#define MCDI_EVENT_CODE_RX_FLUSH 0x10
+/* enum: Receive error */
+#define MCDI_EVENT_CODE_RX_ERR 0x11
+/* enum: AOE fault */
+#define MCDI_EVENT_CODE_AOE 0x12
+/* enum: Network port calibration failed (VCAL). */
+#define MCDI_EVENT_CODE_VCAL_FAIL 0x13
+/* enum: HW PPS event */
+#define MCDI_EVENT_CODE_HW_PPS 0x14
+/* enum: The MC has rebooted (huntington and later, siena uses CODE_REBOOT and
+ * a different format)
+ */
+#define MCDI_EVENT_CODE_MC_REBOOT 0x15
+/* enum: the MC has detected a parity error */
+#define MCDI_EVENT_CODE_PAR_ERR 0x16
+/* enum: the MC has detected a correctable error */
+#define MCDI_EVENT_CODE_ECC_CORR_ERR 0x17
+/* enum: the MC has detected an uncorrectable error */
+#define MCDI_EVENT_CODE_ECC_FATAL_ERR 0x18
+/* enum: The MC has entered offline BIST mode */
+#define MCDI_EVENT_CODE_MC_BIST 0x19
+/* enum: PTP tick event providing current NIC time */
+#define MCDI_EVENT_CODE_PTP_TIME 0x1a
+/* enum: MUM fault */
+#define MCDI_EVENT_CODE_MUM 0x1b
+/* enum: notify the designated PF of a new authorization request */
+#define MCDI_EVENT_CODE_PROXY_REQUEST 0x1c
+/* enum: notify a function that awaits an authorization that its request has
+ * been processed and it may now resend the command
+ */
+#define MCDI_EVENT_CODE_PROXY_RESPONSE 0x1d
+/* enum: Artificial event generated by host and posted via MC for test
+ * purposes.
+ */
+#define MCDI_EVENT_CODE_TESTGEN 0xfa
#define MCDI_EVENT_CMDDONE_DATA_OFST 0
#define MCDI_EVENT_CMDDONE_DATA_LBN 0
#define MCDI_EVENT_CMDDONE_DATA_WIDTH 32
@@ -364,15 +593,81 @@
#define MCDI_EVENT_TX_ERR_DATA_OFST 0
#define MCDI_EVENT_TX_ERR_DATA_LBN 0
#define MCDI_EVENT_TX_ERR_DATA_WIDTH 32
+/* For CODE_PTP_RX, CODE_PTP_PPS and CODE_HW_PPS events the seconds field of
+ * timestamp
+ */
#define MCDI_EVENT_PTP_SECONDS_OFST 0
#define MCDI_EVENT_PTP_SECONDS_LBN 0
#define MCDI_EVENT_PTP_SECONDS_WIDTH 32
+/* For CODE_PTP_RX, CODE_PTP_PPS and CODE_HW_PPS events the major field of
+ * timestamp
+ */
+#define MCDI_EVENT_PTP_MAJOR_OFST 0
+#define MCDI_EVENT_PTP_MAJOR_LBN 0
+#define MCDI_EVENT_PTP_MAJOR_WIDTH 32
+/* For CODE_PTP_RX, CODE_PTP_PPS and CODE_HW_PPS events the nanoseconds field
+ * of timestamp
+ */
#define MCDI_EVENT_PTP_NANOSECONDS_OFST 0
#define MCDI_EVENT_PTP_NANOSECONDS_LBN 0
#define MCDI_EVENT_PTP_NANOSECONDS_WIDTH 32
+/* For CODE_PTP_RX, CODE_PTP_PPS and CODE_HW_PPS events the minor field of
+ * timestamp
+ */
+#define MCDI_EVENT_PTP_MINOR_OFST 0
+#define MCDI_EVENT_PTP_MINOR_LBN 0
+#define MCDI_EVENT_PTP_MINOR_WIDTH 32
+/* For CODE_PTP_RX events, the lowest four bytes of sourceUUID from PTP packet
+ */
#define MCDI_EVENT_PTP_UUID_OFST 0
#define MCDI_EVENT_PTP_UUID_LBN 0
#define MCDI_EVENT_PTP_UUID_WIDTH 32
+#define MCDI_EVENT_RX_ERR_DATA_OFST 0
+#define MCDI_EVENT_RX_ERR_DATA_LBN 0
+#define MCDI_EVENT_RX_ERR_DATA_WIDTH 32
+#define MCDI_EVENT_PAR_ERR_DATA_OFST 0
+#define MCDI_EVENT_PAR_ERR_DATA_LBN 0
+#define MCDI_EVENT_PAR_ERR_DATA_WIDTH 32
+#define MCDI_EVENT_ECC_CORR_ERR_DATA_OFST 0
+#define MCDI_EVENT_ECC_CORR_ERR_DATA_LBN 0
+#define MCDI_EVENT_ECC_CORR_ERR_DATA_WIDTH 32
+#define MCDI_EVENT_ECC_FATAL_ERR_DATA_OFST 0
+#define MCDI_EVENT_ECC_FATAL_ERR_DATA_LBN 0
+#define MCDI_EVENT_ECC_FATAL_ERR_DATA_WIDTH 32
+/* For CODE_PTP_TIME events, the major value of the PTP clock */
+#define MCDI_EVENT_PTP_TIME_MAJOR_OFST 0
+#define MCDI_EVENT_PTP_TIME_MAJOR_LBN 0
+#define MCDI_EVENT_PTP_TIME_MAJOR_WIDTH 32
+/* For CODE_PTP_TIME events, bits 19-26 of the minor value of the PTP clock */
+#define MCDI_EVENT_PTP_TIME_MINOR_26_19_LBN 36
+#define MCDI_EVENT_PTP_TIME_MINOR_26_19_WIDTH 8
+/* For CODE_PTP_TIME events where report sync status is enabled, indicates
+ * whether the NIC clock has ever been set
+ */
+#define MCDI_EVENT_PTP_TIME_NIC_CLOCK_VALID_LBN 36
+#define MCDI_EVENT_PTP_TIME_NIC_CLOCK_VALID_WIDTH 1
+/* For CODE_PTP_TIME events where report sync status is enabled, indicates
+ * whether the NIC and System clocks are in sync
+ */
+#define MCDI_EVENT_PTP_TIME_HOST_NIC_IN_SYNC_LBN 37
+#define MCDI_EVENT_PTP_TIME_HOST_NIC_IN_SYNC_WIDTH 1
+/* For CODE_PTP_TIME events where report sync status is enabled, bits 21-26 of
+ * the minor value of the PTP clock
+ */
+#define MCDI_EVENT_PTP_TIME_MINOR_26_21_LBN 38
+#define MCDI_EVENT_PTP_TIME_MINOR_26_21_WIDTH 6
+#define MCDI_EVENT_PROXY_REQUEST_BUFF_INDEX_OFST 0
+#define MCDI_EVENT_PROXY_REQUEST_BUFF_INDEX_LBN 0
+#define MCDI_EVENT_PROXY_REQUEST_BUFF_INDEX_WIDTH 32
+#define MCDI_EVENT_PROXY_RESPONSE_HANDLE_OFST 0
+#define MCDI_EVENT_PROXY_RESPONSE_HANDLE_LBN 0
+#define MCDI_EVENT_PROXY_RESPONSE_HANDLE_WIDTH 32
+/* Zero means that the request has been completed or authorized, and the driver
+ * should resend it. A non-zero value means that the authorization has been
+ * denied, and gives the reason. Typically it will be EPERM.
+ */
+#define MCDI_EVENT_PROXY_RESPONSE_RC_LBN 36
+#define MCDI_EVENT_PROXY_RESPONSE_RC_WIDTH 8
/* FCDI_EVENT structuredef */
#define FCDI_EVENT_LEN 8
@@ -380,10 +675,14 @@
#define FCDI_EVENT_CONT_WIDTH 1
#define FCDI_EVENT_LEVEL_LBN 33
#define FCDI_EVENT_LEVEL_WIDTH 3
-#define FCDI_EVENT_LEVEL_INFO 0x0 /* enum */
-#define FCDI_EVENT_LEVEL_WARN 0x1 /* enum */
-#define FCDI_EVENT_LEVEL_ERR 0x2 /* enum */
-#define FCDI_EVENT_LEVEL_FATAL 0x3 /* enum */
+/* enum: Info. */
+#define FCDI_EVENT_LEVEL_INFO 0x0
+/* enum: Warning. */
+#define FCDI_EVENT_LEVEL_WARN 0x1
+/* enum: Error. */
+#define FCDI_EVENT_LEVEL_ERR 0x2
+/* enum: Fatal. */
+#define FCDI_EVENT_LEVEL_FATAL 0x3
#define FCDI_EVENT_DATA_OFST 0
#define FCDI_EVENT_LINK_STATE_STATUS_LBN 0
#define FCDI_EVENT_LINK_STATE_STATUS_WIDTH 1
@@ -397,15 +696,26 @@
#define FCDI_EVENT_EV_CODE_WIDTH 4
#define FCDI_EVENT_CODE_LBN 44
#define FCDI_EVENT_CODE_WIDTH 8
-#define FCDI_EVENT_CODE_REBOOT 0x1 /* enum */
-#define FCDI_EVENT_CODE_ASSERT 0x2 /* enum */
-#define FCDI_EVENT_CODE_DDR_TEST_RESULT 0x3 /* enum */
-#define FCDI_EVENT_CODE_LINK_STATE 0x4 /* enum */
-#define FCDI_EVENT_CODE_TIMED_READ 0x5 /* enum */
-#define FCDI_EVENT_CODE_PPS_IN 0x6 /* enum */
-#define FCDI_EVENT_CODE_PTP_TICK 0x7 /* enum */
-#define FCDI_EVENT_CODE_DDR_ECC_STATUS 0x8 /* enum */
-#define FCDI_EVENT_CODE_PTP_STATUS 0x9 /* enum */
+/* enum: The FC was rebooted. */
+#define FCDI_EVENT_CODE_REBOOT 0x1
+/* enum: Bad assert. */
+#define FCDI_EVENT_CODE_ASSERT 0x2
+/* enum: DDR3 test result. */
+#define FCDI_EVENT_CODE_DDR_TEST_RESULT 0x3
+/* enum: Link status. */
+#define FCDI_EVENT_CODE_LINK_STATE 0x4
+/* enum: A timed read is ready to be serviced. */
+#define FCDI_EVENT_CODE_TIMED_READ 0x5
+/* enum: One or more PPS IN events */
+#define FCDI_EVENT_CODE_PPS_IN 0x6
+/* enum: Tick event from PTP clock */
+#define FCDI_EVENT_CODE_PTP_TICK 0x7
+/* enum: ECC error counters */
+#define FCDI_EVENT_CODE_DDR_ECC_STATUS 0x8
+/* enum: Current status of PTP */
+#define FCDI_EVENT_CODE_PTP_STATUS 0x9
+/* enum: Port id config to map MC-FC port idx */
+#define FCDI_EVENT_CODE_PORT_CONFIG 0xa
#define FCDI_EVENT_ASSERT_INSTR_ADDRESS_OFST 0
#define FCDI_EVENT_ASSERT_INSTR_ADDRESS_LBN 0
#define FCDI_EVENT_ASSERT_INSTR_ADDRESS_WIDTH 32
@@ -430,20 +740,36 @@
#define FCDI_EVENT_DDR_ECC_STATUS_STATUS_OFST 0
#define FCDI_EVENT_DDR_ECC_STATUS_STATUS_LBN 0
#define FCDI_EVENT_DDR_ECC_STATUS_STATUS_WIDTH 32
-
-/* FCDI_EXTENDED_EVENT_PPS structuredef */
+/* Index of MC port being referred to */
+#define FCDI_EVENT_PORT_CONFIG_SRC_LBN 36
+#define FCDI_EVENT_PORT_CONFIG_SRC_WIDTH 8
+/* FC Port index that matches the MC port index in SRC */
+#define FCDI_EVENT_PORT_CONFIG_DATA_OFST 0
+#define FCDI_EVENT_PORT_CONFIG_DATA_LBN 0
+#define FCDI_EVENT_PORT_CONFIG_DATA_WIDTH 32
+
+/* FCDI_EXTENDED_EVENT_PPS structuredef: Extended FCDI event to send PPS events
+ * to the MC. Note that this structure | is overlayed over a normal FCDI event
+ * such that bits 32-63 containing | event code, level, source etc remain the
+ * same. In this case the data | field of the header is defined to be the
+ * number of timestamps
+ */
#define FCDI_EXTENDED_EVENT_PPS_LENMIN 16
#define FCDI_EXTENDED_EVENT_PPS_LENMAX 248
#define FCDI_EXTENDED_EVENT_PPS_LEN(num) (8+8*(num))
+/* Number of timestamps following */
#define FCDI_EXTENDED_EVENT_PPS_COUNT_OFST 0
#define FCDI_EXTENDED_EVENT_PPS_COUNT_LBN 0
#define FCDI_EXTENDED_EVENT_PPS_COUNT_WIDTH 32
+/* Seconds field of a timestamp record */
#define FCDI_EXTENDED_EVENT_PPS_SECONDS_OFST 8
#define FCDI_EXTENDED_EVENT_PPS_SECONDS_LBN 64
#define FCDI_EXTENDED_EVENT_PPS_SECONDS_WIDTH 32
+/* Nanoseconds field of a timestamp record */
#define FCDI_EXTENDED_EVENT_PPS_NANOSECONDS_OFST 12
#define FCDI_EXTENDED_EVENT_PPS_NANOSECONDS_LBN 96
#define FCDI_EXTENDED_EVENT_PPS_NANOSECONDS_WIDTH 32
+/* Timestamp records comprising the event */
#define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_OFST 8
#define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_LEN 8
#define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_LO_OFST 8
@@ -453,12 +779,99 @@
#define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_LBN 64
#define FCDI_EXTENDED_EVENT_PPS_TIMESTAMPS_WIDTH 64
+/* MUM_EVENT structuredef */
+#define MUM_EVENT_LEN 8
+#define MUM_EVENT_CONT_LBN 32
+#define MUM_EVENT_CONT_WIDTH 1
+#define MUM_EVENT_LEVEL_LBN 33
+#define MUM_EVENT_LEVEL_WIDTH 3
+/* enum: Info. */
+#define MUM_EVENT_LEVEL_INFO 0x0
+/* enum: Warning. */
+#define MUM_EVENT_LEVEL_WARN 0x1
+/* enum: Error. */
+#define MUM_EVENT_LEVEL_ERR 0x2
+/* enum: Fatal. */
+#define MUM_EVENT_LEVEL_FATAL 0x3
+#define MUM_EVENT_DATA_OFST 0
+#define MUM_EVENT_SENSOR_ID_LBN 0
+#define MUM_EVENT_SENSOR_ID_WIDTH 8
+/* Enum values, see field(s): */
+/* MC_CMD_SENSOR_INFO/MC_CMD_SENSOR_INFO_OUT/MASK */
+#define MUM_EVENT_SENSOR_STATE_LBN 8
+#define MUM_EVENT_SENSOR_STATE_WIDTH 8
+#define MUM_EVENT_PORT_PHY_READY_LBN 0
+#define MUM_EVENT_PORT_PHY_READY_WIDTH 1
+#define MUM_EVENT_PORT_PHY_LINK_UP_LBN 1
+#define MUM_EVENT_PORT_PHY_LINK_UP_WIDTH 1
+#define MUM_EVENT_PORT_PHY_TX_LOL_LBN 2
+#define MUM_EVENT_PORT_PHY_TX_LOL_WIDTH 1
+#define MUM_EVENT_PORT_PHY_RX_LOL_LBN 3
+#define MUM_EVENT_PORT_PHY_RX_LOL_WIDTH 1
+#define MUM_EVENT_PORT_PHY_TX_LOS_LBN 4
+#define MUM_EVENT_PORT_PHY_TX_LOS_WIDTH 1
+#define MUM_EVENT_PORT_PHY_RX_LOS_LBN 5
+#define MUM_EVENT_PORT_PHY_RX_LOS_WIDTH 1
+#define MUM_EVENT_PORT_PHY_TX_FAULT_LBN 6
+#define MUM_EVENT_PORT_PHY_TX_FAULT_WIDTH 1
+#define MUM_EVENT_DATA_LBN 0
+#define MUM_EVENT_DATA_WIDTH 32
+#define MUM_EVENT_SRC_LBN 36
+#define MUM_EVENT_SRC_WIDTH 8
+#define MUM_EVENT_EV_CODE_LBN 60
+#define MUM_EVENT_EV_CODE_WIDTH 4
+#define MUM_EVENT_CODE_LBN 44
+#define MUM_EVENT_CODE_WIDTH 8
+/* enum: The MUM was rebooted. */
+#define MUM_EVENT_CODE_REBOOT 0x1
+/* enum: Bad assert. */
+#define MUM_EVENT_CODE_ASSERT 0x2
+/* enum: Sensor failure. */
+#define MUM_EVENT_CODE_SENSOR 0x3
+/* enum: Link fault has been asserted, or has cleared. */
+#define MUM_EVENT_CODE_QSFP_LASI_INTERRUPT 0x4
+#define MUM_EVENT_SENSOR_DATA_OFST 0
+#define MUM_EVENT_SENSOR_DATA_LBN 0
+#define MUM_EVENT_SENSOR_DATA_WIDTH 32
+#define MUM_EVENT_PORT_PHY_FLAGS_OFST 0
+#define MUM_EVENT_PORT_PHY_FLAGS_LBN 0
+#define MUM_EVENT_PORT_PHY_FLAGS_WIDTH 32
+#define MUM_EVENT_PORT_PHY_COPPER_LEN_OFST 0
+#define MUM_EVENT_PORT_PHY_COPPER_LEN_LBN 0
+#define MUM_EVENT_PORT_PHY_COPPER_LEN_WIDTH 32
+#define MUM_EVENT_PORT_PHY_CAPS_OFST 0
+#define MUM_EVENT_PORT_PHY_CAPS_LBN 0
+#define MUM_EVENT_PORT_PHY_CAPS_WIDTH 32
+#define MUM_EVENT_PORT_PHY_TECH_OFST 0
+#define MUM_EVENT_PORT_PHY_STATE_QSFP_MODULE_TECH_UNKNOWN 0x0 /* enum */
+#define MUM_EVENT_PORT_PHY_STATE_QSFP_MODULE_TECH_OPTICAL 0x1 /* enum */
+#define MUM_EVENT_PORT_PHY_STATE_QSFP_MODULE_TECH_COPPER_PASSIVE 0x2 /* enum */
+#define MUM_EVENT_PORT_PHY_STATE_QSFP_MODULE_TECH_COPPER_PASSIVE_EQUALIZED 0x3 /* enum */
+#define MUM_EVENT_PORT_PHY_STATE_QSFP_MODULE_TECH_COPPER_ACTIVE_LIMITING 0x4 /* enum */
+#define MUM_EVENT_PORT_PHY_STATE_QSFP_MODULE_TECH_COPPER_ACTIVE_LINEAR 0x5 /* enum */
+#define MUM_EVENT_PORT_PHY_STATE_QSFP_MODULE_TECH_BASE_T 0x6 /* enum */
+#define MUM_EVENT_PORT_PHY_STATE_QSFP_MODULE_TECH_LOOPBACK_PASSIVE 0x7 /* enum */
+#define MUM_EVENT_PORT_PHY_TECH_LBN 0
+#define MUM_EVENT_PORT_PHY_TECH_WIDTH 32
+#define MUM_EVENT_PORT_PHY_SRC_DATA_ID_LBN 36
+#define MUM_EVENT_PORT_PHY_SRC_DATA_ID_WIDTH 4
+#define MUM_EVENT_PORT_PHY_SRC_DATA_ID_FLAGS 0x0 /* enum */
+#define MUM_EVENT_PORT_PHY_SRC_DATA_ID_COPPER_LEN 0x1 /* enum */
+#define MUM_EVENT_PORT_PHY_SRC_DATA_ID_CAPS 0x2 /* enum */
+#define MUM_EVENT_PORT_PHY_SRC_DATA_ID_TECH 0x3 /* enum */
+#define MUM_EVENT_PORT_PHY_SRC_DATA_ID_MAX 0x4 /* enum */
+#define MUM_EVENT_PORT_PHY_SRC_PORT_NO_LBN 40
+#define MUM_EVENT_PORT_PHY_SRC_PORT_NO_WIDTH 4
+
/***********************************/
/* MC_CMD_READ32
* Read multiple 32byte words from MC memory.
*/
#define MC_CMD_READ32 0x1
+#undef MC_CMD_0x1_PRIVILEGE_CTG
+
+#define MC_CMD_0x1_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_READ32_IN msgrequest */
#define MC_CMD_READ32_IN_LEN 8
@@ -480,6 +893,9 @@
* Write multiple 32byte words to MC memory.
*/
#define MC_CMD_WRITE32 0x2
+#undef MC_CMD_0x2_PRIVILEGE_CTG
+
+#define MC_CMD_0x2_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_WRITE32_IN msgrequest */
#define MC_CMD_WRITE32_IN_LENMIN 8
@@ -500,26 +916,64 @@
* Copy MC code between two locations and jump.
*/
#define MC_CMD_COPYCODE 0x3
+#undef MC_CMD_0x3_PRIVILEGE_CTG
+
+#define MC_CMD_0x3_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_COPYCODE_IN msgrequest */
#define MC_CMD_COPYCODE_IN_LEN 16
+/* Source address
+ *
+ * The main image should be entered via a copy of a single word from and to a
+ * magic address, which controls various aspects of the boot. The magic address
+ * is a bitfield, with each bit as documented below.
+ */
#define MC_CMD_COPYCODE_IN_SRC_ADDR_OFST 0
+/* enum: Deprecated; equivalent to setting BOOT_MAGIC_PRESENT (see below) */
+#define MC_CMD_COPYCODE_HUNT_NO_MAGIC_ADDR 0x10000
+/* enum: Deprecated; equivalent to setting BOOT_MAGIC_PRESENT and
+ * BOOT_MAGIC_SATELLITE_CPUS_NOT_LOADED (see below)
+ */
+#define MC_CMD_COPYCODE_HUNT_NO_DATAPATH_MAGIC_ADDR 0x1d0d0
+/* enum: Deprecated; equivalent to setting BOOT_MAGIC_PRESENT,
+ * BOOT_MAGIC_SATELLITE_CPUS_NOT_LOADED and BOOT_MAGIC_IGNORE_CONFIG (see
+ * below)
+ */
+#define MC_CMD_COPYCODE_HUNT_IGNORE_CONFIG_MAGIC_ADDR 0x1badc
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_PRESENT_LBN 17
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_PRESENT_WIDTH 1
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_SATELLITE_CPUS_NOT_LOADED_LBN 2
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_SATELLITE_CPUS_NOT_LOADED_WIDTH 1
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_IGNORE_CONFIG_LBN 3
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_IGNORE_CONFIG_WIDTH 1
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_SKIP_BOOT_ICORE_SYNC_LBN 4
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_SKIP_BOOT_ICORE_SYNC_WIDTH 1
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_FORCE_STANDALONE_LBN 5
+#define MC_CMD_COPYCODE_IN_BOOT_MAGIC_FORCE_STANDALONE_WIDTH 1
+/* Destination address */
#define MC_CMD_COPYCODE_IN_DEST_ADDR_OFST 4
#define MC_CMD_COPYCODE_IN_NUMWORDS_OFST 8
+/* Address of where to jump after copy. */
#define MC_CMD_COPYCODE_IN_JUMP_OFST 12
-#define MC_CMD_COPYCODE_JUMP_NONE 0x1 /* enum */
+/* enum: Control should return to the caller rather than jumping */
+#define MC_CMD_COPYCODE_JUMP_NONE 0x1
/* MC_CMD_COPYCODE_OUT msgresponse */
#define MC_CMD_COPYCODE_OUT_LEN 0
/***********************************/
-/* MC_CMD_SET_FUNC
+/* MC_CMD_SET_FUNC
+ * Select function for function-specific commands.
*/
-#define MC_CMD_SET_FUNC 0x4
+#define MC_CMD_SET_FUNC 0x4
+#undef MC_CMD_0x4_PRIVILEGE_CTG
+
+#define MC_CMD_0x4_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_SET_FUNC_IN msgrequest */
#define MC_CMD_SET_FUNC_IN_LEN 4
+/* Set function */
#define MC_CMD_SET_FUNC_IN_FUNC_OFST 0
/* MC_CMD_SET_FUNC_OUT msgresponse */
@@ -528,15 +982,22 @@
/***********************************/
/* MC_CMD_GET_BOOT_STATUS
+ * Get the instruction address from which the MC booted.
*/
#define MC_CMD_GET_BOOT_STATUS 0x5
+#undef MC_CMD_0x5_PRIVILEGE_CTG
+
+#define MC_CMD_0x5_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_GET_BOOT_STATUS_IN msgrequest */
#define MC_CMD_GET_BOOT_STATUS_IN_LEN 0
/* MC_CMD_GET_BOOT_STATUS_OUT msgresponse */
#define MC_CMD_GET_BOOT_STATUS_OUT_LEN 8
+/* ?? */
#define MC_CMD_GET_BOOT_STATUS_OUT_BOOT_OFFSET_OFST 0
+/* enum: indicates that the MC wasn't flash booted */
+#define MC_CMD_GET_BOOT_STATUS_OUT_BOOT_OFFSET_NULL 0xdeadbeef
#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_OFST 4
#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_WATCHDOG_LBN 0
#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_WATCHDOG_WIDTH 1
@@ -547,41 +1008,69 @@
/***********************************/
-/* MC_CMD_GET_ASSERTS
- * Get and clear any assertion status.
+/* MC_CMD_GET_ASSERTS
+ * Get (and optionally clear) the current assertion status. Only
+ * OUT.GLOBAL_FLAGS is guaranteed to exist in the completion payload. The other
+ * fields will only be present if OUT.GLOBAL_FLAGS != NO_FAILS
*/
-#define MC_CMD_GET_ASSERTS 0x6
+#define MC_CMD_GET_ASSERTS 0x6
+#undef MC_CMD_0x6_PRIVILEGE_CTG
+
+#define MC_CMD_0x6_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_GET_ASSERTS_IN msgrequest */
#define MC_CMD_GET_ASSERTS_IN_LEN 4
+/* Set to clear assertion */
#define MC_CMD_GET_ASSERTS_IN_CLEAR_OFST 0
/* MC_CMD_GET_ASSERTS_OUT msgresponse */
#define MC_CMD_GET_ASSERTS_OUT_LEN 140
+/* Assertion status flag. */
#define MC_CMD_GET_ASSERTS_OUT_GLOBAL_FLAGS_OFST 0
-#define MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS 0x1 /* enum */
-#define MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL 0x2 /* enum */
-#define MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL 0x3 /* enum */
-#define MC_CMD_GET_ASSERTS_FLAGS_WDOG_FIRED 0x4 /* enum */
+/* enum: No assertions have failed. */
+#define MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS 0x1
+/* enum: A system-level assertion has failed. */
+#define MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL 0x2
+/* enum: A thread-level assertion has failed. */
+#define MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL 0x3
+/* enum: The system was reset by the watchdog. */
+#define MC_CMD_GET_ASSERTS_FLAGS_WDOG_FIRED 0x4
+/* enum: An illegal address trap stopped the system (huntington and later) */
+#define MC_CMD_GET_ASSERTS_FLAGS_ADDR_TRAP 0x5
+/* Failing PC value */
#define MC_CMD_GET_ASSERTS_OUT_SAVED_PC_OFFS_OFST 4
+/* Saved GP regs */
#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST 8
#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_LEN 4
#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_NUM 31
+/* enum: A magic value hinting that the value in this register at the time of
+ * the failure has likely been lost.
+ */
+#define MC_CMD_GET_ASSERTS_REG_NO_DATA 0xda7a1057
+/* Failing thread address */
#define MC_CMD_GET_ASSERTS_OUT_THREAD_OFFS_OFST 132
#define MC_CMD_GET_ASSERTS_OUT_RESERVED_OFST 136
/***********************************/
-/* MC_CMD_LOG_CTRL
- * Configure the output stream for various events and messages.
+/* MC_CMD_LOG_CTRL
+ * Configure the output stream for log events such as link state changes,
+ * sensor notifications and MCDI completions
*/
-#define MC_CMD_LOG_CTRL 0x7
+#define MC_CMD_LOG_CTRL 0x7
+#undef MC_CMD_0x7_PRIVILEGE_CTG
+
+#define MC_CMD_0x7_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_LOG_CTRL_IN msgrequest */
#define MC_CMD_LOG_CTRL_IN_LEN 8
+/* Log destination */
#define MC_CMD_LOG_CTRL_IN_LOG_DEST_OFST 0
-#define MC_CMD_LOG_CTRL_IN_LOG_DEST_UART 0x1 /* enum */
-#define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ 0x2 /* enum */
+/* enum: UART. */
+#define MC_CMD_LOG_CTRL_IN_LOG_DEST_UART 0x1
+/* enum: Event queue. */
+#define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ 0x2
+/* Legacy argument. Must be zero. */
#define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ_OFST 4
/* MC_CMD_LOG_CTRL_OUT msgresponse */
@@ -589,21 +1078,31 @@
/***********************************/
-/* MC_CMD_GET_VERSION
+/* MC_CMD_GET_VERSION
* Get version information about the MC firmware.
*/
-#define MC_CMD_GET_VERSION 0x8
+#define MC_CMD_GET_VERSION 0x8
+#undef MC_CMD_0x8_PRIVILEGE_CTG
+
+#define MC_CMD_0x8_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_GET_VERSION_IN msgrequest */
#define MC_CMD_GET_VERSION_IN_LEN 0
-/* MC_CMD_GET_VERSION_V0_OUT msgresponse */
+/* MC_CMD_GET_VERSION_EXT_IN msgrequest: Asks for the extended version */
+#define MC_CMD_GET_VERSION_EXT_IN_LEN 4
+/* placeholder, set to 0 */
+#define MC_CMD_GET_VERSION_EXT_IN_EXT_FLAGS_OFST 0
+
+/* MC_CMD_GET_VERSION_V0_OUT msgresponse: deprecated version format */
#define MC_CMD_GET_VERSION_V0_OUT_LEN 4
#define MC_CMD_GET_VERSION_OUT_FIRMWARE_OFST 0
-#define MC_CMD_GET_VERSION_OUT_FIRMWARE_ANY 0xffffffff /* enum */
-#define MC_CMD_GET_VERSION_OUT_FIRMWARE_BOOTROM 0xb0070000 /* enum */
-#define MC_CMD_GET_VERSION_OUT_FIRMWARE_SIENA_BOOTROM 0xb0070000 /* enum */
-#define MC_CMD_GET_VERSION_OUT_FIRMWARE_HUNT_BOOTROM 0xb0070001 /* enum */
+/* enum: Reserved version number to indicate "any" version. */
+#define MC_CMD_GET_VERSION_OUT_FIRMWARE_ANY 0xffffffff
+/* enum: Bootrom version value for Siena. */
+#define MC_CMD_GET_VERSION_OUT_FIRMWARE_SIENA_BOOTROM 0xb0070000
+/* enum: Bootrom version value for Huntington. */
+#define MC_CMD_GET_VERSION_OUT_FIRMWARE_HUNT_BOOTROM 0xb0070001
/* MC_CMD_GET_VERSION_OUT msgresponse */
#define MC_CMD_GET_VERSION_OUT_LEN 32
@@ -611,6 +1110,7 @@
/* Enum values, see field(s): */
/* MC_CMD_GET_VERSION_V0_OUT/MC_CMD_GET_VERSION_OUT_FIRMWARE */
#define MC_CMD_GET_VERSION_OUT_PCOL_OFST 4
+/* 128bit mask of functions supported by the current firmware */
#define MC_CMD_GET_VERSION_OUT_SUPPORTED_FUNCS_OFST 8
#define MC_CMD_GET_VERSION_OUT_SUPPORTED_FUNCS_LEN 16
#define MC_CMD_GET_VERSION_OUT_VERSION_OFST 24
@@ -618,77 +1118,187 @@
#define MC_CMD_GET_VERSION_OUT_VERSION_LO_OFST 24
#define MC_CMD_GET_VERSION_OUT_VERSION_HI_OFST 28
+/* MC_CMD_GET_VERSION_EXT_OUT msgresponse */
+#define MC_CMD_GET_VERSION_EXT_OUT_LEN 48
+/* MC_CMD_GET_VERSION_OUT_FIRMWARE_OFST 0 */
+/* Enum values, see field(s): */
+/* MC_CMD_GET_VERSION_V0_OUT/MC_CMD_GET_VERSION_OUT_FIRMWARE */
+#define MC_CMD_GET_VERSION_EXT_OUT_PCOL_OFST 4
+/* 128bit mask of functions supported by the current firmware */
+#define MC_CMD_GET_VERSION_EXT_OUT_SUPPORTED_FUNCS_OFST 8
+#define MC_CMD_GET_VERSION_EXT_OUT_SUPPORTED_FUNCS_LEN 16
+#define MC_CMD_GET_VERSION_EXT_OUT_VERSION_OFST 24
+#define MC_CMD_GET_VERSION_EXT_OUT_VERSION_LEN 8
+#define MC_CMD_GET_VERSION_EXT_OUT_VERSION_LO_OFST 24
+#define MC_CMD_GET_VERSION_EXT_OUT_VERSION_HI_OFST 28
+/* extra info */
+#define MC_CMD_GET_VERSION_EXT_OUT_EXTRA_OFST 32
+#define MC_CMD_GET_VERSION_EXT_OUT_EXTRA_LEN 16
+
/***********************************/
-/* MC_CMD_FC
+/* MC_CMD_FC
* Perform an FC operation
*/
-#define MC_CMD_FC 0x9
+#define MC_CMD_FC 0x9
/* MC_CMD_FC_IN msgrequest */
#define MC_CMD_FC_IN_LEN 4
#define MC_CMD_FC_IN_OP_HDR_OFST 0
#define MC_CMD_FC_IN_OP_LBN 0
#define MC_CMD_FC_IN_OP_WIDTH 8
-#define MC_CMD_FC_OP_NULL 0x1 /* enum */
-#define MC_CMD_FC_OP_UNUSED 0x2 /* enum */
-#define MC_CMD_FC_OP_MAC 0x3 /* enum */
-#define MC_CMD_FC_OP_READ32 0x4 /* enum */
-#define MC_CMD_FC_OP_WRITE32 0x5 /* enum */
-#define MC_CMD_FC_OP_TRC_READ 0x6 /* enum */
-#define MC_CMD_FC_OP_TRC_WRITE 0x7 /* enum */
-#define MC_CMD_FC_OP_GET_VERSION 0x8 /* enum */
-#define MC_CMD_FC_OP_TRC_RX_READ 0x9 /* enum */
-#define MC_CMD_FC_OP_TRC_RX_WRITE 0xa /* enum */
-#define MC_CMD_FC_OP_SFP 0xb /* enum */
-#define MC_CMD_FC_OP_DDR_TEST 0xc /* enum */
-#define MC_CMD_FC_OP_GET_ASSERT 0xd /* enum */
-#define MC_CMD_FC_OP_FPGA_BUILD 0xe /* enum */
-#define MC_CMD_FC_OP_READ_MAP 0xf /* enum */
-#define MC_CMD_FC_OP_CAPABILITIES 0x10 /* enum */
-#define MC_CMD_FC_OP_GLOBAL_FLAGS 0x11 /* enum */
-#define MC_CMD_FC_OP_IO_REL 0x12 /* enum */
-#define MC_CMD_FC_OP_UHLINK 0x13 /* enum */
-#define MC_CMD_FC_OP_SET_LINK 0x14 /* enum */
-#define MC_CMD_FC_OP_LICENSE 0x15 /* enum */
-#define MC_CMD_FC_OP_STARTUP 0x16 /* enum */
-#define MC_CMD_FC_OP_DMA 0x17 /* enum */
-#define MC_CMD_FC_OP_TIMED_READ 0x18 /* enum */
-#define MC_CMD_FC_OP_LOG 0x19 /* enum */
-#define MC_CMD_FC_OP_CLOCK 0x1a /* enum */
-#define MC_CMD_FC_OP_DDR 0x1b /* enum */
-#define MC_CMD_FC_OP_TIMESTAMP 0x1c /* enum */
-#define MC_CMD_FC_OP_SPI 0x1d /* enum */
-#define MC_CMD_FC_OP_DIAG 0x1e /* enum */
-#define MC_CMD_FC_IN_PORT_EXT_OFST 0x0 /* enum */
-#define MC_CMD_FC_IN_PORT_INT_OFST 0x40 /* enum */
+/* enum: NULL MCDI command to FC. */
+#define MC_CMD_FC_OP_NULL 0x1
+/* enum: Unused opcode */
+#define MC_CMD_FC_OP_UNUSED 0x2
+/* enum: MAC driver commands */
+#define MC_CMD_FC_OP_MAC 0x3
+/* enum: Read FC memory */
+#define MC_CMD_FC_OP_READ32 0x4
+/* enum: Write to FC memory */
+#define MC_CMD_FC_OP_WRITE32 0x5
+/* enum: Read FC memory */
+#define MC_CMD_FC_OP_TRC_READ 0x6
+/* enum: Write to FC memory */
+#define MC_CMD_FC_OP_TRC_WRITE 0x7
+/* enum: FC firmware Version */
+#define MC_CMD_FC_OP_GET_VERSION 0x8
+/* enum: Read FC memory */
+#define MC_CMD_FC_OP_TRC_RX_READ 0x9
+/* enum: Write to FC memory */
+#define MC_CMD_FC_OP_TRC_RX_WRITE 0xa
+/* enum: SFP parameters */
+#define MC_CMD_FC_OP_SFP 0xb
+/* enum: DDR3 test */
+#define MC_CMD_FC_OP_DDR_TEST 0xc
+/* enum: Get Crash context from FC */
+#define MC_CMD_FC_OP_GET_ASSERT 0xd
+/* enum: Get FPGA Build registers */
+#define MC_CMD_FC_OP_FPGA_BUILD 0xe
+/* enum: Read map support commands */
+#define MC_CMD_FC_OP_READ_MAP 0xf
+/* enum: FC Capabilities */
+#define MC_CMD_FC_OP_CAPABILITIES 0x10
+/* enum: FC Global flags */
+#define MC_CMD_FC_OP_GLOBAL_FLAGS 0x11
+/* enum: FC IO using relative addressing modes */
+#define MC_CMD_FC_OP_IO_REL 0x12
+/* enum: FPGA link information */
+#define MC_CMD_FC_OP_UHLINK 0x13
+/* enum: Configure loopbacks and link on FPGA ports */
+#define MC_CMD_FC_OP_SET_LINK 0x14
+/* enum: Licensing operations relating to AOE */
+#define MC_CMD_FC_OP_LICENSE 0x15
+/* enum: Startup information to the FC */
+#define MC_CMD_FC_OP_STARTUP 0x16
+/* enum: Configure a DMA read */
+#define MC_CMD_FC_OP_DMA 0x17
+/* enum: Configure a timed read */
+#define MC_CMD_FC_OP_TIMED_READ 0x18
+/* enum: Control UART logging */
+#define MC_CMD_FC_OP_LOG 0x19
+/* enum: Get the value of a given clock_id */
+#define MC_CMD_FC_OP_CLOCK 0x1a
+/* enum: DDR3/QDR3 parameters */
+#define MC_CMD_FC_OP_DDR 0x1b
+/* enum: PTP and timestamp control */
+#define MC_CMD_FC_OP_TIMESTAMP 0x1c
+/* enum: Commands for SPI Flash interface */
+#define MC_CMD_FC_OP_SPI 0x1d
+/* enum: Commands for diagnostic components */
+#define MC_CMD_FC_OP_DIAG 0x1e
+/* enum: External AOE port. */
+#define MC_CMD_FC_IN_PORT_EXT_OFST 0x0
+/* enum: Internal AOE port. */
+#define MC_CMD_FC_IN_PORT_INT_OFST 0x40
/* MC_CMD_FC_IN_NULL msgrequest */
#define MC_CMD_FC_IN_NULL_LEN 4
#define MC_CMD_FC_IN_CMD_OFST 0
+/* MC_CMD_FC_IN_PHY msgrequest */
+#define MC_CMD_FC_IN_PHY_LEN 5
+/* MC_CMD_FC_IN_CMD_OFST 0 */
+/* FC PHY driver operation code */
+#define MC_CMD_FC_IN_PHY_OP_OFST 4
+#define MC_CMD_FC_IN_PHY_OP_LEN 1
+/* enum: PHY init handler */
+#define MC_CMD_FC_OP_PHY_OP_INIT 0x1
+/* enum: PHY reconfigure handler */
+#define MC_CMD_FC_OP_PHY_OP_RECONFIGURE 0x2
+/* enum: PHY reboot handler */
+#define MC_CMD_FC_OP_PHY_OP_REBOOT 0x3
+/* enum: PHY get_supported_cap handler */
+#define MC_CMD_FC_OP_PHY_OP_GET_SUPPORTED_CAP 0x4
+/* enum: PHY get_config handler */
+#define MC_CMD_FC_OP_PHY_OP_GET_CONFIG 0x5
+/* enum: PHY get_media_info handler */
+#define MC_CMD_FC_OP_PHY_OP_GET_MEDIA_INFO 0x6
+/* enum: PHY set_led handler */
+#define MC_CMD_FC_OP_PHY_OP_SET_LED 0x7
+/* enum: PHY lasi_interrupt handler */
+#define MC_CMD_FC_OP_PHY_OP_LASI_INTERRUPT 0x8
+/* enum: PHY check_link handler */
+#define MC_CMD_FC_OP_PHY_OP_CHECK_LINK 0x9
+/* enum: PHY fill_stats handler */
+#define MC_CMD_FC_OP_PHY_OP_FILL_STATS 0xa
+/* enum: PHY bpx_link_state_changed handler */
+#define MC_CMD_FC_OP_PHY_OP_BPX_LINK_STATE_CHANGED 0xb
+/* enum: PHY get_state handler */
+#define MC_CMD_FC_OP_PHY_OP_GET_STATE 0xc
+/* enum: PHY start_bist handler */
+#define MC_CMD_FC_OP_PHY_OP_START_BIST 0xd
+/* enum: PHY poll_bist handler */
+#define MC_CMD_FC_OP_PHY_OP_POLL_BIST 0xe
+/* enum: PHY nvram_test handler */
+#define MC_CMD_FC_OP_PHY_OP_NVRAM_TEST 0xf
+/* enum: PHY relinquish handler */
+#define MC_CMD_FC_OP_PHY_OP_RELINQUISH_SPI 0x10
+/* enum: PHY read connection from FC - may be not required */
+#define MC_CMD_FC_OP_PHY_OP_GET_CONNECTION 0x11
+/* enum: PHY read flags from FC - may be not required */
+#define MC_CMD_FC_OP_PHY_OP_GET_FLAGS 0x12
+
+/* MC_CMD_FC_IN_PHY_INIT msgrequest */
+#define MC_CMD_FC_IN_PHY_INIT_LEN 4
+#define MC_CMD_FC_IN_PHY_CMD_OFST 0
+
/* MC_CMD_FC_IN_MAC msgrequest */
#define MC_CMD_FC_IN_MAC_LEN 8
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_MAC_HEADER_OFST 4
#define MC_CMD_FC_IN_MAC_OP_LBN 0
#define MC_CMD_FC_IN_MAC_OP_WIDTH 8
-#define MC_CMD_FC_OP_MAC_OP_RECONFIGURE 0x1 /* enum */
-#define MC_CMD_FC_OP_MAC_OP_SET_LINK 0x2 /* enum */
-#define MC_CMD_FC_OP_MAC_OP_GET_STATS 0x3 /* enum */
-#define MC_CMD_FC_OP_MAC_OP_GET_RX_STATS 0x6 /* enum */
-#define MC_CMD_FC_OP_MAC_OP_GET_TX_STATS 0x7 /* enum */
-#define MC_CMD_FC_OP_MAC_OP_READ_STATUS 0x8 /* enum */
+/* enum: MAC reconfigure handler */
+#define MC_CMD_FC_OP_MAC_OP_RECONFIGURE 0x1
+/* enum: MAC Set command - same as MC_CMD_SET_MAC */
+#define MC_CMD_FC_OP_MAC_OP_SET_LINK 0x2
+/* enum: MAC statistics */
+#define MC_CMD_FC_OP_MAC_OP_GET_STATS 0x3
+/* enum: MAC RX statistics */
+#define MC_CMD_FC_OP_MAC_OP_GET_RX_STATS 0x6
+/* enum: MAC TX statistics */
+#define MC_CMD_FC_OP_MAC_OP_GET_TX_STATS 0x7
+/* enum: MAC Read status */
+#define MC_CMD_FC_OP_MAC_OP_READ_STATUS 0x8
#define MC_CMD_FC_IN_MAC_PORT_TYPE_LBN 8
#define MC_CMD_FC_IN_MAC_PORT_TYPE_WIDTH 8
-#define MC_CMD_FC_PORT_EXT 0x0 /* enum */
-#define MC_CMD_FC_PORT_INT 0x1 /* enum */
+/* enum: External FPGA port. */
+#define MC_CMD_FC_PORT_EXT 0x0
+/* enum: Internal Siena-facing FPGA ports. */
+#define MC_CMD_FC_PORT_INT 0x1
#define MC_CMD_FC_IN_MAC_PORT_IDX_LBN 16
#define MC_CMD_FC_IN_MAC_PORT_IDX_WIDTH 8
#define MC_CMD_FC_IN_MAC_CMD_FORMAT_LBN 24
#define MC_CMD_FC_IN_MAC_CMD_FORMAT_WIDTH 8
-#define MC_CMD_FC_OP_MAC_CMD_FORMAT_DEFAULT 0x0 /* enum */
-#define MC_CMD_FC_OP_MAC_CMD_FORMAT_PORT_OVERRIDE 0x1 /* enum */
+/* enum: Default FC command format; the fields PORT_TYPE and PORT_IDX are
+ * irrelevant. Port number is derived from pci_fn; passed in FC header.
+ */
+#define MC_CMD_FC_OP_MAC_CMD_FORMAT_DEFAULT 0x0
+/* enum: Override default port number. Port number determined by fields
+ * PORT_TYPE and PORT_IDX.
+ */
+#define MC_CMD_FC_OP_MAC_CMD_FORMAT_PORT_OVERRIDE 0x1
/* MC_CMD_FC_IN_MAC_RECONFIGURE msgrequest */
#define MC_CMD_FC_IN_MAC_RECONFIGURE_LEN 8
@@ -699,7 +1309,9 @@
#define MC_CMD_FC_IN_MAC_SET_LINK_LEN 32
/* MC_CMD_FC_IN_CMD_OFST 0 */
/* MC_CMD_FC_IN_MAC_HEADER_OFST 4 */
+/* MTU size */
#define MC_CMD_FC_IN_MAC_SET_LINK_MTU_OFST 8
+/* Drain Tx FIFO */
#define MC_CMD_FC_IN_MAC_SET_LINK_DRAIN_OFST 12
#define MC_CMD_FC_IN_MAC_SET_LINK_ADDR_OFST 16
#define MC_CMD_FC_IN_MAC_SET_LINK_ADDR_LEN 8
@@ -731,6 +1343,7 @@
#define MC_CMD_FC_IN_MAC_GET_STATS_LEN 20
/* MC_CMD_FC_IN_CMD_OFST 0 */
/* MC_CMD_FC_IN_MAC_HEADER_OFST 4 */
+/* MC Statistics index */
#define MC_CMD_FC_IN_MAC_GET_STATS_STATS_INDEX_OFST 8
#define MC_CMD_FC_IN_MAC_GET_STATS_FLAGS_OFST 12
#define MC_CMD_FC_IN_MAC_GET_STATS_CLEAR_ALL_LBN 0
@@ -739,6 +1352,7 @@
#define MC_CMD_FC_IN_MAC_GET_STATS_CLEAR_WIDTH 1
#define MC_CMD_FC_IN_MAC_GET_STATS_UPDATE_LBN 2
#define MC_CMD_FC_IN_MAC_GET_STATS_UPDATE_WIDTH 1
+/* Number of statistics to read */
#define MC_CMD_FC_IN_MAC_GET_STATS_NUM_OFST 16
#define MC_CMD_FC_MAC_NSTATS_PER_BLOCK 0x1e /* enum */
#define MC_CMD_FC_MAC_NBYTES_PER_STAT 0x8 /* enum */
@@ -797,13 +1411,24 @@
#define MC_CMD_FC_IN_TRC_RX_WRITE_DATA_NUM 2
/* MC_CMD_FC_IN_SFP msgrequest */
-#define MC_CMD_FC_IN_SFP_LEN 24
+#define MC_CMD_FC_IN_SFP_LEN 28
/* MC_CMD_FC_IN_CMD_OFST 0 */
+/* Link speed is 100, 1000, 10000, 40000 */
#define MC_CMD_FC_IN_SFP_SPEED_OFST 4
+/* Length of copper cable - zero when not relevant (e.g. if cable is fibre) */
#define MC_CMD_FC_IN_SFP_COPPER_LEN_OFST 8
+/* Not relevant for cards with QSFP modules. For older cards, true if module is
+ * a dual speed SFP+ module.
+ */
#define MC_CMD_FC_IN_SFP_DUAL_SPEED_OFST 12
+/* True if an SFP Module is present (other fields valid when true) */
#define MC_CMD_FC_IN_SFP_PRESENT_OFST 16
+/* The type of the SFP+ Module. For later cards with QSFP modules, this field
+ * is unused and the type is communicated by other means.
+ */
#define MC_CMD_FC_IN_SFP_TYPE_OFST 20
+/* Capabilities corresponding to 1 bits. */
+#define MC_CMD_FC_IN_SFP_CAPS_OFST 24
/* MC_CMD_FC_IN_DDR_TEST msgrequest */
#define MC_CMD_FC_IN_DDR_TEST_LEN 8
@@ -811,8 +1436,10 @@
#define MC_CMD_FC_IN_DDR_TEST_HEADER_OFST 4
#define MC_CMD_FC_IN_DDR_TEST_OP_LBN 0
#define MC_CMD_FC_IN_DDR_TEST_OP_WIDTH 8
-#define MC_CMD_FC_OP_DDR_TEST_START 0x1 /* enum */
-#define MC_CMD_FC_OP_DDR_TEST_POLL 0x2 /* enum */
+/* enum: DRAM Test Start */
+#define MC_CMD_FC_OP_DDR_TEST_START 0x1
+/* enum: DRAM Test Poll */
+#define MC_CMD_FC_OP_DDR_TEST_POLL 0x2
/* MC_CMD_FC_IN_DDR_TEST_START msgrequest */
#define MC_CMD_FC_IN_DDR_TEST_START_LEN 12
@@ -840,10 +1467,14 @@
/* MC_CMD_FC_IN_FPGA_BUILD msgrequest */
#define MC_CMD_FC_IN_FPGA_BUILD_LEN 8
/* MC_CMD_FC_IN_CMD_OFST 0 */
+/* FPGA build info operation code */
#define MC_CMD_FC_IN_FPGA_BUILD_OP_OFST 4
-#define MC_CMD_FC_IN_FPGA_BUILD_BUILD 0x1 /* enum */
-#define MC_CMD_FC_IN_FPGA_BUILD_SERVICES 0x2 /* enum */
-#define MC_CMD_FC_IN_FPGA_BUILD_BSP_VERSION 0x3 /* enum */
+/* enum: Get the build registers */
+#define MC_CMD_FC_IN_FPGA_BUILD_BUILD 0x1
+/* enum: Get the services registers */
+#define MC_CMD_FC_IN_FPGA_BUILD_SERVICES 0x2
+/* enum: Get the BSP version */
+#define MC_CMD_FC_IN_FPGA_BUILD_BSP_VERSION 0x3
/* MC_CMD_FC_IN_READ_MAP msgrequest */
#define MC_CMD_FC_IN_READ_MAP_LEN 8
@@ -851,8 +1482,10 @@
#define MC_CMD_FC_IN_READ_MAP_HEADER_OFST 4
#define MC_CMD_FC_IN_READ_MAP_OP_LBN 0
#define MC_CMD_FC_IN_READ_MAP_OP_WIDTH 8
-#define MC_CMD_FC_OP_READ_MAP_COUNT 0x1 /* enum */
-#define MC_CMD_FC_OP_READ_MAP_INDEX 0x2 /* enum */
+/* enum: Get the number of map regions */
+#define MC_CMD_FC_OP_READ_MAP_COUNT 0x1
+/* enum: Get the specified map */
+#define MC_CMD_FC_OP_READ_MAP_INDEX 0x2
/* MC_CMD_FC_IN_READ_MAP_COUNT msgrequest */
#define MC_CMD_FC_IN_READ_MAP_COUNT_LEN 8
@@ -892,13 +1525,18 @@
#define MC_CMD_FC_IN_IO_REL_HEADER_OFST 4
#define MC_CMD_FC_IN_IO_REL_OP_LBN 0
#define MC_CMD_FC_IN_IO_REL_OP_WIDTH 8
-#define MC_CMD_FC_IN_IO_REL_GET_ADDR 0x1 /* enum */
-#define MC_CMD_FC_IN_IO_REL_READ32 0x2 /* enum */
-#define MC_CMD_FC_IN_IO_REL_WRITE32 0x3 /* enum */
+/* enum: Get the base address that the FC applies to relative commands */
+#define MC_CMD_FC_IN_IO_REL_GET_ADDR 0x1
+/* enum: Read data */
+#define MC_CMD_FC_IN_IO_REL_READ32 0x2
+/* enum: Write data */
+#define MC_CMD_FC_IN_IO_REL_WRITE32 0x3
#define MC_CMD_FC_IN_IO_REL_COMP_TYPE_LBN 8
#define MC_CMD_FC_IN_IO_REL_COMP_TYPE_WIDTH 8
-#define MC_CMD_FC_COMP_TYPE_APP_ADDR_SPACE 0x1 /* enum */
-#define MC_CMD_FC_COMP_TYPE_FLASH 0x2 /* enum */
+/* enum: Application address space */
+#define MC_CMD_FC_COMP_TYPE_APP_ADDR_SPACE 0x1
+/* enum: Flash address space */
+#define MC_CMD_FC_COMP_TYPE_FLASH 0x2
/* MC_CMD_FC_IN_IO_REL_GET_ADDR msgrequest */
#define MC_CMD_FC_IN_IO_REL_GET_ADDR_LEN 8
@@ -932,22 +1570,36 @@
#define MC_CMD_FC_IN_UHLINK_HEADER_OFST 4
#define MC_CMD_FC_IN_UHLINK_OP_LBN 0
#define MC_CMD_FC_IN_UHLINK_OP_WIDTH 8
-#define MC_CMD_FC_OP_UHLINK_PHY 0x1 /* enum */
-#define MC_CMD_FC_OP_UHLINK_MAC 0x2 /* enum */
-#define MC_CMD_FC_OP_UHLINK_RX_EYE 0x3 /* enum */
-#define MC_CMD_FC_OP_UHLINK_DUMP_RX_EYE_PLOT 0x4 /* enum */
-#define MC_CMD_FC_OP_UHLINK_READ_RX_EYE_PLOT 0x5 /* enum */
-#define MC_CMD_FC_OP_UHLINK_RX_TUNE 0x6 /* enum */
-#define MC_CMD_FC_OP_UHLINK_LOOPBACK_SET 0x7 /* enum */
-#define MC_CMD_FC_OP_UHLINK_LOOPBACK_GET 0x8 /* enum */
+/* enum: Get PHY configuration info */
+#define MC_CMD_FC_OP_UHLINK_PHY 0x1
+/* enum: Get MAC configuration info */
+#define MC_CMD_FC_OP_UHLINK_MAC 0x2
+/* enum: Get Rx eye table */
+#define MC_CMD_FC_OP_UHLINK_RX_EYE 0x3
+/* enum: Get Rx eye plot */
+#define MC_CMD_FC_OP_UHLINK_DUMP_RX_EYE_PLOT 0x4
+/* enum: Get Rx eye plot */
+#define MC_CMD_FC_OP_UHLINK_READ_RX_EYE_PLOT 0x5
+/* enum: Retune Rx settings */
+#define MC_CMD_FC_OP_UHLINK_RX_TUNE 0x6
+/* enum: Set loopback mode on fpga port */
+#define MC_CMD_FC_OP_UHLINK_LOOPBACK_SET 0x7
+/* enum: Get loopback mode config state on fpga port */
+#define MC_CMD_FC_OP_UHLINK_LOOPBACK_GET 0x8
#define MC_CMD_FC_IN_UHLINK_PORT_TYPE_LBN 8
#define MC_CMD_FC_IN_UHLINK_PORT_TYPE_WIDTH 8
#define MC_CMD_FC_IN_UHLINK_PORT_IDX_LBN 16
#define MC_CMD_FC_IN_UHLINK_PORT_IDX_WIDTH 8
#define MC_CMD_FC_IN_UHLINK_CMD_FORMAT_LBN 24
#define MC_CMD_FC_IN_UHLINK_CMD_FORMAT_WIDTH 8
-#define MC_CMD_FC_OP_UHLINK_CMD_FORMAT_DEFAULT 0x0 /* enum */
-#define MC_CMD_FC_OP_UHLINK_CMD_FORMAT_PORT_OVERRIDE 0x1 /* enum */
+/* enum: Default FC command format; the fields PORT_TYPE and PORT_IDX are
+ * irrelevant. Port number is derived from pci_fn; passed in FC header.
+ */
+#define MC_CMD_FC_OP_UHLINK_CMD_FORMAT_DEFAULT 0x0
+/* enum: Override default port number. Port number determined by fields
+ * PORT_TYPE and PORT_IDX.
+ */
+#define MC_CMD_FC_OP_UHLINK_CMD_FORMAT_PORT_OVERRIDE 0x1
/* MC_CMD_FC_OP_UHLINK_PHY msgrequest */
#define MC_CMD_FC_OP_UHLINK_PHY_LEN 8
@@ -1006,6 +1658,7 @@
/* MC_CMD_FC_IN_SET_LINK msgrequest */
#define MC_CMD_FC_IN_SET_LINK_LEN 16
/* MC_CMD_FC_IN_CMD_OFST 0 */
+/* See MC_CMD_GET_LOOPBACK_MODES/MC_CMD_GET_LOOPBACK_MODES_OUT/100M */
#define MC_CMD_FC_IN_SET_LINK_MODE_OFST 4
#define MC_CMD_FC_IN_SET_LINK_SPEED_OFST 8
#define MC_CMD_FC_IN_SET_LINK_FLAGS_OFST 12
@@ -1028,7 +1681,9 @@
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_STARTUP_BASE_OFST 4
#define MC_CMD_FC_IN_STARTUP_LENGTH_OFST 8
+/* Length of identifier */
#define MC_CMD_FC_IN_STARTUP_IDLENGTH_OFST 12
+/* Identifier for AOE FPGA */
#define MC_CMD_FC_IN_STARTUP_ID_OFST 16
#define MC_CMD_FC_IN_STARTUP_ID_LEN 1
#define MC_CMD_FC_IN_STARTUP_ID_NUM 24
@@ -1044,6 +1699,7 @@
#define MC_CMD_FC_IN_DMA_STOP_LEN 12
/* MC_CMD_FC_IN_CMD_OFST 0 */
/* MC_CMD_FC_IN_DMA_OP_OFST 4 */
+/* FC supplied handle */
#define MC_CMD_FC_IN_DMA_STOP_FC_HANDLE_OFST 8
/* MC_CMD_FC_IN_DMA_READ msgrequest */
@@ -1065,18 +1721,25 @@
#define MC_CMD_FC_IN_TIMED_READ_SET_LEN 52
/* MC_CMD_FC_IN_CMD_OFST 0 */
/* MC_CMD_FC_IN_TIMED_READ_OP_OFST 4 */
+/* Host supplied handle (unique) */
#define MC_CMD_FC_IN_TIMED_READ_SET_HOST_HANDLE_OFST 8
+/* Address into which to transfer data in host */
#define MC_CMD_FC_IN_TIMED_READ_SET_HOST_DMA_ADDRESS_OFST 12
#define MC_CMD_FC_IN_TIMED_READ_SET_HOST_DMA_ADDRESS_LEN 8
#define MC_CMD_FC_IN_TIMED_READ_SET_HOST_DMA_ADDRESS_LO_OFST 12
#define MC_CMD_FC_IN_TIMED_READ_SET_HOST_DMA_ADDRESS_HI_OFST 16
+/* AOE address from which to transfer data */
#define MC_CMD_FC_IN_TIMED_READ_SET_AOE_ADDRESS_OFST 20
#define MC_CMD_FC_IN_TIMED_READ_SET_AOE_ADDRESS_LEN 8
#define MC_CMD_FC_IN_TIMED_READ_SET_AOE_ADDRESS_LO_OFST 20
#define MC_CMD_FC_IN_TIMED_READ_SET_AOE_ADDRESS_HI_OFST 24
+/* Length of AOE transfer (total) */
#define MC_CMD_FC_IN_TIMED_READ_SET_AOE_LENGTH_OFST 28
+/* Length of host transfer (total) */
#define MC_CMD_FC_IN_TIMED_READ_SET_HOST_LENGTH_OFST 32
+/* Offset back from aoe_address to apply operation to */
#define MC_CMD_FC_IN_TIMED_READ_SET_OFFSET_OFST 36
+/* Data to apply at offset */
#define MC_CMD_FC_IN_TIMED_READ_SET_DATA_OFST 40
#define MC_CMD_FC_IN_TIMED_READ_SET_FLAGS_OFST 44
#define MC_CMD_FC_IN_TIMED_READ_SET_INDIRECT_LBN 0
@@ -1091,18 +1754,21 @@
#define MC_CMD_FC_IN_TIMED_READ_SET_READ 0x1 /* enum */
#define MC_CMD_FC_IN_TIMED_READ_SET_WRITE 0x2 /* enum */
#define MC_CMD_FC_IN_TIMED_READ_SET_READWRITE 0x3 /* enum */
+/* Period at which reads are performed (100ms units) */
#define MC_CMD_FC_IN_TIMED_READ_SET_PERIOD_OFST 48
/* MC_CMD_FC_IN_TIMED_READ_GET msgrequest */
#define MC_CMD_FC_IN_TIMED_READ_GET_LEN 12
/* MC_CMD_FC_IN_CMD_OFST 0 */
/* MC_CMD_FC_IN_TIMED_READ_OP_OFST 4 */
+/* FC supplied handle */
#define MC_CMD_FC_IN_TIMED_READ_GET_FC_HANDLE_OFST 8
/* MC_CMD_FC_IN_TIMED_READ_CLEAR msgrequest */
#define MC_CMD_FC_IN_TIMED_READ_CLEAR_LEN 12
/* MC_CMD_FC_IN_CMD_OFST 0 */
/* MC_CMD_FC_IN_TIMED_READ_OP_OFST 4 */
+/* FC supplied handle */
#define MC_CMD_FC_IN_TIMED_READ_CLEAR_FC_HANDLE_OFST 8
/* MC_CMD_FC_IN_LOG msgrequest */
@@ -1116,14 +1782,18 @@
#define MC_CMD_FC_IN_LOG_ADDR_RANGE_LEN 20
/* MC_CMD_FC_IN_CMD_OFST 0 */
/* MC_CMD_FC_IN_LOG_OP_OFST 4 */
+/* Partition offset into flash */
#define MC_CMD_FC_IN_LOG_ADDR_RANGE_OFFSET_OFST 8
+/* Partition length */
#define MC_CMD_FC_IN_LOG_ADDR_RANGE_LENGTH_OFST 12
+/* Partition erase size */
#define MC_CMD_FC_IN_LOG_ADDR_RANGE_ERASE_SIZE_OFST 16
/* MC_CMD_FC_IN_LOG_JTAG_UART msgrequest */
#define MC_CMD_FC_IN_LOG_JTAG_UART_LEN 12
/* MC_CMD_FC_IN_CMD_OFST 0 */
/* MC_CMD_FC_IN_LOG_OP_OFST 4 */
+/* Enable/disable printing to JTAG UART */
#define MC_CMD_FC_IN_LOG_JTAG_UART_ENABLE_OFST 8
/* MC_CMD_FC_IN_CLOCK msgrequest */
@@ -1132,6 +1802,7 @@
#define MC_CMD_FC_IN_CLOCK_OP_OFST 4
#define MC_CMD_FC_IN_CLOCK_GET_TIME 0x0 /* enum */
#define MC_CMD_FC_IN_CLOCK_SET_TIME 0x1 /* enum */
+/* Perform a clock operation */
#define MC_CMD_FC_IN_CLOCK_ID_OFST 8
#define MC_CMD_FC_IN_CLOCK_STATS 0x0 /* enum */
#define MC_CMD_FC_IN_CLOCK_MAC 0x1 /* enum */
@@ -1140,6 +1811,7 @@
#define MC_CMD_FC_IN_CLOCK_GET_TIME_LEN 12
/* MC_CMD_FC_IN_CMD_OFST 0 */
/* MC_CMD_FC_IN_CLOCK_OP_OFST 4 */
+/* Retrieve the clock value of the specified clock */
/* MC_CMD_FC_IN_CLOCK_ID_OFST 8 */
/* MC_CMD_FC_IN_CLOCK_SET_TIME msgrequest */
@@ -1151,6 +1823,7 @@
#define MC_CMD_FC_IN_CLOCK_SET_TIME_SECONDS_LEN 8
#define MC_CMD_FC_IN_CLOCK_SET_TIME_SECONDS_LO_OFST 12
#define MC_CMD_FC_IN_CLOCK_SET_TIME_SECONDS_HI_OFST 16
+/* Set the clock value of the specified clock */
#define MC_CMD_FC_IN_CLOCK_SET_TIME_NANOSECONDS_OFST 20
/* MC_CMD_FC_IN_DDR msgrequest */
@@ -1170,40 +1843,59 @@
#define MC_CMD_FC_IN_DDR_SET_SPD_LEN 148
/* MC_CMD_FC_IN_CMD_OFST 0 */
/* MC_CMD_FC_IN_DDR_OP_OFST 4 */
+/* Affected bank */
/* MC_CMD_FC_IN_DDR_BANK_OFST 8 */
+/* Flags */
#define MC_CMD_FC_IN_DDR_FLAGS_OFST 12
#define MC_CMD_FC_IN_DDR_SET_SPD_ACTIVE 0x1 /* enum */
+/* 128-byte page of serial presence detect data read from module's EEPROM */
#define MC_CMD_FC_IN_DDR_SPD_OFST 16
#define MC_CMD_FC_IN_DDR_SPD_LEN 1
#define MC_CMD_FC_IN_DDR_SPD_NUM 128
+/* Page index of the spd data copied into MC_CMD_FC_IN_DDR_SPD */
#define MC_CMD_FC_IN_DDR_SPD_PAGE_ID_OFST 144
/* MC_CMD_FC_IN_DDR_GET_STATUS msgrequest */
#define MC_CMD_FC_IN_DDR_GET_STATUS_LEN 12
/* MC_CMD_FC_IN_CMD_OFST 0 */
/* MC_CMD_FC_IN_DDR_OP_OFST 4 */
+/* Affected bank */
/* MC_CMD_FC_IN_DDR_BANK_OFST 8 */
/* MC_CMD_FC_IN_TIMESTAMP msgrequest */
#define MC_CMD_FC_IN_TIMESTAMP_LEN 8
/* MC_CMD_FC_IN_CMD_OFST 0 */
+/* FC timestamp operation code */
#define MC_CMD_FC_IN_TIMESTAMP_OP_OFST 4
-#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT 0x0 /* enum */
-#define MC_CMD_FC_IN_TIMESTAMP_READ_SNAPSHOT 0x1 /* enum */
-#define MC_CMD_FC_IN_TIMESTAMP_CLEAR_TRANSMIT 0x2 /* enum */
+/* enum: Read transmit timestamp(s) */
+#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT 0x0
+/* enum: Read snapshot timestamps */
+#define MC_CMD_FC_IN_TIMESTAMP_READ_SNAPSHOT 0x1
+/* enum: Clear all transmit timestamps */
+#define MC_CMD_FC_IN_TIMESTAMP_CLEAR_TRANSMIT 0x2
/* MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT msgrequest */
#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_LEN 28
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_OP_OFST 4
+/* Control filtering of the returned timestamp and sequence number specified
+ * here
+ */
#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_FILTER_OFST 8
-#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_LATEST 0x0 /* enum */
-#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_MATCH 0x1 /* enum */
+/* enum: Return most recent timestamp. No filtering */
+#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_LATEST 0x0
+/* enum: Match timestamp against the PTP clock ID, port number and sequence
+ * number specified
+ */
+#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_MATCH 0x1
+/* Clock identity of PTP packet for which timestamp required */
#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_CLOCK_ID_OFST 12
#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_CLOCK_ID_LEN 8
#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_CLOCK_ID_LO_OFST 12
#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_CLOCK_ID_HI_OFST 16
+/* Port number of PTP packet for which timestamp required */
#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_PORT_NUM_OFST 20
+/* Sequence number of PTP packet for which timestamp required */
#define MC_CMD_FC_IN_TIMESTAMP_READ_TRANSMIT_SEQ_NUM_OFST 24
/* MC_CMD_FC_IN_TIMESTAMP_READ_SNAPSHOT msgrequest */
@@ -1219,10 +1911,14 @@
/* MC_CMD_FC_IN_SPI msgrequest */
#define MC_CMD_FC_IN_SPI_LEN 8
/* MC_CMD_FC_IN_CMD_OFST 0 */
+/* Basic commands for SPI Flash. */
#define MC_CMD_FC_IN_SPI_OP_OFST 4
-#define MC_CMD_FC_IN_SPI_READ 0x0 /* enum */
-#define MC_CMD_FC_IN_SPI_WRITE 0x1 /* enum */
-#define MC_CMD_FC_IN_SPI_ERASE 0x2 /* enum */
+/* enum: SPI Flash read */
+#define MC_CMD_FC_IN_SPI_READ 0x0
+/* enum: SPI Flash write */
+#define MC_CMD_FC_IN_SPI_WRITE 0x1
+/* enum: SPI Flash erase */
+#define MC_CMD_FC_IN_SPI_ERASE 0x2
/* MC_CMD_FC_IN_SPI_READ msgrequest */
#define MC_CMD_FC_IN_SPI_READ_LEN 16
@@ -1253,18 +1949,29 @@
/* MC_CMD_FC_IN_DIAG msgrequest */
#define MC_CMD_FC_IN_DIAG_LEN 8
/* MC_CMD_FC_IN_CMD_OFST 0 */
+/* Operation code indicating component type */
#define MC_CMD_FC_IN_DIAG_OP_OFST 4
-#define MC_CMD_FC_IN_DIAG_POWER_NOISE 0x0 /* enum */
-#define MC_CMD_FC_IN_DIAG_DDR_SOAK 0x1 /* enum */
-#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL 0x2 /* enum */
+/* enum: Power noise generator. */
+#define MC_CMD_FC_IN_DIAG_POWER_NOISE 0x0
+/* enum: DDR soak test component. */
+#define MC_CMD_FC_IN_DIAG_DDR_SOAK 0x1
+/* enum: Diagnostics datapath control component. */
+#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL 0x2
/* MC_CMD_FC_IN_DIAG_POWER_NOISE msgrequest */
#define MC_CMD_FC_IN_DIAG_POWER_NOISE_LEN 12
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_DIAG_POWER_NOISE_OP_OFST 4
+/* Sub-opcode describing the operation to be carried out */
#define MC_CMD_FC_IN_DIAG_POWER_NOISE_SUB_OP_OFST 8
-#define MC_CMD_FC_IN_DIAG_POWER_NOISE_READ_CONFIG 0x0 /* enum */
-#define MC_CMD_FC_IN_DIAG_POWER_NOISE_WRITE_CONFIG 0x1 /* enum */
+/* enum: Read the configuration (the 32-bit values in each of the clock enable
+ * count and toggle count registers)
+ */
+#define MC_CMD_FC_IN_DIAG_POWER_NOISE_READ_CONFIG 0x0
+/* enum: Write a new configuration to the clock enable count and toggle count
+ * registers
+ */
+#define MC_CMD_FC_IN_DIAG_POWER_NOISE_WRITE_CONFIG 0x1
/* MC_CMD_FC_IN_DIAG_POWER_NOISE_READ_CONFIG msgrequest */
#define MC_CMD_FC_IN_DIAG_POWER_NOISE_READ_CONFIG_LEN 12
@@ -1277,28 +1984,42 @@
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_DIAG_POWER_NOISE_WRITE_CONFIG_OP_OFST 4
#define MC_CMD_FC_IN_DIAG_POWER_NOISE_WRITE_CONFIG_SUB_OP_OFST 8
+/* The 32-bit value to be written to the toggle count register */
#define MC_CMD_FC_IN_DIAG_POWER_NOISE_WRITE_CONFIG_TOGGLE_COUNT_OFST 12
+/* The 32-bit value to be written to the clock enable count register */
#define MC_CMD_FC_IN_DIAG_POWER_NOISE_WRITE_CONFIG_CLKEN_COUNT_OFST 16
/* MC_CMD_FC_IN_DIAG_DDR_SOAK msgrequest */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_LEN 12
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_OP_OFST 4
+/* Sub-opcode describing the operation to be carried out */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_SUB_OP_OFST 8
-#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START 0x0 /* enum */
-#define MC_CMD_FC_IN_DIAG_DDR_SOAK_RESULT 0x1 /* enum */
-#define MC_CMD_FC_IN_DIAG_DDR_SOAK_STOP 0x2 /* enum */
-#define MC_CMD_FC_IN_DIAG_DDR_SOAK_ERROR 0x3 /* enum */
+/* enum: Starts DDR soak test on selected banks */
+#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START 0x0
+/* enum: Read status of DDR soak test */
+#define MC_CMD_FC_IN_DIAG_DDR_SOAK_RESULT 0x1
+/* enum: Stop test */
+#define MC_CMD_FC_IN_DIAG_DDR_SOAK_STOP 0x2
+/* enum: Set or clear bit that triggers fake errors. These cause subsequent
+ * tests to fail until the bit is cleared.
+ */
+#define MC_CMD_FC_IN_DIAG_DDR_SOAK_ERROR 0x3
/* MC_CMD_FC_IN_DIAG_DDR_SOAK_START msgrequest */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START_LEN 24
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START_OP_OFST 4
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START_SUB_OP_OFST 8
+/* Mask of DDR banks to be tested */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START_BANK_MASK_OFST 12
+/* Pattern to use in the soak test */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START_TEST_PATTERN_OFST 16
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START_ZEROS 0x0 /* enum */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START_ONES 0x1 /* enum */
+/* Either multiple automatic tests until a STOP command is issued, or one
+ * single test
+ */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START_TEST_TYPE_OFST 20
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START_ONGOING_TEST 0x0 /* enum */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_START_SINGLE_TEST 0x1 /* enum */
@@ -1308,6 +2029,7 @@
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_RESULT_OP_OFST 4
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_RESULT_SUB_OP_OFST 8
+/* DDR bank to read status from */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_RESULT_BANK_ID_OFST 12
#define MC_CMD_FC_DDR_BANK0 0x0 /* enum */
#define MC_CMD_FC_DDR_BANK1 0x1 /* enum */
@@ -1320,6 +2042,7 @@
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_STOP_OP_OFST 4
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_STOP_SUB_OP_OFST 8
+/* Mask of DDR banks to be tested */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_STOP_BANK_MASK_OFST 12
/* MC_CMD_FC_IN_DIAG_DDR_SOAK_ERROR msgrequest */
@@ -1327,6 +2050,7 @@
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_ERROR_OP_OFST 4
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_ERROR_SUB_OP_OFST 8
+/* Mask of DDR banks to set/clear error flag on */
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_ERROR_BANK_MASK_OFST 12
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_ERROR_FLAG_ACTION_OFST 16
#define MC_CMD_FC_IN_DIAG_DDR_SOAK_ERROR_CLEAR 0x0 /* enum */
@@ -1336,15 +2060,19 @@
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_LEN 12
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_OP_OFST 4
+/* Sub-opcode describing the operation to be carried out */
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_SUB_OP_OFST 8
-#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_SET_MODE 0x0 /* enum */
-#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_RAW_CONFIG 0x1 /* enum */
+/* enum: Set a known datapath configuration */
+#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_SET_MODE 0x0
+/* enum: Apply raw config to datapath control registers */
+#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_RAW_CONFIG 0x1
/* MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_SET_MODE msgrequest */
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_SET_MODE_LEN 16
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_SET_MODE_OP_OFST 4
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_SET_MODE_SUB_OP_OFST 8
+/* Datapath configuration identifier */
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_SET_MODE_MODE_OFST 12
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_SET_MODE_PASSTHROUGH 0x0 /* enum */
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_SET_MODE_SNAKE 0x1 /* enum */
@@ -1354,8 +2082,11 @@
/* MC_CMD_FC_IN_CMD_OFST 0 */
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_RAW_CONFIG_OP_OFST 4
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_RAW_CONFIG_SUB_OP_OFST 8
+/* Value to write into control register 1 */
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_RAW_CONFIG_CONTROL1_OFST 12
+/* Value to write into control register 2 */
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_RAW_CONFIG_CONTROL2_OFST 16
+/* Value to write into control register 3 */
#define MC_CMD_FC_IN_DIAG_DATAPATH_CTRL_RAW_CONFIG_CONTROL3_OFST 20
/* MC_CMD_FC_OUT msgresponse */
@@ -1444,7 +2175,8 @@
#define MC_CMD_FC_MAC_RX_STATS_JABBERS 0x16 /* enum */
#define MC_CMD_FC_MAC_RX_STATS_FRAGMENTS 0x17 /* enum */
#define MC_CMD_FC_MAC_RX_MAC_CONTROL_FRAMES 0x18 /* enum */
-#define MC_CMD_FC_MAC_RX_NSTATS 0x19 /* enum */
+/* enum: (Last entry) */
+#define MC_CMD_FC_MAC_RX_NSTATS 0x19
/* MC_CMD_FC_OUT_MAC_GET_TX_STATS msgresponse */
#define MC_CMD_FC_OUT_MAC_GET_TX_STATS_LEN ((((0-1+(64*MC_CMD_FC_MAC_TX_NSTATS))+1))>>3)
@@ -1475,10 +2207,12 @@
#define MC_CMD_FC_MAC_TX_STATS_PKTS_1024_1518 0x13 /* enum */
#define MC_CMD_FC_MAC_TX_STATS_PKTS_1519_TX_MTU 0x14 /* enum */
#define MC_CMD_FC_MAC_TX_MAC_CONTROL_FRAMES 0x15 /* enum */
-#define MC_CMD_FC_MAC_TX_NSTATS 0x16 /* enum */
+/* enum: (Last entry) */
+#define MC_CMD_FC_MAC_TX_NSTATS 0x16
/* MC_CMD_FC_OUT_MAC_GET_STATS msgresponse */
#define MC_CMD_FC_OUT_MAC_GET_STATS_LEN ((((0-1+(64*MC_CMD_FC_MAC_NSTATS_PER_BLOCK))+1))>>3)
+/* MAC Statistics */
#define MC_CMD_FC_OUT_MAC_GET_STATS_STATISTICS_OFST 0
#define MC_CMD_FC_OUT_MAC_GET_STATS_STATISTICS_LEN 8
#define MC_CMD_FC_OUT_MAC_GET_STATS_STATISTICS_LO_OFST 0
@@ -1499,10 +2233,14 @@
#define MC_CMD_FC_OUT_DDR_TEST_POLL_STATUS_OFST 0
#define MC_CMD_FC_OUT_DDR_TEST_POLL_CODE_LBN 0
#define MC_CMD_FC_OUT_DDR_TEST_POLL_CODE_WIDTH 8
-#define MC_CMD_FC_OP_DDR_TEST_NONE 0x0 /* enum */
-#define MC_CMD_FC_OP_DDR_TEST_INPROGRESS 0x1 /* enum */
-#define MC_CMD_FC_OP_DDR_TEST_SUCCESS 0x2 /* enum */
-#define MC_CMD_FC_OP_DDR_TEST_TIMER_EXPIRED 0x3 /* enum */
+/* enum: Test not yet initiated */
+#define MC_CMD_FC_OP_DDR_TEST_NONE 0x0
+/* enum: Test is in progress */
+#define MC_CMD_FC_OP_DDR_TEST_INPROGRESS 0x1
+/* enum: Timed completed */
+#define MC_CMD_FC_OP_DDR_TEST_SUCCESS 0x2
+/* enum: Test did not complete in specified time */
+#define MC_CMD_FC_OP_DDR_TEST_TIMER_EXPIRED 0x3
#define MC_CMD_FC_OUT_DDR_TEST_POLL_PRESENT_T0_LBN 11
#define MC_CMD_FC_OUT_DDR_TEST_POLL_PRESENT_T0_WIDTH 1
#define MC_CMD_FC_OUT_DDR_TEST_POLL_PRESENT_T1_LBN 10
@@ -1511,6 +2249,7 @@
#define MC_CMD_FC_OUT_DDR_TEST_POLL_PRESENT_B0_WIDTH 1
#define MC_CMD_FC_OUT_DDR_TEST_POLL_PRESENT_B1_LBN 8
#define MC_CMD_FC_OUT_DDR_TEST_POLL_PRESENT_B1_WIDTH 1
+/* Test result from FPGA */
#define MC_CMD_FC_OUT_DDR_TEST_POLL_RESULT_OFST 4
#define MC_CMD_FC_OUT_DDR_TEST_POLL_FPGA_SUPPORTS_T0_LBN 31
#define MC_CMD_FC_OUT_DDR_TEST_POLL_FPGA_SUPPORTS_T0_WIDTH 1
@@ -1539,23 +2278,35 @@
/* MC_CMD_FC_OUT_GET_ASSERT msgresponse */
#define MC_CMD_FC_OUT_GET_ASSERT_LEN 144
+/* Assertion status flag. */
#define MC_CMD_FC_OUT_GET_ASSERT_GLOBAL_FLAGS_OFST 0
#define MC_CMD_FC_OUT_GET_ASSERT_STATE_LBN 8
#define MC_CMD_FC_OUT_GET_ASSERT_STATE_WIDTH 8
-#define MC_CMD_FC_GET_ASSERT_FLAGS_STATE_CLEAR 0x0 /* enum */
-#define MC_CMD_FC_GET_ASSERT_FLAGS_STATE_NEW 0x1 /* enum */
-#define MC_CMD_FC_GET_ASSERT_FLAGS_STATE_NOTIFIED 0x2 /* enum */
+/* enum: No crash data available */
+#define MC_CMD_FC_GET_ASSERT_FLAGS_STATE_CLEAR 0x0
+/* enum: New crash data available */
+#define MC_CMD_FC_GET_ASSERT_FLAGS_STATE_NEW 0x1
+/* enum: Crash data has been sent */
+#define MC_CMD_FC_GET_ASSERT_FLAGS_STATE_NOTIFIED 0x2
#define MC_CMD_FC_OUT_GET_ASSERT_TYPE_LBN 0
#define MC_CMD_FC_OUT_GET_ASSERT_TYPE_WIDTH 8
-#define MC_CMD_FC_GET_ASSERT_FLAGS_TYPE_NONE 0x0 /* enum */
-#define MC_CMD_FC_GET_ASSERT_FLAGS_TYPE_EXCEPTION 0x1 /* enum */
-#define MC_CMD_FC_GET_ASSERT_FLAGS_TYPE_ASSERTION 0x2 /* enum */
+/* enum: No crash has been recorded. */
+#define MC_CMD_FC_GET_ASSERT_FLAGS_TYPE_NONE 0x0
+/* enum: Crash due to exception. */
+#define MC_CMD_FC_GET_ASSERT_FLAGS_TYPE_EXCEPTION 0x1
+/* enum: Crash due to assertion. */
+#define MC_CMD_FC_GET_ASSERT_FLAGS_TYPE_ASSERTION 0x2
+/* Failing PC value */
#define MC_CMD_FC_OUT_GET_ASSERT_SAVED_PC_OFFS_OFST 4
+/* Saved GP regs */
#define MC_CMD_FC_OUT_GET_ASSERT_GP_REGS_OFFS_OFST 8
#define MC_CMD_FC_OUT_GET_ASSERT_GP_REGS_OFFS_LEN 4
#define MC_CMD_FC_OUT_GET_ASSERT_GP_REGS_OFFS_NUM 31
+/* Exception Type */
#define MC_CMD_FC_OUT_GET_ASSERT_EXCEPTION_TYPE_OFFS_OFST 132
+/* Instruction at which exception occurred */
#define MC_CMD_FC_OUT_GET_ASSERT_EXCEPTION_PC_ADDR_OFFS_OFST 136
+/* BAD Address that triggered address-based exception */
#define MC_CMD_FC_OUT_GET_ASSERT_EXCEPTION_BAD_ADDR_OFFS_OFST 140
/* MC_CMD_FC_OUT_FPGA_BUILD msgresponse */
@@ -1573,6 +2324,7 @@
#define MC_CMD_FC_OUT_FPGA_BUILD_VERSION_MINOR_WIDTH 8
#define MC_CMD_FC_OUT_FPGA_BUILD_BUILD_NUM_LBN 0
#define MC_CMD_FC_OUT_FPGA_BUILD_BUILD_NUM_WIDTH 4
+/* Build timestamp (seconds since epoch) */
#define MC_CMD_FC_OUT_FPGA_BUILD_TIMESTAMP_OFST 4
#define MC_CMD_FC_OUT_FPGA_BUILD_PARAMETERS_OFST 8
#define MC_CMD_FC_OUT_FPGA_BUILD_FPGA_TYPE_LBN 0
@@ -1650,6 +2402,7 @@
#define MC_CMD_FC_OUT_FPGA_SERVICES_VERSION_MINOR_WIDTH 8
#define MC_CMD_FC_OUT_FPGA_SERVICES_BUILD_NUM_LBN 0
#define MC_CMD_FC_OUT_FPGA_SERVICES_BUILD_NUM_WIDTH 4
+/* Build timestamp (seconds since epoch) */
#define MC_CMD_FC_OUT_FPGA_SERVICES_TIMESTAMP_OFST 4
#define MC_CMD_FC_OUT_FPGA_SERVICES_PARAMETERS_OFST 8
#define MC_CMD_FC_OUT_FPGA_SERVICES_FC_FLASH_BOOTED_LBN 8
@@ -1686,6 +2439,7 @@
/* MC_CMD_FC_OUT_BSP_VERSION msgresponse */
#define MC_CMD_FC_OUT_BSP_VERSION_LEN 4
+/* Qsys system ID */
#define MC_CMD_FC_OUT_BSP_VERSION_SYSID_OFST 0
#define MC_CMD_FC_OUT_BSP_VERSION_VERSION_MAJOR_LBN 12
#define MC_CMD_FC_OUT_BSP_VERSION_VERSION_MAJOR_WIDTH 4
@@ -1696,11 +2450,14 @@
/* MC_CMD_FC_OUT_READ_MAP_COUNT msgresponse */
#define MC_CMD_FC_OUT_READ_MAP_COUNT_LEN 4
+/* Number of maps */
#define MC_CMD_FC_OUT_READ_MAP_COUNT_NUM_MAPS_OFST 0
/* MC_CMD_FC_OUT_READ_MAP_INDEX msgresponse */
#define MC_CMD_FC_OUT_READ_MAP_INDEX_LEN 164
+/* Index of the map */
#define MC_CMD_FC_OUT_READ_MAP_INDEX_INDEX_OFST 0
+/* Options for the map */
#define MC_CMD_FC_OUT_READ_MAP_INDEX_OPTIONS_OFST 4
#define MC_CMD_FC_OUT_READ_MAP_INDEX_ALIGN_8 0x0 /* enum */
#define MC_CMD_FC_OUT_READ_MAP_INDEX_ALIGN_16 0x1 /* enum */
@@ -1713,19 +2470,24 @@
#define MC_CMD_FC_OUT_READ_MAP_INDEX_PERM_WRITE 0x20 /* enum */
#define MC_CMD_FC_OUT_READ_MAP_INDEX_LICENSE_FREE 0x0 /* enum */
#define MC_CMD_FC_OUT_READ_MAP_INDEX_LICENSE_LICENSED 0x40 /* enum */
+/* Address of start of map */
#define MC_CMD_FC_OUT_READ_MAP_INDEX_ADDRESS_OFST 8
#define MC_CMD_FC_OUT_READ_MAP_INDEX_ADDRESS_LEN 8
#define MC_CMD_FC_OUT_READ_MAP_INDEX_ADDRESS_LO_OFST 8
#define MC_CMD_FC_OUT_READ_MAP_INDEX_ADDRESS_HI_OFST 12
+/* Length of address map */
#define MC_CMD_FC_OUT_READ_MAP_INDEX_LEN_OFST 16
#define MC_CMD_FC_OUT_READ_MAP_INDEX_LEN_LEN 8
#define MC_CMD_FC_OUT_READ_MAP_INDEX_LEN_LO_OFST 16
#define MC_CMD_FC_OUT_READ_MAP_INDEX_LEN_HI_OFST 20
+/* Component information field */
#define MC_CMD_FC_OUT_READ_MAP_INDEX_COMP_INFO_OFST 24
+/* License expiry data for map */
#define MC_CMD_FC_OUT_READ_MAP_INDEX_LICENSE_DATE_OFST 28
#define MC_CMD_FC_OUT_READ_MAP_INDEX_LICENSE_DATE_LEN 8
#define MC_CMD_FC_OUT_READ_MAP_INDEX_LICENSE_DATE_LO_OFST 28
#define MC_CMD_FC_OUT_READ_MAP_INDEX_LICENSE_DATE_HI_OFST 32
+/* Name of the component */
#define MC_CMD_FC_OUT_READ_MAP_INDEX_NAME_OFST 36
#define MC_CMD_FC_OUT_READ_MAP_INDEX_NAME_LEN 1
#define MC_CMD_FC_OUT_READ_MAP_INDEX_NAME_NUM 128
@@ -1735,7 +2497,9 @@
/* MC_CMD_FC_OUT_CAPABILITIES msgresponse */
#define MC_CMD_FC_OUT_CAPABILITIES_LEN 8
+/* Number of internal ports */
#define MC_CMD_FC_OUT_CAPABILITIES_INTERNAL_OFST 0
+/* Number of external ports */
#define MC_CMD_FC_OUT_CAPABILITIES_EXTERNAL_OFST 4
/* MC_CMD_FC_OUT_GLOBAL_FLAGS msgresponse */
@@ -1769,34 +2533,46 @@
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_TX_VOD_WIDTH 16
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_TX_PREEMP_1STPOSTTAP_LBN 16
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_TX_PREEMP_1STPOSTTAP_WIDTH 16
+/* Transceiver Transmit settings */
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_TX_SETTINGS_1_OFST 4
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_TX_PREEMP_PRETAP_LBN 0
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_TX_PREEMP_PRETAP_WIDTH 16
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_TX_PREEMP_2NDPOSTTAP_LBN 16
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_TX_PREEMP_2NDPOSTTAP_WIDTH 16
+/* Transceiver Receive settings */
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_RX_SETTINGS_OFST 8
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_RX_DC_GAIN_LBN 0
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_RX_DC_GAIN_WIDTH 16
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_RX_EQ_CONTROL_LBN 16
#define MC_CMD_FC_OUT_UHLINK_PHY_TRC_RX_EQ_CONTROL_WIDTH 16
+/* Rx eye opening */
#define MC_CMD_FC_OUT_UHLINK_PHY_RX_EYE_OFST 12
#define MC_CMD_FC_OUT_UHLINK_PHY_RX_EYE_WIDTH_LBN 0
#define MC_CMD_FC_OUT_UHLINK_PHY_RX_EYE_WIDTH_WIDTH 16
#define MC_CMD_FC_OUT_UHLINK_PHY_RX_EYE_HEIGHT_LBN 16
#define MC_CMD_FC_OUT_UHLINK_PHY_RX_EYE_HEIGHT_WIDTH 16
+/* PCS status word */
#define MC_CMD_FC_OUT_UHLINK_PHY_PCS_STATUS_OFST 16
+/* Link status word */
#define MC_CMD_FC_OUT_UHLINK_PHY_LINK_STATE_WORD_OFST 20
#define MC_CMD_FC_OUT_UHLINK_PHY_LINK_STATE_LBN 0
#define MC_CMD_FC_OUT_UHLINK_PHY_LINK_STATE_WIDTH 1
#define MC_CMD_FC_OUT_UHLINK_PHY_LINK_CONFIGURED_LBN 1
#define MC_CMD_FC_OUT_UHLINK_PHY_LINK_CONFIGURED_WIDTH 1
+/* Current SFp parameters applied */
#define MC_CMD_FC_OUT_UHLINK_PHY_SFP_PARAMS_OFST 24
#define MC_CMD_FC_OUT_UHLINK_PHY_SFP_PARAMS_LEN 20
+/* Link speed is 100, 1000, 10000 */
#define MC_CMD_FC_OUT_UHLINK_PHY_SFP_SPEED_OFST 24
+/* Length of copper cable - zero when not relevant */
#define MC_CMD_FC_OUT_UHLINK_PHY_SFP_COPPER_LEN_OFST 28
+/* True if a dual speed SFP+ module */
#define MC_CMD_FC_OUT_UHLINK_PHY_SFP_DUAL_SPEED_OFST 32
+/* True if an SFP Module is present (other fields valid when true) */
#define MC_CMD_FC_OUT_UHLINK_PHY_SFP_PRESENT_OFST 36
+/* The type of the SFP+ Module */
#define MC_CMD_FC_OUT_UHLINK_PHY_SFP_TYPE_OFST 40
+/* PHY config flags */
#define MC_CMD_FC_OUT_UHLINK_PHY_PHY_CFG_OFST 44
#define MC_CMD_FC_OUT_UHLINK_PHY_PHY_CFG_DFE_LBN 0
#define MC_CMD_FC_OUT_UHLINK_PHY_PHY_CFG_DFE_WIDTH 1
@@ -1807,9 +2583,13 @@
/* MC_CMD_FC_OUT_UHLINK_MAC msgresponse */
#define MC_CMD_FC_OUT_UHLINK_MAC_LEN 20
+/* MAC configuration applied */
#define MC_CMD_FC_OUT_UHLINK_MAC_CONFIG_OFST 0
+/* MTU size */
#define MC_CMD_FC_OUT_UHLINK_MAC_MTU_OFST 4
+/* IF Mode status */
#define MC_CMD_FC_OUT_UHLINK_MAC_IF_STATUS_OFST 8
+/* MAC address configured */
#define MC_CMD_FC_OUT_UHLINK_MAC_ADDR_OFST 12
#define MC_CMD_FC_OUT_UHLINK_MAC_ADDR_LEN 8
#define MC_CMD_FC_OUT_UHLINK_MAC_ADDR_LO_OFST 12
@@ -1817,6 +2597,7 @@
/* MC_CMD_FC_OUT_UHLINK_RX_EYE msgresponse */
#define MC_CMD_FC_OUT_UHLINK_RX_EYE_LEN ((((0-1+(32*MC_CMD_FC_UHLINK_RX_EYE_PER_BLOCK))+1))>>3)
+/* Rx Eye measurements */
#define MC_CMD_FC_OUT_UHLINK_RX_EYE_RX_EYE_OFST 0
#define MC_CMD_FC_OUT_UHLINK_RX_EYE_RX_EYE_LEN 4
#define MC_CMD_FC_OUT_UHLINK_RX_EYE_RX_EYE_NUM MC_CMD_FC_UHLINK_RX_EYE_PER_BLOCK
@@ -1826,7 +2607,9 @@
/* MC_CMD_FC_OUT_UHLINK_READ_RX_EYE_PLOT msgresponse */
#define MC_CMD_FC_OUT_UHLINK_READ_RX_EYE_PLOT_LEN ((((32-1+(64*MC_CMD_FC_UHLINK_RX_EYE_PLOT_ROWS_PER_BLOCK))+1))>>3)
+/* Has the eye plot dump completed and data returned is valid? */
#define MC_CMD_FC_OUT_UHLINK_READ_RX_EYE_PLOT_VALID_OFST 0
+/* Rx Eye binary plot */
#define MC_CMD_FC_OUT_UHLINK_READ_RX_EYE_PLOT_ROWS_OFST 4
#define MC_CMD_FC_OUT_UHLINK_READ_RX_EYE_PLOT_ROWS_LEN 8
#define MC_CMD_FC_OUT_UHLINK_READ_RX_EYE_PLOT_ROWS_LO_OFST 4
@@ -1851,12 +2634,16 @@
/* MC_CMD_FC_OUT_LICENSE msgresponse */
#define MC_CMD_FC_OUT_LICENSE_LEN 12
+/* Count of valid keys */
#define MC_CMD_FC_OUT_LICENSE_VALID_KEYS_OFST 0
+/* Count of invalid keys */
#define MC_CMD_FC_OUT_LICENSE_INVALID_KEYS_OFST 4
+/* Count of blacklisted keys */
#define MC_CMD_FC_OUT_LICENSE_BLACKLISTED_KEYS_OFST 8
/* MC_CMD_FC_OUT_STARTUP msgresponse */
#define MC_CMD_FC_OUT_STARTUP_LEN 4
+/* Capabilities of the FPGA/FC */
#define MC_CMD_FC_OUT_STARTUP_CAPABILITIES_OFST 0
#define MC_CMD_FC_OUT_STARTUP_CAN_ACCESS_FLASH_LBN 0
#define MC_CMD_FC_OUT_STARTUP_CAN_ACCESS_FLASH_WIDTH 1
@@ -1865,6 +2652,7 @@
#define MC_CMD_FC_OUT_DMA_READ_LENMIN 1
#define MC_CMD_FC_OUT_DMA_READ_LENMAX 252
#define MC_CMD_FC_OUT_DMA_READ_LEN(num) (0+1*(num))
+/* The data read */
#define MC_CMD_FC_OUT_DMA_READ_DATA_OFST 0
#define MC_CMD_FC_OUT_DMA_READ_DATA_LEN 1
#define MC_CMD_FC_OUT_DMA_READ_DATA_MINNUM 1
@@ -1872,27 +2660,36 @@
/* MC_CMD_FC_OUT_TIMED_READ_SET msgresponse */
#define MC_CMD_FC_OUT_TIMED_READ_SET_LEN 4
+/* Timer handle */
#define MC_CMD_FC_OUT_TIMED_READ_SET_FC_HANDLE_OFST 0
/* MC_CMD_FC_OUT_TIMED_READ_GET msgresponse */
#define MC_CMD_FC_OUT_TIMED_READ_GET_LEN 52
+/* Host supplied handle (unique) */
#define MC_CMD_FC_OUT_TIMED_READ_GET_HOST_HANDLE_OFST 0
+/* Address into which to transfer data in host */
#define MC_CMD_FC_OUT_TIMED_READ_GET_HOST_DMA_ADDRESS_OFST 4
#define MC_CMD_FC_OUT_TIMED_READ_GET_HOST_DMA_ADDRESS_LEN 8
#define MC_CMD_FC_OUT_TIMED_READ_GET_HOST_DMA_ADDRESS_LO_OFST 4
#define MC_CMD_FC_OUT_TIMED_READ_GET_HOST_DMA_ADDRESS_HI_OFST 8
+/* AOE address from which to transfer data */
#define MC_CMD_FC_OUT_TIMED_READ_GET_AOE_ADDRESS_OFST 12
#define MC_CMD_FC_OUT_TIMED_READ_GET_AOE_ADDRESS_LEN 8
#define MC_CMD_FC_OUT_TIMED_READ_GET_AOE_ADDRESS_LO_OFST 12
#define MC_CMD_FC_OUT_TIMED_READ_GET_AOE_ADDRESS_HI_OFST 16
+/* Length of AOE transfer (total) */
#define MC_CMD_FC_OUT_TIMED_READ_GET_AOE_LENGTH_OFST 20
+/* Length of host transfer (total) */
#define MC_CMD_FC_OUT_TIMED_READ_GET_HOST_LENGTH_OFST 24
+/* See FLAGS entry for MC_CMD_FC_IN_TIMED_READ_SET */
#define MC_CMD_FC_OUT_TIMED_READ_GET_FLAGS_OFST 28
#define MC_CMD_FC_OUT_TIMED_READ_GET_PERIOD_OFST 32
+/* When active, start read time */
#define MC_CMD_FC_OUT_TIMED_READ_GET_CLOCK_START_OFST 36
#define MC_CMD_FC_OUT_TIMED_READ_GET_CLOCK_START_LEN 8
#define MC_CMD_FC_OUT_TIMED_READ_GET_CLOCK_START_LO_OFST 36
#define MC_CMD_FC_OUT_TIMED_READ_GET_CLOCK_START_HI_OFST 40
+/* When active, end read time */
#define MC_CMD_FC_OUT_TIMED_READ_GET_CLOCK_END_OFST 44
#define MC_CMD_FC_OUT_TIMED_READ_GET_CLOCK_END_LEN 8
#define MC_CMD_FC_OUT_TIMED_READ_GET_CLOCK_END_LO_OFST 44
@@ -1964,7 +2761,9 @@
/* MC_CMD_FC_OUT_DIAG_POWER_NOISE_READ_CONFIG msgresponse */
#define MC_CMD_FC_OUT_DIAG_POWER_NOISE_READ_CONFIG_LEN 8
+/* The 32-bit value read from the toggle count register */
#define MC_CMD_FC_OUT_DIAG_POWER_NOISE_READ_CONFIG_TOGGLE_COUNT_OFST 0
+/* The 32-bit value read from the clock enable count register */
#define MC_CMD_FC_OUT_DIAG_POWER_NOISE_READ_CONFIG_CLKEN_COUNT_OFST 4
/* MC_CMD_FC_OUT_DIAG_POWER_NOISE_WRITE_CONFIG msgresponse */
@@ -1975,6 +2774,7 @@
/* MC_CMD_FC_OUT_DIAG_DDR_SOAK_RESULT msgresponse */
#define MC_CMD_FC_OUT_DIAG_DDR_SOAK_RESULT_LEN 8
+/* DDR soak test status word; bits [4:0] are relevant. */
#define MC_CMD_FC_OUT_DIAG_DDR_SOAK_RESULT_STATUS_OFST 0
#define MC_CMD_FC_OUT_DIAG_DDR_SOAK_RESULT_PASSED_LBN 0
#define MC_CMD_FC_OUT_DIAG_DDR_SOAK_RESULT_PASSED_WIDTH 1
@@ -1986,6 +2786,7 @@
#define MC_CMD_FC_OUT_DIAG_DDR_SOAK_RESULT_TIMEOUT_WIDTH 1
#define MC_CMD_FC_OUT_DIAG_DDR_SOAK_RESULT_PNF_LBN 4
#define MC_CMD_FC_OUT_DIAG_DDR_SOAK_RESULT_PNF_WIDTH 1
+/* DDR soak test error count */
#define MC_CMD_FC_OUT_DIAG_DDR_SOAK_RESULT_ERR_COUNT_OFST 4
/* MC_CMD_FC_OUT_DIAG_DDR_SOAK_STOP msgresponse */
@@ -2002,39 +2803,70 @@
/***********************************/
-/* MC_CMD_AOE
- * AOE operations (on MC rather than FC)
+/* MC_CMD_AOE
+ * AOE operations on MC
*/
-#define MC_CMD_AOE 0xa
+#define MC_CMD_AOE 0xa
/* MC_CMD_AOE_IN msgrequest */
#define MC_CMD_AOE_IN_LEN 4
#define MC_CMD_AOE_IN_OP_HDR_OFST 0
#define MC_CMD_AOE_IN_OP_LBN 0
#define MC_CMD_AOE_IN_OP_WIDTH 8
-#define MC_CMD_AOE_OP_INFO 0x1 /* enum */
-#define MC_CMD_AOE_OP_CURRENTS 0x2 /* enum */
-#define MC_CMD_AOE_OP_TEMPERATURES 0x3 /* enum */
-#define MC_CMD_AOE_OP_CPLD_IDLE 0x4 /* enum */
-#define MC_CMD_AOE_OP_CPLD_READ 0x5 /* enum */
-#define MC_CMD_AOE_OP_CPLD_WRITE 0x6 /* enum */
-#define MC_CMD_AOE_OP_CPLD_INSTRUCTION 0x7 /* enum */
-#define MC_CMD_AOE_OP_CPLD_REPROGRAM 0x8 /* enum */
-#define MC_CMD_AOE_OP_POWER 0x9 /* enum */
-#define MC_CMD_AOE_OP_LOAD 0xa /* enum */
-#define MC_CMD_AOE_OP_FAN_CONTROL 0xb /* enum */
-#define MC_CMD_AOE_OP_FAN_FAILURES 0xc /* enum */
-#define MC_CMD_AOE_OP_MAC_STATS 0xd /* enum */
-#define MC_CMD_AOE_OP_GET_PHY_MEDIA_INFO 0xe /* enum */
-#define MC_CMD_AOE_OP_JTAG_WRITE 0xf /* enum */
-#define MC_CMD_AOE_OP_FPGA_ACCESS 0x10 /* enum */
-#define MC_CMD_AOE_OP_SET_MTU_OFFSET 0x11 /* enum */
-#define MC_CMD_AOE_OP_LINK_STATE 0x12 /* enum */
-#define MC_CMD_AOE_OP_SIENA_STATS 0x13 /* enum */
-#define MC_CMD_AOE_OP_DDR 0x14 /* enum */
-#define MC_CMD_AOE_OP_FC 0x15 /* enum */
-#define MC_CMD_AOE_OP_DDR_ECC_STATUS 0x16 /* enum */
-#define MC_CMD_AOE_OP_MC_SPI_MASTER 0x17 /* enum */
+/* enum: FPGA and CPLD information */
+#define MC_CMD_AOE_OP_INFO 0x1
+/* enum: Currents and voltages read from MCP3424s; DEBUG */
+#define MC_CMD_AOE_OP_CURRENTS 0x2
+/* enum: Temperatures at locations around the PCB; DEBUG */
+#define MC_CMD_AOE_OP_TEMPERATURES 0x3
+/* enum: Set CPLD to idle */
+#define MC_CMD_AOE_OP_CPLD_IDLE 0x4
+/* enum: Read from CPLD register */
+#define MC_CMD_AOE_OP_CPLD_READ 0x5
+/* enum: Write to CPLD register */
+#define MC_CMD_AOE_OP_CPLD_WRITE 0x6
+/* enum: Execute CPLD instruction */
+#define MC_CMD_AOE_OP_CPLD_INSTRUCTION 0x7
+/* enum: Reprogram the CPLD on the AOE device */
+#define MC_CMD_AOE_OP_CPLD_REPROGRAM 0x8
+/* enum: AOE power control */
+#define MC_CMD_AOE_OP_POWER 0x9
+/* enum: AOE image loading */
+#define MC_CMD_AOE_OP_LOAD 0xa
+/* enum: Fan monitoring */
+#define MC_CMD_AOE_OP_FAN_CONTROL 0xb
+/* enum: Fan failures since last reset */
+#define MC_CMD_AOE_OP_FAN_FAILURES 0xc
+/* enum: Get generic AOE MAC statistics */
+#define MC_CMD_AOE_OP_MAC_STATS 0xd
+/* enum: Retrieve PHY specific information */
+#define MC_CMD_AOE_OP_GET_PHY_MEDIA_INFO 0xe
+/* enum: Write a number of JTAG primitive commands, return will give data */
+#define MC_CMD_AOE_OP_JTAG_WRITE 0xf
+/* enum: Control access to the FPGA via the Siena JTAG Chain */
+#define MC_CMD_AOE_OP_FPGA_ACCESS 0x10
+/* enum: Set the MTU offset between Siena and AOE MACs */
+#define MC_CMD_AOE_OP_SET_MTU_OFFSET 0x11
+/* enum: How link state is handled */
+#define MC_CMD_AOE_OP_LINK_STATE 0x12
+/* enum: How Siena MAC statistics are reported (deprecated - use
+ * MC_CMD_AOE_OP_ASIC_STATS)
+ */
+#define MC_CMD_AOE_OP_SIENA_STATS 0x13
+/* enum: How native ASIC MAC statistics are reported - replaces the deprecated
+ * command MC_CMD_AOE_OP_SIENA_STATS
+ */
+#define MC_CMD_AOE_OP_ASIC_STATS 0x13
+/* enum: DDR memory information */
+#define MC_CMD_AOE_OP_DDR 0x14
+/* enum: FC control */
+#define MC_CMD_AOE_OP_FC 0x15
+/* enum: DDR ECC status reads */
+#define MC_CMD_AOE_OP_DDR_ECC_STATUS 0x16
+/* enum: Commands for MC-SPI Master emulation */
+#define MC_CMD_AOE_OP_MC_SPI_MASTER 0x17
+/* enum: Commands for FC boot control */
+#define MC_CMD_AOE_OP_FC_BOOT 0x18
/* MC_CMD_AOE_OUT msgresponse */
#define MC_CMD_AOE_OUT_LEN 0
@@ -2077,31 +2909,46 @@
#define MC_CMD_AOE_IN_CPLD_REPROGRAM_LEN 8
/* MC_CMD_AOE_IN_CMD_OFST 0 */
#define MC_CMD_AOE_IN_CPLD_REPROGRAM_OP_OFST 4
-#define MC_CMD_AOE_IN_CPLD_REPROGRAM_REPROGRAM 0x1 /* enum */
-#define MC_CMD_AOE_IN_CPLD_REPROGRAM_REPROGRAM_EVENT 0x3 /* enum */
-#define MC_CMD_AOE_IN_CPLD_REPROGRAM_STATUS 0x4 /* enum */
+/* enum: Reprogram CPLD, poll for completion */
+#define MC_CMD_AOE_IN_CPLD_REPROGRAM_REPROGRAM 0x1
+/* enum: Reprogram CPLD, send event on completion */
+#define MC_CMD_AOE_IN_CPLD_REPROGRAM_REPROGRAM_EVENT 0x3
+/* enum: Get status of reprogramming operation */
+#define MC_CMD_AOE_IN_CPLD_REPROGRAM_STATUS 0x4
/* MC_CMD_AOE_IN_POWER msgrequest */
#define MC_CMD_AOE_IN_POWER_LEN 8
/* MC_CMD_AOE_IN_CMD_OFST 0 */
+/* Turn on or off AOE power */
#define MC_CMD_AOE_IN_POWER_OP_OFST 4
-#define MC_CMD_AOE_IN_POWER_OFF 0x0 /* enum */
-#define MC_CMD_AOE_IN_POWER_ON 0x1 /* enum */
-#define MC_CMD_AOE_IN_POWER_CLEAR 0x2 /* enum */
-#define MC_CMD_AOE_IN_POWER_SHOW_CURRENT 0x3 /* enum */
-#define MC_CMD_AOE_IN_POWER_SHOW_PEAK 0x4 /* enum */
-#define MC_CMD_AOE_IN_POWER_DDR_LAST 0x5 /* enum */
-#define MC_CMD_AOE_IN_POWER_DDR_PEAK 0x6 /* enum */
-#define MC_CMD_AOE_IN_POWER_DDR_CLEAR 0x7 /* enum */
+/* enum: Turn off FPGA power */
+#define MC_CMD_AOE_IN_POWER_OFF 0x0
+/* enum: Turn on FPGA power */
+#define MC_CMD_AOE_IN_POWER_ON 0x1
+/* enum: Clear peak power measurement */
+#define MC_CMD_AOE_IN_POWER_CLEAR 0x2
+/* enum: Show current power in sensors output */
+#define MC_CMD_AOE_IN_POWER_SHOW_CURRENT 0x3
+/* enum: Show peak power in sensors output */
+#define MC_CMD_AOE_IN_POWER_SHOW_PEAK 0x4
+/* enum: Show current DDR current */
+#define MC_CMD_AOE_IN_POWER_DDR_LAST 0x5
+/* enum: Show peak DDR current */
+#define MC_CMD_AOE_IN_POWER_DDR_PEAK 0x6
+/* enum: Clear peak DDR current */
+#define MC_CMD_AOE_IN_POWER_DDR_CLEAR 0x7
/* MC_CMD_AOE_IN_LOAD msgrequest */
#define MC_CMD_AOE_IN_LOAD_LEN 8
/* MC_CMD_AOE_IN_CMD_OFST 0 */
+/* Image to be loaded (0 - main or 1 - diagnostic) to load in normal sequence
+ */
#define MC_CMD_AOE_IN_LOAD_IMAGE_OFST 4
/* MC_CMD_AOE_IN_FAN_CONTROL msgrequest */
#define MC_CMD_AOE_IN_FAN_CONTROL_LEN 8
/* MC_CMD_AOE_IN_CMD_OFST 0 */
+/* If non zero report measured fan RPM rather than nominal */
#define MC_CMD_AOE_IN_FAN_CONTROL_REAL_RPM_OFST 4
/* MC_CMD_AOE_IN_FAN_FAILURES msgrequest */
@@ -2111,7 +2958,9 @@
/* MC_CMD_AOE_IN_MAC_STATS msgrequest */
#define MC_CMD_AOE_IN_MAC_STATS_LEN 24
/* MC_CMD_AOE_IN_CMD_OFST 0 */
+/* AOE port */
#define MC_CMD_AOE_IN_MAC_STATS_PORT_OFST 4
+/* Host memory address for statistics */
#define MC_CMD_AOE_IN_MAC_STATS_DMA_ADDR_OFST 8
#define MC_CMD_AOE_IN_MAC_STATS_DMA_ADDR_LEN 8
#define MC_CMD_AOE_IN_MAC_STATS_DMA_ADDR_LO_OFST 8
@@ -2131,11 +2980,13 @@
#define MC_CMD_AOE_IN_MAC_STATS_PERIODIC_NOEVENT_WIDTH 1
#define MC_CMD_AOE_IN_MAC_STATS_PERIOD_MS_LBN 16
#define MC_CMD_AOE_IN_MAC_STATS_PERIOD_MS_WIDTH 16
+/* Length of DMA data (optional) */
#define MC_CMD_AOE_IN_MAC_STATS_DMA_LEN_OFST 20
/* MC_CMD_AOE_IN_GET_PHY_MEDIA_INFO msgrequest */
#define MC_CMD_AOE_IN_GET_PHY_MEDIA_INFO_LEN 12
/* MC_CMD_AOE_IN_CMD_OFST 0 */
+/* AOE port */
#define MC_CMD_AOE_IN_GET_PHY_MEDIA_INFO_PORT_OFST 4
#define MC_CMD_AOE_IN_GET_PHY_MEDIA_INFO_PAGE_OFST 8
@@ -2153,16 +3004,23 @@
/* MC_CMD_AOE_IN_FPGA_ACCESS msgrequest */
#define MC_CMD_AOE_IN_FPGA_ACCESS_LEN 8
/* MC_CMD_AOE_IN_CMD_OFST 0 */
+/* Enable or disable access */
#define MC_CMD_AOE_IN_FPGA_ACCESS_OP_OFST 4
-#define MC_CMD_AOE_IN_FPGA_ACCESS_ENABLE 0x1 /* enum */
-#define MC_CMD_AOE_IN_FPGA_ACCESS_DISABLE 0x2 /* enum */
+/* enum: Enable access */
+#define MC_CMD_AOE_IN_FPGA_ACCESS_ENABLE 0x1
+/* enum: Disable access */
+#define MC_CMD_AOE_IN_FPGA_ACCESS_DISABLE 0x2
/* MC_CMD_AOE_IN_SET_MTU_OFFSET msgrequest */
#define MC_CMD_AOE_IN_SET_MTU_OFFSET_LEN 12
/* MC_CMD_AOE_IN_CMD_OFST 0 */
+/* AOE port - when not ALL_EXTERNAL or ALL_INTERNAL specifies port number */
#define MC_CMD_AOE_IN_SET_MTU_OFFSET_PORT_OFST 4
-#define MC_CMD_AOE_IN_SET_MTU_OFFSET_ALL_EXTERNAL 0x8000 /* enum */
-#define MC_CMD_AOE_IN_SET_MTU_OFFSET_ALL_INTERNAL 0x4000 /* enum */
+/* enum: Apply to all external ports */
+#define MC_CMD_AOE_IN_SET_MTU_OFFSET_ALL_EXTERNAL 0x8000
+/* enum: Apply to all internal ports */
+#define MC_CMD_AOE_IN_SET_MTU_OFFSET_ALL_INTERNAL 0x4000
+/* The MTU offset to be applied to the external ports */
#define MC_CMD_AOE_IN_SET_MTU_OFFSET_OFFSET_OFST 8
/* MC_CMD_AOE_IN_LINK_STATE msgrequest */
@@ -2171,31 +3029,52 @@
#define MC_CMD_AOE_IN_LINK_STATE_MODE_OFST 4
#define MC_CMD_AOE_IN_LINK_STATE_CONFIG_MODE_LBN 0
#define MC_CMD_AOE_IN_LINK_STATE_CONFIG_MODE_WIDTH 8
-#define MC_CMD_AOE_IN_LINK_STATE_SIMPLE_SEPARATE 0x0 /* enum */
-#define MC_CMD_AOE_IN_LINK_STATE_SIMPLE_COMBINED 0x1 /* enum */
-#define MC_CMD_AOE_IN_LINK_STATE_DIAGNOSTIC 0x2 /* enum */
-#define MC_CMD_AOE_IN_LINK_STATE_CUSTOM 0x3 /* enum */
+/* enum: AOE and associated external port */
+#define MC_CMD_AOE_IN_LINK_STATE_SIMPLE_SEPARATE 0x0
+/* enum: AOE and OR of all external ports */
+#define MC_CMD_AOE_IN_LINK_STATE_SIMPLE_COMBINED 0x1
+/* enum: Individual ports */
+#define MC_CMD_AOE_IN_LINK_STATE_DIAGNOSTIC 0x2
+/* enum: Configure link state mode on given AOE port */
+#define MC_CMD_AOE_IN_LINK_STATE_CUSTOM 0x3
#define MC_CMD_AOE_IN_LINK_STATE_OPERATION_LBN 8
#define MC_CMD_AOE_IN_LINK_STATE_OPERATION_WIDTH 8
-#define MC_CMD_AOE_IN_LINK_STATE_OP_NONE 0x0 /* enum */
-#define MC_CMD_AOE_IN_LINK_STATE_OP_OR 0x1 /* enum */
-#define MC_CMD_AOE_IN_LINK_STATE_OP_AND 0x2 /* enum */
+/* enum: No-op */
+#define MC_CMD_AOE_IN_LINK_STATE_OP_NONE 0x0
+/* enum: logical OR of all SFP ports link status */
+#define MC_CMD_AOE_IN_LINK_STATE_OP_OR 0x1
+/* enum: logical AND of all SFP ports link status */
+#define MC_CMD_AOE_IN_LINK_STATE_OP_AND 0x2
#define MC_CMD_AOE_IN_LINK_STATE_SFP_MASK_LBN 16
#define MC_CMD_AOE_IN_LINK_STATE_SFP_MASK_WIDTH 16
/* MC_CMD_AOE_IN_SIENA_STATS msgrequest */
#define MC_CMD_AOE_IN_SIENA_STATS_LEN 8
/* MC_CMD_AOE_IN_CMD_OFST 0 */
+/* How MAC statistics are reported */
#define MC_CMD_AOE_IN_SIENA_STATS_MODE_OFST 4
-#define MC_CMD_AOE_IN_SIENA_STATS_STATS_SIENA 0x0 /* enum */
-#define MC_CMD_AOE_IN_SIENA_STATS_STATS_AOE 0x1 /* enum */
+/* enum: Statistics from Siena (default) */
+#define MC_CMD_AOE_IN_SIENA_STATS_STATS_SIENA 0x0
+/* enum: Statistics from AOE external ports */
+#define MC_CMD_AOE_IN_SIENA_STATS_STATS_AOE 0x1
+
+/* MC_CMD_AOE_IN_ASIC_STATS msgrequest */
+#define MC_CMD_AOE_IN_ASIC_STATS_LEN 8
+/* MC_CMD_AOE_IN_CMD_OFST 0 */
+/* How MAC statistics are reported */
+#define MC_CMD_AOE_IN_ASIC_STATS_MODE_OFST 4
+/* enum: Statistics from the ASIC (default) */
+#define MC_CMD_AOE_IN_ASIC_STATS_STATS_ASIC 0x0
+/* enum: Statistics from AOE external ports */
+#define MC_CMD_AOE_IN_ASIC_STATS_STATS_AOE 0x1
/* MC_CMD_AOE_IN_DDR msgrequest */
#define MC_CMD_AOE_IN_DDR_LEN 12
/* MC_CMD_AOE_IN_CMD_OFST 0 */
#define MC_CMD_AOE_IN_DDR_BANK_OFST 4
/* Enum values, see field(s): */
-/* MC_CMD_FC_IN_DDR_BANK */
+/* MC_CMD_FC/MC_CMD_FC_IN_DDR/MC_CMD_FC_IN_DDR_BANK */
+/* Page index of SPD data */
#define MC_CMD_AOE_IN_DDR_SPD_PAGE_ID_OFST 8
/* MC_CMD_AOE_IN_FC msgrequest */
@@ -2207,14 +3086,17 @@
/* MC_CMD_AOE_IN_CMD_OFST 0 */
#define MC_CMD_AOE_IN_DDR_ECC_STATUS_BANK_OFST 4
/* Enum values, see field(s): */
-/* MC_CMD_FC_IN_DDR_BANK */
+/* MC_CMD_FC/MC_CMD_FC_IN_DDR/MC_CMD_FC_IN_DDR_BANK */
/* MC_CMD_AOE_IN_MC_SPI_MASTER msgrequest */
#define MC_CMD_AOE_IN_MC_SPI_MASTER_LEN 8
/* MC_CMD_AOE_IN_CMD_OFST 0 */
+/* Basic commands for MC SPI Master emulation. */
#define MC_CMD_AOE_IN_MC_SPI_MASTER_OP_OFST 4
-#define MC_CMD_AOE_IN_MC_SPI_MASTER_READ 0x0 /* enum */
-#define MC_CMD_AOE_IN_MC_SPI_MASTER_WRITE 0x1 /* enum */
+/* enum: MC SPI read */
+#define MC_CMD_AOE_IN_MC_SPI_MASTER_READ 0x0
+/* enum: MC SPI write */
+#define MC_CMD_AOE_IN_MC_SPI_MASTER_WRITE 0x1
/* MC_CMD_AOE_IN_MC_SPI_MASTER_READ msgrequest */
#define MC_CMD_AOE_IN_MC_SPI_MASTER_READ_LEN 12
@@ -2229,42 +3111,80 @@
#define MC_CMD_AOE_IN_MC_SPI_MASTER_WRITE_OFFSET_OFST 8
#define MC_CMD_AOE_IN_MC_SPI_MASTER_WRITE_DATA_OFST 12
+/* MC_CMD_AOE_IN_FC_BOOT msgrequest */
+#define MC_CMD_AOE_IN_FC_BOOT_LEN 8
+/* MC_CMD_AOE_IN_CMD_OFST 0 */
+/* FC boot control flags */
+#define MC_CMD_AOE_IN_FC_BOOT_CONTROL_OFST 4
+#define MC_CMD_AOE_IN_FC_BOOT_CONTROL_BOOT_ENABLE_LBN 0
+#define MC_CMD_AOE_IN_FC_BOOT_CONTROL_BOOT_ENABLE_WIDTH 1
+
/* MC_CMD_AOE_OUT_INFO msgresponse */
#define MC_CMD_AOE_OUT_INFO_LEN 44
+/* JTAG IDCODE of CPLD */
#define MC_CMD_AOE_OUT_INFO_CPLD_IDCODE_OFST 0
+/* Version of CPLD */
#define MC_CMD_AOE_OUT_INFO_CPLD_VERSION_OFST 4
+/* JTAG IDCODE of FPGA */
#define MC_CMD_AOE_OUT_INFO_FPGA_IDCODE_OFST 8
+/* JTAG USERCODE of FPGA */
#define MC_CMD_AOE_OUT_INFO_FPGA_VERSION_OFST 12
+/* FPGA type - read from CPLD straps */
#define MC_CMD_AOE_OUT_INFO_FPGA_TYPE_OFST 16
+/* FPGA state (debug) */
#define MC_CMD_AOE_OUT_INFO_FPGA_STATE_OFST 20
+/* FPGA image - partition from which loaded */
#define MC_CMD_AOE_OUT_INFO_FPGA_IMAGE_OFST 24
+/* FC state */
#define MC_CMD_AOE_OUT_INFO_FC_STATE_OFST 28
-#define MC_CMD_AOE_OUT_INFO_WATCHDOG 0x1 /* enum */
-#define MC_CMD_AOE_OUT_INFO_COMMS 0x2 /* enum */
+/* enum: Set if watchdog working */
+#define MC_CMD_AOE_OUT_INFO_WATCHDOG 0x1
+/* enum: Set if MC-FC communications working */
+#define MC_CMD_AOE_OUT_INFO_COMMS 0x2
+/* Random pieces of information */
#define MC_CMD_AOE_OUT_INFO_FLAGS_OFST 32
-#define MC_CMD_AOE_OUT_INFO_PEG_POWER 0x1 /* enum */
-#define MC_CMD_AOE_OUT_INFO_CPLD_GOOD 0x2 /* enum */
-#define MC_CMD_AOE_OUT_INFO_FPGA_GOOD 0x4 /* enum */
-#define MC_CMD_AOE_OUT_INFO_FPGA_POWER 0x8 /* enum */
-#define MC_CMD_AOE_OUT_INFO_BAD_SODIMM 0x10 /* enum */
-#define MC_CMD_AOE_OUT_INFO_HAS_BYTEBLASTER 0x20 /* enum */
+/* enum: Power to FPGA supplied by PEG connector, not PCIe bus */
+#define MC_CMD_AOE_OUT_INFO_PEG_POWER 0x1
+/* enum: CPLD apparently good */
+#define MC_CMD_AOE_OUT_INFO_CPLD_GOOD 0x2
+/* enum: FPGA working normally */
+#define MC_CMD_AOE_OUT_INFO_FPGA_GOOD 0x4
+/* enum: FPGA is powered */
+#define MC_CMD_AOE_OUT_INFO_FPGA_POWER 0x8
+/* enum: Board has incompatible SODIMMs fitted */
+#define MC_CMD_AOE_OUT_INFO_BAD_SODIMM 0x10
+/* enum: Board has ByteBlaster connected */
+#define MC_CMD_AOE_OUT_INFO_HAS_BYTEBLASTER 0x20
+/* Revision of Modena board */
#define MC_CMD_AOE_OUT_INFO_BOARD_REVISION_OFST 36
#define MC_CMD_AOE_OUT_INFO_UNKNOWN 0x0 /* enum */
#define MC_CMD_AOE_OUT_INFO_R1_0 0x10 /* enum */
#define MC_CMD_AOE_OUT_INFO_R1_1 0x11 /* enum */
#define MC_CMD_AOE_OUT_INFO_R1_2 0x12 /* enum */
+/* Result of FC booting - not valid while a ByteBlaster is connected. */
#define MC_CMD_AOE_OUT_INFO_FC_BOOT_RESULT_OFST 40
-#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_NO_ERROR 0x0 /* enum */
-#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_BAD_ADDRESS 0x1 /* enum */
-#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_BAD_MAGIC 0x2 /* enum */
-#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_BAD_TEXT 0x3 /* enum */
-#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_BAD_CHECKSUM 0x4 /* enum */
-#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_BAD_BSP 0x5 /* enum */
-#define MC_CMD_AOE_OUT_INFO_FC_BOOT_APP_EXECUTE 0x80 /* enum */
-#define MC_CMD_AOE_OUT_INFO_FC_BOOT_NO_BOOTROM 0xff /* enum */
+/* enum: No error */
+#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_NO_ERROR 0x0
+/* enum: Bad address set in CPLD */
+#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_BAD_ADDRESS 0x1
+/* enum: Bad header */
+#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_BAD_MAGIC 0x2
+/* enum: Bad text section details */
+#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_BAD_TEXT 0x3
+/* enum: Bad checksum */
+#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_BAD_CHECKSUM 0x4
+/* enum: Bad BSP */
+#define MC_CMD_AOE_OUT_INFO_FC_BOOT_FAIL_BAD_BSP 0x5
+/* enum: FC application loaded and execution attempted */
+#define MC_CMD_AOE_OUT_INFO_FC_BOOT_APP_EXECUTE 0x80
+/* enum: FC application Started */
+#define MC_CMD_AOE_OUT_INFO_FC_BOOT_APP_STARTED 0x81
+/* enum: No bootrom in FPGA */
+#define MC_CMD_AOE_OUT_INFO_FC_BOOT_NO_BOOTROM 0xff
/* MC_CMD_AOE_OUT_CURRENTS msgresponse */
#define MC_CMD_AOE_OUT_CURRENTS_LEN 68
+/* Set of currents and voltages (mA or mV as appropriate) */
#define MC_CMD_AOE_OUT_CURRENTS_VALUES_OFST 0
#define MC_CMD_AOE_OUT_CURRENTS_VALUES_LEN 4
#define MC_CMD_AOE_OUT_CURRENTS_VALUES_NUM 17
@@ -2288,10 +3208,12 @@
/* MC_CMD_AOE_OUT_TEMPERATURES msgresponse */
#define MC_CMD_AOE_OUT_TEMPERATURES_LEN 40
+/* Set of temperatures */
#define MC_CMD_AOE_OUT_TEMPERATURES_VALUES_OFST 0
#define MC_CMD_AOE_OUT_TEMPERATURES_VALUES_LEN 4
#define MC_CMD_AOE_OUT_TEMPERATURES_VALUES_NUM 10
-#define MC_CMD_AOE_OUT_TEMPERATURES_MAIN_0 0x0 /* enum */
+/* enum: The first set of enum values are for Modena code. */
+#define MC_CMD_AOE_OUT_TEMPERATURES_MAIN_0 0x0
#define MC_CMD_AOE_OUT_TEMPERATURES_MAIN_1 0x1 /* enum */
#define MC_CMD_AOE_OUT_TEMPERATURES_IND_0 0x2 /* enum */
#define MC_CMD_AOE_OUT_TEMPERATURES_IND_1 0x3 /* enum */
@@ -2301,15 +3223,27 @@
#define MC_CMD_AOE_OUT_TEMPERATURES_PSU 0x7 /* enum */
#define MC_CMD_AOE_OUT_TEMPERATURES_FPGA 0x8 /* enum */
#define MC_CMD_AOE_OUT_TEMPERATURES_SIENA 0x9 /* enum */
+/* enum: The second set of enum values are for Sorrento code. */
+#define MC_CMD_AOE_OUT_TEMPERATURES_SORRENTO_MAIN_0 0x0
+#define MC_CMD_AOE_OUT_TEMPERATURES_SORRENTO_MAIN_1 0x1 /* enum */
+#define MC_CMD_AOE_OUT_TEMPERATURES_SORRENTO_IND_0 0x2 /* enum */
+#define MC_CMD_AOE_OUT_TEMPERATURES_SORRENTO_IND_1 0x3 /* enum */
+#define MC_CMD_AOE_OUT_TEMPERATURES_SORRENTO_SODIMM_0 0x4 /* enum */
+#define MC_CMD_AOE_OUT_TEMPERATURES_SORRENTO_SODIMM_1 0x5 /* enum */
+#define MC_CMD_AOE_OUT_TEMPERATURES_SORRENTO_FPGA 0x6 /* enum */
+#define MC_CMD_AOE_OUT_TEMPERATURES_SORRENTO_PHY0 0x7 /* enum */
+#define MC_CMD_AOE_OUT_TEMPERATURES_SORRENTO_PHY1 0x8 /* enum */
/* MC_CMD_AOE_OUT_CPLD_READ msgresponse */
#define MC_CMD_AOE_OUT_CPLD_READ_LEN 4
+/* The value read from the CPLD */
#define MC_CMD_AOE_OUT_CPLD_READ_VALUE_OFST 0
/* MC_CMD_AOE_OUT_FAN_FAILURES msgresponse */
#define MC_CMD_AOE_OUT_FAN_FAILURES_LENMIN 4
#define MC_CMD_AOE_OUT_FAN_FAILURES_LENMAX 252
#define MC_CMD_AOE_OUT_FAN_FAILURES_LEN(num) (0+4*(num))
+/* Failure counts for each fan */
#define MC_CMD_AOE_OUT_FAN_FAILURES_COUNT_OFST 0
#define MC_CMD_AOE_OUT_FAN_FAILURES_COUNT_LEN 4
#define MC_CMD_AOE_OUT_FAN_FAILURES_COUNT_MINNUM 1
@@ -2317,12 +3251,24 @@
/* MC_CMD_AOE_OUT_CPLD_REPROGRAM msgresponse */
#define MC_CMD_AOE_OUT_CPLD_REPROGRAM_LEN 4
+/* Results of status command (only) */
#define MC_CMD_AOE_OUT_CPLD_REPROGRAM_STATUS_OFST 0
+/* MC_CMD_AOE_OUT_POWER_OFF msgresponse */
+#define MC_CMD_AOE_OUT_POWER_OFF_LEN 0
+
+/* MC_CMD_AOE_OUT_POWER_ON msgresponse */
+#define MC_CMD_AOE_OUT_POWER_ON_LEN 0
+
+/* MC_CMD_AOE_OUT_LOAD msgresponse */
+#define MC_CMD_AOE_OUT_LOAD_LEN 0
+
/* MC_CMD_AOE_OUT_MAC_STATS_DMA msgresponse */
#define MC_CMD_AOE_OUT_MAC_STATS_DMA_LEN 0
-/* MC_CMD_AOE_OUT_MAC_STATS_NO_DMA msgresponse */
+/* MC_CMD_AOE_OUT_MAC_STATS_NO_DMA msgresponse: See MC_CMD_MAC_STATS_OUT_NO_DMA
+ * for details
+ */
#define MC_CMD_AOE_OUT_MAC_STATS_NO_DMA_LEN (((MC_CMD_MAC_NSTATS*64))>>3)
#define MC_CMD_AOE_OUT_MAC_STATS_NO_DMA_STATISTICS_OFST 0
#define MC_CMD_AOE_OUT_MAC_STATS_NO_DMA_STATISTICS_LEN 8
@@ -2334,6 +3280,7 @@
#define MC_CMD_AOE_OUT_GET_PHY_MEDIA_INFO_LENMIN 5
#define MC_CMD_AOE_OUT_GET_PHY_MEDIA_INFO_LENMAX 252
#define MC_CMD_AOE_OUT_GET_PHY_MEDIA_INFO_LEN(num) (4+1*(num))
+/* in bytes */
#define MC_CMD_AOE_OUT_GET_PHY_MEDIA_INFO_DATALEN_OFST 0
#define MC_CMD_AOE_OUT_GET_PHY_MEDIA_INFO_DATA_OFST 4
#define MC_CMD_AOE_OUT_GET_PHY_MEDIA_INFO_DATA_LEN 1
@@ -2344,7 +3291,9 @@
#define MC_CMD_AOE_OUT_JTAG_WRITE_LENMIN 12
#define MC_CMD_AOE_OUT_JTAG_WRITE_LENMAX 252
#define MC_CMD_AOE_OUT_JTAG_WRITE_LEN(num) (8+4*(num))
+/* Used to align the in and out data blocks so the MC can re-use the cmd */
#define MC_CMD_AOE_OUT_JTAG_WRITE_DATALEN_OFST 0
+/* out bytes */
#define MC_CMD_AOE_OUT_JTAG_WRITE_PAD_OFST 4
#define MC_CMD_AOE_OUT_JTAG_WRITE_DATA_OFST 8
#define MC_CMD_AOE_OUT_JTAG_WRITE_DATA_LEN 4
@@ -2358,6 +3307,7 @@
#define MC_CMD_AOE_OUT_DDR_LENMIN 17
#define MC_CMD_AOE_OUT_DDR_LENMAX 252
#define MC_CMD_AOE_OUT_DDR_LEN(num) (16+1*(num))
+/* Information on the module. */
#define MC_CMD_AOE_OUT_DDR_FLAGS_OFST 0
#define MC_CMD_AOE_OUT_DDR_PRESENT_LBN 0
#define MC_CMD_AOE_OUT_DDR_PRESENT_WIDTH 1
@@ -2365,25 +3315,42 @@
#define MC_CMD_AOE_OUT_DDR_POWERED_WIDTH 1
#define MC_CMD_AOE_OUT_DDR_OPERATIONAL_LBN 2
#define MC_CMD_AOE_OUT_DDR_OPERATIONAL_WIDTH 1
+#define MC_CMD_AOE_OUT_DDR_NOT_REACHABLE_LBN 3
+#define MC_CMD_AOE_OUT_DDR_NOT_REACHABLE_WIDTH 1
+/* Memory size, in MB. */
#define MC_CMD_AOE_OUT_DDR_CAPACITY_OFST 4
+/* The memory type, as reported from SPD information */
#define MC_CMD_AOE_OUT_DDR_TYPE_OFST 8
+/* Nominal voltage of the module (as applied) */
#define MC_CMD_AOE_OUT_DDR_VOLTAGE_OFST 12
+/* SPD data read from the module */
#define MC_CMD_AOE_OUT_DDR_SPD_OFST 16
#define MC_CMD_AOE_OUT_DDR_SPD_LEN 1
#define MC_CMD_AOE_OUT_DDR_SPD_MINNUM 1
#define MC_CMD_AOE_OUT_DDR_SPD_MAXNUM 236
+/* MC_CMD_AOE_OUT_SET_MTU_OFFSET msgresponse */
+#define MC_CMD_AOE_OUT_SET_MTU_OFFSET_LEN 0
+
/* MC_CMD_AOE_OUT_LINK_STATE msgresponse */
#define MC_CMD_AOE_OUT_LINK_STATE_LEN 0
+/* MC_CMD_AOE_OUT_SIENA_STATS msgresponse */
+#define MC_CMD_AOE_OUT_SIENA_STATS_LEN 0
+
+/* MC_CMD_AOE_OUT_ASIC_STATS msgresponse */
+#define MC_CMD_AOE_OUT_ASIC_STATS_LEN 0
+
/* MC_CMD_AOE_OUT_FC msgresponse */
#define MC_CMD_AOE_OUT_FC_LEN 0
/* MC_CMD_AOE_OUT_DDR_ECC_STATUS msgresponse */
#define MC_CMD_AOE_OUT_DDR_ECC_STATUS_LEN 8
+/* Flags describing status info on the module. */
#define MC_CMD_AOE_OUT_DDR_ECC_STATUS_FLAGS_OFST 0
#define MC_CMD_AOE_OUT_DDR_ECC_STATUS_VALID_LBN 0
#define MC_CMD_AOE_OUT_DDR_ECC_STATUS_VALID_WIDTH 1
+/* DDR ECC status on the module. */
#define MC_CMD_AOE_OUT_DDR_ECC_STATUS_STATUS_OFST 4
#define MC_CMD_AOE_OUT_DDR_ECC_STATUS_SBE_LBN 0
#define MC_CMD_AOE_OUT_DDR_ECC_STATUS_SBE_WIDTH 1
@@ -2408,51 +3375,113 @@
/* MC_CMD_AOE_OUT_MC_SPI_MASTER msgresponse */
#define MC_CMD_AOE_OUT_MC_SPI_MASTER_LEN 0
+/* MC_CMD_AOE_OUT_FC_BOOT msgresponse */
+#define MC_CMD_AOE_OUT_FC_BOOT_LEN 0
+
/***********************************/
-/* MC_CMD_PTP
+/* MC_CMD_PTP
* Perform PTP operation
*/
-#define MC_CMD_PTP 0xb
+#define MC_CMD_PTP 0xb
+#undef MC_CMD_0xb_PRIVILEGE_CTG
+
+#define MC_CMD_0xb_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_PTP_IN msgrequest */
#define MC_CMD_PTP_IN_LEN 1
+/* PTP operation code */
#define MC_CMD_PTP_IN_OP_OFST 0
#define MC_CMD_PTP_IN_OP_LEN 1
-#define MC_CMD_PTP_OP_ENABLE 0x1 /* enum */
-#define MC_CMD_PTP_OP_DISABLE 0x2 /* enum */
-#define MC_CMD_PTP_OP_TRANSMIT 0x3 /* enum */
-#define MC_CMD_PTP_OP_READ_NIC_TIME 0x4 /* enum */
-#define MC_CMD_PTP_OP_STATUS 0x5 /* enum */
-#define MC_CMD_PTP_OP_ADJUST 0x6 /* enum */
-#define MC_CMD_PTP_OP_SYNCHRONIZE 0x7 /* enum */
-#define MC_CMD_PTP_OP_MANFTEST_BASIC 0x8 /* enum */
-#define MC_CMD_PTP_OP_MANFTEST_PACKET 0x9 /* enum */
-#define MC_CMD_PTP_OP_RESET_STATS 0xa /* enum */
-#define MC_CMD_PTP_OP_DEBUG 0xb /* enum */
-#define MC_CMD_PTP_OP_FPGAREAD 0xc /* enum */
-#define MC_CMD_PTP_OP_FPGAWRITE 0xd /* enum */
-#define MC_CMD_PTP_OP_CLOCK_OFFSET_ADJUST 0xe /* enum */
-#define MC_CMD_PTP_OP_CLOCK_FREQ_ADJUST 0xf /* enum */
-#define MC_CMD_PTP_OP_RX_SET_VLAN_FILTER 0x10 /* enum */
-#define MC_CMD_PTP_OP_RX_SET_UUID_FILTER 0x11 /* enum */
-#define MC_CMD_PTP_OP_RX_SET_DOMAIN_FILTER 0x12 /* enum */
-#define MC_CMD_PTP_OP_SET_CLK_SRC 0x13 /* enum */
-#define MC_CMD_PTP_OP_RST_CLK 0x14 /* enum */
-#define MC_CMD_PTP_OP_PPS_ENABLE 0x15 /* enum */
-#define MC_CMD_PTP_OP_MAX 0x16 /* enum */
+/* enum: Enable PTP packet timestamping operation. */
+#define MC_CMD_PTP_OP_ENABLE 0x1
+/* enum: Disable PTP packet timestamping operation. */
+#define MC_CMD_PTP_OP_DISABLE 0x2
+/* enum: Send a PTP packet. */
+#define MC_CMD_PTP_OP_TRANSMIT 0x3
+/* enum: Read the current NIC time. */
+#define MC_CMD_PTP_OP_READ_NIC_TIME 0x4
+/* enum: Get the current PTP status. */
+#define MC_CMD_PTP_OP_STATUS 0x5
+/* enum: Adjust the PTP NIC's time. */
+#define MC_CMD_PTP_OP_ADJUST 0x6
+/* enum: Synchronize host and NIC time. */
+#define MC_CMD_PTP_OP_SYNCHRONIZE 0x7
+/* enum: Basic manufacturing tests. */
+#define MC_CMD_PTP_OP_MANFTEST_BASIC 0x8
+/* enum: Packet based manufacturing tests. */
+#define MC_CMD_PTP_OP_MANFTEST_PACKET 0x9
+/* enum: Reset some of the PTP related statistics */
+#define MC_CMD_PTP_OP_RESET_STATS 0xa
+/* enum: Debug operations to MC. */
+#define MC_CMD_PTP_OP_DEBUG 0xb
+/* enum: Read an FPGA register */
+#define MC_CMD_PTP_OP_FPGAREAD 0xc
+/* enum: Write an FPGA register */
+#define MC_CMD_PTP_OP_FPGAWRITE 0xd
+/* enum: Apply an offset to the NIC clock */
+#define MC_CMD_PTP_OP_CLOCK_OFFSET_ADJUST 0xe
+/* enum: Change Apply an offset to the NIC clock */
+#define MC_CMD_PTP_OP_CLOCK_FREQ_ADJUST 0xf
+/* enum: Set the MC packet filter VLAN tags for received PTP packets */
+#define MC_CMD_PTP_OP_RX_SET_VLAN_FILTER 0x10
+/* enum: Set the MC packet filter UUID for received PTP packets */
+#define MC_CMD_PTP_OP_RX_SET_UUID_FILTER 0x11
+/* enum: Set the MC packet filter Domain for received PTP packets */
+#define MC_CMD_PTP_OP_RX_SET_DOMAIN_FILTER 0x12
+/* enum: Set the clock source */
+#define MC_CMD_PTP_OP_SET_CLK_SRC 0x13
+/* enum: Reset value of Timer Reg. */
+#define MC_CMD_PTP_OP_RST_CLK 0x14
+/* enum: Enable the forwarding of PPS events to the host */
+#define MC_CMD_PTP_OP_PPS_ENABLE 0x15
+/* enum: Get the time format used by this NIC for PTP operations */
+#define MC_CMD_PTP_OP_GET_TIME_FORMAT 0x16
+/* enum: Get the clock attributes. NOTE- extended version of
+ * MC_CMD_PTP_OP_GET_TIME_FORMAT
+ */
+#define MC_CMD_PTP_OP_GET_ATTRIBUTES 0x16
+/* enum: Get corrections that should be applied to the various different
+ * timestamps
+ */
+#define MC_CMD_PTP_OP_GET_TIMESTAMP_CORRECTIONS 0x17
+/* enum: Subscribe to receive periodic time events indicating the current NIC
+ * time
+ */
+#define MC_CMD_PTP_OP_TIME_EVENT_SUBSCRIBE 0x18
+/* enum: Unsubscribe to stop receiving time events */
+#define MC_CMD_PTP_OP_TIME_EVENT_UNSUBSCRIBE 0x19
+/* enum: PPS based manfacturing tests. Requires PPS output to be looped to PPS
+ * input on the same NIC.
+ */
+#define MC_CMD_PTP_OP_MANFTEST_PPS 0x1a
+/* enum: Set the PTP sync status. Status is used by firmware to report to event
+ * subscribers.
+ */
+#define MC_CMD_PTP_OP_SET_SYNC_STATUS 0x1b
+/* enum: Above this for future use. */
+#define MC_CMD_PTP_OP_MAX 0x1c
/* MC_CMD_PTP_IN_ENABLE msgrequest */
#define MC_CMD_PTP_IN_ENABLE_LEN 16
#define MC_CMD_PTP_IN_CMD_OFST 0
#define MC_CMD_PTP_IN_PERIPH_ID_OFST 4
+/* Event queue for PTP events */
#define MC_CMD_PTP_IN_ENABLE_QUEUE_OFST 8
+/* PTP timestamping mode */
#define MC_CMD_PTP_IN_ENABLE_MODE_OFST 12
-#define MC_CMD_PTP_MODE_V1 0x0 /* enum */
-#define MC_CMD_PTP_MODE_V1_VLAN 0x1 /* enum */
-#define MC_CMD_PTP_MODE_V2 0x2 /* enum */
-#define MC_CMD_PTP_MODE_V2_VLAN 0x3 /* enum */
-#define MC_CMD_PTP_MODE_V2_ENHANCED 0x4 /* enum */
+/* enum: PTP, version 1 */
+#define MC_CMD_PTP_MODE_V1 0x0
+/* enum: PTP, version 1, with VLAN headers - deprecated */
+#define MC_CMD_PTP_MODE_V1_VLAN 0x1
+/* enum: PTP, version 2 */
+#define MC_CMD_PTP_MODE_V2 0x2
+/* enum: PTP, version 2, with VLAN headers - deprecated */
+#define MC_CMD_PTP_MODE_V2_VLAN 0x3
+/* enum: PTP, version 2, with improved UUID filtering */
+#define MC_CMD_PTP_MODE_V2_ENHANCED 0x4
+/* enum: FCoE (seconds and microseconds) */
+#define MC_CMD_PTP_MODE_FCOE 0x5
/* MC_CMD_PTP_IN_DISABLE msgrequest */
#define MC_CMD_PTP_IN_DISABLE_LEN 8
@@ -2465,7 +3494,9 @@
#define MC_CMD_PTP_IN_TRANSMIT_LEN(num) (12+1*(num))
/* MC_CMD_PTP_IN_CMD_OFST 0 */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* Transmit packet length */
#define MC_CMD_PTP_IN_TRANSMIT_LENGTH_OFST 8
+/* Transmit packet data */
#define MC_CMD_PTP_IN_TRANSMIT_PACKET_OFST 12
#define MC_CMD_PTP_IN_TRANSMIT_PACKET_LEN 1
#define MC_CMD_PTP_IN_TRANSMIT_PACKET_MINNUM 1
@@ -2485,19 +3516,31 @@
#define MC_CMD_PTP_IN_ADJUST_LEN 24
/* MC_CMD_PTP_IN_CMD_OFST 0 */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* Frequency adjustment 40 bit fixed point ns */
#define MC_CMD_PTP_IN_ADJUST_FREQ_OFST 8
#define MC_CMD_PTP_IN_ADJUST_FREQ_LEN 8
#define MC_CMD_PTP_IN_ADJUST_FREQ_LO_OFST 8
#define MC_CMD_PTP_IN_ADJUST_FREQ_HI_OFST 12
-#define MC_CMD_PTP_IN_ADJUST_BITS 0x28 /* enum */
+/* enum: Number of fractional bits in frequency adjustment */
+#define MC_CMD_PTP_IN_ADJUST_BITS 0x28
+/* Time adjustment in seconds */
#define MC_CMD_PTP_IN_ADJUST_SECONDS_OFST 16
+/* Time adjustment major value */
+#define MC_CMD_PTP_IN_ADJUST_MAJOR_OFST 16
+/* Time adjustment in nanoseconds */
#define MC_CMD_PTP_IN_ADJUST_NANOSECONDS_OFST 20
+/* Time adjustment minor value */
+#define MC_CMD_PTP_IN_ADJUST_MINOR_OFST 20
/* MC_CMD_PTP_IN_SYNCHRONIZE msgrequest */
#define MC_CMD_PTP_IN_SYNCHRONIZE_LEN 20
/* MC_CMD_PTP_IN_CMD_OFST 0 */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* Number of time readings to capture */
#define MC_CMD_PTP_IN_SYNCHRONIZE_NUMTIMESETS_OFST 8
+/* Host address in which to write "synchronization started" indication (64
+ * bits)
+ */
#define MC_CMD_PTP_IN_SYNCHRONIZE_START_ADDR_OFST 12
#define MC_CMD_PTP_IN_SYNCHRONIZE_START_ADDR_LEN 8
#define MC_CMD_PTP_IN_SYNCHRONIZE_START_ADDR_LO_OFST 12
@@ -2512,17 +3555,20 @@
#define MC_CMD_PTP_IN_MANFTEST_PACKET_LEN 12
/* MC_CMD_PTP_IN_CMD_OFST 0 */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* Enable or disable packet testing */
#define MC_CMD_PTP_IN_MANFTEST_PACKET_TEST_ENABLE_OFST 8
/* MC_CMD_PTP_IN_RESET_STATS msgrequest */
#define MC_CMD_PTP_IN_RESET_STATS_LEN 8
/* MC_CMD_PTP_IN_CMD_OFST 0 */
+/* Reset PTP statistics */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
/* MC_CMD_PTP_IN_DEBUG msgrequest */
#define MC_CMD_PTP_IN_DEBUG_LEN 12
/* MC_CMD_PTP_IN_CMD_OFST 0 */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* Debug operations */
#define MC_CMD_PTP_IN_DEBUG_DEBUG_PARAM_OFST 8
/* MC_CMD_PTP_IN_FPGAREAD msgrequest */
@@ -2548,24 +3594,34 @@
#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_LEN 16
/* MC_CMD_PTP_IN_CMD_OFST 0 */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* Time adjustment in seconds */
#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_SECONDS_OFST 8
+/* Time adjustment major value */
+#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_MAJOR_OFST 8
+/* Time adjustment in nanoseconds */
#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_NANOSECONDS_OFST 12
+/* Time adjustment minor value */
+#define MC_CMD_PTP_IN_CLOCK_OFFSET_ADJUST_MINOR_OFST 12
/* MC_CMD_PTP_IN_CLOCK_FREQ_ADJUST msgrequest */
#define MC_CMD_PTP_IN_CLOCK_FREQ_ADJUST_LEN 16
/* MC_CMD_PTP_IN_CMD_OFST 0 */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* Frequency adjustment 40 bit fixed point ns */
#define MC_CMD_PTP_IN_CLOCK_FREQ_ADJUST_FREQ_OFST 8
#define MC_CMD_PTP_IN_CLOCK_FREQ_ADJUST_FREQ_LEN 8
#define MC_CMD_PTP_IN_CLOCK_FREQ_ADJUST_FREQ_LO_OFST 8
#define MC_CMD_PTP_IN_CLOCK_FREQ_ADJUST_FREQ_HI_OFST 12
+/* enum: Number of fractional bits in frequency adjustment */
/* MC_CMD_PTP_IN_ADJUST_BITS 0x28 */
/* MC_CMD_PTP_IN_RX_SET_VLAN_FILTER msgrequest */
#define MC_CMD_PTP_IN_RX_SET_VLAN_FILTER_LEN 24
/* MC_CMD_PTP_IN_CMD_OFST 0 */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* Number of VLAN tags, 0 if not VLAN */
#define MC_CMD_PTP_IN_RX_SET_VLAN_FILTER_NUM_VLAN_TAGS_OFST 8
+/* Set of VLAN tags to filter against */
#define MC_CMD_PTP_IN_RX_SET_VLAN_FILTER_VLAN_TAG_OFST 12
#define MC_CMD_PTP_IN_RX_SET_VLAN_FILTER_VLAN_TAG_LEN 4
#define MC_CMD_PTP_IN_RX_SET_VLAN_FILTER_VLAN_TAG_NUM 3
@@ -2574,7 +3630,9 @@
#define MC_CMD_PTP_IN_RX_SET_UUID_FILTER_LEN 20
/* MC_CMD_PTP_IN_CMD_OFST 0 */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* 1 to enable UUID filtering, 0 to disable */
#define MC_CMD_PTP_IN_RX_SET_UUID_FILTER_ENABLE_OFST 8
+/* UUID to filter against */
#define MC_CMD_PTP_IN_RX_SET_UUID_FILTER_UUID_OFST 12
#define MC_CMD_PTP_IN_RX_SET_UUID_FILTER_UUID_LEN 8
#define MC_CMD_PTP_IN_RX_SET_UUID_FILTER_UUID_LO_OFST 12
@@ -2584,82 +3642,237 @@
#define MC_CMD_PTP_IN_RX_SET_DOMAIN_FILTER_LEN 16
/* MC_CMD_PTP_IN_CMD_OFST 0 */
/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* 1 to enable Domain filtering, 0 to disable */
#define MC_CMD_PTP_IN_RX_SET_DOMAIN_FILTER_ENABLE_OFST 8
+/* Domain number to filter against */
#define MC_CMD_PTP_IN_RX_SET_DOMAIN_FILTER_DOMAIN_OFST 12
+/* MC_CMD_PTP_IN_SET_CLK_SRC msgrequest */
+#define MC_CMD_PTP_IN_SET_CLK_SRC_LEN 12
+/* MC_CMD_PTP_IN_CMD_OFST 0 */
+/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* Set the clock source. */
+#define MC_CMD_PTP_IN_SET_CLK_SRC_CLK_OFST 8
+/* enum: Internal. */
+#define MC_CMD_PTP_CLK_SRC_INTERNAL 0x0
+/* enum: External. */
+#define MC_CMD_PTP_CLK_SRC_EXTERNAL 0x1
+
+/* MC_CMD_PTP_IN_RST_CLK msgrequest */
+#define MC_CMD_PTP_IN_RST_CLK_LEN 8
+/* MC_CMD_PTP_IN_CMD_OFST 0 */
+/* Reset value of Timer Reg. */
+/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+
/* MC_CMD_PTP_IN_PPS_ENABLE msgrequest */
#define MC_CMD_PTP_IN_PPS_ENABLE_LEN 12
/* MC_CMD_PTP_IN_CMD_OFST 0 */
+/* Enable or disable */
#define MC_CMD_PTP_IN_PPS_ENABLE_OP_OFST 4
-#define MC_CMD_PTP_ENABLE_PPS 0x0 /* enum */
-#define MC_CMD_PTP_DISABLE_PPS 0x1 /* enum */
+/* enum: Enable */
+#define MC_CMD_PTP_ENABLE_PPS 0x0
+/* enum: Disable */
+#define MC_CMD_PTP_DISABLE_PPS 0x1
+/* Queue id to send events back */
#define MC_CMD_PTP_IN_PPS_ENABLE_QUEUE_ID_OFST 8
+/* MC_CMD_PTP_IN_GET_TIME_FORMAT msgrequest */
+#define MC_CMD_PTP_IN_GET_TIME_FORMAT_LEN 8
+/* MC_CMD_PTP_IN_CMD_OFST 0 */
+/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+
+/* MC_CMD_PTP_IN_GET_ATTRIBUTES msgrequest */
+#define MC_CMD_PTP_IN_GET_ATTRIBUTES_LEN 8
+/* MC_CMD_PTP_IN_CMD_OFST 0 */
+/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+
+/* MC_CMD_PTP_IN_GET_TIMESTAMP_CORRECTIONS msgrequest */
+#define MC_CMD_PTP_IN_GET_TIMESTAMP_CORRECTIONS_LEN 8
+/* MC_CMD_PTP_IN_CMD_OFST 0 */
+/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+
+/* MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE msgrequest */
+#define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_LEN 12
+/* MC_CMD_PTP_IN_CMD_OFST 0 */
+/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* Original field containing queue ID. Now extended to include flags. */
+#define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_QUEUE_OFST 8
+#define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_QUEUE_ID_LBN 0
+#define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_QUEUE_ID_WIDTH 16
+#define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_REPORT_SYNC_STATUS_LBN 31
+#define MC_CMD_PTP_IN_TIME_EVENT_SUBSCRIBE_REPORT_SYNC_STATUS_WIDTH 1
+
+/* MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE msgrequest */
+#define MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_LEN 16
+/* MC_CMD_PTP_IN_CMD_OFST 0 */
+/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* Unsubscribe options */
+#define MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_CONTROL_OFST 8
+/* enum: Unsubscribe a single queue */
+#define MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_SINGLE 0x0
+/* enum: Unsubscribe all queues */
+#define MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_ALL 0x1
+/* Event queue ID */
+#define MC_CMD_PTP_IN_TIME_EVENT_UNSUBSCRIBE_QUEUE_OFST 12
+
+/* MC_CMD_PTP_IN_MANFTEST_PPS msgrequest */
+#define MC_CMD_PTP_IN_MANFTEST_PPS_LEN 12
+/* MC_CMD_PTP_IN_CMD_OFST 0 */
+/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* 1 to enable PPS test mode, 0 to disable and return result. */
+#define MC_CMD_PTP_IN_MANFTEST_PPS_TEST_ENABLE_OFST 8
+
+/* MC_CMD_PTP_IN_SET_SYNC_STATUS msgrequest */
+#define MC_CMD_PTP_IN_SET_SYNC_STATUS_LEN 24
+/* MC_CMD_PTP_IN_CMD_OFST 0 */
+/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */
+/* NIC - Host System Clock Synchronization status */
+#define MC_CMD_PTP_IN_SET_SYNC_STATUS_STATUS_OFST 8
+/* enum: Host System clock and NIC clock are not in sync */
+#define MC_CMD_PTP_IN_SET_SYNC_STATUS_NOT_IN_SYNC 0x0
+/* enum: Host System clock and NIC clock are synchronized */
+#define MC_CMD_PTP_IN_SET_SYNC_STATUS_IN_SYNC 0x1
+/* If synchronized, number of seconds until clocks should be considered to be
+ * no longer in sync.
+ */
+#define MC_CMD_PTP_IN_SET_SYNC_STATUS_TIMEOUT_OFST 12
+#define MC_CMD_PTP_IN_SET_SYNC_STATUS_RESERVED0_OFST 16
+#define MC_CMD_PTP_IN_SET_SYNC_STATUS_RESERVED1_OFST 20
+
/* MC_CMD_PTP_OUT msgresponse */
#define MC_CMD_PTP_OUT_LEN 0
/* MC_CMD_PTP_OUT_TRANSMIT msgresponse */
#define MC_CMD_PTP_OUT_TRANSMIT_LEN 8
+/* Value of seconds timestamp */
#define MC_CMD_PTP_OUT_TRANSMIT_SECONDS_OFST 0
+/* Timestamp major value */
+#define MC_CMD_PTP_OUT_TRANSMIT_MAJOR_OFST 0
+/* Value of nanoseconds timestamp */
#define MC_CMD_PTP_OUT_TRANSMIT_NANOSECONDS_OFST 4
+/* Timestamp minor value */
+#define MC_CMD_PTP_OUT_TRANSMIT_MINOR_OFST 4
+
+/* MC_CMD_PTP_OUT_TIME_EVENT_SUBSCRIBE msgresponse */
+#define MC_CMD_PTP_OUT_TIME_EVENT_SUBSCRIBE_LEN 0
+
+/* MC_CMD_PTP_OUT_TIME_EVENT_UNSUBSCRIBE msgresponse */
+#define MC_CMD_PTP_OUT_TIME_EVENT_UNSUBSCRIBE_LEN 0
/* MC_CMD_PTP_OUT_READ_NIC_TIME msgresponse */
#define MC_CMD_PTP_OUT_READ_NIC_TIME_LEN 8
+/* Value of seconds timestamp */
#define MC_CMD_PTP_OUT_READ_NIC_TIME_SECONDS_OFST 0
+/* Timestamp major value */
+#define MC_CMD_PTP_OUT_READ_NIC_TIME_MAJOR_OFST 0
+/* Value of nanoseconds timestamp */
#define MC_CMD_PTP_OUT_READ_NIC_TIME_NANOSECONDS_OFST 4
+/* Timestamp minor value */
+#define MC_CMD_PTP_OUT_READ_NIC_TIME_MINOR_OFST 4
/* MC_CMD_PTP_OUT_STATUS msgresponse */
#define MC_CMD_PTP_OUT_STATUS_LEN 64
+/* Frequency of NIC's hardware clock */
#define MC_CMD_PTP_OUT_STATUS_CLOCK_FREQ_OFST 0
+/* Number of packets transmitted and timestamped */
#define MC_CMD_PTP_OUT_STATUS_STATS_TX_OFST 4
+/* Number of packets received and timestamped */
#define MC_CMD_PTP_OUT_STATUS_STATS_RX_OFST 8
+/* Number of packets timestamped by the FPGA */
#define MC_CMD_PTP_OUT_STATUS_STATS_TS_OFST 12
+/* Number of packets filter matched */
#define MC_CMD_PTP_OUT_STATUS_STATS_FM_OFST 16
+/* Number of packets not filter matched */
#define MC_CMD_PTP_OUT_STATUS_STATS_NFM_OFST 20
+/* Number of PPS overflows (noise on input?) */
#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFLOW_OFST 24
+/* Number of PPS bad periods */
#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_BAD_OFST 28
+/* Minimum period of PPS pulse in nanoseconds */
#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MIN_OFST 32
+/* Maximum period of PPS pulse in nanoseconds */
#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MAX_OFST 36
+/* Last period of PPS pulse in nanoseconds */
#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_LAST_OFST 40
+/* Mean period of PPS pulse in nanoseconds */
#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MEAN_OFST 44
+/* Minimum offset of PPS pulse in nanoseconds (signed) */
#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MIN_OFST 48
+/* Maximum offset of PPS pulse in nanoseconds (signed) */
#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MAX_OFST 52
+/* Last offset of PPS pulse in nanoseconds (signed) */
#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_LAST_OFST 56
+/* Mean offset of PPS pulse in nanoseconds (signed) */
#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MEAN_OFST 60
/* MC_CMD_PTP_OUT_SYNCHRONIZE msgresponse */
#define MC_CMD_PTP_OUT_SYNCHRONIZE_LENMIN 20
#define MC_CMD_PTP_OUT_SYNCHRONIZE_LENMAX 240
#define MC_CMD_PTP_OUT_SYNCHRONIZE_LEN(num) (0+20*(num))
+/* A set of host and NIC times */
#define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_OFST 0
#define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_LEN 20
#define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_MINNUM 1
#define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_MAXNUM 12
+/* Host time immediately before NIC's hardware clock read */
#define MC_CMD_PTP_OUT_SYNCHRONIZE_HOSTSTART_OFST 0
+/* Value of seconds timestamp */
#define MC_CMD_PTP_OUT_SYNCHRONIZE_SECONDS_OFST 4
+/* Timestamp major value */
+#define MC_CMD_PTP_OUT_SYNCHRONIZE_MAJOR_OFST 4
+/* Value of nanoseconds timestamp */
#define MC_CMD_PTP_OUT_SYNCHRONIZE_NANOSECONDS_OFST 8
+/* Timestamp minor value */
+#define MC_CMD_PTP_OUT_SYNCHRONIZE_MINOR_OFST 8
+/* Host time immediately after NIC's hardware clock read */
#define MC_CMD_PTP_OUT_SYNCHRONIZE_HOSTEND_OFST 12
+/* Number of nanoseconds waited after reading NIC's hardware clock */
#define MC_CMD_PTP_OUT_SYNCHRONIZE_WAITNS_OFST 16
/* MC_CMD_PTP_OUT_MANFTEST_BASIC msgresponse */
#define MC_CMD_PTP_OUT_MANFTEST_BASIC_LEN 8
+/* Results of testing */
#define MC_CMD_PTP_OUT_MANFTEST_BASIC_TEST_RESULT_OFST 0
-#define MC_CMD_PTP_MANF_SUCCESS 0x0 /* enum */
-#define MC_CMD_PTP_MANF_FPGA_LOAD 0x1 /* enum */
-#define MC_CMD_PTP_MANF_FPGA_VERSION 0x2 /* enum */
-#define MC_CMD_PTP_MANF_FPGA_REGISTERS 0x3 /* enum */
-#define MC_CMD_PTP_MANF_OSCILLATOR 0x4 /* enum */
-#define MC_CMD_PTP_MANF_TIMESTAMPS 0x5 /* enum */
-#define MC_CMD_PTP_MANF_PACKET_COUNT 0x6 /* enum */
-#define MC_CMD_PTP_MANF_FILTER_COUNT 0x7 /* enum */
-#define MC_CMD_PTP_MANF_PACKET_ENOUGH 0x8 /* enum */
-#define MC_CMD_PTP_MANF_GPIO_TRIGGER 0x9 /* enum */
+/* enum: Successful test */
+#define MC_CMD_PTP_MANF_SUCCESS 0x0
+/* enum: FPGA load failed */
+#define MC_CMD_PTP_MANF_FPGA_LOAD 0x1
+/* enum: FPGA version invalid */
+#define MC_CMD_PTP_MANF_FPGA_VERSION 0x2
+/* enum: FPGA registers incorrect */
+#define MC_CMD_PTP_MANF_FPGA_REGISTERS 0x3
+/* enum: Oscillator possibly not working? */
+#define MC_CMD_PTP_MANF_OSCILLATOR 0x4
+/* enum: Timestamps not increasing */
+#define MC_CMD_PTP_MANF_TIMESTAMPS 0x5
+/* enum: Mismatched packet count */
+#define MC_CMD_PTP_MANF_PACKET_COUNT 0x6
+/* enum: Mismatched packet count (Siena filter and FPGA) */
+#define MC_CMD_PTP_MANF_FILTER_COUNT 0x7
+/* enum: Not enough packets to perform timestamp check */
+#define MC_CMD_PTP_MANF_PACKET_ENOUGH 0x8
+/* enum: Timestamp trigger GPIO not working */
+#define MC_CMD_PTP_MANF_GPIO_TRIGGER 0x9
+/* enum: Insufficient PPS events to perform checks */
+#define MC_CMD_PTP_MANF_PPS_ENOUGH 0xa
+/* enum: PPS time event period not sufficiently close to 1s. */
+#define MC_CMD_PTP_MANF_PPS_PERIOD 0xb
+/* enum: PPS time event nS reading not sufficiently close to zero. */
+#define MC_CMD_PTP_MANF_PPS_NS 0xc
+/* enum: PTP peripheral registers incorrect */
+#define MC_CMD_PTP_MANF_REGISTERS 0xd
+/* enum: Failed to read time from PTP peripheral */
+#define MC_CMD_PTP_MANF_CLOCK_READ 0xe
+/* Presence of external oscillator */
#define MC_CMD_PTP_OUT_MANFTEST_BASIC_TEST_EXTOSC_OFST 4
/* MC_CMD_PTP_OUT_MANFTEST_PACKET msgresponse */
#define MC_CMD_PTP_OUT_MANFTEST_PACKET_LEN 12
+/* Results of testing */
#define MC_CMD_PTP_OUT_MANFTEST_PACKET_TEST_RESULT_OFST 0
+/* Number of packets received by FPGA */
#define MC_CMD_PTP_OUT_MANFTEST_PACKET_TEST_FPGACOUNT_OFST 4
+/* Number of packets received by Siena filters */
#define MC_CMD_PTP_OUT_MANFTEST_PACKET_TEST_FILTERCOUNT_OFST 8
/* MC_CMD_PTP_OUT_FPGAREAD msgresponse */
@@ -2671,15 +3884,85 @@
#define MC_CMD_PTP_OUT_FPGAREAD_BUFFER_MINNUM 1
#define MC_CMD_PTP_OUT_FPGAREAD_BUFFER_MAXNUM 252
+/* MC_CMD_PTP_OUT_GET_TIME_FORMAT msgresponse */
+#define MC_CMD_PTP_OUT_GET_TIME_FORMAT_LEN 4
+/* Time format required/used by for this NIC. Applies to all PTP MCDI
+ * operations that pass times between the host and firmware. If this operation
+ * is not supported (older firmware) a format of seconds and nanoseconds should
+ * be assumed.
+ */
+#define MC_CMD_PTP_OUT_GET_TIME_FORMAT_FORMAT_OFST 0
+/* enum: Times are in seconds and nanoseconds */
+#define MC_CMD_PTP_OUT_GET_TIME_FORMAT_SECONDS_NANOSECONDS 0x0
+/* enum: Major register has units of 16 second per tick, minor 8 ns per tick */
+#define MC_CMD_PTP_OUT_GET_TIME_FORMAT_16SECONDS_8NANOSECONDS 0x1
+/* enum: Major register has units of seconds, minor 2^-27s per tick */
+#define MC_CMD_PTP_OUT_GET_TIME_FORMAT_SECONDS_27FRACTION 0x2
+
+/* MC_CMD_PTP_OUT_GET_ATTRIBUTES msgresponse */
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_LEN 24
+/* Time format required/used by for this NIC. Applies to all PTP MCDI
+ * operations that pass times between the host and firmware. If this operation
+ * is not supported (older firmware) a format of seconds and nanoseconds should
+ * be assumed.
+ */
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_TIME_FORMAT_OFST 0
+/* enum: Times are in seconds and nanoseconds */
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_SECONDS_NANOSECONDS 0x0
+/* enum: Major register has units of 16 second per tick, minor 8 ns per tick */
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_16SECONDS_8NANOSECONDS 0x1
+/* enum: Major register has units of seconds, minor 2^-27s per tick */
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_SECONDS_27FRACTION 0x2
+/* Minimum acceptable value for a corrected synchronization timeset. When
+ * comparing host and NIC clock times, the MC returns a set of samples that
+ * contain the host start and end time, the MC time when the host start was
+ * detected and the time the MC waited between reading the time and detecting
+ * the host end. The corrected sync window is the difference between the host
+ * end and start times minus the time that the MC waited for host end.
+ */
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_SYNC_WINDOW_MIN_OFST 4
+/* Various PTP capabilities */
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_CAPABILITIES_OFST 8
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_REPORT_SYNC_STATUS_LBN 0
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_REPORT_SYNC_STATUS_WIDTH 1
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_RESERVED0_OFST 12
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_RESERVED1_OFST 16
+#define MC_CMD_PTP_OUT_GET_ATTRIBUTES_RESERVED2_OFST 20
+
+/* MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS msgresponse */
+#define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_LEN 16
+/* Uncorrected error on transmit timestamps in NIC clock format */
+#define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_TRANSMIT_OFST 0
+/* Uncorrected error on receive timestamps in NIC clock format */
+#define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_RECEIVE_OFST 4
+/* Uncorrected error on PPS output in NIC clock format */
+#define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_PPS_OUT_OFST 8
+/* Uncorrected error on PPS input in NIC clock format */
+#define MC_CMD_PTP_OUT_GET_TIMESTAMP_CORRECTIONS_PPS_IN_OFST 12
+
+/* MC_CMD_PTP_OUT_MANFTEST_PPS msgresponse */
+#define MC_CMD_PTP_OUT_MANFTEST_PPS_LEN 4
+/* Results of testing */
+#define MC_CMD_PTP_OUT_MANFTEST_PPS_TEST_RESULT_OFST 0
+/* Enum values, see field(s): */
+/* MC_CMD_PTP_OUT_MANFTEST_BASIC/TEST_RESULT */
+
+/* MC_CMD_PTP_OUT_SET_SYNC_STATUS msgresponse */
+#define MC_CMD_PTP_OUT_SET_SYNC_STATUS_LEN 0
+
/***********************************/
-/* MC_CMD_CSR_READ32
+/* MC_CMD_CSR_READ32
* Read 32bit words from the indirect memory map.
*/
-#define MC_CMD_CSR_READ32 0xc
+#define MC_CMD_CSR_READ32 0xc
+#undef MC_CMD_0xc_PRIVILEGE_CTG
+
+#define MC_CMD_0xc_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_CSR_READ32_IN msgrequest */
#define MC_CMD_CSR_READ32_IN_LEN 12
+/* Address */
#define MC_CMD_CSR_READ32_IN_ADDR_OFST 0
#define MC_CMD_CSR_READ32_IN_STEP_OFST 4
#define MC_CMD_CSR_READ32_IN_NUMWORDS_OFST 8
@@ -2688,6 +3971,7 @@
#define MC_CMD_CSR_READ32_OUT_LENMIN 4
#define MC_CMD_CSR_READ32_OUT_LENMAX 252
#define MC_CMD_CSR_READ32_OUT_LEN(num) (0+4*(num))
+/* The last dword is the status, not a value read */
#define MC_CMD_CSR_READ32_OUT_BUFFER_OFST 0
#define MC_CMD_CSR_READ32_OUT_BUFFER_LEN 4
#define MC_CMD_CSR_READ32_OUT_BUFFER_MINNUM 1
@@ -2695,15 +3979,19 @@
/***********************************/
-/* MC_CMD_CSR_WRITE32
+/* MC_CMD_CSR_WRITE32
* Write 32bit dwords to the indirect memory map.
*/
-#define MC_CMD_CSR_WRITE32 0xd
+#define MC_CMD_CSR_WRITE32 0xd
+#undef MC_CMD_0xd_PRIVILEGE_CTG
+
+#define MC_CMD_0xd_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_CSR_WRITE32_IN msgrequest */
#define MC_CMD_CSR_WRITE32_IN_LENMIN 12
#define MC_CMD_CSR_WRITE32_IN_LENMAX 252
#define MC_CMD_CSR_WRITE32_IN_LEN(num) (8+4*(num))
+/* Address */
#define MC_CMD_CSR_WRITE32_IN_ADDR_OFST 0
#define MC_CMD_CSR_WRITE32_IN_STEP_OFST 4
#define MC_CMD_CSR_WRITE32_IN_BUFFER_OFST 8
@@ -2717,35 +4005,58 @@
/***********************************/
-/* MC_CMD_HP
- * HP specific commands.
+/* MC_CMD_HP
+ * These commands are used for HP related features. They are grouped under one
+ * MCDI command to avoid creating too many MCDI commands.
*/
-#define MC_CMD_HP 0x54
+#define MC_CMD_HP 0x54
+#undef MC_CMD_0x54_PRIVILEGE_CTG
+
+#define MC_CMD_0x54_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_HP_IN msgrequest */
#define MC_CMD_HP_IN_LEN 16
+/* HP OCSD sub-command. When address is not NULL, request activation of OCSD at
+ * the specified address with the specified interval.When address is NULL,
+ * INTERVAL is interpreted as a command: 0: stop OCSD / 1: Report OCSD current
+ * state / 2: (debug) Show temperature reported by one of the supported
+ * sensors.
+ */
#define MC_CMD_HP_IN_SUBCMD_OFST 0
-#define MC_CMD_HP_IN_OCSD_SUBCMD 0x0 /* enum */
-#define MC_CMD_HP_IN_LAST_SUBCMD 0x0 /* enum */
+/* enum: OCSD (Option Card Sensor Data) sub-command. */
+#define MC_CMD_HP_IN_OCSD_SUBCMD 0x0
+/* enum: Last known valid HP sub-command. */
+#define MC_CMD_HP_IN_LAST_SUBCMD 0x0
+/* The address to the array of sensor fields. (Or NULL to use a sub-command.)
+ */
#define MC_CMD_HP_IN_OCSD_ADDR_OFST 4
#define MC_CMD_HP_IN_OCSD_ADDR_LEN 8
#define MC_CMD_HP_IN_OCSD_ADDR_LO_OFST 4
#define MC_CMD_HP_IN_OCSD_ADDR_HI_OFST 8
+/* The requested update interval, in seconds. (Or the sub-command if ADDR is
+ * NULL.)
+ */
#define MC_CMD_HP_IN_OCSD_INTERVAL_OFST 12
/* MC_CMD_HP_OUT msgresponse */
#define MC_CMD_HP_OUT_LEN 4
#define MC_CMD_HP_OUT_OCSD_STATUS_OFST 0
-#define MC_CMD_HP_OUT_OCSD_STOPPED 0x1 /* enum */
-#define MC_CMD_HP_OUT_OCSD_STARTED 0x2 /* enum */
-#define MC_CMD_HP_OUT_OCSD_ALREADY_STARTED 0x3 /* enum */
+/* enum: OCSD stopped for this card. */
+#define MC_CMD_HP_OUT_OCSD_STOPPED 0x1
+/* enum: OCSD was successfully started with the address provided. */
+#define MC_CMD_HP_OUT_OCSD_STARTED 0x2
+/* enum: OCSD was already started for this card. */
+#define MC_CMD_HP_OUT_OCSD_ALREADY_STARTED 0x3
/***********************************/
-/* MC_CMD_STACKINFO
+/* MC_CMD_STACKINFO
* Get stack information.
*/
-#define MC_CMD_STACKINFO 0xf
+#define MC_CMD_STACKINFO 0xf
+#undef MC_CMD_0xf_PRIVILEGE_CTG
+
+#define MC_CMD_0xf_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_STACKINFO_IN msgrequest */
#define MC_CMD_STACKINFO_IN_LEN 0
@@ -2754,6 +4065,7 @@
#define MC_CMD_STACKINFO_OUT_LENMIN 12
#define MC_CMD_STACKINFO_OUT_LENMAX 252
#define MC_CMD_STACKINFO_OUT_LEN(num) (0+12*(num))
+/* (thread ptr, stack size, free space) for each thread in system */
#define MC_CMD_STACKINFO_OUT_THREAD_INFO_OFST 0
#define MC_CMD_STACKINFO_OUT_THREAD_INFO_LEN 12
#define MC_CMD_STACKINFO_OUT_THREAD_INFO_MINNUM 1
@@ -2761,61 +4073,105 @@
/***********************************/
-/* MC_CMD_MDIO_READ
+/* MC_CMD_MDIO_READ
* MDIO register read.
*/
-#define MC_CMD_MDIO_READ 0x10
+#define MC_CMD_MDIO_READ 0x10
+#undef MC_CMD_0x10_PRIVILEGE_CTG
+
+#define MC_CMD_0x10_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_MDIO_READ_IN msgrequest */
#define MC_CMD_MDIO_READ_IN_LEN 16
+/* Bus number; there are two MDIO buses: one for the internal PHY, and one for
+ * external devices.
+ */
#define MC_CMD_MDIO_READ_IN_BUS_OFST 0
-#define MC_CMD_MDIO_BUS_INTERNAL 0x0 /* enum */
-#define MC_CMD_MDIO_BUS_EXTERNAL 0x1 /* enum */
+/* enum: Internal. */
+#define MC_CMD_MDIO_BUS_INTERNAL 0x0
+/* enum: External. */
+#define MC_CMD_MDIO_BUS_EXTERNAL 0x1
+/* Port address */
#define MC_CMD_MDIO_READ_IN_PRTAD_OFST 4
+/* Device Address or clause 22. */
#define MC_CMD_MDIO_READ_IN_DEVAD_OFST 8
-#define MC_CMD_MDIO_CLAUSE22 0x20 /* enum */
+/* enum: By default all the MCDI MDIO operations perform clause45 mode. If you
+ * want to use clause22 then set DEVAD = MC_CMD_MDIO_CLAUSE22.
+ */
+#define MC_CMD_MDIO_CLAUSE22 0x20
+/* Address */
#define MC_CMD_MDIO_READ_IN_ADDR_OFST 12
/* MC_CMD_MDIO_READ_OUT msgresponse */
#define MC_CMD_MDIO_READ_OUT_LEN 8
+/* Value */
#define MC_CMD_MDIO_READ_OUT_VALUE_OFST 0
+/* Status the MDIO commands return the raw status bits from the MDIO block. A
+ * "good" transaction should have the DONE bit set and all other bits clear.
+ */
#define MC_CMD_MDIO_READ_OUT_STATUS_OFST 4
-#define MC_CMD_MDIO_STATUS_GOOD 0x8 /* enum */
+/* enum: Good. */
+#define MC_CMD_MDIO_STATUS_GOOD 0x8
/***********************************/
-/* MC_CMD_MDIO_WRITE
+/* MC_CMD_MDIO_WRITE
* MDIO register write.
*/
-#define MC_CMD_MDIO_WRITE 0x11
+#define MC_CMD_MDIO_WRITE 0x11
+#undef MC_CMD_0x11_PRIVILEGE_CTG
+
+#define MC_CMD_0x11_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_MDIO_WRITE_IN msgrequest */
#define MC_CMD_MDIO_WRITE_IN_LEN 20
+/* Bus number; there are two MDIO buses: one for the internal PHY, and one for
+ * external devices.
+ */
#define MC_CMD_MDIO_WRITE_IN_BUS_OFST 0
+/* enum: Internal. */
/* MC_CMD_MDIO_BUS_INTERNAL 0x0 */
+/* enum: External. */
/* MC_CMD_MDIO_BUS_EXTERNAL 0x1 */
+/* Port address */
#define MC_CMD_MDIO_WRITE_IN_PRTAD_OFST 4
+/* Device Address or clause 22. */
#define MC_CMD_MDIO_WRITE_IN_DEVAD_OFST 8
+/* enum: By default all the MCDI MDIO operations perform clause45 mode. If you
+ * want to use clause22 then set DEVAD = MC_CMD_MDIO_CLAUSE22.
+ */
/* MC_CMD_MDIO_CLAUSE22 0x20 */
+/* Address */
#define MC_CMD_MDIO_WRITE_IN_ADDR_OFST 12
+/* Value */
#define MC_CMD_MDIO_WRITE_IN_VALUE_OFST 16
/* MC_CMD_MDIO_WRITE_OUT msgresponse */
#define MC_CMD_MDIO_WRITE_OUT_LEN 4
+/* Status; the MDIO commands return the raw status bits from the MDIO block. A
+ * "good" transaction should have the DONE bit set and all other bits clear.
+ */
#define MC_CMD_MDIO_WRITE_OUT_STATUS_OFST 0
+/* enum: Good. */
/* MC_CMD_MDIO_STATUS_GOOD 0x8 */
/***********************************/
-/* MC_CMD_DBI_WRITE
+/* MC_CMD_DBI_WRITE
* Write DBI register(s).
*/
-#define MC_CMD_DBI_WRITE 0x12
+#define MC_CMD_DBI_WRITE 0x12
+#undef MC_CMD_0x12_PRIVILEGE_CTG
+
+#define MC_CMD_0x12_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_DBI_WRITE_IN msgrequest */
#define MC_CMD_DBI_WRITE_IN_LENMIN 12
#define MC_CMD_DBI_WRITE_IN_LENMAX 252
#define MC_CMD_DBI_WRITE_IN_LEN(num) (0+12*(num))
+/* Each write op consists of an address (offset 0), byte enable/VF/CS2 (offset
+ * 32) and value (offset 64). See MC_CMD_DBIWROP_TYPEDEF.
+ */
#define MC_CMD_DBI_WRITE_IN_DBIWROP_OFST 0
#define MC_CMD_DBI_WRITE_IN_DBIWROP_LEN 12
#define MC_CMD_DBI_WRITE_IN_DBIWROP_MINNUM 1
@@ -2829,85 +4185,136 @@
#define MC_CMD_DBIWROP_TYPEDEF_ADDRESS_OFST 0
#define MC_CMD_DBIWROP_TYPEDEF_ADDRESS_LBN 0
#define MC_CMD_DBIWROP_TYPEDEF_ADDRESS_WIDTH 32
-#define MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_OFST 4
-#define MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_LBN 32
-#define MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_WIDTH 32
+#define MC_CMD_DBIWROP_TYPEDEF_PARMS_OFST 4
+#define MC_CMD_DBIWROP_TYPEDEF_VF_NUM_LBN 16
+#define MC_CMD_DBIWROP_TYPEDEF_VF_NUM_WIDTH 16
+#define MC_CMD_DBIWROP_TYPEDEF_VF_ACTIVE_LBN 15
+#define MC_CMD_DBIWROP_TYPEDEF_VF_ACTIVE_WIDTH 1
+#define MC_CMD_DBIWROP_TYPEDEF_CS2_LBN 14
+#define MC_CMD_DBIWROP_TYPEDEF_CS2_WIDTH 1
+#define MC_CMD_DBIWROP_TYPEDEF_PARMS_LBN 32
+#define MC_CMD_DBIWROP_TYPEDEF_PARMS_WIDTH 32
#define MC_CMD_DBIWROP_TYPEDEF_VALUE_OFST 8
#define MC_CMD_DBIWROP_TYPEDEF_VALUE_LBN 64
#define MC_CMD_DBIWROP_TYPEDEF_VALUE_WIDTH 32
/***********************************/
-/* MC_CMD_PORT_READ32
- * Read a 32-bit register from the indirect port register map.
+/* MC_CMD_PORT_READ32
+ * Read a 32-bit register from the indirect port register map. The port to
+ * access is implied by the Shared memory channel used.
*/
-#define MC_CMD_PORT_READ32 0x14
+#define MC_CMD_PORT_READ32 0x14
/* MC_CMD_PORT_READ32_IN msgrequest */
#define MC_CMD_PORT_READ32_IN_LEN 4
+/* Address */
#define MC_CMD_PORT_READ32_IN_ADDR_OFST 0
/* MC_CMD_PORT_READ32_OUT msgresponse */
#define MC_CMD_PORT_READ32_OUT_LEN 8
+/* Value */
#define MC_CMD_PORT_READ32_OUT_VALUE_OFST 0
+/* Status */
#define MC_CMD_PORT_READ32_OUT_STATUS_OFST 4
/***********************************/
-/* MC_CMD_PORT_WRITE32
- * Write a 32-bit register to the indirect port register map.
+/* MC_CMD_PORT_WRITE32
+ * Write a 32-bit register to the indirect port register map. The port to
+ * access is implied by the Shared memory channel used.
*/
-#define MC_CMD_PORT_WRITE32 0x15
+#define MC_CMD_PORT_WRITE32 0x15
/* MC_CMD_PORT_WRITE32_IN msgrequest */
#define MC_CMD_PORT_WRITE32_IN_LEN 8
+/* Address */
#define MC_CMD_PORT_WRITE32_IN_ADDR_OFST 0
+/* Value */
#define MC_CMD_PORT_WRITE32_IN_VALUE_OFST 4
/* MC_CMD_PORT_WRITE32_OUT msgresponse */
#define MC_CMD_PORT_WRITE32_OUT_LEN 4
+/* Status */
#define MC_CMD_PORT_WRITE32_OUT_STATUS_OFST 0
/***********************************/
-/* MC_CMD_PORT_READ128
- * Read a 128-bit register from the indirect port register map.
+/* MC_CMD_PORT_READ128
+ * Read a 128-bit register from the indirect port register map. The port to
+ * access is implied by the Shared memory channel used.
*/
-#define MC_CMD_PORT_READ128 0x16
+#define MC_CMD_PORT_READ128 0x16
/* MC_CMD_PORT_READ128_IN msgrequest */
#define MC_CMD_PORT_READ128_IN_LEN 4
+/* Address */
#define MC_CMD_PORT_READ128_IN_ADDR_OFST 0
/* MC_CMD_PORT_READ128_OUT msgresponse */
#define MC_CMD_PORT_READ128_OUT_LEN 20
+/* Value */
#define MC_CMD_PORT_READ128_OUT_VALUE_OFST 0
#define MC_CMD_PORT_READ128_OUT_VALUE_LEN 16
+/* Status */
#define MC_CMD_PORT_READ128_OUT_STATUS_OFST 16
/***********************************/
-/* MC_CMD_PORT_WRITE128
- * Write a 128-bit register to the indirect port register map.
+/* MC_CMD_PORT_WRITE128
+ * Write a 128-bit register to the indirect port register map. The port to
+ * access is implied by the Shared memory channel used.
*/
-#define MC_CMD_PORT_WRITE128 0x17
+#define MC_CMD_PORT_WRITE128 0x17
/* MC_CMD_PORT_WRITE128_IN msgrequest */
#define MC_CMD_PORT_WRITE128_IN_LEN 20
+/* Address */
#define MC_CMD_PORT_WRITE128_IN_ADDR_OFST 0
+/* Value */
#define MC_CMD_PORT_WRITE128_IN_VALUE_OFST 4
#define MC_CMD_PORT_WRITE128_IN_VALUE_LEN 16
/* MC_CMD_PORT_WRITE128_OUT msgresponse */
#define MC_CMD_PORT_WRITE128_OUT_LEN 4
+/* Status */
#define MC_CMD_PORT_WRITE128_OUT_STATUS_OFST 0
+/* MC_CMD_CAPABILITIES structuredef */
+#define MC_CMD_CAPABILITIES_LEN 4
+/* Small buf table. */
+#define MC_CMD_CAPABILITIES_SMALL_BUF_TBL_LBN 0
+#define MC_CMD_CAPABILITIES_SMALL_BUF_TBL_WIDTH 1
+/* Turbo mode (for Maranello). */
+#define MC_CMD_CAPABILITIES_TURBO_LBN 1
+#define MC_CMD_CAPABILITIES_TURBO_WIDTH 1
+/* Turbo mode active (for Maranello). */
+#define MC_CMD_CAPABILITIES_TURBO_ACTIVE_LBN 2
+#define MC_CMD_CAPABILITIES_TURBO_ACTIVE_WIDTH 1
+/* PTP offload. */
+#define MC_CMD_CAPABILITIES_PTP_LBN 3
+#define MC_CMD_CAPABILITIES_PTP_WIDTH 1
+/* AOE mode. */
+#define MC_CMD_CAPABILITIES_AOE_LBN 4
+#define MC_CMD_CAPABILITIES_AOE_WIDTH 1
+/* AOE mode active. */
+#define MC_CMD_CAPABILITIES_AOE_ACTIVE_LBN 5
+#define MC_CMD_CAPABILITIES_AOE_ACTIVE_WIDTH 1
+/* AOE mode active. */
+#define MC_CMD_CAPABILITIES_FC_ACTIVE_LBN 6
+#define MC_CMD_CAPABILITIES_FC_ACTIVE_WIDTH 1
+#define MC_CMD_CAPABILITIES_RESERVED_LBN 7
+#define MC_CMD_CAPABILITIES_RESERVED_WIDTH 25
+
/***********************************/
-/* MC_CMD_GET_BOARD_CFG
+/* MC_CMD_GET_BOARD_CFG
* Returns the MC firmware configuration structure.
*/
-#define MC_CMD_GET_BOARD_CFG 0x18
+#define MC_CMD_GET_BOARD_CFG 0x18
+#undef MC_CMD_0x18_PRIVILEGE_CTG
+
+#define MC_CMD_0x18_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_GET_BOARD_CFG_IN msgrequest */
#define MC_CMD_GET_BOARD_CFG_IN_LEN 0
@@ -2919,24 +4326,10 @@
#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_TYPE_OFST 0
#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_OFST 4
#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_LEN 32
+/* See MC_CMD_CAPABILITIES */
#define MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT0_OFST 36
-#define MC_CMD_CAPABILITIES_SMALL_BUF_TBL_LBN 0x0 /* enum */
-#define MC_CMD_CAPABILITIES_SMALL_BUF_TBL_WIDTH 0x1 /* enum */
-#define MC_CMD_CAPABILITIES_TURBO_LBN 0x1 /* enum */
-#define MC_CMD_CAPABILITIES_TURBO_WIDTH 0x1 /* enum */
-#define MC_CMD_CAPABILITIES_TURBO_ACTIVE_LBN 0x2 /* enum */
-#define MC_CMD_CAPABILITIES_TURBO_ACTIVE_WIDTH 0x1 /* enum */
-#define MC_CMD_CAPABILITIES_PTP_LBN 0x3 /* enum */
-#define MC_CMD_CAPABILITIES_PTP_WIDTH 0x1 /* enum */
-#define MC_CMD_CAPABILITIES_AOE_LBN 0x4 /* enum */
-#define MC_CMD_CAPABILITIES_AOE_WIDTH 0x1 /* enum */
-#define MC_CMD_CAPABILITIES_AOE_ACTIVE_LBN 0x5 /* enum */
-#define MC_CMD_CAPABILITIES_AOE_ACTIVE_WIDTH 0x1 /* enum */
-#define MC_CMD_CAPABILITIES_FC_ACTIVE_LBN 0x6 /* enum */
-#define MC_CMD_CAPABILITIES_FC_ACTIVE_WIDTH 0x1 /* enum */
+/* See MC_CMD_CAPABILITIES */
#define MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT1_OFST 40
-/* Enum values, see field(s): */
-/* CAPABILITIES_PORT0 */
#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_OFST 44
#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_LEN 6
#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_OFST 50
@@ -2945,6 +4338,11 @@
#define MC_CMD_GET_BOARD_CFG_OUT_MAC_COUNT_PORT1_OFST 60
#define MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT0_OFST 64
#define MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT1_OFST 68
+/* This field contains a 16-bit value for each of the types of NVRAM area. The
+ * values are defined in the firmware/mc/platform/.c file for a specific board
+ * type, but otherwise have no meaning to the MC; they are used by the driver
+ * to manage selection of appropriate firmware updates.
+ */
#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST 72
#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN 2
#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MINNUM 12
@@ -2952,15 +4350,19 @@
/***********************************/
-/* MC_CMD_DBI_READX
- * Read DBI register(s).
+/* MC_CMD_DBI_READX
+ * Read DBI register(s) -- extended functionality
*/
-#define MC_CMD_DBI_READX 0x19
+#define MC_CMD_DBI_READX 0x19
+#undef MC_CMD_0x19_PRIVILEGE_CTG
+
+#define MC_CMD_0x19_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_DBI_READX_IN msgrequest */
#define MC_CMD_DBI_READX_IN_LENMIN 8
#define MC_CMD_DBI_READX_IN_LENMAX 248
#define MC_CMD_DBI_READX_IN_LEN(num) (0+8*(num))
+/* Each Read op consists of an address (offset 0), VF/CS2) */
#define MC_CMD_DBI_READX_IN_DBIRDOP_OFST 0
#define MC_CMD_DBI_READX_IN_DBIRDOP_LEN 8
#define MC_CMD_DBI_READX_IN_DBIRDOP_LO_OFST 0
@@ -2972,20 +4374,40 @@
#define MC_CMD_DBI_READX_OUT_LENMIN 4
#define MC_CMD_DBI_READX_OUT_LENMAX 252
#define MC_CMD_DBI_READX_OUT_LEN(num) (0+4*(num))
+/* Value */
#define MC_CMD_DBI_READX_OUT_VALUE_OFST 0
#define MC_CMD_DBI_READX_OUT_VALUE_LEN 4
#define MC_CMD_DBI_READX_OUT_VALUE_MINNUM 1
#define MC_CMD_DBI_READX_OUT_VALUE_MAXNUM 63
+/* MC_CMD_DBIRDOP_TYPEDEF structuredef */
+#define MC_CMD_DBIRDOP_TYPEDEF_LEN 8
+#define MC_CMD_DBIRDOP_TYPEDEF_ADDRESS_OFST 0
+#define MC_CMD_DBIRDOP_TYPEDEF_ADDRESS_LBN 0
+#define MC_CMD_DBIRDOP_TYPEDEF_ADDRESS_WIDTH 32
+#define MC_CMD_DBIRDOP_TYPEDEF_PARMS_OFST 4
+#define MC_CMD_DBIRDOP_TYPEDEF_VF_NUM_LBN 16
+#define MC_CMD_DBIRDOP_TYPEDEF_VF_NUM_WIDTH 16
+#define MC_CMD_DBIRDOP_TYPEDEF_VF_ACTIVE_LBN 15
+#define MC_CMD_DBIRDOP_TYPEDEF_VF_ACTIVE_WIDTH 1
+#define MC_CMD_DBIRDOP_TYPEDEF_CS2_LBN 14
+#define MC_CMD_DBIRDOP_TYPEDEF_CS2_WIDTH 1
+#define MC_CMD_DBIRDOP_TYPEDEF_PARMS_LBN 32
+#define MC_CMD_DBIRDOP_TYPEDEF_PARMS_WIDTH 32
+
/***********************************/
-/* MC_CMD_SET_RAND_SEED
+/* MC_CMD_SET_RAND_SEED
* Set the 16byte seed for the MC pseudo-random generator.
*/
-#define MC_CMD_SET_RAND_SEED 0x1a
+#define MC_CMD_SET_RAND_SEED 0x1a
+#undef MC_CMD_0x1a_PRIVILEGE_CTG
+
+#define MC_CMD_0x1a_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_SET_RAND_SEED_IN msgrequest */
#define MC_CMD_SET_RAND_SEED_IN_LEN 16
+/* Seed value. */
#define MC_CMD_SET_RAND_SEED_IN_SEED_OFST 0
#define MC_CMD_SET_RAND_SEED_IN_SEED_LEN 16
@@ -2994,10 +4416,10 @@
/***********************************/
-/* MC_CMD_LTSSM_HIST
- * Retrieve the history of the PCIE LTSSM.
+/* MC_CMD_LTSSM_HIST
+ * Retrieve the history of the LTSSM, if the build supports it.
*/
-#define MC_CMD_LTSSM_HIST 0x1b
+#define MC_CMD_LTSSM_HIST 0x1b
/* MC_CMD_LTSSM_HIST_IN msgrequest */
#define MC_CMD_LTSSM_HIST_IN_LEN 0
@@ -3006,6 +4428,7 @@
#define MC_CMD_LTSSM_HIST_OUT_LENMIN 0
#define MC_CMD_LTSSM_HIST_OUT_LENMAX 252
#define MC_CMD_LTSSM_HIST_OUT_LEN(num) (0+4*(num))
+/* variable number of LTSSM values, as bytes. The history is read-to-clear. */
#define MC_CMD_LTSSM_HIST_OUT_DATA_OFST 0
#define MC_CMD_LTSSM_HIST_OUT_DATA_LEN 4
#define MC_CMD_LTSSM_HIST_OUT_DATA_MINNUM 0
@@ -3013,29 +4436,72 @@
/***********************************/
-/* MC_CMD_DRV_ATTACH
- * Inform MCPU that this port is managed on the host.
+/* MC_CMD_DRV_ATTACH
+ * Inform MCPU that this port is managed on the host (i.e. driver active). For
+ * Huntington, also request the preferred datapath firmware to use if possible
+ * (it may not be possible for this request to be fulfilled; the driver must
+ * issue a subsequent MC_CMD_GET_CAPABILITIES command to determine which
+ * features are actually available). The FIRMWARE_ID field is ignored by older
+ * platforms.
*/
-#define MC_CMD_DRV_ATTACH 0x1c
+#define MC_CMD_DRV_ATTACH 0x1c
+#undef MC_CMD_0x1c_PRIVILEGE_CTG
+
+#define MC_CMD_0x1c_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_DRV_ATTACH_IN msgrequest */
-#define MC_CMD_DRV_ATTACH_IN_LEN 8
+#define MC_CMD_DRV_ATTACH_IN_LEN 12
+/* new state (0=detached, 1=attached) to set if UPDATE=1 */
#define MC_CMD_DRV_ATTACH_IN_NEW_STATE_OFST 0
+/* 1 to set new state, or 0 to just report the existing state */
#define MC_CMD_DRV_ATTACH_IN_UPDATE_OFST 4
+/* preferred datapath firmware (for Huntington; ignored for Siena) */
+#define MC_CMD_DRV_ATTACH_IN_FIRMWARE_ID_OFST 8
+/* enum: Prefer to use full featured firmware */
+#define MC_CMD_FW_FULL_FEATURED 0x0
+/* enum: Prefer to use firmware with fewer features but lower latency */
+#define MC_CMD_FW_LOW_LATENCY 0x1
+/* enum: Prefer to use firmware for SolarCapture packed stream mode */
+#define MC_CMD_FW_PACKED_STREAM 0x2
+/* enum: Prefer to use firmware with fewer features and simpler TX event
+ * batching but higher TX packet rate
+ */
+#define MC_CMD_FW_HIGH_TX_RATE 0x3
+/* enum: Reserved value */
+#define MC_CMD_FW_PACKED_STREAM_HASH_MODE_1 0x4
+/* enum: Only this option is allowed for non-admin functions */
+#define MC_CMD_FW_DONT_CARE 0xffffffff
/* MC_CMD_DRV_ATTACH_OUT msgresponse */
#define MC_CMD_DRV_ATTACH_OUT_LEN 4
+/* previous or existing state (0=detached, 1=attached) */
#define MC_CMD_DRV_ATTACH_OUT_OLD_STATE_OFST 0
+/* MC_CMD_DRV_ATTACH_EXT_OUT msgresponse */
+#define MC_CMD_DRV_ATTACH_EXT_OUT_LEN 8
+/* previous or existing state (0=detached, 1=attached) */
+#define MC_CMD_DRV_ATTACH_EXT_OUT_OLD_STATE_OFST 0
+/* Flags associated with this function */
+#define MC_CMD_DRV_ATTACH_EXT_OUT_FUNC_FLAGS_OFST 4
+/* enum: Labels the lowest-numbered function visible to the OS */
+#define MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_PRIMARY 0x0
+/* enum: The function can control the link state of the physical port it is
+ * bound to.
+ */
+#define MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_LINKCTRL 0x1
+/* enum: The function can perform privileged operations */
+#define MC_CMD_DRV_ATTACH_EXT_OUT_FLAG_TRUSTED 0x2
+
/***********************************/
-/* MC_CMD_SHMUART
+/* MC_CMD_SHMUART
* Route UART output to circular buffer in shared memory instead.
*/
-#define MC_CMD_SHMUART 0x1f
+#define MC_CMD_SHMUART 0x1f
/* MC_CMD_SHMUART_IN msgrequest */
#define MC_CMD_SHMUART_IN_LEN 4
+/* ??? */
#define MC_CMD_SHMUART_IN_FLAG_OFST 0
/* MC_CMD_SHMUART_OUT msgresponse */
@@ -3043,10 +4509,15 @@
/***********************************/
-/* MC_CMD_PORT_RESET
- * Generic per-port reset.
+/* MC_CMD_PORT_RESET
+ * Generic per-port reset. There is no equivalent for per-board reset. Locks
+ * required: None; Return code: 0, ETIME. NOTE: This command is deprecated -
+ * use MC_CMD_ENTITY_RESET instead.
*/
-#define MC_CMD_PORT_RESET 0x20
+#define MC_CMD_PORT_RESET 0x20
+#undef MC_CMD_0x20_PRIVILEGE_CTG
+
+#define MC_CMD_0x20_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_PORT_RESET_IN msgrequest */
#define MC_CMD_PORT_RESET_IN_LEN 0
@@ -3056,14 +4527,38 @@
/***********************************/
-/* MC_CMD_PCIE_CREDITS
+/* MC_CMD_ENTITY_RESET
+ * Generic per-resource reset. There is no equivalent for per-board reset.
+ * Locks required: None; Return code: 0, ETIME. NOTE: This command is an
+ * extended version of the deprecated MC_CMD_PORT_RESET with added fields.
+ */
+#define MC_CMD_ENTITY_RESET 0x20
+/* MC_CMD_0x20_PRIVILEGE_CTG SRIOV_CTG_GENERAL */
+
+/* MC_CMD_ENTITY_RESET_IN msgrequest */
+#define MC_CMD_ENTITY_RESET_IN_LEN 4
+/* Optional flags field. Omitting this will perform a "legacy" reset action
+ * (TBD).
+ */
+#define MC_CMD_ENTITY_RESET_IN_FLAG_OFST 0
+#define MC_CMD_ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET_LBN 0
+#define MC_CMD_ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET_WIDTH 1
+
+/* MC_CMD_ENTITY_RESET_OUT msgresponse */
+#define MC_CMD_ENTITY_RESET_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_PCIE_CREDITS
* Read instantaneous and minimum flow control thresholds.
*/
-#define MC_CMD_PCIE_CREDITS 0x21
+#define MC_CMD_PCIE_CREDITS 0x21
/* MC_CMD_PCIE_CREDITS_IN msgrequest */
#define MC_CMD_PCIE_CREDITS_IN_LEN 8
+/* poll period. 0 is disabled */
#define MC_CMD_PCIE_CREDITS_IN_POLL_PERIOD_OFST 0
+/* wipe statistics */
#define MC_CMD_PCIE_CREDITS_IN_WIPE_OFST 4
/* MC_CMD_PCIE_CREDITS_OUT msgresponse */
@@ -3087,10 +4582,10 @@
/***********************************/
-/* MC_CMD_RXD_MONITOR
+/* MC_CMD_RXD_MONITOR
* Get histogram of RX queue fill level.
*/
-#define MC_CMD_RXD_MONITOR 0x22
+#define MC_CMD_RXD_MONITOR 0x22
/* MC_CMD_RXD_MONITOR_IN msgrequest */
#define MC_CMD_RXD_MONITOR_IN_LEN 12
@@ -3123,10 +4618,13 @@
/***********************************/
-/* MC_CMD_PUTS
- * puts(3) implementation over MCDI
+/* MC_CMD_PUTS
+ * Copy the given ASCII string out onto UART and/or out of the network port.
*/
-#define MC_CMD_PUTS 0x23
+#define MC_CMD_PUTS 0x23
+#undef MC_CMD_0x23_PRIVILEGE_CTG
+
+#define MC_CMD_0x23_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_PUTS_IN msgrequest */
#define MC_CMD_PUTS_IN_LENMIN 13
@@ -3149,16 +4647,21 @@
/***********************************/
-/* MC_CMD_GET_PHY_CFG
- * Report PHY configuration.
+/* MC_CMD_GET_PHY_CFG
+ * Report PHY configuration. This guarantees to succeed even if the PHY is in a
+ * 'zombie' state. Locks required: None
*/
-#define MC_CMD_GET_PHY_CFG 0x24
+#define MC_CMD_GET_PHY_CFG 0x24
+#undef MC_CMD_0x24_PRIVILEGE_CTG
+
+#define MC_CMD_0x24_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_GET_PHY_CFG_IN msgrequest */
#define MC_CMD_GET_PHY_CFG_IN_LEN 0
/* MC_CMD_GET_PHY_CFG_OUT msgresponse */
#define MC_CMD_GET_PHY_CFG_OUT_LEN 72
+/* flags */
#define MC_CMD_GET_PHY_CFG_OUT_FLAGS_OFST 0
#define MC_CMD_GET_PHY_CFG_OUT_PRESENT_LBN 0
#define MC_CMD_GET_PHY_CFG_OUT_PRESENT_WIDTH 1
@@ -3174,7 +4677,9 @@
#define MC_CMD_GET_PHY_CFG_OUT_TXDIS_WIDTH 1
#define MC_CMD_GET_PHY_CFG_OUT_BIST_LBN 6
#define MC_CMD_GET_PHY_CFG_OUT_BIST_WIDTH 1
+/* ?? */
#define MC_CMD_GET_PHY_CFG_OUT_TYPE_OFST 4
+/* Bitmask of supported capabilities */
#define MC_CMD_GET_PHY_CFG_OUT_SUPPORTED_CAP_OFST 8
#define MC_CMD_PHY_CAP_10HDX_LBN 1
#define MC_CMD_PHY_CAP_10HDX_WIDTH 1
@@ -3196,22 +4701,38 @@
#define MC_CMD_PHY_CAP_ASYM_WIDTH 1
#define MC_CMD_PHY_CAP_AN_LBN 10
#define MC_CMD_PHY_CAP_AN_WIDTH 1
+#define MC_CMD_PHY_CAP_40000FDX_LBN 11
+#define MC_CMD_PHY_CAP_40000FDX_WIDTH 1
#define MC_CMD_PHY_CAP_DDM_LBN 12
#define MC_CMD_PHY_CAP_DDM_WIDTH 1
+/* ?? */
#define MC_CMD_GET_PHY_CFG_OUT_CHANNEL_OFST 12
+/* ?? */
#define MC_CMD_GET_PHY_CFG_OUT_PRT_OFST 16
+/* ?? */
#define MC_CMD_GET_PHY_CFG_OUT_STATS_MASK_OFST 20
+/* ?? */
#define MC_CMD_GET_PHY_CFG_OUT_NAME_OFST 24
#define MC_CMD_GET_PHY_CFG_OUT_NAME_LEN 20
+/* ?? */
#define MC_CMD_GET_PHY_CFG_OUT_MEDIA_TYPE_OFST 44
-#define MC_CMD_MEDIA_XAUI 0x1 /* enum */
-#define MC_CMD_MEDIA_CX4 0x2 /* enum */
-#define MC_CMD_MEDIA_KX4 0x3 /* enum */
-#define MC_CMD_MEDIA_XFP 0x4 /* enum */
-#define MC_CMD_MEDIA_SFP_PLUS 0x5 /* enum */
-#define MC_CMD_MEDIA_BASE_T 0x6 /* enum */
+/* enum: Xaui. */
+#define MC_CMD_MEDIA_XAUI 0x1
+/* enum: CX4. */
+#define MC_CMD_MEDIA_CX4 0x2
+/* enum: KX4. */
+#define MC_CMD_MEDIA_KX4 0x3
+/* enum: XFP Far. */
+#define MC_CMD_MEDIA_XFP 0x4
+/* enum: SFP+. */
+#define MC_CMD_MEDIA_SFP_PLUS 0x5
+/* enum: 10GBaseT. */
+#define MC_CMD_MEDIA_BASE_T 0x6
+/* enum: QSFP+. */
+#define MC_CMD_MEDIA_QSFP_PLUS 0x7
#define MC_CMD_GET_PHY_CFG_OUT_MMD_MASK_OFST 48
-#define MC_CMD_MMD_CLAUSE22 0x0 /* enum */
+/* enum: Native clause 22 */
+#define MC_CMD_MMD_CLAUSE22 0x0
#define MC_CMD_MMD_CLAUSE45_PMAPMD 0x1 /* enum */
#define MC_CMD_MMD_CLAUSE45_WIS 0x2 /* enum */
#define MC_CMD_MMD_CLAUSE45_PCS 0x3 /* enum */
@@ -3219,7 +4740,8 @@
#define MC_CMD_MMD_CLAUSE45_DTEXS 0x5 /* enum */
#define MC_CMD_MMD_CLAUSE45_TC 0x6 /* enum */
#define MC_CMD_MMD_CLAUSE45_AN 0x7 /* enum */
-#define MC_CMD_MMD_CLAUSE45_C22EXT 0x1d /* enum */
+/* enum: Clause22 proxied over clause45 by PHY. */
+#define MC_CMD_MMD_CLAUSE45_C22EXT 0x1d
#define MC_CMD_MMD_CLAUSE45_VEND1 0x1e /* enum */
#define MC_CMD_MMD_CLAUSE45_VEND2 0x1f /* enum */
#define MC_CMD_GET_PHY_CFG_OUT_REVISION_OFST 52
@@ -3227,44 +4749,74 @@
/***********************************/
-/* MC_CMD_START_BIST
- * Start a BIST test on the PHY.
+/* MC_CMD_START_BIST
+ * Start a BIST test on the PHY. Locks required: PHY_LOCK if doing a PHY BIST
+ * Return code: 0, EINVAL, EACCES (if PHY_LOCK is not held)
*/
-#define MC_CMD_START_BIST 0x25
+#define MC_CMD_START_BIST 0x25
+#undef MC_CMD_0x25_PRIVILEGE_CTG
+
+#define MC_CMD_0x25_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_START_BIST_IN msgrequest */
#define MC_CMD_START_BIST_IN_LEN 4
+/* Type of test. */
#define MC_CMD_START_BIST_IN_TYPE_OFST 0
-#define MC_CMD_PHY_BIST_CABLE_SHORT 0x1 /* enum */
-#define MC_CMD_PHY_BIST_CABLE_LONG 0x2 /* enum */
-#define MC_CMD_BPX_SERDES_BIST 0x3 /* enum */
-#define MC_CMD_MC_LOOPBACK_BIST 0x4 /* enum */
-#define MC_CMD_PHY_BIST 0x5 /* enum */
+/* enum: Run the PHY's short cable BIST. */
+#define MC_CMD_PHY_BIST_CABLE_SHORT 0x1
+/* enum: Run the PHY's long cable BIST. */
+#define MC_CMD_PHY_BIST_CABLE_LONG 0x2
+/* enum: Run BIST on the currently selected BPX Serdes (XAUI or XFI) . */
+#define MC_CMD_BPX_SERDES_BIST 0x3
+/* enum: Run the MC loopback tests. */
+#define MC_CMD_MC_LOOPBACK_BIST 0x4
+/* enum: Run the PHY's standard BIST. */
+#define MC_CMD_PHY_BIST 0x5
+/* enum: Run MC RAM test. */
+#define MC_CMD_MC_MEM_BIST 0x6
+/* enum: Run Port RAM test. */
+#define MC_CMD_PORT_MEM_BIST 0x7
+/* enum: Run register test. */
+#define MC_CMD_REG_BIST 0x8
/* MC_CMD_START_BIST_OUT msgresponse */
#define MC_CMD_START_BIST_OUT_LEN 0
/***********************************/
-/* MC_CMD_POLL_BIST
- * Poll for BIST completion.
+/* MC_CMD_POLL_BIST
+ * Poll for BIST completion. Returns a single status code, and optionally some
+ * PHY specific bist output. The driver should only consume the BIST output
+ * after validating OUTLEN and MC_CMD_GET_PHY_CFG.TYPE. If a driver can't
+ * successfully parse the BIST output, it should still respect the pass/Fail in
+ * OUT.RESULT. Locks required: PHY_LOCK if doing a PHY BIST. Return code: 0,
+ * EACCES (if PHY_LOCK is not held).
*/
-#define MC_CMD_POLL_BIST 0x26
+#define MC_CMD_POLL_BIST 0x26
+#undef MC_CMD_0x26_PRIVILEGE_CTG
+
+#define MC_CMD_0x26_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_POLL_BIST_IN msgrequest */
#define MC_CMD_POLL_BIST_IN_LEN 0
/* MC_CMD_POLL_BIST_OUT msgresponse */
#define MC_CMD_POLL_BIST_OUT_LEN 8
+/* result */
#define MC_CMD_POLL_BIST_OUT_RESULT_OFST 0
-#define MC_CMD_POLL_BIST_RUNNING 0x1 /* enum */
-#define MC_CMD_POLL_BIST_PASSED 0x2 /* enum */
-#define MC_CMD_POLL_BIST_FAILED 0x3 /* enum */
-#define MC_CMD_POLL_BIST_TIMEOUT 0x4 /* enum */
+/* enum: Running. */
+#define MC_CMD_POLL_BIST_RUNNING 0x1
+/* enum: Passed. */
+#define MC_CMD_POLL_BIST_PASSED 0x2
+/* enum: Failed. */
+#define MC_CMD_POLL_BIST_FAILED 0x3
+/* enum: Timed-out. */
+#define MC_CMD_POLL_BIST_TIMEOUT 0x4
#define MC_CMD_POLL_BIST_OUT_PRIVATE_OFST 4
/* MC_CMD_POLL_BIST_OUT_SFT9001 msgresponse */
#define MC_CMD_POLL_BIST_OUT_SFT9001_LEN 36
+/* result */
/* MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 */
/* Enum values, see field(s): */
/* MC_CMD_POLL_BIST_OUT/MC_CMD_POLL_BIST_OUT_RESULT */
@@ -3272,44 +4824,118 @@
#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_B_OFST 8
#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_C_OFST 12
#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_D_OFST 16
+/* Status of each channel A */
#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_A_OFST 20
-#define MC_CMD_POLL_BIST_SFT9001_PAIR_OK 0x1 /* enum */
-#define MC_CMD_POLL_BIST_SFT9001_PAIR_OPEN 0x2 /* enum */
-#define MC_CMD_POLL_BIST_SFT9001_INTRA_PAIR_SHORT 0x3 /* enum */
-#define MC_CMD_POLL_BIST_SFT9001_INTER_PAIR_SHORT 0x4 /* enum */
-#define MC_CMD_POLL_BIST_SFT9001_PAIR_BUSY 0x9 /* enum */
+/* enum: Ok. */
+#define MC_CMD_POLL_BIST_SFT9001_PAIR_OK 0x1
+/* enum: Open. */
+#define MC_CMD_POLL_BIST_SFT9001_PAIR_OPEN 0x2
+/* enum: Intra-pair short. */
+#define MC_CMD_POLL_BIST_SFT9001_INTRA_PAIR_SHORT 0x3
+/* enum: Inter-pair short. */
+#define MC_CMD_POLL_BIST_SFT9001_INTER_PAIR_SHORT 0x4
+/* enum: Busy. */
+#define MC_CMD_POLL_BIST_SFT9001_PAIR_BUSY 0x9
+/* Status of each channel B */
#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_B_OFST 24
/* Enum values, see field(s): */
/* CABLE_STATUS_A */
+/* Status of each channel C */
#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_C_OFST 28
/* Enum values, see field(s): */
/* CABLE_STATUS_A */
+/* Status of each channel D */
#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_D_OFST 32
/* Enum values, see field(s): */
/* CABLE_STATUS_A */
/* MC_CMD_POLL_BIST_OUT_MRSFP msgresponse */
#define MC_CMD_POLL_BIST_OUT_MRSFP_LEN 8
+/* result */
/* MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 */
/* Enum values, see field(s): */
/* MC_CMD_POLL_BIST_OUT/MC_CMD_POLL_BIST_OUT_RESULT */
#define MC_CMD_POLL_BIST_OUT_MRSFP_TEST_OFST 4
-#define MC_CMD_POLL_BIST_MRSFP_TEST_COMPLETE 0x0 /* enum */
-#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_WRITE 0x1 /* enum */
-#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_IO_EXP 0x2 /* enum */
-#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_MODULE 0x3 /* enum */
-#define MC_CMD_POLL_BIST_MRSFP_TEST_IO_EXP_I2C_CONFIGURE 0x4 /* enum */
-#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_I2C_NO_CROSSTALK 0x5 /* enum */
-#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_PRESENCE 0x6 /* enum */
-#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_I2C_ACCESS 0x7 /* enum */
-#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_SANE_VALUE 0x8 /* enum */
+/* enum: Complete. */
+#define MC_CMD_POLL_BIST_MRSFP_TEST_COMPLETE 0x0
+/* enum: Bus switch off I2C write. */
+#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_WRITE 0x1
+/* enum: Bus switch off I2C no access IO exp. */
+#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_IO_EXP 0x2
+/* enum: Bus switch off I2C no access module. */
+#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_MODULE 0x3
+/* enum: IO exp I2C configure. */
+#define MC_CMD_POLL_BIST_MRSFP_TEST_IO_EXP_I2C_CONFIGURE 0x4
+/* enum: Bus switch I2C no cross talk. */
+#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_I2C_NO_CROSSTALK 0x5
+/* enum: Module presence. */
+#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_PRESENCE 0x6
+/* enum: Module ID I2C access. */
+#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_I2C_ACCESS 0x7
+/* enum: Module ID sane value. */
+#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_SANE_VALUE 0x8
+
+/* MC_CMD_POLL_BIST_OUT_MEM msgresponse */
+#define MC_CMD_POLL_BIST_OUT_MEM_LEN 36
+/* result */
+/* MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 */
+/* Enum values, see field(s): */
+/* MC_CMD_POLL_BIST_OUT/MC_CMD_POLL_BIST_OUT_RESULT */
+#define MC_CMD_POLL_BIST_OUT_MEM_TEST_OFST 4
+/* enum: Test has completed. */
+#define MC_CMD_POLL_BIST_MEM_COMPLETE 0x0
+/* enum: RAM test - walk ones. */
+#define MC_CMD_POLL_BIST_MEM_MEM_WALK_ONES 0x1
+/* enum: RAM test - walk zeros. */
+#define MC_CMD_POLL_BIST_MEM_MEM_WALK_ZEROS 0x2
+/* enum: RAM test - walking inversions zeros/ones. */
+#define MC_CMD_POLL_BIST_MEM_MEM_INV_ZERO_ONE 0x3
+/* enum: RAM test - walking inversions checkerboard. */
+#define MC_CMD_POLL_BIST_MEM_MEM_INV_CHKBOARD 0x4
+/* enum: Register test - set / clear individual bits. */
+#define MC_CMD_POLL_BIST_MEM_REG 0x5
+/* enum: ECC error detected. */
+#define MC_CMD_POLL_BIST_MEM_ECC 0x6
+/* Failure address, only valid if result is POLL_BIST_FAILED */
+#define MC_CMD_POLL_BIST_OUT_MEM_ADDR_OFST 8
+/* Bus or address space to which the failure address corresponds */
+#define MC_CMD_POLL_BIST_OUT_MEM_BUS_OFST 12
+/* enum: MC MIPS bus. */
+#define MC_CMD_POLL_BIST_MEM_BUS_MC 0x0
+/* enum: CSR IREG bus. */
+#define MC_CMD_POLL_BIST_MEM_BUS_CSR 0x1
+/* enum: RX DPCPU bus. */
+#define MC_CMD_POLL_BIST_MEM_BUS_DPCPU_RX 0x2
+/* enum: TX0 DPCPU bus. */
+#define MC_CMD_POLL_BIST_MEM_BUS_DPCPU_TX0 0x3
+/* enum: TX1 DPCPU bus. */
+#define MC_CMD_POLL_BIST_MEM_BUS_DPCPU_TX1 0x4
+/* enum: RX DICPU bus. */
+#define MC_CMD_POLL_BIST_MEM_BUS_DICPU_RX 0x5
+/* enum: TX DICPU bus. */
+#define MC_CMD_POLL_BIST_MEM_BUS_DICPU_TX 0x6
+/* Pattern written to RAM / register */
+#define MC_CMD_POLL_BIST_OUT_MEM_EXPECT_OFST 16
+/* Actual value read from RAM / register */
+#define MC_CMD_POLL_BIST_OUT_MEM_ACTUAL_OFST 20
+/* ECC error mask */
+#define MC_CMD_POLL_BIST_OUT_MEM_ECC_OFST 24
+/* ECC parity error mask */
+#define MC_CMD_POLL_BIST_OUT_MEM_ECC_PARITY_OFST 28
+/* ECC fatal error mask */
+#define MC_CMD_POLL_BIST_OUT_MEM_ECC_FATAL_OFST 32
/***********************************/
-/* MC_CMD_FLUSH_RX_QUEUES
- * Flush receive queue(s).
+/* MC_CMD_FLUSH_RX_QUEUES
+ * Flush receive queue(s). If SRIOV is enabled (via MC_CMD_SRIOV), then RXQ
+ * flushes should be initiated via this MCDI operation, rather than via
+ * directly writing FLUSH_CMD.
+ *
+ * The flush is completed (either done/fail) asynchronously (after this command
+ * returns). The driver must still wait for flush done/failure events as usual.
*/
-#define MC_CMD_FLUSH_RX_QUEUES 0x27
+#define MC_CMD_FLUSH_RX_QUEUES 0x27
/* MC_CMD_FLUSH_RX_QUEUES_IN msgrequest */
#define MC_CMD_FLUSH_RX_QUEUES_IN_LENMIN 4
@@ -3325,82 +4951,156 @@
/***********************************/
-/* MC_CMD_GET_LOOPBACK_MODES
- * Get port's loopback modes.
+/* MC_CMD_GET_LOOPBACK_MODES
+ * Returns a bitmask of loopback modes available at each speed.
*/
-#define MC_CMD_GET_LOOPBACK_MODES 0x28
+#define MC_CMD_GET_LOOPBACK_MODES 0x28
+#undef MC_CMD_0x28_PRIVILEGE_CTG
+
+#define MC_CMD_0x28_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_GET_LOOPBACK_MODES_IN msgrequest */
#define MC_CMD_GET_LOOPBACK_MODES_IN_LEN 0
/* MC_CMD_GET_LOOPBACK_MODES_OUT msgresponse */
-#define MC_CMD_GET_LOOPBACK_MODES_OUT_LEN 32
+#define MC_CMD_GET_LOOPBACK_MODES_OUT_LEN 40
+/* Supported loopbacks. */
#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_OFST 0
#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_LEN 8
#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_LO_OFST 0
#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_HI_OFST 4
-#define MC_CMD_LOOPBACK_NONE 0x0 /* enum */
-#define MC_CMD_LOOPBACK_DATA 0x1 /* enum */
-#define MC_CMD_LOOPBACK_GMAC 0x2 /* enum */
-#define MC_CMD_LOOPBACK_XGMII 0x3 /* enum */
-#define MC_CMD_LOOPBACK_XGXS 0x4 /* enum */
-#define MC_CMD_LOOPBACK_XAUI 0x5 /* enum */
-#define MC_CMD_LOOPBACK_GMII 0x6 /* enum */
-#define MC_CMD_LOOPBACK_SGMII 0x7 /* enum */
-#define MC_CMD_LOOPBACK_XGBR 0x8 /* enum */
-#define MC_CMD_LOOPBACK_XFI 0x9 /* enum */
-#define MC_CMD_LOOPBACK_XAUI_FAR 0xa /* enum */
-#define MC_CMD_LOOPBACK_GMII_FAR 0xb /* enum */
-#define MC_CMD_LOOPBACK_SGMII_FAR 0xc /* enum */
-#define MC_CMD_LOOPBACK_XFI_FAR 0xd /* enum */
-#define MC_CMD_LOOPBACK_GPHY 0xe /* enum */
-#define MC_CMD_LOOPBACK_PHYXS 0xf /* enum */
-#define MC_CMD_LOOPBACK_PCS 0x10 /* enum */
-#define MC_CMD_LOOPBACK_PMAPMD 0x11 /* enum */
-#define MC_CMD_LOOPBACK_XPORT 0x12 /* enum */
-#define MC_CMD_LOOPBACK_XGMII_WS 0x13 /* enum */
-#define MC_CMD_LOOPBACK_XAUI_WS 0x14 /* enum */
-#define MC_CMD_LOOPBACK_XAUI_WS_FAR 0x15 /* enum */
-#define MC_CMD_LOOPBACK_XAUI_WS_NEAR 0x16 /* enum */
-#define MC_CMD_LOOPBACK_GMII_WS 0x17 /* enum */
-#define MC_CMD_LOOPBACK_XFI_WS 0x18 /* enum */
-#define MC_CMD_LOOPBACK_XFI_WS_FAR 0x19 /* enum */
-#define MC_CMD_LOOPBACK_PHYXS_WS 0x1a /* enum */
-#define MC_CMD_LOOPBACK_AOE_INT_NEAR 0x23 /* enum */
+/* enum: None. */
+#define MC_CMD_LOOPBACK_NONE 0x0
+/* enum: Data. */
+#define MC_CMD_LOOPBACK_DATA 0x1
+/* enum: GMAC. */
+#define MC_CMD_LOOPBACK_GMAC 0x2
+/* enum: XGMII. */
+#define MC_CMD_LOOPBACK_XGMII 0x3
+/* enum: XGXS. */
+#define MC_CMD_LOOPBACK_XGXS 0x4
+/* enum: XAUI. */
+#define MC_CMD_LOOPBACK_XAUI 0x5
+/* enum: GMII. */
+#define MC_CMD_LOOPBACK_GMII 0x6
+/* enum: SGMII. */
+#define MC_CMD_LOOPBACK_SGMII 0x7
+/* enum: XGBR. */
+#define MC_CMD_LOOPBACK_XGBR 0x8
+/* enum: XFI. */
+#define MC_CMD_LOOPBACK_XFI 0x9
+/* enum: XAUI Far. */
+#define MC_CMD_LOOPBACK_XAUI_FAR 0xa
+/* enum: GMII Far. */
+#define MC_CMD_LOOPBACK_GMII_FAR 0xb
+/* enum: SGMII Far. */
+#define MC_CMD_LOOPBACK_SGMII_FAR 0xc
+/* enum: XFI Far. */
+#define MC_CMD_LOOPBACK_XFI_FAR 0xd
+/* enum: GPhy. */
+#define MC_CMD_LOOPBACK_GPHY 0xe
+/* enum: PhyXS. */
+#define MC_CMD_LOOPBACK_PHYXS 0xf
+/* enum: PCS. */
+#define MC_CMD_LOOPBACK_PCS 0x10
+/* enum: PMA-PMD. */
+#define MC_CMD_LOOPBACK_PMAPMD 0x11
+/* enum: Cross-Port. */
+#define MC_CMD_LOOPBACK_XPORT 0x12
+/* enum: XGMII-Wireside. */
+#define MC_CMD_LOOPBACK_XGMII_WS 0x13
+/* enum: XAUI Wireside. */
+#define MC_CMD_LOOPBACK_XAUI_WS 0x14
+/* enum: XAUI Wireside Far. */
+#define MC_CMD_LOOPBACK_XAUI_WS_FAR 0x15
+/* enum: XAUI Wireside near. */
+#define MC_CMD_LOOPBACK_XAUI_WS_NEAR 0x16
+/* enum: GMII Wireside. */
+#define MC_CMD_LOOPBACK_GMII_WS 0x17
+/* enum: XFI Wireside. */
+#define MC_CMD_LOOPBACK_XFI_WS 0x18
+/* enum: XFI Wireside Far. */
+#define MC_CMD_LOOPBACK_XFI_WS_FAR 0x19
+/* enum: PhyXS Wireside. */
+#define MC_CMD_LOOPBACK_PHYXS_WS 0x1a
+/* enum: PMA lanes MAC-Serdes. */
+#define MC_CMD_LOOPBACK_PMA_INT 0x1b
+/* enum: KR Serdes Parallel (Encoder). */
+#define MC_CMD_LOOPBACK_SD_NEAR 0x1c
+/* enum: KR Serdes Serial. */
+#define MC_CMD_LOOPBACK_SD_FAR 0x1d
+/* enum: PMA lanes MAC-Serdes Wireside. */
+#define MC_CMD_LOOPBACK_PMA_INT_WS 0x1e
+/* enum: KR Serdes Parallel Wireside (Full PCS). */
+#define MC_CMD_LOOPBACK_SD_FEP2_WS 0x1f
+/* enum: KR Serdes Parallel Wireside (Sym Aligner to TX). */
+#define MC_CMD_LOOPBACK_SD_FEP1_5_WS 0x20
+/* enum: KR Serdes Parallel Wireside (Deserializer to Serializer). */
+#define MC_CMD_LOOPBACK_SD_FEP_WS 0x21
+/* enum: KR Serdes Serial Wireside. */
+#define MC_CMD_LOOPBACK_SD_FES_WS 0x22
+/* enum: Near side of AOE Siena side port */
+#define MC_CMD_LOOPBACK_AOE_INT_NEAR 0x23
+/* enum: Medford Wireside datapath loopback */
+#define MC_CMD_LOOPBACK_DATA_WS 0x24
+/* enum: Force link up without setting up any physical loopback (snapper use
+ * only)
+ */
+#define MC_CMD_LOOPBACK_FORCE_EXT_LINK 0x25
+/* Supported loopbacks. */
#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_OFST 8
#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_LEN 8
#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_LO_OFST 8
#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_HI_OFST 12
/* Enum values, see field(s): */
/* 100M */
+/* Supported loopbacks. */
#define MC_CMD_GET_LOOPBACK_MODES_OUT_10G_OFST 16
#define MC_CMD_GET_LOOPBACK_MODES_OUT_10G_LEN 8
#define MC_CMD_GET_LOOPBACK_MODES_OUT_10G_LO_OFST 16
#define MC_CMD_GET_LOOPBACK_MODES_OUT_10G_HI_OFST 20
/* Enum values, see field(s): */
/* 100M */
+/* Supported loopbacks. */
#define MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST 24
#define MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN 8
#define MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LO_OFST 24
#define MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_HI_OFST 28
/* Enum values, see field(s): */
/* 100M */
+/* Supported loopbacks. */
+#define MC_CMD_GET_LOOPBACK_MODES_OUT_40G_OFST 32
+#define MC_CMD_GET_LOOPBACK_MODES_OUT_40G_LEN 8
+#define MC_CMD_GET_LOOPBACK_MODES_OUT_40G_LO_OFST 32
+#define MC_CMD_GET_LOOPBACK_MODES_OUT_40G_HI_OFST 36
+/* Enum values, see field(s): */
+/* 100M */
/***********************************/
-/* MC_CMD_GET_LINK
- * Read the unified MAC/PHY link state.
+/* MC_CMD_GET_LINK
+ * Read the unified MAC/PHY link state. Locks required: None Return code: 0,
+ * ETIME.
*/
-#define MC_CMD_GET_LINK 0x29
+#define MC_CMD_GET_LINK 0x29
+#undef MC_CMD_0x29_PRIVILEGE_CTG
+
+#define MC_CMD_0x29_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_GET_LINK_IN msgrequest */
#define MC_CMD_GET_LINK_IN_LEN 0
/* MC_CMD_GET_LINK_OUT msgresponse */
#define MC_CMD_GET_LINK_OUT_LEN 28
+/* near-side advertised capabilities */
#define MC_CMD_GET_LINK_OUT_CAP_OFST 0
+/* link-partner advertised capabilities */
#define MC_CMD_GET_LINK_OUT_LP_CAP_OFST 4
+/* Autonegotiated speed in mbit/s. The link may still be down even if this
+ * reads non-zero.
+ */
#define MC_CMD_GET_LINK_OUT_LINK_SPEED_OFST 8
+/* Current loopback setting. */
#define MC_CMD_GET_LINK_OUT_LOOPBACK_MODE_OFST 12
/* Enum values, see field(s): */
/* MC_CMD_GET_LOOPBACK_MODES/MC_CMD_GET_LOOPBACK_MODES_OUT/100M */
@@ -3417,10 +5117,10 @@
#define MC_CMD_GET_LINK_OUT_LINK_FAULT_RX_WIDTH 1
#define MC_CMD_GET_LINK_OUT_LINK_FAULT_TX_LBN 7
#define MC_CMD_GET_LINK_OUT_LINK_FAULT_TX_WIDTH 1
+/* This returns the negotiated flow control value. */
#define MC_CMD_GET_LINK_OUT_FCNTL_OFST 20
-#define MC_CMD_FCNTL_OFF 0x0 /* enum */
-#define MC_CMD_FCNTL_RESPOND 0x1 /* enum */
-#define MC_CMD_FCNTL_BIDIR 0x2 /* enum */
+/* Enum values, see field(s): */
+/* MC_CMD_SET_MAC/MC_CMD_SET_MAC_IN/FCNTL */
#define MC_CMD_GET_LINK_OUT_MAC_FAULT_OFST 24
#define MC_CMD_MAC_FAULT_XGMII_LOCAL_LBN 0
#define MC_CMD_MAC_FAULT_XGMII_LOCAL_WIDTH 1
@@ -3433,14 +5133,20 @@
/***********************************/
-/* MC_CMD_SET_LINK
- * Write the unified MAC/PHY link configuration.
+/* MC_CMD_SET_LINK
+ * Write the unified MAC/PHY link configuration. Locks required: None. Return
+ * code: 0, EINVAL, ETIME
*/
-#define MC_CMD_SET_LINK 0x2a
+#define MC_CMD_SET_LINK 0x2a
+#undef MC_CMD_0x2a_PRIVILEGE_CTG
+
+#define MC_CMD_0x2a_PRIVILEGE_CTG SRIOV_CTG_LINK
/* MC_CMD_SET_LINK_IN msgrequest */
#define MC_CMD_SET_LINK_IN_LEN 16
+/* ??? */
#define MC_CMD_SET_LINK_IN_CAP_OFST 0
+/* Flags */
#define MC_CMD_SET_LINK_IN_FLAGS_OFST 4
#define MC_CMD_SET_LINK_IN_LOWPOWER_LBN 0
#define MC_CMD_SET_LINK_IN_LOWPOWER_WIDTH 1
@@ -3448,9 +5154,13 @@
#define MC_CMD_SET_LINK_IN_POWEROFF_WIDTH 1
#define MC_CMD_SET_LINK_IN_TXDIS_LBN 2
#define MC_CMD_SET_LINK_IN_TXDIS_WIDTH 1
+/* Loopback mode. */
#define MC_CMD_SET_LINK_IN_LOOPBACK_MODE_OFST 8
/* Enum values, see field(s): */
/* MC_CMD_GET_LOOPBACK_MODES/MC_CMD_GET_LOOPBACK_MODES_OUT/100M */
+/* A loopback speed of "0" is supported, and means (choose any available
+ * speed).
+ */
#define MC_CMD_SET_LINK_IN_LOOPBACK_SPEED_OFST 12
/* MC_CMD_SET_LINK_OUT msgresponse */
@@ -3458,13 +5168,17 @@
/***********************************/
-/* MC_CMD_SET_ID_LED
- * Set indentification LED state.
+/* MC_CMD_SET_ID_LED
+ * Set identification LED state. Locks required: None. Return code: 0, EINVAL
*/
-#define MC_CMD_SET_ID_LED 0x2b
+#define MC_CMD_SET_ID_LED 0x2b
+#undef MC_CMD_0x2b_PRIVILEGE_CTG
+
+#define MC_CMD_0x2b_PRIVILEGE_CTG SRIOV_CTG_LINK
/* MC_CMD_SET_ID_LED_IN msgrequest */
#define MC_CMD_SET_ID_LED_IN_LEN 4
+/* Set LED state. */
#define MC_CMD_SET_ID_LED_IN_STATE_OFST 0
#define MC_CMD_LED_OFF 0x0 /* enum */
#define MC_CMD_LED_ON 0x1 /* enum */
@@ -3475,13 +5189,19 @@
/***********************************/
-/* MC_CMD_SET_MAC
- * Set MAC configuration.
+/* MC_CMD_SET_MAC
+ * Set MAC configuration. Locks required: None. Return code: 0, EINVAL
*/
-#define MC_CMD_SET_MAC 0x2c
+#define MC_CMD_SET_MAC 0x2c
+#undef MC_CMD_0x2c_PRIVILEGE_CTG
+
+#define MC_CMD_0x2c_PRIVILEGE_CTG SRIOV_CTG_LINK
/* MC_CMD_SET_MAC_IN msgrequest */
-#define MC_CMD_SET_MAC_IN_LEN 24
+#define MC_CMD_SET_MAC_IN_LEN 28
+/* The MTU is the MTU programmed directly into the XMAC/GMAC (inclusive of
+ * EtherII, VLAN, bug16011 padding).
+ */
#define MC_CMD_SET_MAC_IN_MTU_OFST 0
#define MC_CMD_SET_MAC_IN_DRAIN_OFST 4
#define MC_CMD_SET_MAC_IN_ADDR_OFST 8
@@ -3494,23 +5214,43 @@
#define MC_CMD_SET_MAC_IN_REJECT_BRDCST_LBN 1
#define MC_CMD_SET_MAC_IN_REJECT_BRDCST_WIDTH 1
#define MC_CMD_SET_MAC_IN_FCNTL_OFST 20
-/* MC_CMD_FCNTL_OFF 0x0 */
-/* MC_CMD_FCNTL_RESPOND 0x1 */
-/* MC_CMD_FCNTL_BIDIR 0x2 */
-#define MC_CMD_FCNTL_AUTO 0x3 /* enum */
+/* enum: Flow control is off. */
+#define MC_CMD_FCNTL_OFF 0x0
+/* enum: Respond to flow control. */
+#define MC_CMD_FCNTL_RESPOND 0x1
+/* enum: Respond to and Issue flow control. */
+#define MC_CMD_FCNTL_BIDIR 0x2
+/* enum: Auto neg flow control. */
+#define MC_CMD_FCNTL_AUTO 0x3
+/* enum: Priority flow control (eftest builds only). */
+#define MC_CMD_FCNTL_QBB 0x4
+/* enum: Issue flow control. */
+#define MC_CMD_FCNTL_GENERATE 0x5
+#define MC_CMD_SET_MAC_IN_FLAGS_OFST 24
+#define MC_CMD_SET_MAC_IN_FLAG_INCLUDE_FCS_LBN 0
+#define MC_CMD_SET_MAC_IN_FLAG_INCLUDE_FCS_WIDTH 1
/* MC_CMD_SET_MAC_OUT msgresponse */
#define MC_CMD_SET_MAC_OUT_LEN 0
/***********************************/
-/* MC_CMD_PHY_STATS
- * Get generic PHY statistics.
+/* MC_CMD_PHY_STATS
+ * Get generic PHY statistics. This call returns the statistics for a generic
+ * PHY in a sparse array (indexed by the enumerate). Each value is represented
+ * by a 32bit number. If the DMA_ADDR is 0, then no DMA is performed, and the
+ * statistics may be read from the message response. If DMA_ADDR != 0, then the
+ * statistics are dmad to that (page-aligned location). Locks required: None.
+ * Returns: 0, ETIME
*/
-#define MC_CMD_PHY_STATS 0x2d
+#define MC_CMD_PHY_STATS 0x2d
+#undef MC_CMD_0x2d_PRIVILEGE_CTG
+
+#define MC_CMD_0x2d_PRIVILEGE_CTG SRIOV_CTG_LINK
/* MC_CMD_PHY_STATS_IN msgrequest */
#define MC_CMD_PHY_STATS_IN_LEN 8
+/* ??? */
#define MC_CMD_PHY_STATS_IN_DMA_ADDR_OFST 0
#define MC_CMD_PHY_STATS_IN_DMA_ADDR_LEN 8
#define MC_CMD_PHY_STATS_IN_DMA_ADDR_LO_OFST 0
@@ -3524,40 +5264,75 @@
#define MC_CMD_PHY_STATS_OUT_NO_DMA_STATISTICS_OFST 0
#define MC_CMD_PHY_STATS_OUT_NO_DMA_STATISTICS_LEN 4
#define MC_CMD_PHY_STATS_OUT_NO_DMA_STATISTICS_NUM MC_CMD_PHY_NSTATS
-#define MC_CMD_OUI 0x0 /* enum */
-#define MC_CMD_PMA_PMD_LINK_UP 0x1 /* enum */
-#define MC_CMD_PMA_PMD_RX_FAULT 0x2 /* enum */
-#define MC_CMD_PMA_PMD_TX_FAULT 0x3 /* enum */
-#define MC_CMD_PMA_PMD_SIGNAL 0x4 /* enum */
-#define MC_CMD_PMA_PMD_SNR_A 0x5 /* enum */
-#define MC_CMD_PMA_PMD_SNR_B 0x6 /* enum */
-#define MC_CMD_PMA_PMD_SNR_C 0x7 /* enum */
-#define MC_CMD_PMA_PMD_SNR_D 0x8 /* enum */
-#define MC_CMD_PCS_LINK_UP 0x9 /* enum */
-#define MC_CMD_PCS_RX_FAULT 0xa /* enum */
-#define MC_CMD_PCS_TX_FAULT 0xb /* enum */
-#define MC_CMD_PCS_BER 0xc /* enum */
-#define MC_CMD_PCS_BLOCK_ERRORS 0xd /* enum */
-#define MC_CMD_PHYXS_LINK_UP 0xe /* enum */
-#define MC_CMD_PHYXS_RX_FAULT 0xf /* enum */
-#define MC_CMD_PHYXS_TX_FAULT 0x10 /* enum */
-#define MC_CMD_PHYXS_ALIGN 0x11 /* enum */
-#define MC_CMD_PHYXS_SYNC 0x12 /* enum */
-#define MC_CMD_AN_LINK_UP 0x13 /* enum */
-#define MC_CMD_AN_COMPLETE 0x14 /* enum */
-#define MC_CMD_AN_10GBT_STATUS 0x15 /* enum */
-#define MC_CMD_CL22_LINK_UP 0x16 /* enum */
-#define MC_CMD_PHY_NSTATS 0x17 /* enum */
-
-
-/***********************************/
-/* MC_CMD_MAC_STATS
- * Get generic MAC statistics.
- */
-#define MC_CMD_MAC_STATS 0x2e
+/* enum: OUI. */
+#define MC_CMD_OUI 0x0
+/* enum: PMA-PMD Link Up. */
+#define MC_CMD_PMA_PMD_LINK_UP 0x1
+/* enum: PMA-PMD RX Fault. */
+#define MC_CMD_PMA_PMD_RX_FAULT 0x2
+/* enum: PMA-PMD TX Fault. */
+#define MC_CMD_PMA_PMD_TX_FAULT 0x3
+/* enum: PMA-PMD Signal */
+#define MC_CMD_PMA_PMD_SIGNAL 0x4
+/* enum: PMA-PMD SNR A. */
+#define MC_CMD_PMA_PMD_SNR_A 0x5
+/* enum: PMA-PMD SNR B. */
+#define MC_CMD_PMA_PMD_SNR_B 0x6
+/* enum: PMA-PMD SNR C. */
+#define MC_CMD_PMA_PMD_SNR_C 0x7
+/* enum: PMA-PMD SNR D. */
+#define MC_CMD_PMA_PMD_SNR_D 0x8
+/* enum: PCS Link Up. */
+#define MC_CMD_PCS_LINK_UP 0x9
+/* enum: PCS RX Fault. */
+#define MC_CMD_PCS_RX_FAULT 0xa
+/* enum: PCS TX Fault. */
+#define MC_CMD_PCS_TX_FAULT 0xb
+/* enum: PCS BER. */
+#define MC_CMD_PCS_BER 0xc
+/* enum: PCS Block Errors. */
+#define MC_CMD_PCS_BLOCK_ERRORS 0xd
+/* enum: PhyXS Link Up. */
+#define MC_CMD_PHYXS_LINK_UP 0xe
+/* enum: PhyXS RX Fault. */
+#define MC_CMD_PHYXS_RX_FAULT 0xf
+/* enum: PhyXS TX Fault. */
+#define MC_CMD_PHYXS_TX_FAULT 0x10
+/* enum: PhyXS Align. */
+#define MC_CMD_PHYXS_ALIGN 0x11
+/* enum: PhyXS Sync. */
+#define MC_CMD_PHYXS_SYNC 0x12
+/* enum: AN link-up. */
+#define MC_CMD_AN_LINK_UP 0x13
+/* enum: AN Complete. */
+#define MC_CMD_AN_COMPLETE 0x14
+/* enum: AN 10GBaseT Status. */
+#define MC_CMD_AN_10GBT_STATUS 0x15
+/* enum: Clause 22 Link-Up. */
+#define MC_CMD_CL22_LINK_UP 0x16
+/* enum: (Last entry) */
+#define MC_CMD_PHY_NSTATS 0x17
+
+
+/***********************************/
+/* MC_CMD_MAC_STATS
+ * Get generic MAC statistics. This call returns unified statistics maintained
+ * by the MC as it switches between the GMAC and XMAC. The MC will write out
+ * all supported stats. The driver should zero initialise the buffer to
+ * guarantee consistent results. If the DMA_ADDR is 0, then no DMA is
+ * performed, and the statistics may be read from the message response. If
+ * DMA_ADDR != 0, then the statistics are dmad to that (page-aligned location).
+ * Locks required: None. The PERIODIC_CLEAR option is not used and now has no
+ * effect. Returns: 0, ETIME
+ */
+#define MC_CMD_MAC_STATS 0x2e
+#undef MC_CMD_0x2e_PRIVILEGE_CTG
+
+#define MC_CMD_0x2e_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_MAC_STATS_IN msgrequest */
-#define MC_CMD_MAC_STATS_IN_LEN 16
+#define MC_CMD_MAC_STATS_IN_LEN 20
+/* ??? */
#define MC_CMD_MAC_STATS_IN_DMA_ADDR_OFST 0
#define MC_CMD_MAC_STATS_IN_DMA_ADDR_LEN 8
#define MC_CMD_MAC_STATS_IN_DMA_ADDR_LO_OFST 0
@@ -3578,6 +5353,8 @@
#define MC_CMD_MAC_STATS_IN_PERIOD_MS_LBN 16
#define MC_CMD_MAC_STATS_IN_PERIOD_MS_WIDTH 16
#define MC_CMD_MAC_STATS_IN_DMA_LEN_OFST 12
+/* port id so vadapter stats can be provided */
+#define MC_CMD_MAC_STATS_IN_PORT_ID_OFST 16
/* MC_CMD_MAC_STATS_OUT_DMA msgresponse */
#define MC_CMD_MAC_STATS_OUT_DMA_LEN 0
@@ -3590,6 +5367,7 @@
#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_HI_OFST 4
#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_NUM MC_CMD_MAC_NSTATS
#define MC_CMD_MAC_GENERATION_START 0x0 /* enum */
+#define MC_CMD_MAC_DMABUF_START 0x1 /* enum */
#define MC_CMD_MAC_TX_PKTS 0x1 /* enum */
#define MC_CMD_MAC_TX_PAUSE_PKTS 0x2 /* enum */
#define MC_CMD_MAC_TX_CONTROL_PKTS 0x3 /* enum */
@@ -3649,17 +5427,87 @@
#define MC_CMD_MAC_RX_LANES01_DISP_ERR 0x39 /* enum */
#define MC_CMD_MAC_RX_LANES23_DISP_ERR 0x3a /* enum */
#define MC_CMD_MAC_RX_MATCH_FAULT 0x3b /* enum */
-#define MC_CMD_GMAC_DMABUF_START 0x40 /* enum */
-#define MC_CMD_GMAC_DMABUF_END 0x5f /* enum */
+/* enum: PM trunc_bb_overflow counter. Valid for EF10 with PM_AND_RXDP_COUNTERS
+ * capability only.
+ */
+#define MC_CMD_MAC_PM_TRUNC_BB_OVERFLOW 0x3c
+/* enum: PM discard_bb_overflow counter. Valid for EF10 with
+ * PM_AND_RXDP_COUNTERS capability only.
+ */
+#define MC_CMD_MAC_PM_DISCARD_BB_OVERFLOW 0x3d
+/* enum: PM trunc_vfifo_full counter. Valid for EF10 with PM_AND_RXDP_COUNTERS
+ * capability only.
+ */
+#define MC_CMD_MAC_PM_TRUNC_VFIFO_FULL 0x3e
+/* enum: PM discard_vfifo_full counter. Valid for EF10 with
+ * PM_AND_RXDP_COUNTERS capability only.
+ */
+#define MC_CMD_MAC_PM_DISCARD_VFIFO_FULL 0x3f
+/* enum: PM trunc_qbb counter. Valid for EF10 with PM_AND_RXDP_COUNTERS
+ * capability only.
+ */
+#define MC_CMD_MAC_PM_TRUNC_QBB 0x40
+/* enum: PM discard_qbb counter. Valid for EF10 with PM_AND_RXDP_COUNTERS
+ * capability only.
+ */
+#define MC_CMD_MAC_PM_DISCARD_QBB 0x41
+/* enum: PM discard_mapping counter. Valid for EF10 with PM_AND_RXDP_COUNTERS
+ * capability only.
+ */
+#define MC_CMD_MAC_PM_DISCARD_MAPPING 0x42
+/* enum: RXDP counter: Number of packets dropped due to the queue being
+ * disabled. Valid for EF10 with PM_AND_RXDP_COUNTERS capability only.
+ */
+#define MC_CMD_MAC_RXDP_Q_DISABLED_PKTS 0x43
+/* enum: RXDP counter: Number of packets dropped by the DICPU. Valid for EF10
+ * with PM_AND_RXDP_COUNTERS capability only.
+ */
+#define MC_CMD_MAC_RXDP_DI_DROPPED_PKTS 0x45
+/* enum: RXDP counter: Number of non-host packets. Valid for EF10 with
+ * PM_AND_RXDP_COUNTERS capability only.
+ */
+#define MC_CMD_MAC_RXDP_STREAMING_PKTS 0x46
+/* enum: RXDP counter: Number of times an hlb descriptor fetch was performed.
+ * Valid for EF10 with PM_AND_RXDP_COUNTERS capability only.
+ */
+#define MC_CMD_MAC_RXDP_HLB_FETCH_CONDITIONS 0x47
+/* enum: RXDP counter: Number of times the DPCPU waited for an existing
+ * descriptor fetch. Valid for EF10 with PM_AND_RXDP_COUNTERS capability only.
+ */
+#define MC_CMD_MAC_RXDP_HLB_WAIT_CONDITIONS 0x48
+#define MC_CMD_MAC_VADAPTER_RX_DMABUF_START 0x4c /* enum */
+#define MC_CMD_MAC_VADAPTER_RX_UNICAST_PACKETS 0x4c /* enum */
+#define MC_CMD_MAC_VADAPTER_RX_UNICAST_BYTES 0x4d /* enum */
+#define MC_CMD_MAC_VADAPTER_RX_MULTICAST_PACKETS 0x4e /* enum */
+#define MC_CMD_MAC_VADAPTER_RX_MULTICAST_BYTES 0x4f /* enum */
+#define MC_CMD_MAC_VADAPTER_RX_BROADCAST_PACKETS 0x50 /* enum */
+#define MC_CMD_MAC_VADAPTER_RX_BROADCAST_BYTES 0x51 /* enum */
+#define MC_CMD_MAC_VADAPTER_RX_BAD_PACKETS 0x52 /* enum */
+#define MC_CMD_MAC_VADAPTER_RX_BAD_BYTES 0x53 /* enum */
+#define MC_CMD_MAC_VADAPTER_RX_OVERFLOW 0x54 /* enum */
+#define MC_CMD_MAC_VADAPTER_TX_DMABUF_START 0x57 /* enum */
+#define MC_CMD_MAC_VADAPTER_TX_UNICAST_PACKETS 0x57 /* enum */
+#define MC_CMD_MAC_VADAPTER_TX_UNICAST_BYTES 0x58 /* enum */
+#define MC_CMD_MAC_VADAPTER_TX_MULTICAST_PACKETS 0x59 /* enum */
+#define MC_CMD_MAC_VADAPTER_TX_MULTICAST_BYTES 0x5a /* enum */
+#define MC_CMD_MAC_VADAPTER_TX_BROADCAST_PACKETS 0x5b /* enum */
+#define MC_CMD_MAC_VADAPTER_TX_BROADCAST_BYTES 0x5c /* enum */
+#define MC_CMD_MAC_VADAPTER_TX_BAD_PACKETS 0x5d /* enum */
+#define MC_CMD_MAC_VADAPTER_TX_BAD_BYTES 0x5e /* enum */
+#define MC_CMD_MAC_VADAPTER_TX_OVERFLOW 0x5f /* enum */
+/* enum: Start of GMAC stats buffer space, for Siena only. */
+#define MC_CMD_GMAC_DMABUF_START 0x40
+/* enum: End of GMAC stats buffer space, for Siena only. */
+#define MC_CMD_GMAC_DMABUF_END 0x5f
#define MC_CMD_MAC_GENERATION_END 0x60 /* enum */
#define MC_CMD_MAC_NSTATS 0x61 /* enum */
/***********************************/
-/* MC_CMD_SRIOV
+/* MC_CMD_SRIOV
* to be documented
*/
-#define MC_CMD_SRIOV 0x30
+#define MC_CMD_SRIOV 0x30
/* MC_CMD_SRIOV_IN msgrequest */
#define MC_CMD_SRIOV_IN_LEN 12
@@ -3674,6 +5522,7 @@
/* MC_CMD_MEMCPY_RECORD_TYPEDEF structuredef */
#define MC_CMD_MEMCPY_RECORD_TYPEDEF_LEN 32
+/* this is only used for the first record */
#define MC_CMD_MEMCPY_RECORD_TYPEDEF_NUM_RECORDS_OFST 0
#define MC_CMD_MEMCPY_RECORD_TYPEDEF_NUM_RECORDS_LBN 0
#define MC_CMD_MEMCPY_RECORD_TYPEDEF_NUM_RECORDS_WIDTH 32
@@ -3702,15 +5551,32 @@
/***********************************/
-/* MC_CMD_MEMCPY
- * Perform memory copy operation.
+/* MC_CMD_MEMCPY
+ * DMA write data into (Rid,Addr), either by dma reading (Rid,Addr), or by data
+ * embedded directly in the command.
+ *
+ * A common pattern is for a client to use generation counts to signal a dma
+ * update of a datastructure. To facilitate this, this MCDI operation can
+ * contain multiple requests which are executed in strict order. Requests take
+ * the form of duplicating the entire MCDI request continuously (including the
+ * requests record, which is ignored in all but the first structure)
+ *
+ * The source data can either come from a DMA from the host, or it can be
+ * embedded within the request directly, thereby eliminating a DMA read. To
+ * indicate this, the client sets FROM_RID=%RID_INLINE, ADDR_HI=0, and
+ * ADDR_LO=offset, and inserts the data at %offset from the start of the
+ * payload. It's the callers responsibility to ensure that the embedded data
+ * doesn't overlap the records.
+ *
+ * Returns: 0, EINVAL (invalid RID)
*/
-#define MC_CMD_MEMCPY 0x31
+#define MC_CMD_MEMCPY 0x31
/* MC_CMD_MEMCPY_IN msgrequest */
#define MC_CMD_MEMCPY_IN_LENMIN 32
#define MC_CMD_MEMCPY_IN_LENMAX 224
#define MC_CMD_MEMCPY_IN_LEN(num) (0+32*(num))
+/* see MC_CMD_MEMCPY_RECORD_TYPEDEF */
#define MC_CMD_MEMCPY_IN_RECORD_OFST 0
#define MC_CMD_MEMCPY_IN_RECORD_LEN 32
#define MC_CMD_MEMCPY_IN_RECORD_MINNUM 1
@@ -3721,24 +5587,35 @@
/***********************************/
-/* MC_CMD_WOL_FILTER_SET
+/* MC_CMD_WOL_FILTER_SET
* Set a WoL filter.
*/
-#define MC_CMD_WOL_FILTER_SET 0x32
+#define MC_CMD_WOL_FILTER_SET 0x32
+#undef MC_CMD_0x32_PRIVILEGE_CTG
+
+#define MC_CMD_0x32_PRIVILEGE_CTG SRIOV_CTG_LINK
/* MC_CMD_WOL_FILTER_SET_IN msgrequest */
#define MC_CMD_WOL_FILTER_SET_IN_LEN 192
#define MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0
#define MC_CMD_FILTER_MODE_SIMPLE 0x0 /* enum */
#define MC_CMD_FILTER_MODE_STRUCTURED 0xffffffff /* enum */
+/* A type value of 1 is unused. */
#define MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4
-#define MC_CMD_WOL_TYPE_MAGIC 0x0 /* enum */
-#define MC_CMD_WOL_TYPE_WIN_MAGIC 0x2 /* enum */
-#define MC_CMD_WOL_TYPE_IPV4_SYN 0x3 /* enum */
-#define MC_CMD_WOL_TYPE_IPV6_SYN 0x4 /* enum */
-#define MC_CMD_WOL_TYPE_BITMAP 0x5 /* enum */
-#define MC_CMD_WOL_TYPE_LINK 0x6 /* enum */
-#define MC_CMD_WOL_TYPE_MAX 0x7 /* enum */
+/* enum: Magic */
+#define MC_CMD_WOL_TYPE_MAGIC 0x0
+/* enum: MS Windows Magic */
+#define MC_CMD_WOL_TYPE_WIN_MAGIC 0x2
+/* enum: IPv4 Syn */
+#define MC_CMD_WOL_TYPE_IPV4_SYN 0x3
+/* enum: IPv6 Syn */
+#define MC_CMD_WOL_TYPE_IPV6_SYN 0x4
+/* enum: Bitmap */
+#define MC_CMD_WOL_TYPE_BITMAP 0x5
+/* enum: Link */
+#define MC_CMD_WOL_TYPE_LINK 0x6
+/* enum: (Above this for future use) */
+#define MC_CMD_WOL_TYPE_MAX 0x7
#define MC_CMD_WOL_FILTER_SET_IN_DATA_OFST 8
#define MC_CMD_WOL_FILTER_SET_IN_DATA_LEN 4
#define MC_CMD_WOL_FILTER_SET_IN_DATA_NUM 46
@@ -3807,10 +5684,13 @@
/***********************************/
-/* MC_CMD_WOL_FILTER_REMOVE
- * Remove a WoL filter.
+/* MC_CMD_WOL_FILTER_REMOVE
+ * Remove a WoL filter. Locks required: None. Returns: 0, EINVAL, ENOSYS
*/
-#define MC_CMD_WOL_FILTER_REMOVE 0x33
+#define MC_CMD_WOL_FILTER_REMOVE 0x33
+#undef MC_CMD_0x33_PRIVILEGE_CTG
+
+#define MC_CMD_0x33_PRIVILEGE_CTG SRIOV_CTG_LINK
/* MC_CMD_WOL_FILTER_REMOVE_IN msgrequest */
#define MC_CMD_WOL_FILTER_REMOVE_IN_LEN 4
@@ -3821,10 +5701,14 @@
/***********************************/
-/* MC_CMD_WOL_FILTER_RESET
- * Reset (i.e. remove all) WoL filters.
+/* MC_CMD_WOL_FILTER_RESET
+ * Reset (i.e. remove all) WoL filters. Locks required: None. Returns: 0,
+ * ENOSYS
*/
-#define MC_CMD_WOL_FILTER_RESET 0x34
+#define MC_CMD_WOL_FILTER_RESET 0x34
+#undef MC_CMD_0x34_PRIVILEGE_CTG
+
+#define MC_CMD_0x34_PRIVILEGE_CTG SRIOV_CTG_LINK
/* MC_CMD_WOL_FILTER_RESET_IN msgrequest */
#define MC_CMD_WOL_FILTER_RESET_IN_LEN 4
@@ -3837,10 +5721,10 @@
/***********************************/
-/* MC_CMD_SET_MCAST_HASH
- * Set the MCASH hash value.
+/* MC_CMD_SET_MCAST_HASH
+ * Set the MCAST hash value without otherwise reconfiguring the MAC
*/
-#define MC_CMD_SET_MCAST_HASH 0x35
+#define MC_CMD_SET_MCAST_HASH 0x35
/* MC_CMD_SET_MCAST_HASH_IN msgrequest */
#define MC_CMD_SET_MCAST_HASH_IN_LEN 32
@@ -3854,45 +5738,75 @@
/***********************************/
-/* MC_CMD_NVRAM_TYPES
- * Get virtual NVRAM partitions information.
+/* MC_CMD_NVRAM_TYPES
+ * Return bitfield indicating available types of virtual NVRAM partitions.
+ * Locks required: none. Returns: 0
*/
-#define MC_CMD_NVRAM_TYPES 0x36
+#define MC_CMD_NVRAM_TYPES 0x36
+#undef MC_CMD_0x36_PRIVILEGE_CTG
+
+#define MC_CMD_0x36_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_NVRAM_TYPES_IN msgrequest */
#define MC_CMD_NVRAM_TYPES_IN_LEN 0
/* MC_CMD_NVRAM_TYPES_OUT msgresponse */
#define MC_CMD_NVRAM_TYPES_OUT_LEN 4
+/* Bit mask of supported types. */
#define MC_CMD_NVRAM_TYPES_OUT_TYPES_OFST 0
-#define MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO 0x0 /* enum */
-#define MC_CMD_NVRAM_TYPE_MC_FW 0x1 /* enum */
-#define MC_CMD_NVRAM_TYPE_MC_FW_BACKUP 0x2 /* enum */
-#define MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT0 0x3 /* enum */
-#define MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT1 0x4 /* enum */
-#define MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0 0x5 /* enum */
-#define MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1 0x6 /* enum */
-#define MC_CMD_NVRAM_TYPE_EXP_ROM 0x7 /* enum */
-#define MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT0 0x8 /* enum */
-#define MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT1 0x9 /* enum */
-#define MC_CMD_NVRAM_TYPE_PHY_PORT0 0xa /* enum */
-#define MC_CMD_NVRAM_TYPE_PHY_PORT1 0xb /* enum */
-#define MC_CMD_NVRAM_TYPE_LOG 0xc /* enum */
-#define MC_CMD_NVRAM_TYPE_FPGA 0xd /* enum */
-#define MC_CMD_NVRAM_TYPE_FPGA_BACKUP 0xe /* enum */
-#define MC_CMD_NVRAM_TYPE_FC_FW 0xf /* enum */
-#define MC_CMD_NVRAM_TYPE_FC_FW_BACKUP 0x10 /* enum */
-#define MC_CMD_NVRAM_TYPE_CPLD 0x11 /* enum */
-#define MC_CMD_NVRAM_TYPE_LICENSE 0x12 /* enum */
-#define MC_CMD_NVRAM_TYPE_FC_LOG 0x13 /* enum */
-#define MC_CMD_NVRAM_TYPE_FC_EXTRA 0x14 /* enum */
-
-
-/***********************************/
-/* MC_CMD_NVRAM_INFO
- * Read info about a virtual NVRAM partition.
- */
-#define MC_CMD_NVRAM_INFO 0x37
+/* enum: Disabled callisto. */
+#define MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO 0x0
+/* enum: MC firmware. */
+#define MC_CMD_NVRAM_TYPE_MC_FW 0x1
+/* enum: MC backup firmware. */
+#define MC_CMD_NVRAM_TYPE_MC_FW_BACKUP 0x2
+/* enum: Static configuration Port0. */
+#define MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT0 0x3
+/* enum: Static configuration Port1. */
+#define MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT1 0x4
+/* enum: Dynamic configuration Port0. */
+#define MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0 0x5
+/* enum: Dynamic configuration Port1. */
+#define MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1 0x6
+/* enum: Expansion Rom. */
+#define MC_CMD_NVRAM_TYPE_EXP_ROM 0x7
+/* enum: Expansion Rom Configuration Port0. */
+#define MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT0 0x8
+/* enum: Expansion Rom Configuration Port1. */
+#define MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT1 0x9
+/* enum: Phy Configuration Port0. */
+#define MC_CMD_NVRAM_TYPE_PHY_PORT0 0xa
+/* enum: Phy Configuration Port1. */
+#define MC_CMD_NVRAM_TYPE_PHY_PORT1 0xb
+/* enum: Log. */
+#define MC_CMD_NVRAM_TYPE_LOG 0xc
+/* enum: FPGA image. */
+#define MC_CMD_NVRAM_TYPE_FPGA 0xd
+/* enum: FPGA backup image */
+#define MC_CMD_NVRAM_TYPE_FPGA_BACKUP 0xe
+/* enum: FC firmware. */
+#define MC_CMD_NVRAM_TYPE_FC_FW 0xf
+/* enum: FC backup firmware. */
+#define MC_CMD_NVRAM_TYPE_FC_FW_BACKUP 0x10
+/* enum: CPLD image. */
+#define MC_CMD_NVRAM_TYPE_CPLD 0x11
+/* enum: Licensing information. */
+#define MC_CMD_NVRAM_TYPE_LICENSE 0x12
+/* enum: FC Log. */
+#define MC_CMD_NVRAM_TYPE_FC_LOG 0x13
+/* enum: Additional flash on FPGA. */
+#define MC_CMD_NVRAM_TYPE_FC_EXTRA 0x14
+
+
+/***********************************/
+/* MC_CMD_NVRAM_INFO
+ * Read info about a virtual NVRAM partition. Locks required: none. Returns: 0,
+ * EINVAL (bad type).
+ */
+#define MC_CMD_NVRAM_INFO 0x37
+#undef MC_CMD_0x37_PRIVILEGE_CTG
+
+#define MC_CMD_0x37_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_NVRAM_INFO_IN msgrequest */
#define MC_CMD_NVRAM_INFO_IN_LEN 4
@@ -3910,15 +5824,24 @@
#define MC_CMD_NVRAM_INFO_OUT_FLAGS_OFST 12
#define MC_CMD_NVRAM_INFO_OUT_PROTECTED_LBN 0
#define MC_CMD_NVRAM_INFO_OUT_PROTECTED_WIDTH 1
+#define MC_CMD_NVRAM_INFO_OUT_TLV_LBN 1
+#define MC_CMD_NVRAM_INFO_OUT_TLV_WIDTH 1
+#define MC_CMD_NVRAM_INFO_OUT_A_B_LBN 7
+#define MC_CMD_NVRAM_INFO_OUT_A_B_WIDTH 1
#define MC_CMD_NVRAM_INFO_OUT_PHYSDEV_OFST 16
#define MC_CMD_NVRAM_INFO_OUT_PHYSADDR_OFST 20
/***********************************/
-/* MC_CMD_NVRAM_UPDATE_START
- * Start a group of update operations on a virtual NVRAM partition.
+/* MC_CMD_NVRAM_UPDATE_START
+ * Start a group of update operations on a virtual NVRAM partition. Locks
+ * required: PHY_LOCK if type==*PHY*. Returns: 0, EINVAL (bad type), EACCES (if
+ * PHY_LOCK required and not held).
*/
-#define MC_CMD_NVRAM_UPDATE_START 0x38
+#define MC_CMD_NVRAM_UPDATE_START 0x38
+#undef MC_CMD_0x38_PRIVILEGE_CTG
+
+#define MC_CMD_0x38_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_NVRAM_UPDATE_START_IN msgrequest */
#define MC_CMD_NVRAM_UPDATE_START_IN_LEN 4
@@ -3931,10 +5854,15 @@
/***********************************/
-/* MC_CMD_NVRAM_READ
- * Read data from a virtual NVRAM partition.
+/* MC_CMD_NVRAM_READ
+ * Read data from a virtual NVRAM partition. Locks required: PHY_LOCK if
+ * type==*PHY*. Returns: 0, EINVAL (bad type/offset/length), EACCES (if
+ * PHY_LOCK required and not held)
*/
-#define MC_CMD_NVRAM_READ 0x39
+#define MC_CMD_NVRAM_READ 0x39
+#undef MC_CMD_0x39_PRIVILEGE_CTG
+
+#define MC_CMD_0x39_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_NVRAM_READ_IN msgrequest */
#define MC_CMD_NVRAM_READ_IN_LEN 12
@@ -3942,6 +5870,7 @@
/* Enum values, see field(s): */
/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */
#define MC_CMD_NVRAM_READ_IN_OFFSET_OFST 4
+/* amount to read in bytes */
#define MC_CMD_NVRAM_READ_IN_LENGTH_OFST 8
/* MC_CMD_NVRAM_READ_OUT msgresponse */
@@ -3955,10 +5884,15 @@
/***********************************/
-/* MC_CMD_NVRAM_WRITE
- * Write data to a virtual NVRAM partition.
+/* MC_CMD_NVRAM_WRITE
+ * Write data to a virtual NVRAM partition. Locks required: PHY_LOCK if
+ * type==*PHY*. Returns: 0, EINVAL (bad type/offset/length), EACCES (if
+ * PHY_LOCK required and not held)
*/
-#define MC_CMD_NVRAM_WRITE 0x3a
+#define MC_CMD_NVRAM_WRITE 0x3a
+#undef MC_CMD_0x3a_PRIVILEGE_CTG
+
+#define MC_CMD_0x3a_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_NVRAM_WRITE_IN msgrequest */
#define MC_CMD_NVRAM_WRITE_IN_LENMIN 13
@@ -3979,10 +5913,15 @@
/***********************************/
-/* MC_CMD_NVRAM_ERASE
- * Erase sector(s) from a virtual NVRAM partition.
+/* MC_CMD_NVRAM_ERASE
+ * Erase sector(s) from a virtual NVRAM partition. Locks required: PHY_LOCK if
+ * type==*PHY*. Returns: 0, EINVAL (bad type/offset/length), EACCES (if
+ * PHY_LOCK required and not held)
*/
-#define MC_CMD_NVRAM_ERASE 0x3b
+#define MC_CMD_NVRAM_ERASE 0x3b
+#undef MC_CMD_0x3b_PRIVILEGE_CTG
+
+#define MC_CMD_0x3b_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_NVRAM_ERASE_IN msgrequest */
#define MC_CMD_NVRAM_ERASE_IN_LEN 12
@@ -3997,10 +5936,15 @@
/***********************************/
-/* MC_CMD_NVRAM_UPDATE_FINISH
- * Finish a group of update operations on a virtual NVRAM partition.
+/* MC_CMD_NVRAM_UPDATE_FINISH
+ * Finish a group of update operations on a virtual NVRAM partition. Locks
+ * required: PHY_LOCK if type==*PHY*. Returns: 0, EINVAL (bad
+ * type/offset/length), EACCES (if PHY_LOCK required and not held)
*/
-#define MC_CMD_NVRAM_UPDATE_FINISH 0x3c
+#define MC_CMD_NVRAM_UPDATE_FINISH 0x3c
+#undef MC_CMD_0x3c_PRIVILEGE_CTG
+
+#define MC_CMD_0x3c_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_NVRAM_UPDATE_FINISH_IN msgrequest */
#define MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN 8
@@ -4014,10 +5958,27 @@
/***********************************/
-/* MC_CMD_REBOOT
+/* MC_CMD_REBOOT
* Reboot the MC.
+ *
+ * The AFTER_ASSERTION flag is intended to be used when the driver notices an
+ * assertion failure (at which point it is expected to perform a complete tear
+ * down and reinitialise), to allow both ports to reset the MC once in an
+ * atomic fashion.
+ *
+ * Production mc firmwares are generally compiled with REBOOT_ON_ASSERT=1,
+ * which means that they will automatically reboot out of the assertion
+ * handler, so this is in practise an optional operation. It is still
+ * recommended that drivers execute this to support custom firmwares with
+ * REBOOT_ON_ASSERT=0.
+ *
+ * Locks required: NONE Returns: Nothing. You get back a response with ERR=1,
+ * DATALEN=0
*/
-#define MC_CMD_REBOOT 0x3d
+#define MC_CMD_REBOOT 0x3d
+#undef MC_CMD_0x3d_PRIVILEGE_CTG
+
+#define MC_CMD_0x3d_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_REBOOT_IN msgrequest */
#define MC_CMD_REBOOT_IN_LEN 4
@@ -4029,10 +5990,15 @@
/***********************************/
-/* MC_CMD_SCHEDINFO
- * Request scheduler info.
+/* MC_CMD_SCHEDINFO
+ * Request scheduler info. Locks required: NONE. Returns: An array of
+ * (timeslice,maximum overrun), one for each thread, in ascending order of
+ * thread address.
*/
-#define MC_CMD_SCHEDINFO 0x3e
+#define MC_CMD_SCHEDINFO 0x3e
+#undef MC_CMD_0x3e_PRIVILEGE_CTG
+
+#define MC_CMD_0x3e_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_SCHEDINFO_IN msgrequest */
#define MC_CMD_SCHEDINFO_IN_LEN 0
@@ -4048,15 +6014,28 @@
/***********************************/
-/* MC_CMD_REBOOT_MODE
+/* MC_CMD_REBOOT_MODE
+ * Set the mode for the next MC reboot. Locks required: NONE. Sets the reboot
+ * mode to the specified value. Returns the old mode.
*/
-#define MC_CMD_REBOOT_MODE 0x3f
+#define MC_CMD_REBOOT_MODE 0x3f
+#undef MC_CMD_0x3f_PRIVILEGE_CTG
+
+#define MC_CMD_0x3f_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_REBOOT_MODE_IN msgrequest */
#define MC_CMD_REBOOT_MODE_IN_LEN 4
#define MC_CMD_REBOOT_MODE_IN_VALUE_OFST 0
-#define MC_CMD_REBOOT_MODE_NORMAL 0x0 /* enum */
-#define MC_CMD_REBOOT_MODE_SNAPPER 0x3 /* enum */
+/* enum: Normal. */
+#define MC_CMD_REBOOT_MODE_NORMAL 0x0
+/* enum: Power-on Reset. */
+#define MC_CMD_REBOOT_MODE_POR 0x2
+/* enum: Snapper. */
+#define MC_CMD_REBOOT_MODE_SNAPPER 0x3
+/* enum: snapper fake POR */
+#define MC_CMD_REBOOT_MODE_SNAPPER_POR 0x4
+#define MC_CMD_REBOOT_MODE_IN_FAKE_LBN 7
+#define MC_CMD_REBOOT_MODE_IN_FAKE_WIDTH 1
/* MC_CMD_REBOOT_MODE_OUT msgresponse */
#define MC_CMD_REBOOT_MODE_OUT_LEN 4
@@ -4064,54 +6043,238 @@
/***********************************/
-/* MC_CMD_SENSOR_INFO
+/* MC_CMD_SENSOR_INFO
* Returns information about every available sensor.
+ *
+ * Each sensor has a single (16bit) value, and a corresponding state. The
+ * mapping between value and state is nominally determined by the MC, but may
+ * be implemented using up to 2 ranges per sensor.
+ *
+ * This call returns a mask (32bit) of the sensors that are supported by this
+ * platform, then an array of sensor information structures, in order of sensor
+ * type (but without gaps for unimplemented sensors). Each structure defines
+ * the ranges for the corresponding sensor. An unused range is indicated by
+ * equal limit values. If one range is used, a value outside that range results
+ * in STATE_FATAL. If two ranges are used, a value outside the second range
+ * results in STATE_FATAL while a value outside the first and inside the second
+ * range results in STATE_WARNING.
+ *
+ * Sensor masks and sensor information arrays are organised into pages. For
+ * backward compatibility, older host software can only use sensors in page 0.
+ * Bit 32 in the sensor mask was previously unused, and is no reserved for use
+ * as the next page flag.
+ *
+ * If the request does not contain a PAGE value then firmware will only return
+ * page 0 of sensor information, with bit 31 in the sensor mask cleared.
+ *
+ * If the request contains a PAGE value then firmware responds with the sensor
+ * mask and sensor information array for that page of sensors. In this case bit
+ * 31 in the mask is set if another page exists.
+ *
+ * Locks required: None Returns: 0
*/
-#define MC_CMD_SENSOR_INFO 0x41
+#define MC_CMD_SENSOR_INFO 0x41
+#undef MC_CMD_0x41_PRIVILEGE_CTG
+
+#define MC_CMD_0x41_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_SENSOR_INFO_IN msgrequest */
#define MC_CMD_SENSOR_INFO_IN_LEN 0
+/* MC_CMD_SENSOR_INFO_EXT_IN msgrequest */
+#define MC_CMD_SENSOR_INFO_EXT_IN_LEN 4
+/* Which page of sensors to report.
+ *
+ * Page 0 contains sensors 0 to 30 (sensor 31 is the next page bit).
+ *
+ * Page 1 contains sensors 32 to 62 (sensor 63 is the next page bit). etc.
+ */
+#define MC_CMD_SENSOR_INFO_EXT_IN_PAGE_OFST 0
+
/* MC_CMD_SENSOR_INFO_OUT msgresponse */
-#define MC_CMD_SENSOR_INFO_OUT_LENMIN 12
+#define MC_CMD_SENSOR_INFO_OUT_LENMIN 4
#define MC_CMD_SENSOR_INFO_OUT_LENMAX 252
#define MC_CMD_SENSOR_INFO_OUT_LEN(num) (4+8*(num))
#define MC_CMD_SENSOR_INFO_OUT_MASK_OFST 0
-#define MC_CMD_SENSOR_CONTROLLER_TEMP 0x0 /* enum */
-#define MC_CMD_SENSOR_PHY_COMMON_TEMP 0x1 /* enum */
-#define MC_CMD_SENSOR_CONTROLLER_COOLING 0x2 /* enum */
-#define MC_CMD_SENSOR_PHY0_TEMP 0x3 /* enum */
-#define MC_CMD_SENSOR_PHY0_COOLING 0x4 /* enum */
-#define MC_CMD_SENSOR_PHY1_TEMP 0x5 /* enum */
-#define MC_CMD_SENSOR_PHY1_COOLING 0x6 /* enum */
-#define MC_CMD_SENSOR_IN_1V0 0x7 /* enum */
-#define MC_CMD_SENSOR_IN_1V2 0x8 /* enum */
-#define MC_CMD_SENSOR_IN_1V8 0x9 /* enum */
-#define MC_CMD_SENSOR_IN_2V5 0xa /* enum */
-#define MC_CMD_SENSOR_IN_3V3 0xb /* enum */
-#define MC_CMD_SENSOR_IN_12V0 0xc /* enum */
-#define MC_CMD_SENSOR_IN_1V2A 0xd /* enum */
-#define MC_CMD_SENSOR_IN_VREF 0xe /* enum */
-#define MC_CMD_SENSOR_OUT_VAOE 0xf /* enum */
-#define MC_CMD_SENSOR_AOE_TEMP 0x10 /* enum */
-#define MC_CMD_SENSOR_PSU_AOE_TEMP 0x11 /* enum */
-#define MC_CMD_SENSOR_PSU_TEMP 0x12 /* enum */
-#define MC_CMD_SENSOR_FAN_0 0x13 /* enum */
-#define MC_CMD_SENSOR_FAN_1 0x14 /* enum */
-#define MC_CMD_SENSOR_FAN_2 0x15 /* enum */
-#define MC_CMD_SENSOR_FAN_3 0x16 /* enum */
-#define MC_CMD_SENSOR_FAN_4 0x17 /* enum */
-#define MC_CMD_SENSOR_IN_VAOE 0x18 /* enum */
-#define MC_CMD_SENSOR_OUT_IAOE 0x19 /* enum */
-#define MC_CMD_SENSOR_IN_IAOE 0x1a /* enum */
-#define MC_CMD_SENSOR_NIC_POWER 0x1b /* enum */
+/* enum: Controller temperature: degC */
+#define MC_CMD_SENSOR_CONTROLLER_TEMP 0x0
+/* enum: Phy common temperature: degC */
+#define MC_CMD_SENSOR_PHY_COMMON_TEMP 0x1
+/* enum: Controller cooling: bool */
+#define MC_CMD_SENSOR_CONTROLLER_COOLING 0x2
+/* enum: Phy 0 temperature: degC */
+#define MC_CMD_SENSOR_PHY0_TEMP 0x3
+/* enum: Phy 0 cooling: bool */
+#define MC_CMD_SENSOR_PHY0_COOLING 0x4
+/* enum: Phy 1 temperature: degC */
+#define MC_CMD_SENSOR_PHY1_TEMP 0x5
+/* enum: Phy 1 cooling: bool */
+#define MC_CMD_SENSOR_PHY1_COOLING 0x6
+/* enum: 1.0v power: mV */
+#define MC_CMD_SENSOR_IN_1V0 0x7
+/* enum: 1.2v power: mV */
+#define MC_CMD_SENSOR_IN_1V2 0x8
+/* enum: 1.8v power: mV */
+#define MC_CMD_SENSOR_IN_1V8 0x9
+/* enum: 2.5v power: mV */
+#define MC_CMD_SENSOR_IN_2V5 0xa
+/* enum: 3.3v power: mV */
+#define MC_CMD_SENSOR_IN_3V3 0xb
+/* enum: 12v power: mV */
+#define MC_CMD_SENSOR_IN_12V0 0xc
+/* enum: 1.2v analogue power: mV */
+#define MC_CMD_SENSOR_IN_1V2A 0xd
+/* enum: reference voltage: mV */
+#define MC_CMD_SENSOR_IN_VREF 0xe
+/* enum: AOE FPGA power: mV */
+#define MC_CMD_SENSOR_OUT_VAOE 0xf
+/* enum: AOE FPGA temperature: degC */
+#define MC_CMD_SENSOR_AOE_TEMP 0x10
+/* enum: AOE FPGA PSU temperature: degC */
+#define MC_CMD_SENSOR_PSU_AOE_TEMP 0x11
+/* enum: AOE PSU temperature: degC */
+#define MC_CMD_SENSOR_PSU_TEMP 0x12
+/* enum: Fan 0 speed: RPM */
+#define MC_CMD_SENSOR_FAN_0 0x13
+/* enum: Fan 1 speed: RPM */
+#define MC_CMD_SENSOR_FAN_1 0x14
+/* enum: Fan 2 speed: RPM */
+#define MC_CMD_SENSOR_FAN_2 0x15
+/* enum: Fan 3 speed: RPM */
+#define MC_CMD_SENSOR_FAN_3 0x16
+/* enum: Fan 4 speed: RPM */
+#define MC_CMD_SENSOR_FAN_4 0x17
+/* enum: AOE FPGA input power: mV */
+#define MC_CMD_SENSOR_IN_VAOE 0x18
+/* enum: AOE FPGA current: mA */
+#define MC_CMD_SENSOR_OUT_IAOE 0x19
+/* enum: AOE FPGA input current: mA */
+#define MC_CMD_SENSOR_IN_IAOE 0x1a
+/* enum: NIC power consumption: W */
+#define MC_CMD_SENSOR_NIC_POWER 0x1b
+/* enum: 0.9v power voltage: mV */
+#define MC_CMD_SENSOR_IN_0V9 0x1c
+/* enum: 0.9v power current: mA */
+#define MC_CMD_SENSOR_IN_I0V9 0x1d
+/* enum: 1.2v power current: mA */
+#define MC_CMD_SENSOR_IN_I1V2 0x1e
+/* enum: Not a sensor: reserved for the next page flag */
+#define MC_CMD_SENSOR_PAGE0_NEXT 0x1f
+/* enum: 0.9v power voltage (at ADC): mV */
+#define MC_CMD_SENSOR_IN_0V9_ADC 0x20
+/* enum: Controller temperature 2: degC */
+#define MC_CMD_SENSOR_CONTROLLER_2_TEMP 0x21
+/* enum: Voltage regulator internal temperature: degC */
+#define MC_CMD_SENSOR_VREG_INTERNAL_TEMP 0x22
+/* enum: 0.9V voltage regulator temperature: degC */
+#define MC_CMD_SENSOR_VREG_0V9_TEMP 0x23
+/* enum: 1.2V voltage regulator temperature: degC */
+#define MC_CMD_SENSOR_VREG_1V2_TEMP 0x24
+/* enum: controller internal temperature sensor voltage (internal ADC): mV */
+#define MC_CMD_SENSOR_CONTROLLER_VPTAT 0x25
+/* enum: controller internal temperature (internal ADC): degC */
+#define MC_CMD_SENSOR_CONTROLLER_INTERNAL_TEMP 0x26
+/* enum: controller internal temperature sensor voltage (external ADC): mV */
+#define MC_CMD_SENSOR_CONTROLLER_VPTAT_EXTADC 0x27
+/* enum: controller internal temperature (external ADC): degC */
+#define MC_CMD_SENSOR_CONTROLLER_INTERNAL_TEMP_EXTADC 0x28
+/* enum: ambient temperature: degC */
+#define MC_CMD_SENSOR_AMBIENT_TEMP 0x29
+/* enum: air flow: bool */
+#define MC_CMD_SENSOR_AIRFLOW 0x2a
+/* enum: voltage between VSS08D and VSS08D at CSR: mV */
+#define MC_CMD_SENSOR_VDD08D_VSS08D_CSR 0x2b
+/* enum: voltage between VSS08D and VSS08D at CSR (external ADC): mV */
+#define MC_CMD_SENSOR_VDD08D_VSS08D_CSR_EXTADC 0x2c
+/* enum: Hotpoint temperature: degC */
+#define MC_CMD_SENSOR_HOTPOINT_TEMP 0x2d
+/* enum: Port 0 PHY power switch over-current: bool */
+#define MC_CMD_SENSOR_PHY_POWER_PORT0 0x2e
+/* enum: Port 1 PHY power switch over-current: bool */
+#define MC_CMD_SENSOR_PHY_POWER_PORT1 0x2f
+/* enum: Mop-up microcontroller reference voltage (millivolts) */
+#define MC_CMD_SENSOR_MUM_VCC 0x30
+/* enum: 0.9v power phase A voltage: mV */
+#define MC_CMD_SENSOR_IN_0V9_A 0x31
+/* enum: 0.9v power phase A current: mA */
+#define MC_CMD_SENSOR_IN_I0V9_A 0x32
+/* enum: 0.9V voltage regulator phase A temperature: degC */
+#define MC_CMD_SENSOR_VREG_0V9_A_TEMP 0x33
+/* enum: 0.9v power phase B voltage: mV */
+#define MC_CMD_SENSOR_IN_0V9_B 0x34
+/* enum: 0.9v power phase B current: mA */
+#define MC_CMD_SENSOR_IN_I0V9_B 0x35
+/* enum: 0.9V voltage regulator phase B temperature: degC */
+#define MC_CMD_SENSOR_VREG_0V9_B_TEMP 0x36
+/* enum: CCOM AVREG 1v2 supply (interval ADC): mV */
+#define MC_CMD_SENSOR_CCOM_AVREG_1V2_SUPPLY 0x37
+/* enum: CCOM AVREG 1v2 supply (external ADC): mV */
+#define MC_CMD_SENSOR_CCOM_AVREG_1V2_SUPPLY_EXTADC 0x38
+/* enum: CCOM AVREG 1v8 supply (interval ADC): mV */
+#define MC_CMD_SENSOR_CCOM_AVREG_1V8_SUPPLY 0x39
+/* enum: CCOM AVREG 1v8 supply (external ADC): mV */
+#define MC_CMD_SENSOR_CCOM_AVREG_1V8_SUPPLY_EXTADC 0x3a
+/* enum: Not a sensor: reserved for the next page flag */
+#define MC_CMD_SENSOR_PAGE1_NEXT 0x3f
+/* enum: controller internal temperature sensor voltage on master core
+ * (internal ADC): mV
+ */
+#define MC_CMD_SENSOR_CONTROLLER_MASTER_VPTAT 0x40
+/* enum: controller internal temperature on master core (internal ADC): degC */
+#define MC_CMD_SENSOR_CONTROLLER_MASTER_INTERNAL_TEMP 0x41
+/* enum: controller internal temperature sensor voltage on master core
+ * (external ADC): mV
+ */
+#define MC_CMD_SENSOR_CONTROLLER_MASTER_VPTAT_EXTADC 0x42
+/* enum: controller internal temperature on master core (external ADC): degC */
+#define MC_CMD_SENSOR_CONTROLLER_MASTER_INTERNAL_TEMP_EXTADC 0x43
+/* enum: controller internal temperature on slave core sensor voltage (internal
+ * ADC): mV
+ */
+#define MC_CMD_SENSOR_CONTROLLER_SLAVE_VPTAT 0x44
+/* enum: controller internal temperature on slave core (internal ADC): degC */
+#define MC_CMD_SENSOR_CONTROLLER_SLAVE_INTERNAL_TEMP 0x45
+/* enum: controller internal temperature on slave core sensor voltage (external
+ * ADC): mV
+ */
+#define MC_CMD_SENSOR_CONTROLLER_SLAVE_VPTAT_EXTADC 0x46
+/* enum: controller internal temperature on slave core (external ADC): degC */
+#define MC_CMD_SENSOR_CONTROLLER_SLAVE_INTERNAL_TEMP_EXTADC 0x47
+/* enum: Voltage supplied to the SODIMMs from their power supply: mV */
+#define MC_CMD_SENSOR_SODIMM_VOUT 0x49
+/* enum: Temperature of SODIMM 0 (if installed): degC */
+#define MC_CMD_SENSOR_SODIMM_0_TEMP 0x4a
+/* enum: Temperature of SODIMM 1 (if installed): degC */
+#define MC_CMD_SENSOR_SODIMM_1_TEMP 0x4b
+/* enum: Voltage supplied to the QSFP #0 from their power supply: mV */
+#define MC_CMD_SENSOR_PHY0_VCC 0x4c
+/* enum: Voltage supplied to the QSFP #1 from their power supply: mV */
+#define MC_CMD_SENSOR_PHY1_VCC 0x4d
+/* MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF */
#define MC_CMD_SENSOR_ENTRY_OFST 4
#define MC_CMD_SENSOR_ENTRY_LEN 8
#define MC_CMD_SENSOR_ENTRY_LO_OFST 4
#define MC_CMD_SENSOR_ENTRY_HI_OFST 8
-#define MC_CMD_SENSOR_ENTRY_MINNUM 1
+#define MC_CMD_SENSOR_ENTRY_MINNUM 0
#define MC_CMD_SENSOR_ENTRY_MAXNUM 31
+/* MC_CMD_SENSOR_INFO_EXT_OUT msgresponse */
+#define MC_CMD_SENSOR_INFO_EXT_OUT_LENMIN 4
+#define MC_CMD_SENSOR_INFO_EXT_OUT_LENMAX 252
+#define MC_CMD_SENSOR_INFO_EXT_OUT_LEN(num) (4+8*(num))
+#define MC_CMD_SENSOR_INFO_EXT_OUT_MASK_OFST 0
+/* Enum values, see field(s): */
+/* MC_CMD_SENSOR_INFO_OUT */
+#define MC_CMD_SENSOR_INFO_EXT_OUT_NEXT_PAGE_LBN 31
+#define MC_CMD_SENSOR_INFO_EXT_OUT_NEXT_PAGE_WIDTH 1
+/* MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF */
+/* MC_CMD_SENSOR_ENTRY_OFST 4 */
+/* MC_CMD_SENSOR_ENTRY_LEN 8 */
+/* MC_CMD_SENSOR_ENTRY_LO_OFST 4 */
+/* MC_CMD_SENSOR_ENTRY_HI_OFST 8 */
+/* MC_CMD_SENSOR_ENTRY_MINNUM 0 */
+/* MC_CMD_SENSOR_ENTRY_MAXNUM 31 */
+
/* MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF structuredef */
#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_LEN 8
#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN1_OFST 0
@@ -4133,42 +6296,91 @@
/***********************************/
-/* MC_CMD_READ_SENSORS
- * Returns the current reading from each sensor.
+/* MC_CMD_READ_SENSORS
+ * Returns the current reading from each sensor. DMAs an array of sensor
+ * readings, in order of sensor type (but without gaps for unimplemented
+ * sensors), into host memory. Each array element is a
+ * MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF dword.
+ *
+ * If the request does not contain the LENGTH field then only sensors 0 to 30
+ * are reported, to avoid DMA buffer overflow in older host software. If the
+ * sensor reading require more space than the LENGTH allows, then return
+ * EINVAL.
+ *
+ * The MC will send a SENSOREVT event every time any sensor changes state. The
+ * driver is responsible for ensuring that it doesn't miss any events. The
+ * board will function normally if all sensors are in STATE_OK or
+ * STATE_WARNING. Otherwise the board should not be expected to function.
*/
-#define MC_CMD_READ_SENSORS 0x42
+#define MC_CMD_READ_SENSORS 0x42
+#undef MC_CMD_0x42_PRIVILEGE_CTG
+
+#define MC_CMD_0x42_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_READ_SENSORS_IN msgrequest */
#define MC_CMD_READ_SENSORS_IN_LEN 8
+/* DMA address of host buffer for sensor readings (must be 4Kbyte aligned). */
#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_OFST 0
#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_LEN 8
#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_LO_OFST 0
#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_HI_OFST 4
+/* MC_CMD_READ_SENSORS_EXT_IN msgrequest */
+#define MC_CMD_READ_SENSORS_EXT_IN_LEN 12
+/* DMA address of host buffer for sensor readings */
+#define MC_CMD_READ_SENSORS_EXT_IN_DMA_ADDR_OFST 0
+#define MC_CMD_READ_SENSORS_EXT_IN_DMA_ADDR_LEN 8
+#define MC_CMD_READ_SENSORS_EXT_IN_DMA_ADDR_LO_OFST 0
+#define MC_CMD_READ_SENSORS_EXT_IN_DMA_ADDR_HI_OFST 4
+/* Size in bytes of host buffer. */
+#define MC_CMD_READ_SENSORS_EXT_IN_LENGTH_OFST 8
+
/* MC_CMD_READ_SENSORS_OUT msgresponse */
#define MC_CMD_READ_SENSORS_OUT_LEN 0
+/* MC_CMD_READ_SENSORS_EXT_OUT msgresponse */
+#define MC_CMD_READ_SENSORS_EXT_OUT_LEN 0
+
/* MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF structuredef */
-#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_LEN 3
+#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_LEN 4
#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_OFST 0
#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_LEN 2
#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_LBN 0
#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_WIDTH 16
#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_OFST 2
#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_LEN 1
-#define MC_CMD_SENSOR_STATE_OK 0x0 /* enum */
-#define MC_CMD_SENSOR_STATE_WARNING 0x1 /* enum */
-#define MC_CMD_SENSOR_STATE_FATAL 0x2 /* enum */
-#define MC_CMD_SENSOR_STATE_BROKEN 0x3 /* enum */
+/* enum: Ok. */
+#define MC_CMD_SENSOR_STATE_OK 0x0
+/* enum: Breached warning threshold. */
+#define MC_CMD_SENSOR_STATE_WARNING 0x1
+/* enum: Breached fatal threshold. */
+#define MC_CMD_SENSOR_STATE_FATAL 0x2
+/* enum: Fault with sensor. */
+#define MC_CMD_SENSOR_STATE_BROKEN 0x3
+/* enum: Sensor is working but does not currently have a reading. */
+#define MC_CMD_SENSOR_STATE_NO_READING 0x4
+/* enum: Sensor initialisation failed. */
+#define MC_CMD_SENSOR_STATE_INIT_FAILED 0x5
#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_LBN 16
#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_WIDTH 8
+#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_TYPE_OFST 3
+#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_TYPE_LEN 1
+/* Enum values, see field(s): */
+/* MC_CMD_SENSOR_INFO/MC_CMD_SENSOR_INFO_OUT/MASK */
+#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_TYPE_LBN 24
+#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_TYPE_WIDTH 8
/***********************************/
-/* MC_CMD_GET_PHY_STATE
- * Report current state of PHY.
+/* MC_CMD_GET_PHY_STATE
+ * Report current state of PHY. A 'zombie' PHY is a PHY that has failed to boot
+ * (e.g. due to missing or corrupted firmware). Locks required: None. Return
+ * code: 0
*/
-#define MC_CMD_GET_PHY_STATE 0x43
+#define MC_CMD_GET_PHY_STATE 0x43
+#undef MC_CMD_0x43_PRIVILEGE_CTG
+
+#define MC_CMD_0x43_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_GET_PHY_STATE_IN msgrequest */
#define MC_CMD_GET_PHY_STATE_IN_LEN 0
@@ -4176,15 +6388,18 @@
/* MC_CMD_GET_PHY_STATE_OUT msgresponse */
#define MC_CMD_GET_PHY_STATE_OUT_LEN 4
#define MC_CMD_GET_PHY_STATE_OUT_STATE_OFST 0
-#define MC_CMD_PHY_STATE_OK 0x1 /* enum */
-#define MC_CMD_PHY_STATE_ZOMBIE 0x2 /* enum */
+/* enum: Ok. */
+#define MC_CMD_PHY_STATE_OK 0x1
+/* enum: Faulty. */
+#define MC_CMD_PHY_STATE_ZOMBIE 0x2
/***********************************/
-/* MC_CMD_SETUP_8021QBB
- * 802.1Qbb control.
+/* MC_CMD_SETUP_8021QBB
+ * 802.1Qbb control. 8 Tx queues that map to priorities 0 - 7. Use all 1s to
+ * disable 802.Qbb for a given priority.
*/
-#define MC_CMD_SETUP_8021QBB 0x44
+#define MC_CMD_SETUP_8021QBB 0x44
/* MC_CMD_SETUP_8021QBB_IN msgrequest */
#define MC_CMD_SETUP_8021QBB_IN_LEN 32
@@ -4196,10 +6411,13 @@
/***********************************/
-/* MC_CMD_WOL_FILTER_GET
- * Retrieve ID of any WoL filters.
+/* MC_CMD_WOL_FILTER_GET
+ * Retrieve ID of any WoL filters. Locks required: None. Returns: 0, ENOSYS
*/
-#define MC_CMD_WOL_FILTER_GET 0x45
+#define MC_CMD_WOL_FILTER_GET 0x45
+#undef MC_CMD_0x45_PRIVILEGE_CTG
+
+#define MC_CMD_0x45_PRIVILEGE_CTG SRIOV_CTG_LINK
/* MC_CMD_WOL_FILTER_GET_IN msgrequest */
#define MC_CMD_WOL_FILTER_GET_IN_LEN 0
@@ -4210,10 +6428,14 @@
/***********************************/
-/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD
- * Add a protocol offload to NIC for lights-out state.
+/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD
+ * Add a protocol offload to NIC for lights-out state. Locks required: None.
+ * Returns: 0, ENOSYS
*/
-#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD 0x46
+#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD 0x46
+#undef MC_CMD_0x46_PRIVILEGE_CTG
+
+#define MC_CMD_0x46_PRIVILEGE_CTG SRIOV_CTG_LINK
/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN msgrequest */
#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LENMIN 8
@@ -4250,10 +6472,14 @@
/***********************************/
-/* MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD
- * Remove a protocol offload from NIC for lights-out state.
+/* MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD
+ * Remove a protocol offload from NIC for lights-out state. Locks required:
+ * None. Returns: 0, ENOSYS
*/
-#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD 0x47
+#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD 0x47
+#undef MC_CMD_0x47_PRIVILEGE_CTG
+
+#define MC_CMD_0x47_PRIVILEGE_CTG SRIOV_CTG_LINK
/* MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN msgrequest */
#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN 8
@@ -4265,10 +6491,10 @@
/***********************************/
-/* MC_CMD_MAC_RESET_RESTORE
- * Restore MAC after block reset.
+/* MC_CMD_MAC_RESET_RESTORE
+ * Restore MAC after block reset. Locks required: None. Returns: 0.
*/
-#define MC_CMD_MAC_RESET_RESTORE 0x48
+#define MC_CMD_MAC_RESET_RESTORE 0x48
/* MC_CMD_MAC_RESET_RESTORE_IN msgrequest */
#define MC_CMD_MAC_RESET_RESTORE_IN_LEN 0
@@ -4278,9 +6504,15 @@
/***********************************/
-/* MC_CMD_TESTASSERT
+/* MC_CMD_TESTASSERT
+ * Deliberately trigger an assert-detonation in the firmware for testing
+ * purposes (i.e. to allow tests that the driver copes gracefully). Locks
+ * required: None Returns: 0
*/
-#define MC_CMD_TESTASSERT 0x49
+#define MC_CMD_TESTASSERT 0x49
+#undef MC_CMD_0x49_PRIVILEGE_CTG
+
+#define MC_CMD_0x49_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_TESTASSERT_IN msgrequest */
#define MC_CMD_TESTASSERT_IN_LEN 0
@@ -4290,26 +6522,74 @@
/***********************************/
-/* MC_CMD_WORKAROUND
- * Enable/Disable a given workaround.
+/* MC_CMD_WORKAROUND
+ * Enable/Disable a given workaround. The mcfw will return EINVAL if it doesn't
+ * understand the given workaround number - which should not be treated as a
+ * hard error by client code. This op does not imply any semantics about each
+ * workaround, that's between the driver and the mcfw on a per-workaround
+ * basis. Locks required: None. Returns: 0, EINVAL .
*/
-#define MC_CMD_WORKAROUND 0x4a
+#define MC_CMD_WORKAROUND 0x4a
+#undef MC_CMD_0x4a_PRIVILEGE_CTG
+
+#define MC_CMD_0x4a_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_WORKAROUND_IN msgrequest */
#define MC_CMD_WORKAROUND_IN_LEN 8
+/* The enums here must correspond with those in MC_CMD_GET_WORKAROUND. */
#define MC_CMD_WORKAROUND_IN_TYPE_OFST 0
-#define MC_CMD_WORKAROUND_BUG17230 0x1 /* enum */
+/* enum: Bug 17230 work around. */
+#define MC_CMD_WORKAROUND_BUG17230 0x1
+/* enum: Bug 35388 work around (unsafe EVQ writes). */
+#define MC_CMD_WORKAROUND_BUG35388 0x2
+/* enum: Bug35017 workaround (A64 tables must be identity map) */
+#define MC_CMD_WORKAROUND_BUG35017 0x3
+/* enum: Bug 41750 present (MC_CMD_TRIGGER_INTERRUPT won't work) */
+#define MC_CMD_WORKAROUND_BUG41750 0x4
+/* enum: Bug 42008 present (Interrupts can overtake associated events). Caution
+ * - before adding code that queries this workaround, remember that there's
+ * released Monza firmware that doesn't understand MC_CMD_WORKAROUND_BUG42008,
+ * and will hence (incorrectly) report that the bug doesn't exist.
+ */
+#define MC_CMD_WORKAROUND_BUG42008 0x5
+/* enum: Bug 26807 features present in firmware (multicast filter chaining)
+ * This feature cannot be turned on/off while there are any filters already
+ * present. The behaviour in such case depends on the acting client's privilege
+ * level. If the client has the admin privilege, then all functions that have
+ * filters installed will be FLRed and the FLR_DONE flag will be set. Otherwise
+ * the command will fail with MC_CMD_ERR_FILTERS_PRESENT.
+ */
+#define MC_CMD_WORKAROUND_BUG26807 0x6
+/* 0 = disable the workaround indicated by TYPE; any non-zero value = enable
+ * the workaround
+ */
#define MC_CMD_WORKAROUND_IN_ENABLED_OFST 4
/* MC_CMD_WORKAROUND_OUT msgresponse */
#define MC_CMD_WORKAROUND_OUT_LEN 0
+/* MC_CMD_WORKAROUND_EXT_OUT msgresponse: This response format will be used
+ * when (TYPE == MC_CMD_WORKAROUND_BUG26807)
+ */
+#define MC_CMD_WORKAROUND_EXT_OUT_LEN 4
+#define MC_CMD_WORKAROUND_EXT_OUT_FLAGS_OFST 0
+#define MC_CMD_WORKAROUND_EXT_OUT_FLR_DONE_LBN 0
+#define MC_CMD_WORKAROUND_EXT_OUT_FLR_DONE_WIDTH 1
+
/***********************************/
-/* MC_CMD_GET_PHY_MEDIA_INFO
- * Read media-specific data from PHY.
+/* MC_CMD_GET_PHY_MEDIA_INFO
+ * Read media-specific data from PHY (e.g. SFP/SFP+ module ID information for
+ * SFP+ PHYs). The 'media type' can be found via GET_PHY_CFG
+ * (GET_PHY_CFG_OUT_MEDIA_TYPE); the valid 'page number' input values, and the
+ * output data, are interpreted on a per-type basis. For SFP+: PAGE=0 or 1
+ * returns a 128-byte block read from module I2C address 0xA0 offset 0 or 0x80.
+ * Anything else: currently undefined. Locks required: None. Return code: 0.
*/
-#define MC_CMD_GET_PHY_MEDIA_INFO 0x4b
+#define MC_CMD_GET_PHY_MEDIA_INFO 0x4b
+#undef MC_CMD_0x4b_PRIVILEGE_CTG
+
+#define MC_CMD_0x4b_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_GET_PHY_MEDIA_INFO_IN msgrequest */
#define MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN 4
@@ -4319,6 +6599,7 @@
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMIN 5
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMAX 252
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LEN(num) (4+1*(num))
+/* in bytes */
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATALEN_OFST 0
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST 4
#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_LEN 1
@@ -4327,10 +6608,14 @@
/***********************************/
-/* MC_CMD_NVRAM_TEST
- * Test a particular NVRAM partition.
+/* MC_CMD_NVRAM_TEST
+ * Test a particular NVRAM partition for valid contents (where "valid" depends
+ * on the type of partition).
*/
-#define MC_CMD_NVRAM_TEST 0x4c
+#define MC_CMD_NVRAM_TEST 0x4c
+#undef MC_CMD_0x4c_PRIVILEGE_CTG
+
+#define MC_CMD_0x4c_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_NVRAM_TEST_IN msgrequest */
#define MC_CMD_NVRAM_TEST_IN_LEN 4
@@ -4341,22 +6626,31 @@
/* MC_CMD_NVRAM_TEST_OUT msgresponse */
#define MC_CMD_NVRAM_TEST_OUT_LEN 4
#define MC_CMD_NVRAM_TEST_OUT_RESULT_OFST 0
-#define MC_CMD_NVRAM_TEST_PASS 0x0 /* enum */
-#define MC_CMD_NVRAM_TEST_FAIL 0x1 /* enum */
-#define MC_CMD_NVRAM_TEST_NOTSUPP 0x2 /* enum */
+/* enum: Passed. */
+#define MC_CMD_NVRAM_TEST_PASS 0x0
+/* enum: Failed. */
+#define MC_CMD_NVRAM_TEST_FAIL 0x1
+/* enum: Not supported. */
+#define MC_CMD_NVRAM_TEST_NOTSUPP 0x2
/***********************************/
-/* MC_CMD_MRSFP_TWEAK
- * Read status and/or set parameters for the 'mrsfp' driver.
+/* MC_CMD_MRSFP_TWEAK
+ * Read status and/or set parameters for the 'mrsfp' driver in mr_rusty builds.
+ * I2C I/O expander bits are always read; if equaliser parameters are supplied,
+ * they are configured first. Locks required: None. Return code: 0, EINVAL.
*/
-#define MC_CMD_MRSFP_TWEAK 0x4d
+#define MC_CMD_MRSFP_TWEAK 0x4d
/* MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG msgrequest */
#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_LEN 16
+/* 0-6 low->high de-emph. */
#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_TXEQ_LEVEL_OFST 0
+/* 0-8 low->high ref.V */
#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_TXEQ_DT_CFG_OFST 4
+/* 0-8 0-8 low->high boost */
#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_RXEQ_BOOST_OFST 8
+/* 0-8 low->high ref.V */
#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_RXEQ_DT_CFG_OFST 12
/* MC_CMD_MRSFP_TWEAK_IN_READ_ONLY msgrequest */
@@ -4364,27 +6658,41 @@
/* MC_CMD_MRSFP_TWEAK_OUT msgresponse */
#define MC_CMD_MRSFP_TWEAK_OUT_LEN 12
+/* input bits */
#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_INPUTS_OFST 0
+/* output bits */
#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_OUTPUTS_OFST 4
+/* direction */
#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_OFST 8
-#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_OUT 0x0 /* enum */
-#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_IN 0x1 /* enum */
+/* enum: Out. */
+#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_OUT 0x0
+/* enum: In. */
+#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_IN 0x1
/***********************************/
-/* MC_CMD_SENSOR_SET_LIMS
- * Adjusts the sensor limits.
+/* MC_CMD_SENSOR_SET_LIMS
+ * Adjusts the sensor limits. This is a warranty-voiding operation. Returns:
+ * ENOENT if the sensor specified does not exist, EINVAL if the limits are out
+ * of range.
*/
-#define MC_CMD_SENSOR_SET_LIMS 0x4e
+#define MC_CMD_SENSOR_SET_LIMS 0x4e
+#undef MC_CMD_0x4e_PRIVILEGE_CTG
+
+#define MC_CMD_0x4e_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_SENSOR_SET_LIMS_IN msgrequest */
#define MC_CMD_SENSOR_SET_LIMS_IN_LEN 20
#define MC_CMD_SENSOR_SET_LIMS_IN_SENSOR_OFST 0
/* Enum values, see field(s): */
/* MC_CMD_SENSOR_INFO/MC_CMD_SENSOR_INFO_OUT/MASK */
+/* interpretation is is sensor-specific. */
#define MC_CMD_SENSOR_SET_LIMS_IN_LOW0_OFST 4
+/* interpretation is is sensor-specific. */
#define MC_CMD_SENSOR_SET_LIMS_IN_HI0_OFST 8
+/* interpretation is is sensor-specific. */
#define MC_CMD_SENSOR_SET_LIMS_IN_LOW1_OFST 12
+/* interpretation is is sensor-specific. */
#define MC_CMD_SENSOR_SET_LIMS_IN_HI1_OFST 16
/* MC_CMD_SENSOR_SET_LIMS_OUT msgresponse */
@@ -4392,9 +6700,9 @@
/***********************************/
-/* MC_CMD_GET_RESOURCE_LIMITS
+/* MC_CMD_GET_RESOURCE_LIMITS
*/
-#define MC_CMD_GET_RESOURCE_LIMITS 0x4f
+#define MC_CMD_GET_RESOURCE_LIMITS 0x4f
/* MC_CMD_GET_RESOURCE_LIMITS_IN msgrequest */
#define MC_CMD_GET_RESOURCE_LIMITS_IN_LEN 0
@@ -4408,19 +6716,129 @@
/***********************************/
-/* MC_CMD_CLP
- * CLP support operations
+/* MC_CMD_NVRAM_PARTITIONS
+ * Reads the list of available virtual NVRAM partition types. Locks required:
+ * none. Returns: 0, EINVAL (bad type).
+ */
+#define MC_CMD_NVRAM_PARTITIONS 0x51
+#undef MC_CMD_0x51_PRIVILEGE_CTG
+
+#define MC_CMD_0x51_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_NVRAM_PARTITIONS_IN msgrequest */
+#define MC_CMD_NVRAM_PARTITIONS_IN_LEN 0
+
+/* MC_CMD_NVRAM_PARTITIONS_OUT msgresponse */
+#define MC_CMD_NVRAM_PARTITIONS_OUT_LENMIN 4
+#define MC_CMD_NVRAM_PARTITIONS_OUT_LENMAX 252
+#define MC_CMD_NVRAM_PARTITIONS_OUT_LEN(num) (4+4*(num))
+/* total number of partitions */
+#define MC_CMD_NVRAM_PARTITIONS_OUT_NUM_PARTITIONS_OFST 0
+/* type ID code for each of NUM_PARTITIONS partitions */
+#define MC_CMD_NVRAM_PARTITIONS_OUT_TYPE_ID_OFST 4
+#define MC_CMD_NVRAM_PARTITIONS_OUT_TYPE_ID_LEN 4
+#define MC_CMD_NVRAM_PARTITIONS_OUT_TYPE_ID_MINNUM 0
+#define MC_CMD_NVRAM_PARTITIONS_OUT_TYPE_ID_MAXNUM 62
+
+
+/***********************************/
+/* MC_CMD_NVRAM_METADATA
+ * Reads soft metadata for a virtual NVRAM partition type. Locks required:
+ * none. Returns: 0, EINVAL (bad type).
+ */
+#define MC_CMD_NVRAM_METADATA 0x52
+#undef MC_CMD_0x52_PRIVILEGE_CTG
+
+#define MC_CMD_0x52_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_NVRAM_METADATA_IN msgrequest */
+#define MC_CMD_NVRAM_METADATA_IN_LEN 4
+/* Partition type ID code */
+#define MC_CMD_NVRAM_METADATA_IN_TYPE_OFST 0
+
+/* MC_CMD_NVRAM_METADATA_OUT msgresponse */
+#define MC_CMD_NVRAM_METADATA_OUT_LENMIN 20
+#define MC_CMD_NVRAM_METADATA_OUT_LENMAX 252
+#define MC_CMD_NVRAM_METADATA_OUT_LEN(num) (20+1*(num))
+/* Partition type ID code */
+#define MC_CMD_NVRAM_METADATA_OUT_TYPE_OFST 0
+#define MC_CMD_NVRAM_METADATA_OUT_FLAGS_OFST 4
+#define MC_CMD_NVRAM_METADATA_OUT_SUBTYPE_VALID_LBN 0
+#define MC_CMD_NVRAM_METADATA_OUT_SUBTYPE_VALID_WIDTH 1
+#define MC_CMD_NVRAM_METADATA_OUT_VERSION_VALID_LBN 1
+#define MC_CMD_NVRAM_METADATA_OUT_VERSION_VALID_WIDTH 1
+#define MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_VALID_LBN 2
+#define MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_VALID_WIDTH 1
+/* Subtype ID code for content of this partition */
+#define MC_CMD_NVRAM_METADATA_OUT_SUBTYPE_OFST 8
+/* 1st component of W.X.Y.Z version number for content of this partition */
+#define MC_CMD_NVRAM_METADATA_OUT_VERSION_W_OFST 12
+#define MC_CMD_NVRAM_METADATA_OUT_VERSION_W_LEN 2
+/* 2nd component of W.X.Y.Z version number for content of this partition */
+#define MC_CMD_NVRAM_METADATA_OUT_VERSION_X_OFST 14
+#define MC_CMD_NVRAM_METADATA_OUT_VERSION_X_LEN 2
+/* 3rd component of W.X.Y.Z version number for content of this partition */
+#define MC_CMD_NVRAM_METADATA_OUT_VERSION_Y_OFST 16
+#define MC_CMD_NVRAM_METADATA_OUT_VERSION_Y_LEN 2
+/* 4th component of W.X.Y.Z version number for content of this partition */
+#define MC_CMD_NVRAM_METADATA_OUT_VERSION_Z_OFST 18
+#define MC_CMD_NVRAM_METADATA_OUT_VERSION_Z_LEN 2
+/* Zero-terminated string describing the content of this partition */
+#define MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_OFST 20
+#define MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_LEN 1
+#define MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_MINNUM 0
+#define MC_CMD_NVRAM_METADATA_OUT_DESCRIPTION_MAXNUM 232
+
+
+/***********************************/
+/* MC_CMD_GET_MAC_ADDRESSES
+ * Returns the base MAC, count and stride for the requesting function
*/
-#define MC_CMD_CLP 0x56
+#define MC_CMD_GET_MAC_ADDRESSES 0x55
+#undef MC_CMD_0x55_PRIVILEGE_CTG
+
+#define MC_CMD_0x55_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_MAC_ADDRESSES_IN msgrequest */
+#define MC_CMD_GET_MAC_ADDRESSES_IN_LEN 0
+
+/* MC_CMD_GET_MAC_ADDRESSES_OUT msgresponse */
+#define MC_CMD_GET_MAC_ADDRESSES_OUT_LEN 16
+/* Base MAC address */
+#define MC_CMD_GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE_OFST 0
+#define MC_CMD_GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE_LEN 6
+/* Padding */
+#define MC_CMD_GET_MAC_ADDRESSES_OUT_RESERVED_OFST 6
+#define MC_CMD_GET_MAC_ADDRESSES_OUT_RESERVED_LEN 2
+/* Number of allocated MAC addresses */
+#define MC_CMD_GET_MAC_ADDRESSES_OUT_MAC_COUNT_OFST 8
+/* Spacing of allocated MAC addresses */
+#define MC_CMD_GET_MAC_ADDRESSES_OUT_MAC_STRIDE_OFST 12
+
+
+/***********************************/
+/* MC_CMD_CLP
+ * Perform a CLP related operation
+ */
+#define MC_CMD_CLP 0x56
+#undef MC_CMD_0x56_PRIVILEGE_CTG
+
+#define MC_CMD_0x56_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_CLP_IN msgrequest */
#define MC_CMD_CLP_IN_LEN 4
+/* Sub operation */
#define MC_CMD_CLP_IN_OP_OFST 0
-#define MC_CMD_CLP_OP_DEFAULT 0x1 /* enum */
-#define MC_CMD_CLP_OP_SET_MAC 0x2 /* enum */
-#define MC_CMD_CLP_OP_GET_MAC 0x3 /* enum */
-#define MC_CMD_CLP_OP_SET_BOOT 0x4 /* enum */
-#define MC_CMD_CLP_OP_GET_BOOT 0x5 /* enum */
+/* enum: Return to factory default settings */
+#define MC_CMD_CLP_OP_DEFAULT 0x1
+/* enum: Set MAC address */
+#define MC_CMD_CLP_OP_SET_MAC 0x2
+/* enum: Get MAC address */
+#define MC_CMD_CLP_OP_GET_MAC 0x3
+/* enum: Set UEFI/GPXE boot mode */
+#define MC_CMD_CLP_OP_SET_BOOT 0x4
+/* enum: Get UEFI/GPXE boot mode */
+#define MC_CMD_CLP_OP_GET_BOOT 0x5
/* MC_CMD_CLP_OUT msgresponse */
#define MC_CMD_CLP_OUT_LEN 0
@@ -4435,8 +6853,10 @@
/* MC_CMD_CLP_IN_SET_MAC msgrequest */
#define MC_CMD_CLP_IN_SET_MAC_LEN 12
/* MC_CMD_CLP_IN_OP_OFST 0 */
+/* MAC address assigned to port */
#define MC_CMD_CLP_IN_SET_MAC_ADDR_OFST 4
#define MC_CMD_CLP_IN_SET_MAC_ADDR_LEN 6
+/* Padding */
#define MC_CMD_CLP_IN_SET_MAC_RESERVED_OFST 10
#define MC_CMD_CLP_IN_SET_MAC_RESERVED_LEN 2
@@ -4449,14 +6869,17 @@
/* MC_CMD_CLP_OUT_GET_MAC msgresponse */
#define MC_CMD_CLP_OUT_GET_MAC_LEN 8
+/* MAC address assigned to port */
#define MC_CMD_CLP_OUT_GET_MAC_ADDR_OFST 0
#define MC_CMD_CLP_OUT_GET_MAC_ADDR_LEN 6
+/* Padding */
#define MC_CMD_CLP_OUT_GET_MAC_RESERVED_OFST 6
#define MC_CMD_CLP_OUT_GET_MAC_RESERVED_LEN 2
/* MC_CMD_CLP_IN_SET_BOOT msgrequest */
#define MC_CMD_CLP_IN_SET_BOOT_LEN 5
/* MC_CMD_CLP_IN_OP_OFST 0 */
+/* Boot flag */
#define MC_CMD_CLP_IN_SET_BOOT_FLAG_OFST 4
#define MC_CMD_CLP_IN_SET_BOOT_FLAG_LEN 1
@@ -4469,113 +6892,920 @@
/* MC_CMD_CLP_OUT_GET_BOOT msgresponse */
#define MC_CMD_CLP_OUT_GET_BOOT_LEN 4
+/* Boot flag */
#define MC_CMD_CLP_OUT_GET_BOOT_FLAG_OFST 0
#define MC_CMD_CLP_OUT_GET_BOOT_FLAG_LEN 1
+/* Padding */
#define MC_CMD_CLP_OUT_GET_BOOT_RESERVED_OFST 1
#define MC_CMD_CLP_OUT_GET_BOOT_RESERVED_LEN 3
+
+/***********************************/
+/* MC_CMD_MUM
+ * Perform a MUM operation
+ */
+#define MC_CMD_MUM 0x57
+#undef MC_CMD_0x57_PRIVILEGE_CTG
+
+#define MC_CMD_0x57_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_MUM_IN msgrequest */
+#define MC_CMD_MUM_IN_LEN 4
+#define MC_CMD_MUM_IN_OP_HDR_OFST 0
+#define MC_CMD_MUM_IN_OP_LBN 0
+#define MC_CMD_MUM_IN_OP_WIDTH 8
+/* enum: NULL MCDI command to MUM */
+#define MC_CMD_MUM_OP_NULL 0x1
+/* enum: Get MUM version */
+#define MC_CMD_MUM_OP_GET_VERSION 0x2
+/* enum: Issue raw I2C command to MUM */
+#define MC_CMD_MUM_OP_RAW_CMD 0x3
+/* enum: Read from registers on devices connected to MUM. */
+#define MC_CMD_MUM_OP_READ 0x4
+/* enum: Write to registers on devices connected to MUM. */
+#define MC_CMD_MUM_OP_WRITE 0x5
+/* enum: Control UART logging. */
+#define MC_CMD_MUM_OP_LOG 0x6
+/* enum: Operations on MUM GPIO lines */
+#define MC_CMD_MUM_OP_GPIO 0x7
+/* enum: Get sensor readings from MUM */
+#define MC_CMD_MUM_OP_READ_SENSORS 0x8
+/* enum: Initiate clock programming on the MUM */
+#define MC_CMD_MUM_OP_PROGRAM_CLOCKS 0x9
+/* enum: Initiate FPGA load from flash on the MUM */
+#define MC_CMD_MUM_OP_FPGA_LOAD 0xa
+/* enum: Request sensor reading from MUM ADC resulting from earlier request via
+ * MUM ATB
+ */
+#define MC_CMD_MUM_OP_READ_ATB_SENSOR 0xb
+/* enum: Send commands relating to the QSFP ports via the MUM for PHY
+ * operations
+ */
+#define MC_CMD_MUM_OP_QSFP 0xc
+
+/* MC_CMD_MUM_IN_NULL msgrequest */
+#define MC_CMD_MUM_IN_NULL_LEN 4
+/* MUM cmd header */
+#define MC_CMD_MUM_IN_CMD_OFST 0
+
+/* MC_CMD_MUM_IN_GET_VERSION msgrequest */
+#define MC_CMD_MUM_IN_GET_VERSION_LEN 4
+/* MUM cmd header */
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+
+/* MC_CMD_MUM_IN_READ msgrequest */
+#define MC_CMD_MUM_IN_READ_LEN 16
+/* MUM cmd header */
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+/* ID of (device connected to MUM) to read from registers of */
+#define MC_CMD_MUM_IN_READ_DEVICE_OFST 4
+/* enum: Hittite HMC1035 clock generator on Sorrento board */
+#define MC_CMD_MUM_DEV_HITTITE 0x1
+/* enum: Hittite HMC1035 clock generator for NIC-side on Sorrento board */
+#define MC_CMD_MUM_DEV_HITTITE_NIC 0x2
+/* 32-bit address to read from */
+#define MC_CMD_MUM_IN_READ_ADDR_OFST 8
+/* Number of words to read. */
+#define MC_CMD_MUM_IN_READ_NUMWORDS_OFST 12
+
+/* MC_CMD_MUM_IN_WRITE msgrequest */
+#define MC_CMD_MUM_IN_WRITE_LENMIN 16
+#define MC_CMD_MUM_IN_WRITE_LENMAX 252
+#define MC_CMD_MUM_IN_WRITE_LEN(num) (12+4*(num))
+/* MUM cmd header */
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+/* ID of (device connected to MUM) to write to registers of */
+#define MC_CMD_MUM_IN_WRITE_DEVICE_OFST 4
+/* enum: Hittite HMC1035 clock generator on Sorrento board */
+/* MC_CMD_MUM_DEV_HITTITE 0x1 */
+/* 32-bit address to write to */
+#define MC_CMD_MUM_IN_WRITE_ADDR_OFST 8
+/* Words to write */
+#define MC_CMD_MUM_IN_WRITE_BUFFER_OFST 12
+#define MC_CMD_MUM_IN_WRITE_BUFFER_LEN 4
+#define MC_CMD_MUM_IN_WRITE_BUFFER_MINNUM 1
+#define MC_CMD_MUM_IN_WRITE_BUFFER_MAXNUM 60
+
+/* MC_CMD_MUM_IN_RAW_CMD msgrequest */
+#define MC_CMD_MUM_IN_RAW_CMD_LENMIN 17
+#define MC_CMD_MUM_IN_RAW_CMD_LENMAX 252
+#define MC_CMD_MUM_IN_RAW_CMD_LEN(num) (16+1*(num))
+/* MUM cmd header */
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+/* MUM I2C cmd code */
+#define MC_CMD_MUM_IN_RAW_CMD_CMD_CODE_OFST 4
+/* Number of bytes to write */
+#define MC_CMD_MUM_IN_RAW_CMD_NUM_WRITE_OFST 8
+/* Number of bytes to read */
+#define MC_CMD_MUM_IN_RAW_CMD_NUM_READ_OFST 12
+/* Bytes to write */
+#define MC_CMD_MUM_IN_RAW_CMD_WRITE_DATA_OFST 16
+#define MC_CMD_MUM_IN_RAW_CMD_WRITE_DATA_LEN 1
+#define MC_CMD_MUM_IN_RAW_CMD_WRITE_DATA_MINNUM 1
+#define MC_CMD_MUM_IN_RAW_CMD_WRITE_DATA_MAXNUM 236
+
+/* MC_CMD_MUM_IN_LOG msgrequest */
+#define MC_CMD_MUM_IN_LOG_LEN 8
+/* MUM cmd header */
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_LOG_OP_OFST 4
+#define MC_CMD_MUM_IN_LOG_OP_UART 0x1 /* enum */
+
+/* MC_CMD_MUM_IN_LOG_OP_UART msgrequest */
+#define MC_CMD_MUM_IN_LOG_OP_UART_LEN 12
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+/* MC_CMD_MUM_IN_LOG_OP_OFST 4 */
+/* Enable/disable debug output to UART */
+#define MC_CMD_MUM_IN_LOG_OP_UART_ENABLE_OFST 8
+
+/* MC_CMD_MUM_IN_GPIO msgrequest */
+#define MC_CMD_MUM_IN_GPIO_LEN 8
+/* MUM cmd header */
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_GPIO_HDR_OFST 4
+#define MC_CMD_MUM_IN_GPIO_OPCODE_LBN 0
+#define MC_CMD_MUM_IN_GPIO_OPCODE_WIDTH 8
+#define MC_CMD_MUM_IN_GPIO_IN_READ 0x0 /* enum */
+#define MC_CMD_MUM_IN_GPIO_OUT_WRITE 0x1 /* enum */
+#define MC_CMD_MUM_IN_GPIO_OUT_READ 0x2 /* enum */
+#define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_WRITE 0x3 /* enum */
+#define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_READ 0x4 /* enum */
+#define MC_CMD_MUM_IN_GPIO_OP 0x5 /* enum */
+
+/* MC_CMD_MUM_IN_GPIO_IN_READ msgrequest */
+#define MC_CMD_MUM_IN_GPIO_IN_READ_LEN 8
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_GPIO_IN_READ_HDR_OFST 4
+
+/* MC_CMD_MUM_IN_GPIO_OUT_WRITE msgrequest */
+#define MC_CMD_MUM_IN_GPIO_OUT_WRITE_LEN 16
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_GPIO_OUT_WRITE_HDR_OFST 4
+/* The first 32-bit word to be written to the GPIO OUT register. */
+#define MC_CMD_MUM_IN_GPIO_OUT_WRITE_GPIOMASK1_OFST 8
+/* The second 32-bit word to be written to the GPIO OUT register. */
+#define MC_CMD_MUM_IN_GPIO_OUT_WRITE_GPIOMASK2_OFST 12
+
+/* MC_CMD_MUM_IN_GPIO_OUT_READ msgrequest */
+#define MC_CMD_MUM_IN_GPIO_OUT_READ_LEN 8
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_GPIO_OUT_READ_HDR_OFST 4
+
+/* MC_CMD_MUM_IN_GPIO_OUT_ENABLE_WRITE msgrequest */
+#define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_WRITE_LEN 16
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_WRITE_HDR_OFST 4
+/* The first 32-bit word to be written to the GPIO OUT ENABLE register. */
+#define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_WRITE_GPIOMASK1_OFST 8
+/* The second 32-bit word to be written to the GPIO OUT ENABLE register. */
+#define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_WRITE_GPIOMASK2_OFST 12
+
+/* MC_CMD_MUM_IN_GPIO_OUT_ENABLE_READ msgrequest */
+#define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_READ_LEN 8
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_GPIO_OUT_ENABLE_READ_HDR_OFST 4
+
+/* MC_CMD_MUM_IN_GPIO_OP msgrequest */
+#define MC_CMD_MUM_IN_GPIO_OP_LEN 8
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_GPIO_OP_HDR_OFST 4
+#define MC_CMD_MUM_IN_GPIO_OP_BITWISE_OP_LBN 8
+#define MC_CMD_MUM_IN_GPIO_OP_BITWISE_OP_WIDTH 8
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_READ 0x0 /* enum */
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE 0x1 /* enum */
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG 0x2 /* enum */
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE 0x3 /* enum */
+#define MC_CMD_MUM_IN_GPIO_OP_GPIO_NUMBER_LBN 16
+#define MC_CMD_MUM_IN_GPIO_OP_GPIO_NUMBER_WIDTH 8
+
+/* MC_CMD_MUM_IN_GPIO_OP_OUT_READ msgrequest */
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_READ_LEN 8
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_READ_HDR_OFST 4
+
+/* MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE msgrequest */
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE_LEN 8
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE_HDR_OFST 4
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE_WRITEBIT_LBN 24
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_WRITE_WRITEBIT_WIDTH 8
+
+/* MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG msgrequest */
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG_LEN 8
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG_HDR_OFST 4
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG_CFG_LBN 24
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_CONFIG_CFG_WIDTH 8
+
+/* MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE msgrequest */
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE_LEN 8
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE_HDR_OFST 4
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE_ENABLEBIT_LBN 24
+#define MC_CMD_MUM_IN_GPIO_OP_OUT_ENABLE_ENABLEBIT_WIDTH 8
+
+/* MC_CMD_MUM_IN_READ_SENSORS msgrequest */
+#define MC_CMD_MUM_IN_READ_SENSORS_LEN 8
+/* MUM cmd header */
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_READ_SENSORS_PARAMS_OFST 4
+#define MC_CMD_MUM_IN_READ_SENSORS_SENSOR_ID_LBN 0
+#define MC_CMD_MUM_IN_READ_SENSORS_SENSOR_ID_WIDTH 8
+#define MC_CMD_MUM_IN_READ_SENSORS_NUM_SENSORS_LBN 8
+#define MC_CMD_MUM_IN_READ_SENSORS_NUM_SENSORS_WIDTH 8
+
+/* MC_CMD_MUM_IN_PROGRAM_CLOCKS msgrequest */
+#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_LEN 12
+/* MUM cmd header */
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+/* Bit-mask of clocks to be programmed */
+#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_MASK_OFST 4
+#define MC_CMD_MUM_CLOCK_ID_FPGA 0x0 /* enum */
+#define MC_CMD_MUM_CLOCK_ID_DDR 0x1 /* enum */
+#define MC_CMD_MUM_CLOCK_ID_NIC 0x2 /* enum */
+/* Control flags for clock programming */
+#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_FLAGS_OFST 8
+#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_OVERCLOCK_110_LBN 0
+#define MC_CMD_MUM_IN_PROGRAM_CLOCKS_OVERCLOCK_110_WIDTH 1
+
+/* MC_CMD_MUM_IN_FPGA_LOAD msgrequest */
+#define MC_CMD_MUM_IN_FPGA_LOAD_LEN 8
+/* MUM cmd header */
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+/* Enable/Disable FPGA config from flash */
+#define MC_CMD_MUM_IN_FPGA_LOAD_ENABLE_OFST 4
+
+/* MC_CMD_MUM_IN_READ_ATB_SENSOR msgrequest */
+#define MC_CMD_MUM_IN_READ_ATB_SENSOR_LEN 4
+/* MUM cmd header */
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+
+/* MC_CMD_MUM_IN_QSFP msgrequest */
+#define MC_CMD_MUM_IN_QSFP_LEN 12
+/* MUM cmd header */
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_QSFP_HDR_OFST 4
+#define MC_CMD_MUM_IN_QSFP_OPCODE_LBN 0
+#define MC_CMD_MUM_IN_QSFP_OPCODE_WIDTH 4
+#define MC_CMD_MUM_IN_QSFP_INIT 0x0 /* enum */
+#define MC_CMD_MUM_IN_QSFP_RECONFIGURE 0x1 /* enum */
+#define MC_CMD_MUM_IN_QSFP_GET_SUPPORTED_CAP 0x2 /* enum */
+#define MC_CMD_MUM_IN_QSFP_GET_MEDIA_INFO 0x3 /* enum */
+#define MC_CMD_MUM_IN_QSFP_FILL_STATS 0x4 /* enum */
+#define MC_CMD_MUM_IN_QSFP_POLL_BIST 0x5 /* enum */
+#define MC_CMD_MUM_IN_QSFP_IDX_OFST 8
+
+/* MC_CMD_MUM_IN_QSFP_INIT msgrequest */
+#define MC_CMD_MUM_IN_QSFP_INIT_LEN 16
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_QSFP_INIT_HDR_OFST 4
+#define MC_CMD_MUM_IN_QSFP_INIT_IDX_OFST 8
+#define MC_CMD_MUM_IN_QSFP_INIT_CAGE_OFST 12
+
+/* MC_CMD_MUM_IN_QSFP_RECONFIGURE msgrequest */
+#define MC_CMD_MUM_IN_QSFP_RECONFIGURE_LEN 24
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_QSFP_RECONFIGURE_HDR_OFST 4
+#define MC_CMD_MUM_IN_QSFP_RECONFIGURE_IDX_OFST 8
+#define MC_CMD_MUM_IN_QSFP_RECONFIGURE_TX_DISABLE_OFST 12
+#define MC_CMD_MUM_IN_QSFP_RECONFIGURE_PORT_LANES_OFST 16
+#define MC_CMD_MUM_IN_QSFP_RECONFIGURE_PORT_LINK_SPEED_OFST 20
+
+/* MC_CMD_MUM_IN_QSFP_GET_SUPPORTED_CAP msgrequest */
+#define MC_CMD_MUM_IN_QSFP_GET_SUPPORTED_CAP_LEN 12
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_QSFP_GET_SUPPORTED_CAP_HDR_OFST 4
+#define MC_CMD_MUM_IN_QSFP_GET_SUPPORTED_CAP_IDX_OFST 8
+
+/* MC_CMD_MUM_IN_QSFP_GET_MEDIA_INFO msgrequest */
+#define MC_CMD_MUM_IN_QSFP_GET_MEDIA_INFO_LEN 16
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_QSFP_GET_MEDIA_INFO_HDR_OFST 4
+#define MC_CMD_MUM_IN_QSFP_GET_MEDIA_INFO_IDX_OFST 8
+#define MC_CMD_MUM_IN_QSFP_GET_MEDIA_INFO_PAGE_OFST 12
+
+/* MC_CMD_MUM_IN_QSFP_FILL_STATS msgrequest */
+#define MC_CMD_MUM_IN_QSFP_FILL_STATS_LEN 12
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_QSFP_FILL_STATS_HDR_OFST 4
+#define MC_CMD_MUM_IN_QSFP_FILL_STATS_IDX_OFST 8
+
+/* MC_CMD_MUM_IN_QSFP_POLL_BIST msgrequest */
+#define MC_CMD_MUM_IN_QSFP_POLL_BIST_LEN 12
+/* MC_CMD_MUM_IN_CMD_OFST 0 */
+#define MC_CMD_MUM_IN_QSFP_POLL_BIST_HDR_OFST 4
+#define MC_CMD_MUM_IN_QSFP_POLL_BIST_IDX_OFST 8
+
+/* MC_CMD_MUM_OUT msgresponse */
+#define MC_CMD_MUM_OUT_LEN 0
+
+/* MC_CMD_MUM_OUT_NULL msgresponse */
+#define MC_CMD_MUM_OUT_NULL_LEN 0
+
+/* MC_CMD_MUM_OUT_GET_VERSION msgresponse */
+#define MC_CMD_MUM_OUT_GET_VERSION_LEN 12
+#define MC_CMD_MUM_OUT_GET_VERSION_FIRMWARE_OFST 0
+#define MC_CMD_MUM_OUT_GET_VERSION_VERSION_OFST 4
+#define MC_CMD_MUM_OUT_GET_VERSION_VERSION_LEN 8
+#define MC_CMD_MUM_OUT_GET_VERSION_VERSION_LO_OFST 4
+#define MC_CMD_MUM_OUT_GET_VERSION_VERSION_HI_OFST 8
+
+/* MC_CMD_MUM_OUT_RAW_CMD msgresponse */
+#define MC_CMD_MUM_OUT_RAW_CMD_LENMIN 1
+#define MC_CMD_MUM_OUT_RAW_CMD_LENMAX 252
+#define MC_CMD_MUM_OUT_RAW_CMD_LEN(num) (0+1*(num))
+/* returned data */
+#define MC_CMD_MUM_OUT_RAW_CMD_DATA_OFST 0
+#define MC_CMD_MUM_OUT_RAW_CMD_DATA_LEN 1
+#define MC_CMD_MUM_OUT_RAW_CMD_DATA_MINNUM 1
+#define MC_CMD_MUM_OUT_RAW_CMD_DATA_MAXNUM 252
+
+/* MC_CMD_MUM_OUT_READ msgresponse */
+#define MC_CMD_MUM_OUT_READ_LENMIN 4
+#define MC_CMD_MUM_OUT_READ_LENMAX 252
+#define MC_CMD_MUM_OUT_READ_LEN(num) (0+4*(num))
+#define MC_CMD_MUM_OUT_READ_BUFFER_OFST 0
+#define MC_CMD_MUM_OUT_READ_BUFFER_LEN 4
+#define MC_CMD_MUM_OUT_READ_BUFFER_MINNUM 1
+#define MC_CMD_MUM_OUT_READ_BUFFER_MAXNUM 63
+
+/* MC_CMD_MUM_OUT_WRITE msgresponse */
+#define MC_CMD_MUM_OUT_WRITE_LEN 0
+
+/* MC_CMD_MUM_OUT_LOG msgresponse */
+#define MC_CMD_MUM_OUT_LOG_LEN 0
+
+/* MC_CMD_MUM_OUT_LOG_OP_UART msgresponse */
+#define MC_CMD_MUM_OUT_LOG_OP_UART_LEN 0
+
+/* MC_CMD_MUM_OUT_GPIO_IN_READ msgresponse */
+#define MC_CMD_MUM_OUT_GPIO_IN_READ_LEN 8
+/* The first 32-bit word read from the GPIO IN register. */
+#define MC_CMD_MUM_OUT_GPIO_IN_READ_GPIOMASK1_OFST 0
+/* The second 32-bit word read from the GPIO IN register. */
+#define MC_CMD_MUM_OUT_GPIO_IN_READ_GPIOMASK2_OFST 4
+
+/* MC_CMD_MUM_OUT_GPIO_OUT_WRITE msgresponse */
+#define MC_CMD_MUM_OUT_GPIO_OUT_WRITE_LEN 0
+
+/* MC_CMD_MUM_OUT_GPIO_OUT_READ msgresponse */
+#define MC_CMD_MUM_OUT_GPIO_OUT_READ_LEN 8
+/* The first 32-bit word read from the GPIO OUT register. */
+#define MC_CMD_MUM_OUT_GPIO_OUT_READ_GPIOMASK1_OFST 0
+/* The second 32-bit word read from the GPIO OUT register. */
+#define MC_CMD_MUM_OUT_GPIO_OUT_READ_GPIOMASK2_OFST 4
+
+/* MC_CMD_MUM_OUT_GPIO_OUT_ENABLE_WRITE msgresponse */
+#define MC_CMD_MUM_OUT_GPIO_OUT_ENABLE_WRITE_LEN 0
+
+/* MC_CMD_MUM_OUT_GPIO_OUT_ENABLE_READ msgresponse */
+#define MC_CMD_MUM_OUT_GPIO_OUT_ENABLE_READ_LEN 8
+#define MC_CMD_MUM_OUT_GPIO_OUT_ENABLE_READ_GPIOMASK1_OFST 0
+#define MC_CMD_MUM_OUT_GPIO_OUT_ENABLE_READ_GPIOMASK2_OFST 4
+
+/* MC_CMD_MUM_OUT_GPIO_OP_OUT_READ msgresponse */
+#define MC_CMD_MUM_OUT_GPIO_OP_OUT_READ_LEN 4
+#define MC_CMD_MUM_OUT_GPIO_OP_OUT_READ_BIT_READ_OFST 0
+
+/* MC_CMD_MUM_OUT_GPIO_OP_OUT_WRITE msgresponse */
+#define MC_CMD_MUM_OUT_GPIO_OP_OUT_WRITE_LEN 0
+
+/* MC_CMD_MUM_OUT_GPIO_OP_OUT_CONFIG msgresponse */
+#define MC_CMD_MUM_OUT_GPIO_OP_OUT_CONFIG_LEN 0
+
+/* MC_CMD_MUM_OUT_GPIO_OP_OUT_ENABLE msgresponse */
+#define MC_CMD_MUM_OUT_GPIO_OP_OUT_ENABLE_LEN 0
+
+/* MC_CMD_MUM_OUT_READ_SENSORS msgresponse */
+#define MC_CMD_MUM_OUT_READ_SENSORS_LENMIN 4
+#define MC_CMD_MUM_OUT_READ_SENSORS_LENMAX 252
+#define MC_CMD_MUM_OUT_READ_SENSORS_LEN(num) (0+4*(num))
+#define MC_CMD_MUM_OUT_READ_SENSORS_DATA_OFST 0
+#define MC_CMD_MUM_OUT_READ_SENSORS_DATA_LEN 4
+#define MC_CMD_MUM_OUT_READ_SENSORS_DATA_MINNUM 1
+#define MC_CMD_MUM_OUT_READ_SENSORS_DATA_MAXNUM 63
+#define MC_CMD_MUM_OUT_READ_SENSORS_READING_LBN 0
+#define MC_CMD_MUM_OUT_READ_SENSORS_READING_WIDTH 16
+#define MC_CMD_MUM_OUT_READ_SENSORS_STATE_LBN 16
+#define MC_CMD_MUM_OUT_READ_SENSORS_STATE_WIDTH 8
+#define MC_CMD_MUM_OUT_READ_SENSORS_TYPE_LBN 24
+#define MC_CMD_MUM_OUT_READ_SENSORS_TYPE_WIDTH 8
+
+/* MC_CMD_MUM_OUT_PROGRAM_CLOCKS msgresponse */
+#define MC_CMD_MUM_OUT_PROGRAM_CLOCKS_LEN 4
+#define MC_CMD_MUM_OUT_PROGRAM_CLOCKS_OK_MASK_OFST 0
+
+/* MC_CMD_MUM_OUT_FPGA_LOAD msgresponse */
+#define MC_CMD_MUM_OUT_FPGA_LOAD_LEN 0
+
+/* MC_CMD_MUM_OUT_READ_ATB_SENSOR msgresponse */
+#define MC_CMD_MUM_OUT_READ_ATB_SENSOR_LEN 4
+#define MC_CMD_MUM_OUT_READ_ATB_SENSOR_RESULT_OFST 0
+
+/* MC_CMD_MUM_OUT_QSFP_INIT msgresponse */
+#define MC_CMD_MUM_OUT_QSFP_INIT_LEN 0
+
+/* MC_CMD_MUM_OUT_QSFP_RECONFIGURE msgresponse */
+#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_LEN 8
+#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_LP_CAP_OFST 0
+#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_FLAGS_OFST 4
+#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_READY_LBN 0
+#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_READY_WIDTH 1
+#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_LINK_UP_LBN 1
+#define MC_CMD_MUM_OUT_QSFP_RECONFIGURE_PORT_PHY_LINK_UP_WIDTH 1
+
+/* MC_CMD_MUM_OUT_QSFP_GET_SUPPORTED_CAP msgresponse */
+#define MC_CMD_MUM_OUT_QSFP_GET_SUPPORTED_CAP_LEN 4
+#define MC_CMD_MUM_OUT_QSFP_GET_SUPPORTED_CAP_PORT_PHY_LP_CAP_OFST 0
+
+/* MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO msgresponse */
+#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_LENMIN 5
+#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_LENMAX 252
+#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_LEN(num) (4+1*(num))
+/* in bytes */
+#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_DATALEN_OFST 0
+#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_DATA_OFST 4
+#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_DATA_LEN 1
+#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_DATA_MINNUM 1
+#define MC_CMD_MUM_OUT_QSFP_GET_MEDIA_INFO_DATA_MAXNUM 248
+
+/* MC_CMD_MUM_OUT_QSFP_FILL_STATS msgresponse */
+#define MC_CMD_MUM_OUT_QSFP_FILL_STATS_LEN 8
+#define MC_CMD_MUM_OUT_QSFP_FILL_STATS_PORT_PHY_STATS_PMA_PMD_LINK_UP_OFST 0
+#define MC_CMD_MUM_OUT_QSFP_FILL_STATS_PORT_PHY_STATS_PCS_LINK_UP_OFST 4
+
+/* MC_CMD_MUM_OUT_QSFP_POLL_BIST msgresponse */
+#define MC_CMD_MUM_OUT_QSFP_POLL_BIST_LEN 4
+#define MC_CMD_MUM_OUT_QSFP_POLL_BIST_TEST_OFST 0
+
/* MC_CMD_RESOURCE_SPECIFIER enum */
-#define MC_CMD_RESOURCE_INSTANCE_ANY 0xffffffff /* enum */
-#define MC_CMD_RESOURCE_INSTANCE_NONE 0xfffffffe /* enum */
+/* enum: Any */
+#define MC_CMD_RESOURCE_INSTANCE_ANY 0xffffffff
+/* enum: None */
+#define MC_CMD_RESOURCE_INSTANCE_NONE 0xfffffffe
+
+/* EVB_PORT_ID structuredef */
+#define EVB_PORT_ID_LEN 4
+#define EVB_PORT_ID_PORT_ID_OFST 0
+/* enum: An invalid port handle. */
+#define EVB_PORT_ID_NULL 0x0
+/* enum: The port assigned to this function.. */
+#define EVB_PORT_ID_ASSIGNED 0x1000000
+/* enum: External network port 0 */
+#define EVB_PORT_ID_MAC0 0x2000000
+/* enum: External network port 1 */
+#define EVB_PORT_ID_MAC1 0x2000001
+/* enum: External network port 2 */
+#define EVB_PORT_ID_MAC2 0x2000002
+/* enum: External network port 3 */
+#define EVB_PORT_ID_MAC3 0x2000003
+#define EVB_PORT_ID_PORT_ID_LBN 0
+#define EVB_PORT_ID_PORT_ID_WIDTH 32
+
+/* EVB_VLAN_TAG structuredef */
+#define EVB_VLAN_TAG_LEN 2
+/* The VLAN tag value */
+#define EVB_VLAN_TAG_VLAN_ID_LBN 0
+#define EVB_VLAN_TAG_VLAN_ID_WIDTH 12
+#define EVB_VLAN_TAG_MODE_LBN 12
+#define EVB_VLAN_TAG_MODE_WIDTH 4
+/* enum: Insert the VLAN. */
+#define EVB_VLAN_TAG_INSERT 0x0
+/* enum: Replace the VLAN if already present. */
+#define EVB_VLAN_TAG_REPLACE 0x1
+
+/* BUFTBL_ENTRY structuredef */
+#define BUFTBL_ENTRY_LEN 12
+/* the owner ID */
+#define BUFTBL_ENTRY_OID_OFST 0
+#define BUFTBL_ENTRY_OID_LEN 2
+#define BUFTBL_ENTRY_OID_LBN 0
+#define BUFTBL_ENTRY_OID_WIDTH 16
+/* the page parameter as one of ESE_DZ_SMC_PAGE_SIZE_ */
+#define BUFTBL_ENTRY_PGSZ_OFST 2
+#define BUFTBL_ENTRY_PGSZ_LEN 2
+#define BUFTBL_ENTRY_PGSZ_LBN 16
+#define BUFTBL_ENTRY_PGSZ_WIDTH 16
+/* the raw 64-bit address field from the SMC, not adjusted for page size */
+#define BUFTBL_ENTRY_RAWADDR_OFST 4
+#define BUFTBL_ENTRY_RAWADDR_LEN 8
+#define BUFTBL_ENTRY_RAWADDR_LO_OFST 4
+#define BUFTBL_ENTRY_RAWADDR_HI_OFST 8
+#define BUFTBL_ENTRY_RAWADDR_LBN 32
+#define BUFTBL_ENTRY_RAWADDR_WIDTH 64
+
+/* NVRAM_PARTITION_TYPE structuredef */
+#define NVRAM_PARTITION_TYPE_LEN 2
+#define NVRAM_PARTITION_TYPE_ID_OFST 0
+#define NVRAM_PARTITION_TYPE_ID_LEN 2
+/* enum: Primary MC firmware partition */
+#define NVRAM_PARTITION_TYPE_MC_FIRMWARE 0x100
+/* enum: Secondary MC firmware partition */
+#define NVRAM_PARTITION_TYPE_MC_FIRMWARE_BACKUP 0x200
+/* enum: Expansion ROM partition */
+#define NVRAM_PARTITION_TYPE_EXPANSION_ROM 0x300
+/* enum: Static configuration TLV partition */
+#define NVRAM_PARTITION_TYPE_STATIC_CONFIG 0x400
+/* enum: Dynamic configuration TLV partition */
+#define NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG 0x500
+/* enum: Expansion ROM configuration data for port 0 */
+#define NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT0 0x600
+/* enum: Expansion ROM configuration data for port 1 */
+#define NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT1 0x601
+/* enum: Expansion ROM configuration data for port 2 */
+#define NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT2 0x602
+/* enum: Expansion ROM configuration data for port 3 */
+#define NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT3 0x603
+/* enum: Non-volatile log output partition */
+#define NVRAM_PARTITION_TYPE_LOG 0x700
+/* enum: Device state dump output partition */
+#define NVRAM_PARTITION_TYPE_DUMP 0x800
+/* enum: Application license key storage partition */
+#define NVRAM_PARTITION_TYPE_LICENSE 0x900
+/* enum: Start of range used for PHY partitions (low 8 bits are the PHY ID) */
+#define NVRAM_PARTITION_TYPE_PHY_MIN 0xa00
+/* enum: End of range used for PHY partitions (low 8 bits are the PHY ID) */
+#define NVRAM_PARTITION_TYPE_PHY_MAX 0xaff
+/* enum: Primary FPGA partition */
+#define NVRAM_PARTITION_TYPE_FPGA 0xb00
+/* enum: Secondary FPGA partition */
+#define NVRAM_PARTITION_TYPE_FPGA_BACKUP 0xb01
+/* enum: FC firmware partition */
+#define NVRAM_PARTITION_TYPE_FC_FIRMWARE 0xb02
+/* enum: FC License partition */
+#define NVRAM_PARTITION_TYPE_FC_LICENSE 0xb03
+/* enum: Non-volatile log output partition for FC */
+#define NVRAM_PARTITION_TYPE_FC_LOG 0xb04
+/* enum: MUM firmware partition */
+#define NVRAM_PARTITION_TYPE_MUM_FIRMWARE 0xc00
+/* enum: MUM Non-volatile log output partition. */
+#define NVRAM_PARTITION_TYPE_MUM_LOG 0xc01
+/* enum: MUM Application table partition. */
+#define NVRAM_PARTITION_TYPE_MUM_APPTABLE 0xc02
+/* enum: MUM boot rom partition. */
+#define NVRAM_PARTITION_TYPE_MUM_BOOT_ROM 0xc03
+/* enum: MUM production signatures & calibration rom partition. */
+#define NVRAM_PARTITION_TYPE_MUM_PROD_ROM 0xc04
+/* enum: MUM user signatures & calibration rom partition. */
+#define NVRAM_PARTITION_TYPE_MUM_USER_ROM 0xc05
+/* enum: MUM fuses and lockbits partition. */
+#define NVRAM_PARTITION_TYPE_MUM_FUSELOCK 0xc06
+/* enum: Start of reserved value range (firmware may use for any purpose) */
+#define NVRAM_PARTITION_TYPE_RESERVED_VALUES_MIN 0xff00
+/* enum: End of reserved value range (firmware may use for any purpose) */
+#define NVRAM_PARTITION_TYPE_RESERVED_VALUES_MAX 0xfffd
+/* enum: Recovery partition map (provided if real map is missing or corrupt) */
+#define NVRAM_PARTITION_TYPE_RECOVERY_MAP 0xfffe
+/* enum: Partition map (real map as stored in flash) */
+#define NVRAM_PARTITION_TYPE_PARTITION_MAP 0xffff
+#define NVRAM_PARTITION_TYPE_ID_LBN 0
+#define NVRAM_PARTITION_TYPE_ID_WIDTH 16
+
+/* LICENSED_APP_ID structuredef */
+#define LICENSED_APP_ID_LEN 4
+#define LICENSED_APP_ID_ID_OFST 0
+/* enum: OpenOnload */
+#define LICENSED_APP_ID_ONLOAD 0x1
+/* enum: PTP timestamping */
+#define LICENSED_APP_ID_PTP 0x2
+/* enum: SolarCapture Pro */
+#define LICENSED_APP_ID_SOLARCAPTURE_PRO 0x4
+/* enum: SolarSecure filter engine */
+#define LICENSED_APP_ID_SOLARSECURE 0x8
+/* enum: Performance monitor */
+#define LICENSED_APP_ID_PERF_MONITOR 0x10
+/* enum: SolarCapture Live */
+#define LICENSED_APP_ID_SOLARCAPTURE_LIVE 0x20
+/* enum: Capture SolarSystem */
+#define LICENSED_APP_ID_CAPTURE_SOLARSYSTEM 0x40
+/* enum: Network Access Control */
+#define LICENSED_APP_ID_NETWORK_ACCESS_CONTROL 0x80
+#define LICENSED_APP_ID_ID_LBN 0
+#define LICENSED_APP_ID_ID_WIDTH 32
+
+/* TX_TIMESTAMP_EVENT structuredef */
+#define TX_TIMESTAMP_EVENT_LEN 6
+/* lower 16 bits of timestamp data */
+#define TX_TIMESTAMP_EVENT_TSTAMP_DATA_LO_OFST 0
+#define TX_TIMESTAMP_EVENT_TSTAMP_DATA_LO_LEN 2
+#define TX_TIMESTAMP_EVENT_TSTAMP_DATA_LO_LBN 0
+#define TX_TIMESTAMP_EVENT_TSTAMP_DATA_LO_WIDTH 16
+/* Type of TX event, ordinary TX completion, low or high part of TX timestamp
+ */
+#define TX_TIMESTAMP_EVENT_TX_EV_TYPE_OFST 3
+#define TX_TIMESTAMP_EVENT_TX_EV_TYPE_LEN 1
+/* enum: This is a TX completion event, not a timestamp */
+#define TX_TIMESTAMP_EVENT_TX_EV_COMPLETION 0x0
+/* enum: This is the low part of a TX timestamp event */
+#define TX_TIMESTAMP_EVENT_TX_EV_TSTAMP_LO 0x51
+/* enum: This is the high part of a TX timestamp event */
+#define TX_TIMESTAMP_EVENT_TX_EV_TSTAMP_HI 0x52
+#define TX_TIMESTAMP_EVENT_TX_EV_TYPE_LBN 24
+#define TX_TIMESTAMP_EVENT_TX_EV_TYPE_WIDTH 8
+/* upper 16 bits of timestamp data */
+#define TX_TIMESTAMP_EVENT_TSTAMP_DATA_HI_OFST 4
+#define TX_TIMESTAMP_EVENT_TSTAMP_DATA_HI_LEN 2
+#define TX_TIMESTAMP_EVENT_TSTAMP_DATA_HI_LBN 32
+#define TX_TIMESTAMP_EVENT_TSTAMP_DATA_HI_WIDTH 16
+
+/* RSS_MODE structuredef */
+#define RSS_MODE_LEN 1
+/* The RSS mode for a particular packet type is a value from 0 - 15 which can
+ * be considered as 4 bits selecting which fields are included in the hash. (A
+ * value 0 effectively disables RSS spreading for the packet type.) The YAML
+ * generation tools require this structure to be a whole number of bytes wide,
+ * but only 4 bits are relevant.
+ */
+#define RSS_MODE_HASH_SELECTOR_OFST 0
+#define RSS_MODE_HASH_SELECTOR_LEN 1
+#define RSS_MODE_HASH_SRC_ADDR_LBN 0
+#define RSS_MODE_HASH_SRC_ADDR_WIDTH 1
+#define RSS_MODE_HASH_DST_ADDR_LBN 1
+#define RSS_MODE_HASH_DST_ADDR_WIDTH 1
+#define RSS_MODE_HASH_SRC_PORT_LBN 2
+#define RSS_MODE_HASH_SRC_PORT_WIDTH 1
+#define RSS_MODE_HASH_DST_PORT_LBN 3
+#define RSS_MODE_HASH_DST_PORT_WIDTH 1
+#define RSS_MODE_HASH_SELECTOR_LBN 0
+#define RSS_MODE_HASH_SELECTOR_WIDTH 8
/***********************************/
-/* MC_CMD_INIT_EVQ
+/* MC_CMD_READ_REGS
+ * Get a dump of the MCPU registers
*/
-#define MC_CMD_INIT_EVQ 0x50
+#define MC_CMD_READ_REGS 0x50
+#undef MC_CMD_0x50_PRIVILEGE_CTG
+
+#define MC_CMD_0x50_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_READ_REGS_IN msgrequest */
+#define MC_CMD_READ_REGS_IN_LEN 0
+
+/* MC_CMD_READ_REGS_OUT msgresponse */
+#define MC_CMD_READ_REGS_OUT_LEN 308
+/* Whether the corresponding register entry contains a valid value */
+#define MC_CMD_READ_REGS_OUT_MASK_OFST 0
+#define MC_CMD_READ_REGS_OUT_MASK_LEN 16
+/* Same order as MIPS GDB (r0-r31, sr, lo, hi, bad, cause, 32 x float, fsr,
+ * fir, fp)
+ */
+#define MC_CMD_READ_REGS_OUT_REGS_OFST 16
+#define MC_CMD_READ_REGS_OUT_REGS_LEN 4
+#define MC_CMD_READ_REGS_OUT_REGS_NUM 73
+
+
+/***********************************/
+/* MC_CMD_INIT_EVQ
+ * Set up an event queue according to the supplied parameters. The IN arguments
+ * end with an address for each 4k of host memory required to back the EVQ.
+ */
+#define MC_CMD_INIT_EVQ 0x80
+#undef MC_CMD_0x80_PRIVILEGE_CTG
+
+#define MC_CMD_0x80_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_INIT_EVQ_IN msgrequest */
-#define MC_CMD_INIT_EVQ_IN_LENMIN 36
-#define MC_CMD_INIT_EVQ_IN_LENMAX 540
-#define MC_CMD_INIT_EVQ_IN_LEN(num) (28+8*(num))
+#define MC_CMD_INIT_EVQ_IN_LENMIN 44
+#define MC_CMD_INIT_EVQ_IN_LENMAX 548
+#define MC_CMD_INIT_EVQ_IN_LEN(num) (36+8*(num))
+/* Size, in entries */
#define MC_CMD_INIT_EVQ_IN_SIZE_OFST 0
+/* Desired instance. Must be set to a specific instance, which is a function
+ * local queue index.
+ */
#define MC_CMD_INIT_EVQ_IN_INSTANCE_OFST 4
+/* The initial timer value. The load value is ignored if the timer mode is DIS.
+ */
#define MC_CMD_INIT_EVQ_IN_TMR_LOAD_OFST 8
+/* The reload value is ignored in one-shot modes */
#define MC_CMD_INIT_EVQ_IN_TMR_RELOAD_OFST 12
+/* tbd */
#define MC_CMD_INIT_EVQ_IN_FLAGS_OFST 16
#define MC_CMD_INIT_EVQ_IN_FLAG_INTERRUPTING_LBN 0
#define MC_CMD_INIT_EVQ_IN_FLAG_INTERRUPTING_WIDTH 1
#define MC_CMD_INIT_EVQ_IN_FLAG_RPTR_DOS_LBN 1
#define MC_CMD_INIT_EVQ_IN_FLAG_RPTR_DOS_WIDTH 1
+#define MC_CMD_INIT_EVQ_IN_FLAG_INT_ARMD_LBN 2
+#define MC_CMD_INIT_EVQ_IN_FLAG_INT_ARMD_WIDTH 1
+#define MC_CMD_INIT_EVQ_IN_FLAG_CUT_THRU_LBN 3
+#define MC_CMD_INIT_EVQ_IN_FLAG_CUT_THRU_WIDTH 1
+#define MC_CMD_INIT_EVQ_IN_FLAG_RX_MERGE_LBN 4
+#define MC_CMD_INIT_EVQ_IN_FLAG_RX_MERGE_WIDTH 1
+#define MC_CMD_INIT_EVQ_IN_FLAG_TX_MERGE_LBN 5
+#define MC_CMD_INIT_EVQ_IN_FLAG_TX_MERGE_WIDTH 1
#define MC_CMD_INIT_EVQ_IN_TMR_MODE_OFST 20
-#define MC_CMD_INIT_EVQ_IN_TMR_MODE_DIS 0x0 /* enum */
-#define MC_CMD_INIT_EVQ_IN_TMR_IMMED_START 0x1 /* enum */
-#define MC_CMD_INIT_EVQ_IN_TMR_TRIG_START 0x2 /* enum */
-#define MC_CMD_INIT_EVQ_IN_TMR_INT_HLDOFF 0x3 /* enum */
+/* enum: Disabled */
+#define MC_CMD_INIT_EVQ_IN_TMR_MODE_DIS 0x0
+/* enum: Immediate */
+#define MC_CMD_INIT_EVQ_IN_TMR_IMMED_START 0x1
+/* enum: Triggered */
+#define MC_CMD_INIT_EVQ_IN_TMR_TRIG_START 0x2
+/* enum: Hold-off */
+#define MC_CMD_INIT_EVQ_IN_TMR_INT_HLDOFF 0x3
+/* Target EVQ for wakeups if in wakeup mode. */
#define MC_CMD_INIT_EVQ_IN_TARGET_EVQ_OFST 24
+/* Target interrupt if in interrupting mode (note union with target EVQ). Use
+ * MC_CMD_RESOURCE_INSTANCE_ANY unless a specific one required for test
+ * purposes.
+ */
#define MC_CMD_INIT_EVQ_IN_IRQ_NUM_OFST 24
-#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_OFST 28
+/* Event Counter Mode. */
+#define MC_CMD_INIT_EVQ_IN_COUNT_MODE_OFST 28
+/* enum: Disabled */
+#define MC_CMD_INIT_EVQ_IN_COUNT_MODE_DIS 0x0
+/* enum: Disabled */
+#define MC_CMD_INIT_EVQ_IN_COUNT_MODE_RX 0x1
+/* enum: Disabled */
+#define MC_CMD_INIT_EVQ_IN_COUNT_MODE_TX 0x2
+/* enum: Disabled */
+#define MC_CMD_INIT_EVQ_IN_COUNT_MODE_RXTX 0x3
+/* Event queue packet count threshold. */
+#define MC_CMD_INIT_EVQ_IN_COUNT_THRSHLD_OFST 32
+/* 64-bit address of 4k of 4k-aligned host memory buffer */
+#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_OFST 36
#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_LEN 8
-#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_LO_OFST 28
-#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_HI_OFST 32
+#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_LO_OFST 36
+#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_HI_OFST 40
#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_MINNUM 1
#define MC_CMD_INIT_EVQ_IN_DMA_ADDR_MAXNUM 64
/* MC_CMD_INIT_EVQ_OUT msgresponse */
#define MC_CMD_INIT_EVQ_OUT_LEN 4
+/* Only valid if INTRFLAG was true */
#define MC_CMD_INIT_EVQ_OUT_IRQ_OFST 0
/* QUEUE_CRC_MODE structuredef */
#define QUEUE_CRC_MODE_LEN 1
#define QUEUE_CRC_MODE_MODE_LBN 0
#define QUEUE_CRC_MODE_MODE_WIDTH 4
-#define QUEUE_CRC_MODE_NONE 0x0 /* enum */
-#define QUEUE_CRC_MODE_FCOE 0x1 /* enum */
-#define QUEUE_CRC_MODE_ISCSI_HDR 0x2 /* enum */
-#define QUEUE_CRC_MODE_ISCSI 0x3 /* enum */
-#define QUEUE_CRC_MODE_FCOIPOE 0x4 /* enum */
-#define QUEUE_CRC_MODE_MPA 0x5 /* enum */
+/* enum: No CRC. */
+#define QUEUE_CRC_MODE_NONE 0x0
+/* enum: CRC Fiber channel over ethernet. */
+#define QUEUE_CRC_MODE_FCOE 0x1
+/* enum: CRC (digest) iSCSI header only. */
+#define QUEUE_CRC_MODE_ISCSI_HDR 0x2
+/* enum: CRC (digest) iSCSI header and payload. */
+#define QUEUE_CRC_MODE_ISCSI 0x3
+/* enum: CRC Fiber channel over IP over ethernet. */
+#define QUEUE_CRC_MODE_FCOIPOE 0x4
+/* enum: CRC MPA. */
+#define QUEUE_CRC_MODE_MPA 0x5
#define QUEUE_CRC_MODE_SPARE_LBN 4
#define QUEUE_CRC_MODE_SPARE_WIDTH 4
/***********************************/
-/* MC_CMD_INIT_RXQ
+/* MC_CMD_INIT_RXQ
+ * set up a receive queue according to the supplied parameters. The IN
+ * arguments end with an address for each 4k of host memory required to back
+ * the RXQ.
*/
-#define MC_CMD_INIT_RXQ 0x51
+#define MC_CMD_INIT_RXQ 0x81
+#undef MC_CMD_0x81_PRIVILEGE_CTG
+
+#define MC_CMD_0x81_PRIVILEGE_CTG SRIOV_CTG_GENERAL
-/* MC_CMD_INIT_RXQ_IN msgrequest */
-#define MC_CMD_INIT_RXQ_IN_LENMIN 32
-#define MC_CMD_INIT_RXQ_IN_LENMAX 248
-#define MC_CMD_INIT_RXQ_IN_LEN(num) (24+8*(num))
+/* MC_CMD_INIT_RXQ_IN msgrequest: Legacy RXQ_INIT request. Use extended version
+ * in new code.
+ */
+#define MC_CMD_INIT_RXQ_IN_LENMIN 36
+#define MC_CMD_INIT_RXQ_IN_LENMAX 252
+#define MC_CMD_INIT_RXQ_IN_LEN(num) (28+8*(num))
+/* Size, in entries */
#define MC_CMD_INIT_RXQ_IN_SIZE_OFST 0
+/* The EVQ to send events to. This is an index originally specified to INIT_EVQ
+ */
#define MC_CMD_INIT_RXQ_IN_TARGET_EVQ_OFST 4
+/* The value to put in the event data. Check hardware spec. for valid range. */
#define MC_CMD_INIT_RXQ_IN_LABEL_OFST 8
+/* Desired instance. Must be set to a specific instance, which is a function
+ * local queue index.
+ */
#define MC_CMD_INIT_RXQ_IN_INSTANCE_OFST 12
+/* There will be more flags here. */
#define MC_CMD_INIT_RXQ_IN_FLAGS_OFST 16
#define MC_CMD_INIT_RXQ_IN_FLAG_BUFF_MODE_LBN 0
#define MC_CMD_INIT_RXQ_IN_FLAG_BUFF_MODE_WIDTH 1
#define MC_CMD_INIT_RXQ_IN_FLAG_HDR_SPLIT_LBN 1
#define MC_CMD_INIT_RXQ_IN_FLAG_HDR_SPLIT_WIDTH 1
-#define MC_CMD_INIT_RXQ_IN_FLAG_PKT_EDIT_LBN 2
-#define MC_CMD_INIT_RXQ_IN_FLAG_PKT_EDIT_WIDTH 1
+#define MC_CMD_INIT_RXQ_IN_FLAG_TIMESTAMP_LBN 2
+#define MC_CMD_INIT_RXQ_IN_FLAG_TIMESTAMP_WIDTH 1
#define MC_CMD_INIT_RXQ_IN_CRC_MODE_LBN 3
#define MC_CMD_INIT_RXQ_IN_CRC_MODE_WIDTH 4
+#define MC_CMD_INIT_RXQ_IN_FLAG_CHAIN_LBN 7
+#define MC_CMD_INIT_RXQ_IN_FLAG_CHAIN_WIDTH 1
+#define MC_CMD_INIT_RXQ_IN_FLAG_PREFIX_LBN 8
+#define MC_CMD_INIT_RXQ_IN_FLAG_PREFIX_WIDTH 1
+#define MC_CMD_INIT_RXQ_IN_FLAG_DISABLE_SCATTER_LBN 9
+#define MC_CMD_INIT_RXQ_IN_FLAG_DISABLE_SCATTER_WIDTH 1
+/* Owner ID to use if in buffer mode (zero if physical) */
#define MC_CMD_INIT_RXQ_IN_OWNER_ID_OFST 20
-#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_OFST 24
+/* The port ID associated with the v-adaptor which should contain this DMAQ. */
+#define MC_CMD_INIT_RXQ_IN_PORT_ID_OFST 24
+/* 64-bit address of 4k of 4k-aligned host memory buffer */
+#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_OFST 28
#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_LEN 8
-#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_LO_OFST 24
-#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_HI_OFST 28
+#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_LO_OFST 28
+#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_HI_OFST 32
#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_MINNUM 1
#define MC_CMD_INIT_RXQ_IN_DMA_ADDR_MAXNUM 28
+/* MC_CMD_INIT_RXQ_EXT_IN msgrequest: Extended RXQ_INIT with additional mode
+ * flags
+ */
+#define MC_CMD_INIT_RXQ_EXT_IN_LEN 544
+/* Size, in entries */
+#define MC_CMD_INIT_RXQ_EXT_IN_SIZE_OFST 0
+/* The EVQ to send events to. This is an index originally specified to INIT_EVQ
+ */
+#define MC_CMD_INIT_RXQ_EXT_IN_TARGET_EVQ_OFST 4
+/* The value to put in the event data. Check hardware spec. for valid range. */
+#define MC_CMD_INIT_RXQ_EXT_IN_LABEL_OFST 8
+/* Desired instance. Must be set to a specific instance, which is a function
+ * local queue index.
+ */
+#define MC_CMD_INIT_RXQ_EXT_IN_INSTANCE_OFST 12
+/* There will be more flags here. */
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAGS_OFST 16
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_BUFF_MODE_LBN 0
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_BUFF_MODE_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_HDR_SPLIT_LBN 1
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_HDR_SPLIT_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_TIMESTAMP_LBN 2
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_TIMESTAMP_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_CRC_MODE_LBN 3
+#define MC_CMD_INIT_RXQ_EXT_IN_CRC_MODE_WIDTH 4
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_CHAIN_LBN 7
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_CHAIN_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_PREFIX_LBN 8
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_PREFIX_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_DISABLE_SCATTER_LBN 9
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_DISABLE_SCATTER_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_DMA_MODE_LBN 10
+#define MC_CMD_INIT_RXQ_EXT_IN_DMA_MODE_WIDTH 4
+/* enum: One packet per descriptor (for normal networking) */
+#define MC_CMD_INIT_RXQ_EXT_IN_SINGLE_PACKET 0x0
+/* enum: Pack multiple packets into large descriptors (for SolarCapture) */
+#define MC_CMD_INIT_RXQ_EXT_IN_PACKED_STREAM 0x1
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_SNAPSHOT_MODE_LBN 14
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_SNAPSHOT_MODE_WIDTH 1
+#define MC_CMD_INIT_RXQ_EXT_IN_PACKED_STREAM_BUFF_SIZE_LBN 15
+#define MC_CMD_INIT_RXQ_EXT_IN_PACKED_STREAM_BUFF_SIZE_WIDTH 3
+#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_1M 0x0 /* enum */
+#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_512K 0x1 /* enum */
+#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_256K 0x2 /* enum */
+#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_128K 0x3 /* enum */
+#define MC_CMD_INIT_RXQ_EXT_IN_PS_BUFF_64K 0x4 /* enum */
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_WANT_OUTER_CLASSES_LBN 18
+#define MC_CMD_INIT_RXQ_EXT_IN_FLAG_WANT_OUTER_CLASSES_WIDTH 1
+/* Owner ID to use if in buffer mode (zero if physical) */
+#define MC_CMD_INIT_RXQ_EXT_IN_OWNER_ID_OFST 20
+/* The port ID associated with the v-adaptor which should contain this DMAQ. */
+#define MC_CMD_INIT_RXQ_EXT_IN_PORT_ID_OFST 24
+/* 64-bit address of 4k of 4k-aligned host memory buffer */
+#define MC_CMD_INIT_RXQ_EXT_IN_DMA_ADDR_OFST 28
+#define MC_CMD_INIT_RXQ_EXT_IN_DMA_ADDR_LEN 8
+#define MC_CMD_INIT_RXQ_EXT_IN_DMA_ADDR_LO_OFST 28
+#define MC_CMD_INIT_RXQ_EXT_IN_DMA_ADDR_HI_OFST 32
+#define MC_CMD_INIT_RXQ_EXT_IN_DMA_ADDR_NUM 64
+/* Maximum length of packet to receive, if SNAPSHOT_MODE flag is set */
+#define MC_CMD_INIT_RXQ_EXT_IN_SNAPSHOT_LENGTH_OFST 540
+
/* MC_CMD_INIT_RXQ_OUT msgresponse */
#define MC_CMD_INIT_RXQ_OUT_LEN 0
+/* MC_CMD_INIT_RXQ_EXT_OUT msgresponse */
+#define MC_CMD_INIT_RXQ_EXT_OUT_LEN 0
+
/***********************************/
-/* MC_CMD_INIT_TXQ
+/* MC_CMD_INIT_TXQ
*/
-#define MC_CMD_INIT_TXQ 0x52
+#define MC_CMD_INIT_TXQ 0x82
+#undef MC_CMD_0x82_PRIVILEGE_CTG
+
+#define MC_CMD_0x82_PRIVILEGE_CTG SRIOV_CTG_GENERAL
-/* MC_CMD_INIT_TXQ_IN msgrequest */
-#define MC_CMD_INIT_TXQ_IN_LENMIN 32
-#define MC_CMD_INIT_TXQ_IN_LENMAX 248
-#define MC_CMD_INIT_TXQ_IN_LEN(num) (24+8*(num))
+/* MC_CMD_INIT_TXQ_IN msgrequest: Legacy INIT_TXQ request. Use extended version
+ * in new code.
+ */
+#define MC_CMD_INIT_TXQ_IN_LENMIN 36
+#define MC_CMD_INIT_TXQ_IN_LENMAX 252
+#define MC_CMD_INIT_TXQ_IN_LEN(num) (28+8*(num))
+/* Size, in entries */
#define MC_CMD_INIT_TXQ_IN_SIZE_OFST 0
+/* The EVQ to send events to. This is an index originally specified to
+ * INIT_EVQ.
+ */
#define MC_CMD_INIT_TXQ_IN_TARGET_EVQ_OFST 4
+/* The value to put in the event data. Check hardware spec. for valid range. */
#define MC_CMD_INIT_TXQ_IN_LABEL_OFST 8
+/* Desired instance. Must be set to a specific instance, which is a function
+ * local queue index.
+ */
#define MC_CMD_INIT_TXQ_IN_INSTANCE_OFST 12
+/* There will be more flags here. */
#define MC_CMD_INIT_TXQ_IN_FLAGS_OFST 16
#define MC_CMD_INIT_TXQ_IN_FLAG_BUFF_MODE_LBN 0
#define MC_CMD_INIT_TXQ_IN_FLAG_BUFF_MODE_WIDTH 1
@@ -4587,25 +7817,101 @@
#define MC_CMD_INIT_TXQ_IN_FLAG_TCP_UDP_ONLY_WIDTH 1
#define MC_CMD_INIT_TXQ_IN_CRC_MODE_LBN 4
#define MC_CMD_INIT_TXQ_IN_CRC_MODE_WIDTH 4
+#define MC_CMD_INIT_TXQ_IN_FLAG_TIMESTAMP_LBN 8
+#define MC_CMD_INIT_TXQ_IN_FLAG_TIMESTAMP_WIDTH 1
+#define MC_CMD_INIT_TXQ_IN_FLAG_PACER_BYPASS_LBN 9
+#define MC_CMD_INIT_TXQ_IN_FLAG_PACER_BYPASS_WIDTH 1
+#define MC_CMD_INIT_TXQ_IN_FLAG_INNER_IP_CSUM_EN_LBN 10
+#define MC_CMD_INIT_TXQ_IN_FLAG_INNER_IP_CSUM_EN_WIDTH 1
+#define MC_CMD_INIT_TXQ_IN_FLAG_INNER_TCP_CSUM_EN_LBN 11
+#define MC_CMD_INIT_TXQ_IN_FLAG_INNER_TCP_CSUM_EN_WIDTH 1
+/* Owner ID to use if in buffer mode (zero if physical) */
#define MC_CMD_INIT_TXQ_IN_OWNER_ID_OFST 20
-#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_OFST 24
+/* The port ID associated with the v-adaptor which should contain this DMAQ. */
+#define MC_CMD_INIT_TXQ_IN_PORT_ID_OFST 24
+/* 64-bit address of 4k of 4k-aligned host memory buffer */
+#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_OFST 28
#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_LEN 8
-#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_LO_OFST 24
-#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_HI_OFST 28
+#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_LO_OFST 28
+#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_HI_OFST 32
#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_MINNUM 1
#define MC_CMD_INIT_TXQ_IN_DMA_ADDR_MAXNUM 28
+/* MC_CMD_INIT_TXQ_EXT_IN msgrequest: Extended INIT_TXQ with additional mode
+ * flags
+ */
+#define MC_CMD_INIT_TXQ_EXT_IN_LEN 544
+/* Size, in entries */
+#define MC_CMD_INIT_TXQ_EXT_IN_SIZE_OFST 0
+/* The EVQ to send events to. This is an index originally specified to
+ * INIT_EVQ.
+ */
+#define MC_CMD_INIT_TXQ_EXT_IN_TARGET_EVQ_OFST 4
+/* The value to put in the event data. Check hardware spec. for valid range. */
+#define MC_CMD_INIT_TXQ_EXT_IN_LABEL_OFST 8
+/* Desired instance. Must be set to a specific instance, which is a function
+ * local queue index.
+ */
+#define MC_CMD_INIT_TXQ_EXT_IN_INSTANCE_OFST 12
+/* There will be more flags here. */
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAGS_OFST 16
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_BUFF_MODE_LBN 0
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_BUFF_MODE_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_IP_CSUM_DIS_LBN 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_IP_CSUM_DIS_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TCP_CSUM_DIS_LBN 2
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TCP_CSUM_DIS_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TCP_UDP_ONLY_LBN 3
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TCP_UDP_ONLY_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_CRC_MODE_LBN 4
+#define MC_CMD_INIT_TXQ_EXT_IN_CRC_MODE_WIDTH 4
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TIMESTAMP_LBN 8
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_TIMESTAMP_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_PACER_BYPASS_LBN 9
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_PACER_BYPASS_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_INNER_IP_CSUM_EN_LBN 10
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_INNER_IP_CSUM_EN_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_INNER_TCP_CSUM_EN_LBN 11
+#define MC_CMD_INIT_TXQ_EXT_IN_FLAG_INNER_TCP_CSUM_EN_WIDTH 1
+/* Owner ID to use if in buffer mode (zero if physical) */
+#define MC_CMD_INIT_TXQ_EXT_IN_OWNER_ID_OFST 20
+/* The port ID associated with the v-adaptor which should contain this DMAQ. */
+#define MC_CMD_INIT_TXQ_EXT_IN_PORT_ID_OFST 24
+/* 64-bit address of 4k of 4k-aligned host memory buffer */
+#define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_OFST 28
+#define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_LEN 8
+#define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_LO_OFST 28
+#define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_HI_OFST 32
+#define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_MINNUM 1
+#define MC_CMD_INIT_TXQ_EXT_IN_DMA_ADDR_MAXNUM 64
+/* Flags related to Qbb flow control mode. */
+#define MC_CMD_INIT_TXQ_EXT_IN_QBB_FLAGS_OFST 540
+#define MC_CMD_INIT_TXQ_EXT_IN_QBB_ENABLE_LBN 0
+#define MC_CMD_INIT_TXQ_EXT_IN_QBB_ENABLE_WIDTH 1
+#define MC_CMD_INIT_TXQ_EXT_IN_QBB_PRIORITY_LBN 1
+#define MC_CMD_INIT_TXQ_EXT_IN_QBB_PRIORITY_WIDTH 3
+
/* MC_CMD_INIT_TXQ_OUT msgresponse */
#define MC_CMD_INIT_TXQ_OUT_LEN 0
/***********************************/
-/* MC_CMD_FINI_EVQ
+/* MC_CMD_FINI_EVQ
+ * Teardown an EVQ.
+ *
+ * All DMAQs or EVQs that point to the EVQ to tear down must be torn down first
+ * or the operation will fail with EBUSY
*/
-#define MC_CMD_FINI_EVQ 0x55
+#define MC_CMD_FINI_EVQ 0x83
+#undef MC_CMD_0x83_PRIVILEGE_CTG
+
+#define MC_CMD_0x83_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_FINI_EVQ_IN msgrequest */
#define MC_CMD_FINI_EVQ_IN_LEN 4
+/* Instance of EVQ to destroy. Should be the same instance as that previously
+ * passed to INIT_EVQ
+ */
#define MC_CMD_FINI_EVQ_IN_INSTANCE_OFST 0
/* MC_CMD_FINI_EVQ_OUT msgresponse */
@@ -4613,12 +7919,17 @@
/***********************************/
-/* MC_CMD_FINI_RXQ
+/* MC_CMD_FINI_RXQ
+ * Teardown a RXQ.
*/
-#define MC_CMD_FINI_RXQ 0x56
+#define MC_CMD_FINI_RXQ 0x84
+#undef MC_CMD_0x84_PRIVILEGE_CTG
+
+#define MC_CMD_0x84_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_FINI_RXQ_IN msgrequest */
#define MC_CMD_FINI_RXQ_IN_LEN 4
+/* Instance of RXQ to destroy */
#define MC_CMD_FINI_RXQ_IN_INSTANCE_OFST 0
/* MC_CMD_FINI_RXQ_OUT msgresponse */
@@ -4626,12 +7937,17 @@
/***********************************/
-/* MC_CMD_FINI_TXQ
+/* MC_CMD_FINI_TXQ
+ * Teardown a TXQ.
*/
-#define MC_CMD_FINI_TXQ 0x57
+#define MC_CMD_FINI_TXQ 0x85
+#undef MC_CMD_0x85_PRIVILEGE_CTG
+
+#define MC_CMD_0x85_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_FINI_TXQ_IN msgrequest */
#define MC_CMD_FINI_TXQ_IN_LEN 4
+/* Instance of TXQ to destroy */
#define MC_CMD_FINI_TXQ_IN_INSTANCE_OFST 0
/* MC_CMD_FINI_TXQ_OUT msgresponse */
@@ -4639,102 +7955,247 @@
/***********************************/
-/* MC_CMD_DRIVER_EVENT
+/* MC_CMD_DRIVER_EVENT
+ * Generate an event on an EVQ belonging to the function issuing the command.
*/
-#define MC_CMD_DRIVER_EVENT 0x5a
+#define MC_CMD_DRIVER_EVENT 0x86
+#undef MC_CMD_0x86_PRIVILEGE_CTG
+
+#define MC_CMD_0x86_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_DRIVER_EVENT_IN msgrequest */
#define MC_CMD_DRIVER_EVENT_IN_LEN 12
+/* Handle of target EVQ */
#define MC_CMD_DRIVER_EVENT_IN_EVQ_OFST 0
+/* Bits 0 - 63 of event */
#define MC_CMD_DRIVER_EVENT_IN_DATA_OFST 4
#define MC_CMD_DRIVER_EVENT_IN_DATA_LEN 8
#define MC_CMD_DRIVER_EVENT_IN_DATA_LO_OFST 4
#define MC_CMD_DRIVER_EVENT_IN_DATA_HI_OFST 8
+/* MC_CMD_DRIVER_EVENT_OUT msgresponse */
+#define MC_CMD_DRIVER_EVENT_OUT_LEN 0
+
/***********************************/
-/* MC_CMD_PROXY_CMD
+/* MC_CMD_PROXY_CMD
+ * Execute an arbitrary MCDI command on behalf of a different function, subject
+ * to security restrictions. The command to be proxied follows immediately
+ * afterward in the host buffer (or on the UART). This command supercedes
+ * MC_CMD_SET_FUNC, which remains available for Siena but now deprecated.
*/
-#define MC_CMD_PROXY_CMD 0x5b
+#define MC_CMD_PROXY_CMD 0x5b
+#undef MC_CMD_0x5b_PRIVILEGE_CTG
+
+#define MC_CMD_0x5b_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_PROXY_CMD_IN msgrequest */
#define MC_CMD_PROXY_CMD_IN_LEN 4
+/* The handle of the target function. */
#define MC_CMD_PROXY_CMD_IN_TARGET_OFST 0
+#define MC_CMD_PROXY_CMD_IN_TARGET_PF_LBN 0
+#define MC_CMD_PROXY_CMD_IN_TARGET_PF_WIDTH 16
+#define MC_CMD_PROXY_CMD_IN_TARGET_VF_LBN 16
+#define MC_CMD_PROXY_CMD_IN_TARGET_VF_WIDTH 16
+#define MC_CMD_PROXY_CMD_IN_VF_NULL 0xffff /* enum */
+/* MC_CMD_PROXY_CMD_OUT msgresponse */
+#define MC_CMD_PROXY_CMD_OUT_LEN 0
-/***********************************/
-/* MC_CMD_ALLOC_OWNER_IDS
+/* MC_PROXY_STATUS_BUFFER structuredef: Host memory status buffer used to
+ * manage proxied requests
*/
-#define MC_CMD_ALLOC_OWNER_IDS 0x54
+#define MC_PROXY_STATUS_BUFFER_LEN 16
+/* Handle allocated by the firmware for this proxy transaction */
+#define MC_PROXY_STATUS_BUFFER_HANDLE_OFST 0
+/* enum: An invalid handle. */
+#define MC_PROXY_STATUS_BUFFER_HANDLE_INVALID 0x0
+#define MC_PROXY_STATUS_BUFFER_HANDLE_LBN 0
+#define MC_PROXY_STATUS_BUFFER_HANDLE_WIDTH 32
+/* The requesting physical function number */
+#define MC_PROXY_STATUS_BUFFER_PF_OFST 4
+#define MC_PROXY_STATUS_BUFFER_PF_LEN 2
+#define MC_PROXY_STATUS_BUFFER_PF_LBN 32
+#define MC_PROXY_STATUS_BUFFER_PF_WIDTH 16
+/* The requesting virtual function number. Set to VF_NULL if the target is a
+ * PF.
+ */
+#define MC_PROXY_STATUS_BUFFER_VF_OFST 6
+#define MC_PROXY_STATUS_BUFFER_VF_LEN 2
+#define MC_PROXY_STATUS_BUFFER_VF_LBN 48
+#define MC_PROXY_STATUS_BUFFER_VF_WIDTH 16
+/* The target function RID. */
+#define MC_PROXY_STATUS_BUFFER_RID_OFST 8
+#define MC_PROXY_STATUS_BUFFER_RID_LEN 2
+#define MC_PROXY_STATUS_BUFFER_RID_LBN 64
+#define MC_PROXY_STATUS_BUFFER_RID_WIDTH 16
+/* The status of the proxy as described in MC_CMD_PROXY_COMPLETE. */
+#define MC_PROXY_STATUS_BUFFER_STATUS_OFST 10
+#define MC_PROXY_STATUS_BUFFER_STATUS_LEN 2
+#define MC_PROXY_STATUS_BUFFER_STATUS_LBN 80
+#define MC_PROXY_STATUS_BUFFER_STATUS_WIDTH 16
+/* If a request is authorized rather than carried out by the host, this is the
+ * elevated privilege mask granted to the requesting function.
+ */
+#define MC_PROXY_STATUS_BUFFER_GRANTED_PRIVILEGES_OFST 12
+#define MC_PROXY_STATUS_BUFFER_GRANTED_PRIVILEGES_LBN 96
+#define MC_PROXY_STATUS_BUFFER_GRANTED_PRIVILEGES_WIDTH 32
-/* MC_CMD_ALLOC_OWNER_IDS_IN msgrequest */
-#define MC_CMD_ALLOC_OWNER_IDS_IN_LEN 4
-#define MC_CMD_ALLOC_OWNER_IDS_IN_NIDS_OFST 0
-/* MC_CMD_ALLOC_OWNER_IDS_OUT msgresponse */
-#define MC_CMD_ALLOC_OWNER_IDS_OUT_LEN 12
-#define MC_CMD_ALLOC_OWNER_IDS_OUT_HANDLE_OFST 0
-#define MC_CMD_ALLOC_OWNER_IDS_OUT_NIDS_OFST 4
-#define MC_CMD_ALLOC_OWNER_IDS_OUT_BASE_OFST 8
+/***********************************/
+/* MC_CMD_PROXY_CONFIGURE
+ * Enable/disable authorization of MCDI requests from unprivileged functions by
+ * a designated admin function
+ */
+#define MC_CMD_PROXY_CONFIGURE 0x58
+#undef MC_CMD_0x58_PRIVILEGE_CTG
+
+#define MC_CMD_0x58_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_PROXY_CONFIGURE_IN msgrequest */
+#define MC_CMD_PROXY_CONFIGURE_IN_LEN 108
+#define MC_CMD_PROXY_CONFIGURE_IN_FLAGS_OFST 0
+#define MC_CMD_PROXY_CONFIGURE_IN_ENABLE_LBN 0
+#define MC_CMD_PROXY_CONFIGURE_IN_ENABLE_WIDTH 1
+/* Host provides a contiguous memory buffer that contains at least NUM_BLOCKS
+ * of blocks, each of the size REQUEST_BLOCK_SIZE.
+ */
+#define MC_CMD_PROXY_CONFIGURE_IN_STATUS_BUFF_ADDR_OFST 4
+#define MC_CMD_PROXY_CONFIGURE_IN_STATUS_BUFF_ADDR_LEN 8
+#define MC_CMD_PROXY_CONFIGURE_IN_STATUS_BUFF_ADDR_LO_OFST 4
+#define MC_CMD_PROXY_CONFIGURE_IN_STATUS_BUFF_ADDR_HI_OFST 8
+/* Must be a power of 2 */
+#define MC_CMD_PROXY_CONFIGURE_IN_STATUS_BLOCK_SIZE_OFST 12
+/* Host provides a contiguous memory buffer that contains at least NUM_BLOCKS
+ * of blocks, each of the size REPLY_BLOCK_SIZE.
+ */
+#define MC_CMD_PROXY_CONFIGURE_IN_REQUEST_BUFF_ADDR_OFST 16
+#define MC_CMD_PROXY_CONFIGURE_IN_REQUEST_BUFF_ADDR_LEN 8
+#define MC_CMD_PROXY_CONFIGURE_IN_REQUEST_BUFF_ADDR_LO_OFST 16
+#define MC_CMD_PROXY_CONFIGURE_IN_REQUEST_BUFF_ADDR_HI_OFST 20
+/* Must be a power of 2 */
+#define MC_CMD_PROXY_CONFIGURE_IN_REQUEST_BLOCK_SIZE_OFST 24
+/* Host provides a contiguous memory buffer that contains at least NUM_BLOCKS
+ * of blocks, each of the size STATUS_BLOCK_SIZE. This buffer is only needed if
+ * host intends to complete proxied operations by using MC_CMD_PROXY_CMD.
+ */
+#define MC_CMD_PROXY_CONFIGURE_IN_REPLY_BUFF_ADDR_OFST 28
+#define MC_CMD_PROXY_CONFIGURE_IN_REPLY_BUFF_ADDR_LEN 8
+#define MC_CMD_PROXY_CONFIGURE_IN_REPLY_BUFF_ADDR_LO_OFST 28
+#define MC_CMD_PROXY_CONFIGURE_IN_REPLY_BUFF_ADDR_HI_OFST 32
+/* Must be a power of 2, or zero if this buffer is not provided */
+#define MC_CMD_PROXY_CONFIGURE_IN_REPLY_BLOCK_SIZE_OFST 36
+/* Applies to all three buffers */
+#define MC_CMD_PROXY_CONFIGURE_IN_NUM_BLOCKS_OFST 40
+/* A bit mask defining which MCDI operations may be proxied */
+#define MC_CMD_PROXY_CONFIGURE_IN_ALLOWED_MCDI_MASK_OFST 44
+#define MC_CMD_PROXY_CONFIGURE_IN_ALLOWED_MCDI_MASK_LEN 64
+
+/* MC_CMD_PROXY_CONFIGURE_OUT msgresponse */
+#define MC_CMD_PROXY_CONFIGURE_OUT_LEN 0
/***********************************/
-/* MC_CMD_FREE_OWNER_IDS
+/* MC_CMD_PROXY_COMPLETE
+ * Tells FW that a requested proxy operation has either been completed (by
+ * using MC_CMD_PROXY_CMD) or authorized/declined. May only be sent by the
+ * function that enabled proxying/authorization (by using
+ * MC_CMD_PROXY_CONFIGURE).
*/
-#define MC_CMD_FREE_OWNER_IDS 0x59
+#define MC_CMD_PROXY_COMPLETE 0x5f
+#undef MC_CMD_0x5f_PRIVILEGE_CTG
+
+#define MC_CMD_0x5f_PRIVILEGE_CTG SRIOV_CTG_ADMIN
-/* MC_CMD_FREE_OWNER_IDS_IN msgrequest */
-#define MC_CMD_FREE_OWNER_IDS_IN_LEN 4
-#define MC_CMD_FREE_OWNER_IDS_IN_HANDLE_OFST 0
+/* MC_CMD_PROXY_COMPLETE_IN msgrequest */
+#define MC_CMD_PROXY_COMPLETE_IN_LEN 12
+#define MC_CMD_PROXY_COMPLETE_IN_BLOCK_INDEX_OFST 0
+#define MC_CMD_PROXY_COMPLETE_IN_STATUS_OFST 4
+/* enum: The operation has been completed by using MC_CMD_PROXY_CMD, the reply
+ * is stored in the REPLY_BUFF.
+ */
+#define MC_CMD_PROXY_COMPLETE_IN_COMPLETE 0x0
+/* enum: The operation has been authorized. The originating function may now
+ * try again.
+ */
+#define MC_CMD_PROXY_COMPLETE_IN_AUTHORIZED 0x1
+/* enum: The operation has been declined. */
+#define MC_CMD_PROXY_COMPLETE_IN_DECLINED 0x2
+/* enum: The authorization failed because the relevant application did not
+ * respond in time.
+ */
+#define MC_CMD_PROXY_COMPLETE_IN_TIMEDOUT 0x3
+#define MC_CMD_PROXY_COMPLETE_IN_HANDLE_OFST 8
-/* MC_CMD_FREE_OWNER_IDS_OUT msgresponse */
-#define MC_CMD_FREE_OWNER_IDS_OUT_LEN 0
+/* MC_CMD_PROXY_COMPLETE_OUT msgresponse */
+#define MC_CMD_PROXY_COMPLETE_OUT_LEN 0
/***********************************/
-/* MC_CMD_ALLOC_BUFTBL_CHUNK
+/* MC_CMD_ALLOC_BUFTBL_CHUNK
+ * Allocate a set of buffer table entries using the specified owner ID. This
+ * operation allocates the required buffer table entries (and fails if it
+ * cannot do so). The buffer table entries will initially be zeroed.
*/
-#define MC_CMD_ALLOC_BUFTBL_CHUNK 0x5c
+#define MC_CMD_ALLOC_BUFTBL_CHUNK 0x87
+#undef MC_CMD_0x87_PRIVILEGE_CTG
+
+#define MC_CMD_0x87_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
/* MC_CMD_ALLOC_BUFTBL_CHUNK_IN msgrequest */
#define MC_CMD_ALLOC_BUFTBL_CHUNK_IN_LEN 8
+/* Owner ID to use */
#define MC_CMD_ALLOC_BUFTBL_CHUNK_IN_OWNER_OFST 0
+/* Size of buffer table pages to use, in bytes (note that only a few values are
+ * legal on any specific hardware).
+ */
#define MC_CMD_ALLOC_BUFTBL_CHUNK_IN_PAGE_SIZE_OFST 4
/* MC_CMD_ALLOC_BUFTBL_CHUNK_OUT msgresponse */
#define MC_CMD_ALLOC_BUFTBL_CHUNK_OUT_LEN 12
#define MC_CMD_ALLOC_BUFTBL_CHUNK_OUT_HANDLE_OFST 0
#define MC_CMD_ALLOC_BUFTBL_CHUNK_OUT_NUMENTRIES_OFST 4
+/* Buffer table IDs for use in DMA descriptors. */
#define MC_CMD_ALLOC_BUFTBL_CHUNK_OUT_ID_OFST 8
/***********************************/
-/* MC_CMD_PROGRAM_BUFTBL_ENTRIES
+/* MC_CMD_PROGRAM_BUFTBL_ENTRIES
+ * Reprogram a set of buffer table entries in the specified chunk.
*/
-#define MC_CMD_PROGRAM_BUFTBL_ENTRIES 0x5d
+#define MC_CMD_PROGRAM_BUFTBL_ENTRIES 0x88
+#undef MC_CMD_0x88_PRIVILEGE_CTG
+
+#define MC_CMD_0x88_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
/* MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN msgrequest */
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LENMIN 20
-#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LENMAX 252
+#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LENMAX 268
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_LEN(num) (12+8*(num))
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_HANDLE_OFST 0
+/* ID */
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_FIRSTID_OFST 4
+/* Num entries */
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_NUMENTRIES_OFST 8
+/* Buffer table entry address */
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_OFST 12
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_LEN 8
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_LO_OFST 12
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_HI_OFST 16
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_MINNUM 1
-#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_MAXNUM 30
+#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_IN_ENTRY_MAXNUM 32
/* MC_CMD_PROGRAM_BUFTBL_ENTRIES_OUT msgresponse */
#define MC_CMD_PROGRAM_BUFTBL_ENTRIES_OUT_LEN 0
/***********************************/
-/* MC_CMD_FREE_BUFTBL_CHUNK
+/* MC_CMD_FREE_BUFTBL_CHUNK
*/
-#define MC_CMD_FREE_BUFTBL_CHUNK 0x5e
+#define MC_CMD_FREE_BUFTBL_CHUNK 0x89
+#undef MC_CMD_0x89_PRIVILEGE_CTG
+
+#define MC_CMD_0x89_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
/* MC_CMD_FREE_BUFTBL_CHUNK_IN msgrequest */
#define MC_CMD_FREE_BUFTBL_CHUNK_IN_LEN 4
@@ -4743,35 +8204,80 @@
/* MC_CMD_FREE_BUFTBL_CHUNK_OUT msgresponse */
#define MC_CMD_FREE_BUFTBL_CHUNK_OUT_LEN 0
-
-/***********************************/
-/* MC_CMD_GET_PF_COUNT
- */
-#define MC_CMD_GET_PF_COUNT 0x60
-
-/* MC_CMD_GET_PF_COUNT_IN msgrequest */
-#define MC_CMD_GET_PF_COUNT_IN_LEN 0
-
-/* MC_CMD_GET_PF_COUNT_OUT msgresponse */
-#define MC_CMD_GET_PF_COUNT_OUT_LEN 1
-#define MC_CMD_GET_PF_COUNT_OUT_PF_COUNT_OFST 0
-#define MC_CMD_GET_PF_COUNT_OUT_PF_COUNT_LEN 1
+/* PORT_CONFIG_ENTRY structuredef */
+#define PORT_CONFIG_ENTRY_LEN 16
+/* External port number (label) */
+#define PORT_CONFIG_ENTRY_EXT_NUMBER_OFST 0
+#define PORT_CONFIG_ENTRY_EXT_NUMBER_LEN 1
+#define PORT_CONFIG_ENTRY_EXT_NUMBER_LBN 0
+#define PORT_CONFIG_ENTRY_EXT_NUMBER_WIDTH 8
+/* Port core location */
+#define PORT_CONFIG_ENTRY_CORE_OFST 1
+#define PORT_CONFIG_ENTRY_CORE_LEN 1
+#define PORT_CONFIG_ENTRY_STANDALONE 0x0 /* enum */
+#define PORT_CONFIG_ENTRY_MASTER 0x1 /* enum */
+#define PORT_CONFIG_ENTRY_SLAVE 0x2 /* enum */
+#define PORT_CONFIG_ENTRY_CORE_LBN 8
+#define PORT_CONFIG_ENTRY_CORE_WIDTH 8
+/* Internal number (HW resource) relative to the core */
+#define PORT_CONFIG_ENTRY_INT_NUMBER_OFST 2
+#define PORT_CONFIG_ENTRY_INT_NUMBER_LEN 1
+#define PORT_CONFIG_ENTRY_INT_NUMBER_LBN 16
+#define PORT_CONFIG_ENTRY_INT_NUMBER_WIDTH 8
+/* Reserved */
+#define PORT_CONFIG_ENTRY_RSVD_OFST 3
+#define PORT_CONFIG_ENTRY_RSVD_LEN 1
+#define PORT_CONFIG_ENTRY_RSVD_LBN 24
+#define PORT_CONFIG_ENTRY_RSVD_WIDTH 8
+/* Bitmask of KR lanes used by the port */
+#define PORT_CONFIG_ENTRY_LANES_OFST 4
+#define PORT_CONFIG_ENTRY_LANES_LBN 32
+#define PORT_CONFIG_ENTRY_LANES_WIDTH 32
+/* Port capabilities (MC_CMD_PHY_CAP_*) */
+#define PORT_CONFIG_ENTRY_SUPPORTED_CAPS_OFST 8
+#define PORT_CONFIG_ENTRY_SUPPORTED_CAPS_LBN 64
+#define PORT_CONFIG_ENTRY_SUPPORTED_CAPS_WIDTH 32
+/* Reserved (align to 16 bytes) */
+#define PORT_CONFIG_ENTRY_RSVD2_OFST 12
+#define PORT_CONFIG_ENTRY_RSVD2_LBN 96
+#define PORT_CONFIG_ENTRY_RSVD2_WIDTH 32
/***********************************/
-/* MC_CMD_FILTER_OP
+/* MC_CMD_FILTER_OP
+ * Multiplexed MCDI call for filter operations
*/
-#define MC_CMD_FILTER_OP 0x61
+#define MC_CMD_FILTER_OP 0x8a
+#undef MC_CMD_0x8a_PRIVILEGE_CTG
+
+#define MC_CMD_0x8a_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_FILTER_OP_IN msgrequest */
-#define MC_CMD_FILTER_OP_IN_LEN 100
+#define MC_CMD_FILTER_OP_IN_LEN 108
+/* identifies the type of operation requested */
#define MC_CMD_FILTER_OP_IN_OP_OFST 0
-#define MC_CMD_FILTER_OP_IN_OP_INSERT 0x0 /* enum */
-#define MC_CMD_FILTER_OP_IN_OP_REMOVE 0x1 /* enum */
-#define MC_CMD_FILTER_OP_IN_OP_SUBSCRIBE 0x2 /* enum */
-#define MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE 0x3 /* enum */
+/* enum: single-recipient filter insert */
+#define MC_CMD_FILTER_OP_IN_OP_INSERT 0x0
+/* enum: single-recipient filter remove */
+#define MC_CMD_FILTER_OP_IN_OP_REMOVE 0x1
+/* enum: multi-recipient filter subscribe */
+#define MC_CMD_FILTER_OP_IN_OP_SUBSCRIBE 0x2
+/* enum: multi-recipient filter unsubscribe */
+#define MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE 0x3
+/* enum: replace one recipient with another (warning - the filter handle may
+ * change)
+ */
+#define MC_CMD_FILTER_OP_IN_OP_REPLACE 0x4
+/* filter handle (for remove / unsubscribe operations) */
#define MC_CMD_FILTER_OP_IN_HANDLE_OFST 4
-#define MC_CMD_FILTER_OP_IN_MATCH_FIELDS_OFST 8
+#define MC_CMD_FILTER_OP_IN_HANDLE_LEN 8
+#define MC_CMD_FILTER_OP_IN_HANDLE_LO_OFST 4
+#define MC_CMD_FILTER_OP_IN_HANDLE_HI_OFST 8
+/* The port ID associated with the v-adaptor which should contain this filter.
+ */
+#define MC_CMD_FILTER_OP_IN_PORT_ID_OFST 12
+/* fields to include in match criteria */
+#define MC_CMD_FILTER_OP_IN_MATCH_FIELDS_OFST 16
#define MC_CMD_FILTER_OP_IN_MATCH_SRC_IP_LBN 0
#define MC_CMD_FILTER_OP_IN_MATCH_SRC_IP_WIDTH 1
#define MC_CMD_FILTER_OP_IN_MATCH_DST_IP_LBN 1
@@ -4796,63 +8302,493 @@
#define MC_CMD_FILTER_OP_IN_MATCH_FWDEF0_WIDTH 1
#define MC_CMD_FILTER_OP_IN_MATCH_FWDEF1_LBN 11
#define MC_CMD_FILTER_OP_IN_MATCH_FWDEF1_WIDTH 1
-#define MC_CMD_FILTER_OP_IN_RX_DEST_OFST 12
-#define MC_CMD_FILTER_OP_IN_RX_DEST_DROP 0x0 /* enum */
-#define MC_CMD_FILTER_OP_IN_RX_DEST_HOST 0x1 /* enum */
-#define MC_CMD_FILTER_OP_IN_RX_DEST_MC 0x2 /* enum */
-#define MC_CMD_FILTER_OP_IN_RX_DEST_TX0 0x3 /* enum */
-#define MC_CMD_FILTER_OP_IN_RX_DEST_TX1 0x4 /* enum */
-#define MC_CMD_FILTER_OP_IN_RX_QUEUE_OFST 16
-#define MC_CMD_FILTER_OP_IN_RX_FLAGS_OFST 20
-#define MC_CMD_FILTER_OP_IN_RX_FLAG_RSS_LBN 0
-#define MC_CMD_FILTER_OP_IN_RX_FLAG_RSS_WIDTH 1
-#define MC_CMD_FILTER_OP_IN_RSS_CONTEXT_OFST 24
-#define MC_CMD_FILTER_OP_IN_TX_DOMAIN_OFST 28
-#define MC_CMD_FILTER_OP_IN_TX_DEST_OFST 32
+#define MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_MCAST_DST_LBN 30
+#define MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_MCAST_DST_WIDTH 1
+#define MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_UCAST_DST_LBN 31
+#define MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_UCAST_DST_WIDTH 1
+/* receive destination */
+#define MC_CMD_FILTER_OP_IN_RX_DEST_OFST 20
+/* enum: drop packets */
+#define MC_CMD_FILTER_OP_IN_RX_DEST_DROP 0x0
+/* enum: receive to host */
+#define MC_CMD_FILTER_OP_IN_RX_DEST_HOST 0x1
+/* enum: receive to MC */
+#define MC_CMD_FILTER_OP_IN_RX_DEST_MC 0x2
+/* enum: loop back to TXDP 0 */
+#define MC_CMD_FILTER_OP_IN_RX_DEST_TX0 0x3
+/* enum: loop back to TXDP 1 */
+#define MC_CMD_FILTER_OP_IN_RX_DEST_TX1 0x4
+/* receive queue handle (for multiple queue modes, this is the base queue) */
+#define MC_CMD_FILTER_OP_IN_RX_QUEUE_OFST 24
+/* receive mode */
+#define MC_CMD_FILTER_OP_IN_RX_MODE_OFST 28
+/* enum: receive to just the specified queue */
+#define MC_CMD_FILTER_OP_IN_RX_MODE_SIMPLE 0x0
+/* enum: receive to multiple queues using RSS context */
+#define MC_CMD_FILTER_OP_IN_RX_MODE_RSS 0x1
+/* enum: receive to multiple queues using .1p mapping */
+#define MC_CMD_FILTER_OP_IN_RX_MODE_DOT1P_MAPPING 0x2
+/* enum: install a filter entry that will never match; for test purposes only
+ */
+#define MC_CMD_FILTER_OP_IN_RX_MODE_TEST_NEVER_MATCH 0x80000000
+/* RSS context (for RX_MODE_RSS) or .1p mapping handle (for
+ * RX_MODE_DOT1P_MAPPING), as returned by MC_CMD_RSS_CONTEXT_ALLOC or
+ * MC_CMD_DOT1P_MAPPING_ALLOC.
+ */
+#define MC_CMD_FILTER_OP_IN_RX_CONTEXT_OFST 32
+/* transmit domain (reserved; set to 0) */
+#define MC_CMD_FILTER_OP_IN_TX_DOMAIN_OFST 36
+/* transmit destination (either set the MAC and/or PM bits for explicit
+ * control, or set this field to TX_DEST_DEFAULT for sensible default
+ * behaviour)
+ */
+#define MC_CMD_FILTER_OP_IN_TX_DEST_OFST 40
+/* enum: request default behaviour (based on filter type) */
+#define MC_CMD_FILTER_OP_IN_TX_DEST_DEFAULT 0xffffffff
#define MC_CMD_FILTER_OP_IN_TX_DEST_MAC_LBN 0
#define MC_CMD_FILTER_OP_IN_TX_DEST_MAC_WIDTH 1
#define MC_CMD_FILTER_OP_IN_TX_DEST_PM_LBN 1
#define MC_CMD_FILTER_OP_IN_TX_DEST_PM_WIDTH 1
-#define MC_CMD_FILTER_OP_IN_SRC_MAC_OFST 36
+/* source MAC address to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_IN_SRC_MAC_OFST 44
#define MC_CMD_FILTER_OP_IN_SRC_MAC_LEN 6
-#define MC_CMD_FILTER_OP_IN_SRC_PORT_OFST 42
+/* source port to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_IN_SRC_PORT_OFST 50
#define MC_CMD_FILTER_OP_IN_SRC_PORT_LEN 2
-#define MC_CMD_FILTER_OP_IN_DST_MAC_OFST 44
+/* destination MAC address to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_IN_DST_MAC_OFST 52
#define MC_CMD_FILTER_OP_IN_DST_MAC_LEN 6
-#define MC_CMD_FILTER_OP_IN_DST_PORT_OFST 50
+/* destination port to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_IN_DST_PORT_OFST 58
#define MC_CMD_FILTER_OP_IN_DST_PORT_LEN 2
-#define MC_CMD_FILTER_OP_IN_ETHER_TYPE_OFST 52
+/* Ethernet type to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_IN_ETHER_TYPE_OFST 60
#define MC_CMD_FILTER_OP_IN_ETHER_TYPE_LEN 2
-#define MC_CMD_FILTER_OP_IN_INNER_VLAN_OFST 54
+/* Inner VLAN tag to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_IN_INNER_VLAN_OFST 62
#define MC_CMD_FILTER_OP_IN_INNER_VLAN_LEN 2
-#define MC_CMD_FILTER_OP_IN_OUTER_VLAN_OFST 56
+/* Outer VLAN tag to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_IN_OUTER_VLAN_OFST 64
#define MC_CMD_FILTER_OP_IN_OUTER_VLAN_LEN 2
-#define MC_CMD_FILTER_OP_IN_IP_PROTO_OFST 58
+/* IP protocol to match (in low byte; set high byte to 0) */
+#define MC_CMD_FILTER_OP_IN_IP_PROTO_OFST 66
#define MC_CMD_FILTER_OP_IN_IP_PROTO_LEN 2
-#define MC_CMD_FILTER_OP_IN_FWDEF0_OFST 60
-#define MC_CMD_FILTER_OP_IN_FWDEF1_OFST 64
-#define MC_CMD_FILTER_OP_IN_SRC_IP_OFST 68
+/* Firmware defined register 0 to match (reserved; set to 0) */
+#define MC_CMD_FILTER_OP_IN_FWDEF0_OFST 68
+/* Firmware defined register 1 to match (reserved; set to 0) */
+#define MC_CMD_FILTER_OP_IN_FWDEF1_OFST 72
+/* source IP address to match (as bytes in network order; set last 12 bytes to
+ * 0 for IPv4 address)
+ */
+#define MC_CMD_FILTER_OP_IN_SRC_IP_OFST 76
#define MC_CMD_FILTER_OP_IN_SRC_IP_LEN 16
-#define MC_CMD_FILTER_OP_IN_DST_IP_OFST 84
+/* destination IP address to match (as bytes in network order; set last 12
+ * bytes to 0 for IPv4 address)
+ */
+#define MC_CMD_FILTER_OP_IN_DST_IP_OFST 92
#define MC_CMD_FILTER_OP_IN_DST_IP_LEN 16
+/* MC_CMD_FILTER_OP_EXT_IN msgrequest: Extension to MC_CMD_FILTER_OP_IN to
+ * include handling of VXLAN/NVGRE encapsulated frame filtering (which is
+ * supported on Medford only).
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_LEN 172
+/* identifies the type of operation requested */
+#define MC_CMD_FILTER_OP_EXT_IN_OP_OFST 0
+/* Enum values, see field(s): */
+/* MC_CMD_FILTER_OP_IN/OP */
+/* filter handle (for remove / unsubscribe operations) */
+#define MC_CMD_FILTER_OP_EXT_IN_HANDLE_OFST 4
+#define MC_CMD_FILTER_OP_EXT_IN_HANDLE_LEN 8
+#define MC_CMD_FILTER_OP_EXT_IN_HANDLE_LO_OFST 4
+#define MC_CMD_FILTER_OP_EXT_IN_HANDLE_HI_OFST 8
+/* The port ID associated with the v-adaptor which should contain this filter.
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_PORT_ID_OFST 12
+/* fields to include in match criteria */
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_FIELDS_OFST 16
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_IP_LBN 0
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_IP_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_DST_IP_LBN 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_DST_IP_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_MAC_LBN 2
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_PORT_LBN 3
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_SRC_PORT_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_DST_MAC_LBN 4
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_DST_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_DST_PORT_LBN 5
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_DST_PORT_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_ETHER_TYPE_LBN 6
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_ETHER_TYPE_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_INNER_VLAN_LBN 7
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_INNER_VLAN_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_OUTER_VLAN_LBN 8
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_OUTER_VLAN_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IP_PROTO_LBN 9
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IP_PROTO_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_FWDEF0_LBN 10
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_FWDEF0_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_VNI_OR_VSID_LBN 11
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_VNI_OR_VSID_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_SRC_IP_LBN 12
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_SRC_IP_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_DST_IP_LBN 13
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_DST_IP_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_SRC_MAC_LBN 14
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_SRC_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_SRC_PORT_LBN 15
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_SRC_PORT_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_DST_MAC_LBN 16
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_DST_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_DST_PORT_LBN 17
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_DST_PORT_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_ETHER_TYPE_LBN 18
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_ETHER_TYPE_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_INNER_VLAN_LBN 19
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_INNER_VLAN_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_OUTER_VLAN_LBN 20
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_OUTER_VLAN_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_IP_PROTO_LBN 21
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_IP_PROTO_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_FWDEF0_LBN 22
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_FWDEF0_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_FWDEF1_LBN 23
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_FWDEF1_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_MCAST_DST_LBN 24
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_MCAST_DST_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_UCAST_DST_LBN 25
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_IFRM_UNKNOWN_UCAST_DST_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_MCAST_DST_LBN 30
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_MCAST_DST_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_UCAST_DST_LBN 31
+#define MC_CMD_FILTER_OP_EXT_IN_MATCH_UNKNOWN_UCAST_DST_WIDTH 1
+/* receive destination */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_OFST 20
+/* enum: drop packets */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_DROP 0x0
+/* enum: receive to host */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_HOST 0x1
+/* enum: receive to MC */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_MC 0x2
+/* enum: loop back to TXDP 0 */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_TX0 0x3
+/* enum: loop back to TXDP 1 */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_DEST_TX1 0x4
+/* receive queue handle (for multiple queue modes, this is the base queue) */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_QUEUE_OFST 24
+/* receive mode */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_OFST 28
+/* enum: receive to just the specified queue */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_SIMPLE 0x0
+/* enum: receive to multiple queues using RSS context */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_RSS 0x1
+/* enum: receive to multiple queues using .1p mapping */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_DOT1P_MAPPING 0x2
+/* enum: install a filter entry that will never match; for test purposes only
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_MODE_TEST_NEVER_MATCH 0x80000000
+/* RSS context (for RX_MODE_RSS) or .1p mapping handle (for
+ * RX_MODE_DOT1P_MAPPING), as returned by MC_CMD_RSS_CONTEXT_ALLOC or
+ * MC_CMD_DOT1P_MAPPING_ALLOC.
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_RX_CONTEXT_OFST 32
+/* transmit domain (reserved; set to 0) */
+#define MC_CMD_FILTER_OP_EXT_IN_TX_DOMAIN_OFST 36
+/* transmit destination (either set the MAC and/or PM bits for explicit
+ * control, or set this field to TX_DEST_DEFAULT for sensible default
+ * behaviour)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_OFST 40
+/* enum: request default behaviour (based on filter type) */
+#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_DEFAULT 0xffffffff
+#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_MAC_LBN 0
+#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_MAC_WIDTH 1
+#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_PM_LBN 1
+#define MC_CMD_FILTER_OP_EXT_IN_TX_DEST_PM_WIDTH 1
+/* source MAC address to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_EXT_IN_SRC_MAC_OFST 44
+#define MC_CMD_FILTER_OP_EXT_IN_SRC_MAC_LEN 6
+/* source port to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_EXT_IN_SRC_PORT_OFST 50
+#define MC_CMD_FILTER_OP_EXT_IN_SRC_PORT_LEN 2
+/* destination MAC address to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_EXT_IN_DST_MAC_OFST 52
+#define MC_CMD_FILTER_OP_EXT_IN_DST_MAC_LEN 6
+/* destination port to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_EXT_IN_DST_PORT_OFST 58
+#define MC_CMD_FILTER_OP_EXT_IN_DST_PORT_LEN 2
+/* Ethernet type to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_EXT_IN_ETHER_TYPE_OFST 60
+#define MC_CMD_FILTER_OP_EXT_IN_ETHER_TYPE_LEN 2
+/* Inner VLAN tag to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_EXT_IN_INNER_VLAN_OFST 62
+#define MC_CMD_FILTER_OP_EXT_IN_INNER_VLAN_LEN 2
+/* Outer VLAN tag to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_EXT_IN_OUTER_VLAN_OFST 64
+#define MC_CMD_FILTER_OP_EXT_IN_OUTER_VLAN_LEN 2
+/* IP protocol to match (in low byte; set high byte to 0) */
+#define MC_CMD_FILTER_OP_EXT_IN_IP_PROTO_OFST 66
+#define MC_CMD_FILTER_OP_EXT_IN_IP_PROTO_LEN 2
+/* Firmware defined register 0 to match (reserved; set to 0) */
+#define MC_CMD_FILTER_OP_EXT_IN_FWDEF0_OFST 68
+/* VNI (for VXLAN/Geneve, when IP protocol is UDP) or VSID (for NVGRE, when IP
+ * protocol is GRE) to match (as bytes in network order; set last byte to 0 for
+ * VXLAN/NVGRE, or 1 for Geneve)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_VNI_OR_VSID_OFST 72
+#define MC_CMD_FILTER_OP_EXT_IN_VNI_VALUE_LBN 0
+#define MC_CMD_FILTER_OP_EXT_IN_VNI_VALUE_WIDTH 24
+#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_LBN 24
+#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_WIDTH 8
+/* enum: Match VXLAN traffic with this VNI */
+#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_VXLAN 0x0
+/* enum: Match Geneve traffic with this VNI */
+#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_GENEVE 0x1
+/* enum: Reserved for experimental development use */
+#define MC_CMD_FILTER_OP_EXT_IN_VNI_TYPE_EXPERIMENTAL 0xfe
+#define MC_CMD_FILTER_OP_EXT_IN_VSID_VALUE_LBN 0
+#define MC_CMD_FILTER_OP_EXT_IN_VSID_VALUE_WIDTH 24
+#define MC_CMD_FILTER_OP_EXT_IN_VSID_TYPE_LBN 24
+#define MC_CMD_FILTER_OP_EXT_IN_VSID_TYPE_WIDTH 8
+/* enum: Match NVGRE traffic with this VSID */
+#define MC_CMD_FILTER_OP_EXT_IN_VSID_TYPE_NVGRE 0x0
+/* source IP address to match (as bytes in network order; set last 12 bytes to
+ * 0 for IPv4 address)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_SRC_IP_OFST 76
+#define MC_CMD_FILTER_OP_EXT_IN_SRC_IP_LEN 16
+/* destination IP address to match (as bytes in network order; set last 12
+ * bytes to 0 for IPv4 address)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_DST_IP_OFST 92
+#define MC_CMD_FILTER_OP_EXT_IN_DST_IP_LEN 16
+/* VXLAN/NVGRE inner frame source MAC address to match (as bytes in network
+ * order)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_SRC_MAC_OFST 108
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_SRC_MAC_LEN 6
+/* VXLAN/NVGRE inner frame source port to match (as bytes in network order) */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_SRC_PORT_OFST 114
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_SRC_PORT_LEN 2
+/* VXLAN/NVGRE inner frame destination MAC address to match (as bytes in
+ * network order)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_DST_MAC_OFST 116
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_DST_MAC_LEN 6
+/* VXLAN/NVGRE inner frame destination port to match (as bytes in network
+ * order)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_DST_PORT_OFST 122
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_DST_PORT_LEN 2
+/* VXLAN/NVGRE inner frame Ethernet type to match (as bytes in network order)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_ETHER_TYPE_OFST 124
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_ETHER_TYPE_LEN 2
+/* VXLAN/NVGRE inner frame Inner VLAN tag to match (as bytes in network order)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_INNER_VLAN_OFST 126
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_INNER_VLAN_LEN 2
+/* VXLAN/NVGRE inner frame Outer VLAN tag to match (as bytes in network order)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_OUTER_VLAN_OFST 128
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_OUTER_VLAN_LEN 2
+/* VXLAN/NVGRE inner frame IP protocol to match (in low byte; set high byte to
+ * 0)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_IP_PROTO_OFST 130
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_IP_PROTO_LEN 2
+/* VXLAN/NVGRE inner frame Firmware defined register 0 to match (reserved; set
+ * to 0)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_FWDEF0_OFST 132
+/* VXLAN/NVGRE inner frame Firmware defined register 1 to match (reserved; set
+ * to 0)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_FWDEF1_OFST 136
+/* VXLAN/NVGRE inner frame source IP address to match (as bytes in network
+ * order; set last 12 bytes to 0 for IPv4 address)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_SRC_IP_OFST 140
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_SRC_IP_LEN 16
+/* VXLAN/NVGRE inner frame destination IP address to match (as bytes in network
+ * order; set last 12 bytes to 0 for IPv4 address)
+ */
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_DST_IP_OFST 156
+#define MC_CMD_FILTER_OP_EXT_IN_IFRM_DST_IP_LEN 16
+
/* MC_CMD_FILTER_OP_OUT msgresponse */
-#define MC_CMD_FILTER_OP_OUT_LEN 8
+#define MC_CMD_FILTER_OP_OUT_LEN 12
+/* identifies the type of operation requested */
#define MC_CMD_FILTER_OP_OUT_OP_OFST 0
-#define MC_CMD_FILTER_OP_OUT_OP_INSERT 0x0 /* enum */
-#define MC_CMD_FILTER_OP_OUT_OP_REMOVE 0x1 /* enum */
-#define MC_CMD_FILTER_OP_OUT_OP_SUBSCRIBE 0x2 /* enum */
-#define MC_CMD_FILTER_OP_OUT_OP_UNSUBSCRIBE 0x3 /* enum */
+/* Enum values, see field(s): */
+/* MC_CMD_FILTER_OP_IN/OP */
+/* Returned filter handle (for insert / subscribe operations). Note that these
+ * handles should be considered opaque to the host, although a value of
+ * 0xFFFFFFFF_FFFFFFFF is guaranteed never to be a valid handle.
+ */
#define MC_CMD_FILTER_OP_OUT_HANDLE_OFST 4
+#define MC_CMD_FILTER_OP_OUT_HANDLE_LEN 8
+#define MC_CMD_FILTER_OP_OUT_HANDLE_LO_OFST 4
+#define MC_CMD_FILTER_OP_OUT_HANDLE_HI_OFST 8
+/* enum: guaranteed invalid filter handle (low 32 bits) */
+#define MC_CMD_FILTER_OP_OUT_HANDLE_LO_INVALID 0xffffffff
+/* enum: guaranteed invalid filter handle (high 32 bits) */
+#define MC_CMD_FILTER_OP_OUT_HANDLE_HI_INVALID 0xffffffff
+
+/* MC_CMD_FILTER_OP_EXT_OUT msgresponse */
+#define MC_CMD_FILTER_OP_EXT_OUT_LEN 12
+/* identifies the type of operation requested */
+#define MC_CMD_FILTER_OP_EXT_OUT_OP_OFST 0
+/* Enum values, see field(s): */
+/* MC_CMD_FILTER_OP_EXT_IN/OP */
+/* Returned filter handle (for insert / subscribe operations). Note that these
+ * handles should be considered opaque to the host, although a value of
+ * 0xFFFFFFFF_FFFFFFFF is guaranteed never to be a valid handle.
+ */
+#define MC_CMD_FILTER_OP_EXT_OUT_HANDLE_OFST 4
+#define MC_CMD_FILTER_OP_EXT_OUT_HANDLE_LEN 8
+#define MC_CMD_FILTER_OP_EXT_OUT_HANDLE_LO_OFST 4
+#define MC_CMD_FILTER_OP_EXT_OUT_HANDLE_HI_OFST 8
+/* Enum values, see field(s): */
+/* MC_CMD_FILTER_OP_OUT/HANDLE */
+
+
+/***********************************/
+/* MC_CMD_GET_PARSER_DISP_INFO
+ * Get information related to the parser-dispatcher subsystem
+ */
+#define MC_CMD_GET_PARSER_DISP_INFO 0xe4
+#undef MC_CMD_0xe4_PRIVILEGE_CTG
+
+#define MC_CMD_0xe4_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_PARSER_DISP_INFO_IN msgrequest */
+#define MC_CMD_GET_PARSER_DISP_INFO_IN_LEN 4
+/* identifies the type of operation requested */
+#define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_OFST 0
+/* enum: read the list of supported RX filter matches */
+#define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SUPPORTED_RX_MATCHES 0x1
+/* enum: read flags indicating restrictions on filter insertion for the calling
+ * client
+ */
+#define MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_RESTRICTIONS 0x2
+
+/* MC_CMD_GET_PARSER_DISP_INFO_OUT msgresponse */
+#define MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMIN 8
+#define MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMAX 252
+#define MC_CMD_GET_PARSER_DISP_INFO_OUT_LEN(num) (8+4*(num))
+/* identifies the type of operation requested */
+#define MC_CMD_GET_PARSER_DISP_INFO_OUT_OP_OFST 0
+/* Enum values, see field(s): */
+/* MC_CMD_GET_PARSER_DISP_INFO_IN/OP */
+/* number of supported match types */
+#define MC_CMD_GET_PARSER_DISP_INFO_OUT_NUM_SUPPORTED_MATCHES_OFST 4
+/* array of supported match types (valid MATCH_FIELDS values for
+ * MC_CMD_FILTER_OP) sorted in decreasing priority order
+ */
+#define MC_CMD_GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES_OFST 8
+#define MC_CMD_GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES_LEN 4
+#define MC_CMD_GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES_MINNUM 0
+#define MC_CMD_GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES_MAXNUM 61
+
+/* MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT msgresponse */
+#define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_LEN 8
+/* identifies the type of operation requested */
+#define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_OP_OFST 0
+/* Enum values, see field(s): */
+/* MC_CMD_GET_PARSER_DISP_INFO_IN/OP */
+/* bitfield of filter insertion restrictions */
+#define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_RESTRICTION_FLAGS_OFST 4
+#define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_DST_IP_MCAST_ONLY_LBN 0
+#define MC_CMD_GET_PARSER_DISP_RESTRICTIONS_OUT_DST_IP_MCAST_ONLY_WIDTH 1
+
+
+/***********************************/
+/* MC_CMD_PARSER_DISP_RW
+ * Direct read/write of parser-dispatcher state (DICPUs and LUE) for debugging
+ */
+#define MC_CMD_PARSER_DISP_RW 0xe5
+#undef MC_CMD_0xe5_PRIVILEGE_CTG
+
+#define MC_CMD_0xe5_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_PARSER_DISP_RW_IN msgrequest */
+#define MC_CMD_PARSER_DISP_RW_IN_LEN 32
+/* identifies the target of the operation */
+#define MC_CMD_PARSER_DISP_RW_IN_TARGET_OFST 0
+/* enum: RX dispatcher CPU */
+#define MC_CMD_PARSER_DISP_RW_IN_RX_DICPU 0x0
+/* enum: TX dispatcher CPU */
+#define MC_CMD_PARSER_DISP_RW_IN_TX_DICPU 0x1
+/* enum: Lookup engine (with original metadata format) */
+#define MC_CMD_PARSER_DISP_RW_IN_LUE 0x2
+/* enum: Lookup engine (with requested metadata format) */
+#define MC_CMD_PARSER_DISP_RW_IN_LUE_VERSIONED_METADATA 0x3
+/* identifies the type of operation requested */
+#define MC_CMD_PARSER_DISP_RW_IN_OP_OFST 4
+/* enum: read a word of DICPU DMEM or a LUE entry */
+#define MC_CMD_PARSER_DISP_RW_IN_READ 0x0
+/* enum: write a word of DICPU DMEM or a LUE entry */
+#define MC_CMD_PARSER_DISP_RW_IN_WRITE 0x1
+/* enum: read-modify-write a word of DICPU DMEM (not valid for LUE) */
+#define MC_CMD_PARSER_DISP_RW_IN_RMW 0x2
+/* data memory address or LUE index */
+#define MC_CMD_PARSER_DISP_RW_IN_ADDRESS_OFST 8
+/* value to write (for DMEM writes) */
+#define MC_CMD_PARSER_DISP_RW_IN_DMEM_WRITE_VALUE_OFST 12
+/* XOR value (for DMEM read-modify-writes: new = (old & mask) ^ value) */
+#define MC_CMD_PARSER_DISP_RW_IN_DMEM_RMW_XOR_VALUE_OFST 12
+/* AND mask (for DMEM read-modify-writes: new = (old & mask) ^ value) */
+#define MC_CMD_PARSER_DISP_RW_IN_DMEM_RMW_AND_MASK_OFST 16
+/* metadata format (for LUE reads using LUE_VERSIONED_METADATA) */
+#define MC_CMD_PARSER_DISP_RW_IN_LUE_READ_METADATA_VERSION_OFST 12
+/* value to write (for LUE writes) */
+#define MC_CMD_PARSER_DISP_RW_IN_LUE_WRITE_VALUE_OFST 12
+#define MC_CMD_PARSER_DISP_RW_IN_LUE_WRITE_VALUE_LEN 20
+
+/* MC_CMD_PARSER_DISP_RW_OUT msgresponse */
+#define MC_CMD_PARSER_DISP_RW_OUT_LEN 52
+/* value read (for DMEM reads) */
+#define MC_CMD_PARSER_DISP_RW_OUT_DMEM_READ_VALUE_OFST 0
+/* value read (for LUE reads) */
+#define MC_CMD_PARSER_DISP_RW_OUT_LUE_READ_VALUE_OFST 0
+#define MC_CMD_PARSER_DISP_RW_OUT_LUE_READ_VALUE_LEN 20
+/* up to 8 32-bit words of additional soft state from the LUE manager (the
+ * exact content is firmware-dependent and intended only for debug use)
+ */
+#define MC_CMD_PARSER_DISP_RW_OUT_LUE_MGR_STATE_OFST 20
+#define MC_CMD_PARSER_DISP_RW_OUT_LUE_MGR_STATE_LEN 32
/***********************************/
-/* MC_CMD_SET_PF_COUNT
+/* MC_CMD_GET_PF_COUNT
+ * Get number of PFs on the device.
*/
-#define MC_CMD_SET_PF_COUNT 0x62
+#define MC_CMD_GET_PF_COUNT 0xb6
+#undef MC_CMD_0xb6_PRIVILEGE_CTG
+
+#define MC_CMD_0xb6_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_PF_COUNT_IN msgrequest */
+#define MC_CMD_GET_PF_COUNT_IN_LEN 0
+
+/* MC_CMD_GET_PF_COUNT_OUT msgresponse */
+#define MC_CMD_GET_PF_COUNT_OUT_LEN 1
+/* Identifies the number of PFs on the device. */
+#define MC_CMD_GET_PF_COUNT_OUT_PF_COUNT_OFST 0
+#define MC_CMD_GET_PF_COUNT_OUT_PF_COUNT_LEN 1
+
+
+/***********************************/
+/* MC_CMD_SET_PF_COUNT
+ * Set number of PFs on the device.
+ */
+#define MC_CMD_SET_PF_COUNT 0xb7
/* MC_CMD_SET_PF_COUNT_IN msgrequest */
#define MC_CMD_SET_PF_COUNT_IN_LEN 4
+/* New number of PFs on the device. */
#define MC_CMD_SET_PF_COUNT_IN_PF_COUNT_OFST 0
/* MC_CMD_SET_PF_COUNT_OUT msgresponse */
@@ -4860,25 +8796,35 @@
/***********************************/
-/* MC_CMD_GET_PORT_ASSIGNMENT
+/* MC_CMD_GET_PORT_ASSIGNMENT
+ * Get port assignment for current PCI function.
*/
-#define MC_CMD_GET_PORT_ASSIGNMENT 0x63
+#define MC_CMD_GET_PORT_ASSIGNMENT 0xb8
+#undef MC_CMD_0xb8_PRIVILEGE_CTG
+
+#define MC_CMD_0xb8_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_GET_PORT_ASSIGNMENT_IN msgrequest */
#define MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN 0
/* MC_CMD_GET_PORT_ASSIGNMENT_OUT msgresponse */
#define MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN 4
+/* Identifies the port assignment for this function. */
#define MC_CMD_GET_PORT_ASSIGNMENT_OUT_PORT_OFST 0
/***********************************/
-/* MC_CMD_SET_PORT_ASSIGNMENT
+/* MC_CMD_SET_PORT_ASSIGNMENT
+ * Set port assignment for current PCI function.
*/
-#define MC_CMD_SET_PORT_ASSIGNMENT 0x64
+#define MC_CMD_SET_PORT_ASSIGNMENT 0xb9
+#undef MC_CMD_0xb9_PRIVILEGE_CTG
+
+#define MC_CMD_0xb9_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_SET_PORT_ASSIGNMENT_IN msgrequest */
#define MC_CMD_SET_PORT_ASSIGNMENT_IN_LEN 4
+/* Identifies the port assignment for this function. */
#define MC_CMD_SET_PORT_ASSIGNMENT_IN_PORT_OFST 0
/* MC_CMD_SET_PORT_ASSIGNMENT_OUT msgresponse */
@@ -4886,22 +8832,53 @@
/***********************************/
-/* MC_CMD_ALLOC_VIS
+/* MC_CMD_ALLOC_VIS
+ * Allocate VIs for current PCI function.
*/
-#define MC_CMD_ALLOC_VIS 0x65
+#define MC_CMD_ALLOC_VIS 0x8b
+#undef MC_CMD_0x8b_PRIVILEGE_CTG
-/* MC_CMD_ALLOC_VIS_IN msgrequest */
-#define MC_CMD_ALLOC_VIS_IN_LEN 4
-#define MC_CMD_ALLOC_VIS_IN_VI_COUNT_OFST 0
+#define MC_CMD_0x8b_PRIVILEGE_CTG SRIOV_CTG_GENERAL
-/* MC_CMD_ALLOC_VIS_OUT msgresponse */
-#define MC_CMD_ALLOC_VIS_OUT_LEN 0
+/* MC_CMD_ALLOC_VIS_IN msgrequest */
+#define MC_CMD_ALLOC_VIS_IN_LEN 8
+/* The minimum number of VIs that is acceptable */
+#define MC_CMD_ALLOC_VIS_IN_MIN_VI_COUNT_OFST 0
+/* The maximum number of VIs that would be useful */
+#define MC_CMD_ALLOC_VIS_IN_MAX_VI_COUNT_OFST 4
+
+/* MC_CMD_ALLOC_VIS_OUT msgresponse: Huntington-compatible VI_ALLOC request.
+ * Use extended version in new code.
+ */
+#define MC_CMD_ALLOC_VIS_OUT_LEN 8
+/* The number of VIs allocated on this function */
+#define MC_CMD_ALLOC_VIS_OUT_VI_COUNT_OFST 0
+/* The base absolute VI number allocated to this function. Required to
+ * correctly interpret wakeup events.
+ */
+#define MC_CMD_ALLOC_VIS_OUT_VI_BASE_OFST 4
+
+/* MC_CMD_ALLOC_VIS_EXT_OUT msgresponse */
+#define MC_CMD_ALLOC_VIS_EXT_OUT_LEN 12
+/* The number of VIs allocated on this function */
+#define MC_CMD_ALLOC_VIS_EXT_OUT_VI_COUNT_OFST 0
+/* The base absolute VI number allocated to this function. Required to
+ * correctly interpret wakeup events.
+ */
+#define MC_CMD_ALLOC_VIS_EXT_OUT_VI_BASE_OFST 4
+/* Function's port vi_shift value (always 0 on Huntington) */
+#define MC_CMD_ALLOC_VIS_EXT_OUT_VI_SHIFT_OFST 8
/***********************************/
-/* MC_CMD_FREE_VIS
+/* MC_CMD_FREE_VIS
+ * Free VIs for current PCI function. Any linked PIO buffers will be unlinked,
+ * but not freed.
*/
-#define MC_CMD_FREE_VIS 0x66
+#define MC_CMD_FREE_VIS 0x8c
+#undef MC_CMD_0x8c_PRIVILEGE_CTG
+
+#define MC_CMD_0x8c_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_FREE_VIS_IN msgrequest */
#define MC_CMD_FREE_VIS_IN_LEN 0
@@ -4911,37 +8888,57 @@
/***********************************/
-/* MC_CMD_GET_SRIOV_CFG
+/* MC_CMD_GET_SRIOV_CFG
+ * Get SRIOV config for this PF.
*/
-#define MC_CMD_GET_SRIOV_CFG 0x67
+#define MC_CMD_GET_SRIOV_CFG 0xba
+#undef MC_CMD_0xba_PRIVILEGE_CTG
+
+#define MC_CMD_0xba_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_GET_SRIOV_CFG_IN msgrequest */
#define MC_CMD_GET_SRIOV_CFG_IN_LEN 0
/* MC_CMD_GET_SRIOV_CFG_OUT msgresponse */
#define MC_CMD_GET_SRIOV_CFG_OUT_LEN 20
+/* Number of VFs currently enabled. */
#define MC_CMD_GET_SRIOV_CFG_OUT_VF_CURRENT_OFST 0
+/* Max number of VFs before sriov stride and offset may need to be changed. */
#define MC_CMD_GET_SRIOV_CFG_OUT_VF_MAX_OFST 4
#define MC_CMD_GET_SRIOV_CFG_OUT_FLAGS_OFST 8
#define MC_CMD_GET_SRIOV_CFG_OUT_VF_ENABLED_LBN 0
#define MC_CMD_GET_SRIOV_CFG_OUT_VF_ENABLED_WIDTH 1
+/* RID offset of first VF from PF. */
#define MC_CMD_GET_SRIOV_CFG_OUT_VF_OFFSET_OFST 12
+/* RID offset of each subsequent VF from the previous. */
#define MC_CMD_GET_SRIOV_CFG_OUT_VF_STRIDE_OFST 16
/***********************************/
-/* MC_CMD_SET_SRIOV_CFG
+/* MC_CMD_SET_SRIOV_CFG
+ * Set SRIOV config for this PF.
*/
-#define MC_CMD_SET_SRIOV_CFG 0x68
+#define MC_CMD_SET_SRIOV_CFG 0xbb
+#undef MC_CMD_0xbb_PRIVILEGE_CTG
+
+#define MC_CMD_0xbb_PRIVILEGE_CTG SRIOV_CTG_ADMIN
/* MC_CMD_SET_SRIOV_CFG_IN msgrequest */
#define MC_CMD_SET_SRIOV_CFG_IN_LEN 20
+/* Number of VFs currently enabled. */
#define MC_CMD_SET_SRIOV_CFG_IN_VF_CURRENT_OFST 0
+/* Max number of VFs before sriov stride and offset may need to be changed. */
#define MC_CMD_SET_SRIOV_CFG_IN_VF_MAX_OFST 4
#define MC_CMD_SET_SRIOV_CFG_IN_FLAGS_OFST 8
#define MC_CMD_SET_SRIOV_CFG_IN_VF_ENABLED_LBN 0
#define MC_CMD_SET_SRIOV_CFG_IN_VF_ENABLED_WIDTH 1
+/* RID offset of first VF from PF, or 0 for no change, or
+ * MC_CMD_RESOURCE_INSTANCE_ANY to allow the system to allocate an offset.
+ */
#define MC_CMD_SET_SRIOV_CFG_IN_VF_OFFSET_OFST 12
+/* RID offset of each subsequent VF from the previous, 0 for no change, or
+ * MC_CMD_RESOURCE_INSTANCE_ANY to allow the system to allocate a stride.
+ */
#define MC_CMD_SET_SRIOV_CFG_IN_VF_STRIDE_OFST 16
/* MC_CMD_SET_SRIOV_CFG_OUT msgresponse */
@@ -4949,68 +8946,172 @@
/***********************************/
-/* MC_CMD_GET_VI_COUNT
+/* MC_CMD_GET_VI_ALLOC_INFO
+ * Get information about number of VI's and base VI number allocated to this
+ * function.
*/
-#define MC_CMD_GET_VI_COUNT 0x69
+#define MC_CMD_GET_VI_ALLOC_INFO 0x8d
+#undef MC_CMD_0x8d_PRIVILEGE_CTG
-/* MC_CMD_GET_VI_COUNT_IN msgrequest */
-#define MC_CMD_GET_VI_COUNT_IN_LEN 0
+#define MC_CMD_0x8d_PRIVILEGE_CTG SRIOV_CTG_GENERAL
-/* MC_CMD_GET_VI_COUNT_OUT msgresponse */
-#define MC_CMD_GET_VI_COUNT_OUT_LEN 4
-#define MC_CMD_GET_VI_COUNT_OUT_VI_COUNT_OFST 0
+/* MC_CMD_GET_VI_ALLOC_INFO_IN msgrequest */
+#define MC_CMD_GET_VI_ALLOC_INFO_IN_LEN 0
-
-/***********************************/
-/* MC_CMD_GET_VECTOR_CFG
+/* MC_CMD_GET_VI_ALLOC_INFO_OUT msgresponse */
+#define MC_CMD_GET_VI_ALLOC_INFO_OUT_LEN 12
+/* The number of VIs allocated on this function */
+#define MC_CMD_GET_VI_ALLOC_INFO_OUT_VI_COUNT_OFST 0
+/* The base absolute VI number allocated to this function. Required to
+ * correctly interpret wakeup events.
*/
-#define MC_CMD_GET_VECTOR_CFG 0x70
-
-/* MC_CMD_GET_VECTOR_CFG_IN msgrequest */
-#define MC_CMD_GET_VECTOR_CFG_IN_LEN 0
-
-/* MC_CMD_GET_VECTOR_CFG_OUT msgresponse */
-#define MC_CMD_GET_VECTOR_CFG_OUT_LEN 12
-#define MC_CMD_GET_VECTOR_CFG_OUT_VEC_BASE_OFST 0
-#define MC_CMD_GET_VECTOR_CFG_OUT_VECS_PER_PF_OFST 4
-#define MC_CMD_GET_VECTOR_CFG_OUT_VECS_PER_VF_OFST 8
+#define MC_CMD_GET_VI_ALLOC_INFO_OUT_VI_BASE_OFST 4
+/* Function's port vi_shift value (always 0 on Huntington) */
+#define MC_CMD_GET_VI_ALLOC_INFO_OUT_VI_SHIFT_OFST 8
/***********************************/
-/* MC_CMD_SET_VECTOR_CFG
+/* MC_CMD_DUMP_VI_STATE
+ * For CmdClient use. Dump pertinent information on a specific absolute VI.
*/
-#define MC_CMD_SET_VECTOR_CFG 0x71
-
-/* MC_CMD_SET_VECTOR_CFG_IN msgrequest */
-#define MC_CMD_SET_VECTOR_CFG_IN_LEN 12
-#define MC_CMD_SET_VECTOR_CFG_IN_VEC_BASE_OFST 0
-#define MC_CMD_SET_VECTOR_CFG_IN_VECS_PER_PF_OFST 4
-#define MC_CMD_SET_VECTOR_CFG_IN_VECS_PER_VF_OFST 8
-
-/* MC_CMD_SET_VECTOR_CFG_OUT msgresponse */
-#define MC_CMD_SET_VECTOR_CFG_OUT_LEN 0
+#define MC_CMD_DUMP_VI_STATE 0x8e
+#undef MC_CMD_0x8e_PRIVILEGE_CTG
+
+#define MC_CMD_0x8e_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_DUMP_VI_STATE_IN msgrequest */
+#define MC_CMD_DUMP_VI_STATE_IN_LEN 4
+/* The VI number to query. */
+#define MC_CMD_DUMP_VI_STATE_IN_VI_NUMBER_OFST 0
+
+/* MC_CMD_DUMP_VI_STATE_OUT msgresponse */
+#define MC_CMD_DUMP_VI_STATE_OUT_LEN 96
+/* The PF part of the function owning this VI. */
+#define MC_CMD_DUMP_VI_STATE_OUT_OWNER_PF_OFST 0
+#define MC_CMD_DUMP_VI_STATE_OUT_OWNER_PF_LEN 2
+/* The VF part of the function owning this VI. */
+#define MC_CMD_DUMP_VI_STATE_OUT_OWNER_VF_OFST 2
+#define MC_CMD_DUMP_VI_STATE_OUT_OWNER_VF_LEN 2
+/* Base of VIs allocated to this function. */
+#define MC_CMD_DUMP_VI_STATE_OUT_FUNC_VI_BASE_OFST 4
+#define MC_CMD_DUMP_VI_STATE_OUT_FUNC_VI_BASE_LEN 2
+/* Count of VIs allocated to the owner function. */
+#define MC_CMD_DUMP_VI_STATE_OUT_FUNC_VI_COUNT_OFST 6
+#define MC_CMD_DUMP_VI_STATE_OUT_FUNC_VI_COUNT_LEN 2
+/* Base interrupt vector allocated to this function. */
+#define MC_CMD_DUMP_VI_STATE_OUT_FUNC_VECTOR_BASE_OFST 8
+#define MC_CMD_DUMP_VI_STATE_OUT_FUNC_VECTOR_BASE_LEN 2
+/* Number of interrupt vectors allocated to this function. */
+#define MC_CMD_DUMP_VI_STATE_OUT_FUNC_VECTOR_COUNT_OFST 10
+#define MC_CMD_DUMP_VI_STATE_OUT_FUNC_VECTOR_COUNT_LEN 2
+/* Raw evq ptr table data. */
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EVQ_PTR_RAW_OFST 12
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EVQ_PTR_RAW_LEN 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EVQ_PTR_RAW_LO_OFST 12
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EVQ_PTR_RAW_HI_OFST 16
+/* Raw evq timer table data. */
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_TIMER_RAW_OFST 20
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_TIMER_RAW_LEN 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_TIMER_RAW_LO_OFST 20
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_TIMER_RAW_HI_OFST 24
+/* Combined metadata field. */
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_OFST 28
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_BUFS_BASE_LBN 0
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_BUFS_BASE_WIDTH 16
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_BUFS_NPAGES_LBN 16
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_BUFS_NPAGES_WIDTH 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_WKUP_REF_LBN 24
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_EV_META_WKUP_REF_WIDTH 8
+/* TXDPCPU raw table data for queue. */
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_0_OFST 32
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_0_LEN 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_0_LO_OFST 32
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_0_HI_OFST 36
+/* TXDPCPU raw table data for queue. */
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_1_OFST 40
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_1_LEN 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_1_LO_OFST 40
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_1_HI_OFST 44
+/* TXDPCPU raw table data for queue. */
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_2_OFST 48
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_2_LEN 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_2_LO_OFST 48
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_RAW_TBL_2_HI_OFST 52
+/* Combined metadata field. */
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_OFST 56
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_LEN 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_LO_OFST 56
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_HI_OFST 60
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_BUFS_BASE_LBN 0
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_BUFS_BASE_WIDTH 16
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_BUFS_NPAGES_LBN 16
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_BUFS_NPAGES_WIDTH 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_QSTATE_LBN 24
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_QSTATE_WIDTH 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_WAITCOUNT_LBN 32
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_TX_META_WAITCOUNT_WIDTH 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_PADDING_LBN 40
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_PADDING_WIDTH 24
+/* RXDPCPU raw table data for queue. */
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_0_OFST 64
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_0_LEN 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_0_LO_OFST 64
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_0_HI_OFST 68
+/* RXDPCPU raw table data for queue. */
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_1_OFST 72
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_1_LEN 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_1_LO_OFST 72
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_1_HI_OFST 76
+/* Reserved, currently 0. */
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_2_OFST 80
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_2_LEN 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_2_LO_OFST 80
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_RAW_TBL_2_HI_OFST 84
+/* Combined metadata field. */
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_OFST 88
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_LEN 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_LO_OFST 88
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_HI_OFST 92
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_BUFS_BASE_LBN 0
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_BUFS_BASE_WIDTH 16
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_BUFS_NPAGES_LBN 16
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_BUFS_NPAGES_WIDTH 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_QSTATE_LBN 24
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_QSTATE_WIDTH 8
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_WAITCOUNT_LBN 32
+#define MC_CMD_DUMP_VI_STATE_OUT_VI_RX_META_WAITCOUNT_WIDTH 8
/***********************************/
-/* MC_CMD_ALLOC_PIOBUF
+/* MC_CMD_ALLOC_PIOBUF
+ * Allocate a push I/O buffer for later use with a tx queue.
*/
-#define MC_CMD_ALLOC_PIOBUF 0x72
+#define MC_CMD_ALLOC_PIOBUF 0x8f
+#undef MC_CMD_0x8f_PRIVILEGE_CTG
+
+#define MC_CMD_0x8f_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
/* MC_CMD_ALLOC_PIOBUF_IN msgrequest */
#define MC_CMD_ALLOC_PIOBUF_IN_LEN 0
/* MC_CMD_ALLOC_PIOBUF_OUT msgresponse */
#define MC_CMD_ALLOC_PIOBUF_OUT_LEN 4
+/* Handle for allocated push I/O buffer. */
#define MC_CMD_ALLOC_PIOBUF_OUT_PIOBUF_HANDLE_OFST 0
/***********************************/
-/* MC_CMD_FREE_PIOBUF
+/* MC_CMD_FREE_PIOBUF
+ * Free a push I/O buffer.
*/
-#define MC_CMD_FREE_PIOBUF 0x73
+#define MC_CMD_FREE_PIOBUF 0x90
+#undef MC_CMD_0x90_PRIVILEGE_CTG
+
+#define MC_CMD_0x90_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
/* MC_CMD_FREE_PIOBUF_IN msgrequest */
#define MC_CMD_FREE_PIOBUF_IN_LEN 4
+/* Handle for allocated push I/O buffer. */
#define MC_CMD_FREE_PIOBUF_IN_PIOBUF_HANDLE_OFST 0
/* MC_CMD_FREE_PIOBUF_OUT msgresponse */
@@ -5018,16 +9119,499 @@
/***********************************/
-/* MC_CMD_V2_EXTN
+/* MC_CMD_GET_VI_TLP_PROCESSING
+ * Get TLP steering and ordering information for a VI.
+ */
+#define MC_CMD_GET_VI_TLP_PROCESSING 0xb0
+#undef MC_CMD_0xb0_PRIVILEGE_CTG
+
+#define MC_CMD_0xb0_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_VI_TLP_PROCESSING_IN msgrequest */
+#define MC_CMD_GET_VI_TLP_PROCESSING_IN_LEN 4
+/* VI number to get information for. */
+#define MC_CMD_GET_VI_TLP_PROCESSING_IN_INSTANCE_OFST 0
+
+/* MC_CMD_GET_VI_TLP_PROCESSING_OUT msgresponse */
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_LEN 4
+/* Transaction processing steering hint 1 for use with the Rx Queue. */
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_TPH_TAG1_RX_OFST 0
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_TPH_TAG1_RX_LEN 1
+/* Transaction processing steering hint 2 for use with the Ev Queue. */
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_TPH_TAG2_EV_OFST 1
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_TPH_TAG2_EV_LEN 1
+/* Use Relaxed ordering model for TLPs on this VI. */
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_RELAXED_ORDERING_LBN 16
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_RELAXED_ORDERING_WIDTH 1
+/* Use ID based ordering for TLPs on this VI. */
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_ID_BASED_ORDERING_LBN 17
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_ID_BASED_ORDERING_WIDTH 1
+/* Set no snoop bit for TLPs on this VI. */
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_NO_SNOOP_LBN 18
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_NO_SNOOP_WIDTH 1
+/* Enable TPH for TLPs on this VI. */
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_TPH_ON_LBN 19
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_TPH_ON_WIDTH 1
+#define MC_CMD_GET_VI_TLP_PROCESSING_OUT_DATA_OFST 0
+
+
+/***********************************/
+/* MC_CMD_SET_VI_TLP_PROCESSING
+ * Set TLP steering and ordering information for a VI.
+ */
+#define MC_CMD_SET_VI_TLP_PROCESSING 0xb1
+#undef MC_CMD_0xb1_PRIVILEGE_CTG
+
+#define MC_CMD_0xb1_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_SET_VI_TLP_PROCESSING_IN msgrequest */
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_LEN 8
+/* VI number to set information for. */
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_INSTANCE_OFST 0
+/* Transaction processing steering hint 1 for use with the Rx Queue. */
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_TPH_TAG1_RX_OFST 4
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_TPH_TAG1_RX_LEN 1
+/* Transaction processing steering hint 2 for use with the Ev Queue. */
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_TPH_TAG2_EV_OFST 5
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_TPH_TAG2_EV_LEN 1
+/* Use Relaxed ordering model for TLPs on this VI. */
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_RELAXED_ORDERING_LBN 48
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_RELAXED_ORDERING_WIDTH 1
+/* Use ID based ordering for TLPs on this VI. */
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_ID_BASED_ORDERING_LBN 49
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_ID_BASED_ORDERING_WIDTH 1
+/* Set the no snoop bit for TLPs on this VI. */
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_NO_SNOOP_LBN 50
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_NO_SNOOP_WIDTH 1
+/* Enable TPH for TLPs on this VI. */
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_TPH_ON_LBN 51
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_TPH_ON_WIDTH 1
+#define MC_CMD_SET_VI_TLP_PROCESSING_IN_DATA_OFST 4
+
+/* MC_CMD_SET_VI_TLP_PROCESSING_OUT msgresponse */
+#define MC_CMD_SET_VI_TLP_PROCESSING_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_GET_TLP_PROCESSING_GLOBALS
+ * Get global PCIe steering and transaction processing configuration.
+ */
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS 0xbc
+#undef MC_CMD_0xbc_PRIVILEGE_CTG
+
+#define MC_CMD_0xbc_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN msgrequest */
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_LEN 4
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_OFST 0
+/* enum: MISC. */
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_MISC 0x0
+/* enum: IDO. */
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_IDO 0x1
+/* enum: RO. */
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_RO 0x2
+/* enum: TPH Type. */
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_TPH_TYPE 0x3
+
+/* MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT msgresponse */
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_LEN 8
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_GLOBAL_CATEGORY_OFST 0
+/* Enum values, see field(s): */
+/* MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN/TLP_GLOBAL_CATEGORY */
+/* Amalgamated TLP info word. */
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_WORD_OFST 4
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_MISC_WTAG_EN_LBN 0
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_MISC_WTAG_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_MISC_SPARE_LBN 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_MISC_SPARE_WIDTH 31
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_DL_EN_LBN 0
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_DL_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_TX_EN_LBN 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_TX_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_EV_EN_LBN 2
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_EV_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_RX_EN_LBN 3
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_RX_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_SPARE_LBN 4
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_IDO_SPARE_WIDTH 28
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_RXDMA_EN_LBN 0
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_RXDMA_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_TXDMA_EN_LBN 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_TXDMA_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_DL_EN_LBN 2
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_DL_EN_WIDTH 1
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_SPARE_LBN 3
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_RO_SPARE_WIDTH 29
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_MSIX_LBN 0
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_MSIX_WIDTH 2
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_DL_LBN 2
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_DL_WIDTH 2
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_TX_LBN 4
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_TX_WIDTH 2
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_EV_LBN 6
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_EV_WIDTH 2
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_RX_LBN 8
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TPH_TYPE_RX_WIDTH 2
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TLP_TYPE_SPARE_LBN 9
+#define MC_CMD_GET_TLP_PROCESSING_GLOBALS_OUT_TLP_INFO_TLP_TYPE_SPARE_WIDTH 23
+
+
+/***********************************/
+/* MC_CMD_SET_TLP_PROCESSING_GLOBALS
+ * Set global PCIe steering and transaction processing configuration.
+ */
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS 0xbd
+#undef MC_CMD_0xbd_PRIVILEGE_CTG
+
+#define MC_CMD_0xbd_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN msgrequest */
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_LEN 8
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_GLOBAL_CATEGORY_OFST 0
+/* Enum values, see field(s): */
+/* MC_CMD_GET_TLP_PROCESSING_GLOBALS/MC_CMD_GET_TLP_PROCESSING_GLOBALS_IN/TLP_GLOBAL_CATEGORY */
+/* Amalgamated TLP info word. */
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_WORD_OFST 4
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_MISC_WTAG_EN_LBN 0
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_MISC_WTAG_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_DL_EN_LBN 0
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_DL_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_TX_EN_LBN 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_TX_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_EV_EN_LBN 2
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_EV_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_RX_EN_LBN 3
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_IDO_RX_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_RO_RXDMA_EN_LBN 0
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_RO_RXDMA_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_RO_TXDMA_EN_LBN 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_RO_TXDMA_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_RO_DL_EN_LBN 2
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_RO_DL_EN_WIDTH 1
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_MSIX_LBN 0
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_MSIX_WIDTH 2
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_DL_LBN 2
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_DL_WIDTH 2
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_TX_LBN 4
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_TX_WIDTH 2
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_EV_LBN 6
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_EV_WIDTH 2
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_RX_LBN 8
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_TPH_TYPE_RX_WIDTH 2
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_SPARE_LBN 10
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_IN_TLP_INFO_SPARE_WIDTH 22
+
+/* MC_CMD_SET_TLP_PROCESSING_GLOBALS_OUT msgresponse */
+#define MC_CMD_SET_TLP_PROCESSING_GLOBALS_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_SATELLITE_DOWNLOAD
+ * Download a new set of images to the satellite CPUs from the host.
+ */
+#define MC_CMD_SATELLITE_DOWNLOAD 0x91
+#undef MC_CMD_0x91_PRIVILEGE_CTG
+
+#define MC_CMD_0x91_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_SATELLITE_DOWNLOAD_IN msgrequest: The reset requirements for the CPUs
+ * are subtle, and so downloads must proceed in a number of phases.
+ *
+ * 1) PHASE_RESET with a target of TARGET_ALL and chunk ID/length of 0.
+ *
+ * 2) PHASE_IMEMS for each of the IMEM targets (target IDs 0-11). Each download
+ * may consist of multiple chunks. The final chunk (with CHUNK_ID_LAST) should
+ * be a checksum (a simple 32-bit sum) of the transferred data. An individual
+ * download may be aborted using CHUNK_ID_ABORT.
+ *
+ * 3) PHASE_VECTORS for each of the vector table targets (target IDs 12-15),
+ * similar to PHASE_IMEMS.
+ *
+ * 4) PHASE_READY with a target of TARGET_ALL and chunk ID/length of 0.
+ *
+ * After any error (a requested abort is not considered to be an error) the
+ * sequence must be restarted from PHASE_RESET.
+ */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_LENMIN 20
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_LENMAX 252
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_LEN(num) (16+4*(num))
+/* Download phase. (Note: the IDLE phase is used internally and is never valid
+ * in a command from the host.)
+ */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_OFST 0
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_IDLE 0x0 /* enum */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_RESET 0x1 /* enum */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_IMEMS 0x2 /* enum */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_VECTORS 0x3 /* enum */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_PHASE_READY 0x4 /* enum */
+/* Target for download. (These match the blob numbers defined in
+ * mc_flash_layout.h.)
+ */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_OFST 4
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXDI_TEXT 0x0
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXDI_TEXT 0x1
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXDP_TEXT 0x2
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXDP_TEXT 0x3
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXHRSL_HR_LUT 0x4
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXHRSL_HR_LUT_CFG 0x5
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXHRSL_HR_LUT 0x6
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXHRSL_HR_LUT_CFG 0x7
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXHRSL_HR_PGM 0x8
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXHRSL_SL_PGM 0x9
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXHRSL_HR_PGM 0xa
+/* enum: Valid in phase 2 (PHASE_IMEMS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXHRSL_SL_PGM 0xb
+/* enum: Valid in phase 3 (PHASE_VECTORS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXDI_VTBL0 0xc
+/* enum: Valid in phase 3 (PHASE_VECTORS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXDI_VTBL0 0xd
+/* enum: Valid in phase 3 (PHASE_VECTORS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_RXDI_VTBL1 0xe
+/* enum: Valid in phase 3 (PHASE_VECTORS) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_TXDI_VTBL1 0xf
+/* enum: Valid in phases 1 (PHASE_RESET) and 4 (PHASE_READY) only */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_TARGET_ALL 0xffffffff
+/* Chunk ID, or CHUNK_ID_LAST or CHUNK_ID_ABORT */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_ID_OFST 8
+/* enum: Last chunk, containing checksum rather than data */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_ID_LAST 0xffffffff
+/* enum: Abort download of this item */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_ID_ABORT 0xfffffffe
+/* Length of this chunk in bytes */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_LEN_OFST 12
+/* Data for this chunk */
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_DATA_OFST 16
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_DATA_LEN 4
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_DATA_MINNUM 1
+#define MC_CMD_SATELLITE_DOWNLOAD_IN_CHUNK_DATA_MAXNUM 59
+
+/* MC_CMD_SATELLITE_DOWNLOAD_OUT msgresponse */
+#define MC_CMD_SATELLITE_DOWNLOAD_OUT_LEN 8
+/* Same as MC_CMD_ERR field, but included as 0 in success cases */
+#define MC_CMD_SATELLITE_DOWNLOAD_OUT_RESULT_OFST 0
+/* Extra status information */
+#define MC_CMD_SATELLITE_DOWNLOAD_OUT_INFO_OFST 4
+/* enum: Code download OK, completed. */
+#define MC_CMD_SATELLITE_DOWNLOAD_OUT_OK_COMPLETE 0x0
+/* enum: Code download aborted as requested. */
+#define MC_CMD_SATELLITE_DOWNLOAD_OUT_OK_ABORTED 0x1
+/* enum: Code download OK so far, send next chunk. */
+#define MC_CMD_SATELLITE_DOWNLOAD_OUT_OK_NEXT_CHUNK 0x2
+/* enum: Download phases out of sequence */
+#define MC_CMD_SATELLITE_DOWNLOAD_OUT_ERR_BAD_PHASE 0x100
+/* enum: Bad target for this phase */
+#define MC_CMD_SATELLITE_DOWNLOAD_OUT_ERR_BAD_TARGET 0x101
+/* enum: Chunk ID out of sequence */
+#define MC_CMD_SATELLITE_DOWNLOAD_OUT_ERR_BAD_CHUNK_ID 0x200
+/* enum: Chunk length zero or too large */
+#define MC_CMD_SATELLITE_DOWNLOAD_OUT_ERR_BAD_CHUNK_LEN 0x201
+/* enum: Checksum was incorrect */
+#define MC_CMD_SATELLITE_DOWNLOAD_OUT_ERR_BAD_CHECKSUM 0x300
+
+
+/***********************************/
+/* MC_CMD_GET_CAPABILITIES
+ * Get device capabilities.
+ *
+ * This is supplementary to the MC_CMD_GET_BOARD_CFG command, and intended to
+ * reference inherent device capabilities as opposed to current NVRAM config.
+ */
+#define MC_CMD_GET_CAPABILITIES 0xbe
+#undef MC_CMD_0xbe_PRIVILEGE_CTG
+
+#define MC_CMD_0xbe_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_CAPABILITIES_IN msgrequest */
+#define MC_CMD_GET_CAPABILITIES_IN_LEN 0
+
+/* MC_CMD_GET_CAPABILITIES_OUT msgresponse */
+#define MC_CMD_GET_CAPABILITIES_OUT_LEN 20
+/* First word of flags. */
+#define MC_CMD_GET_CAPABILITIES_OUT_FLAGS1_OFST 0
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_MAC_SECURITY_FILTERING_LBN 12
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_MAC_SECURITY_FILTERING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_ADDITIONAL_RSS_MODES_LBN 13
+#define MC_CMD_GET_CAPABILITIES_OUT_ADDITIONAL_RSS_MODES_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_QBB_LBN 14
+#define MC_CMD_GET_CAPABILITIES_OUT_QBB_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_PACKED_STREAM_VAR_BUFFERS_LBN 15
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_PACKED_STREAM_VAR_BUFFERS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_RSS_LIMITED_LBN 16
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_RSS_LIMITED_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_PACKED_STREAM_LBN 17
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_PACKED_STREAM_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_INCLUDE_FCS_LBN 18
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_INCLUDE_FCS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_VLAN_INSERTION_LBN 19
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_VLAN_INSERTION_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_VLAN_STRIPPING_LBN 20
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_VLAN_STRIPPING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_TSO_LBN 21
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_TSO_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_PREFIX_LEN_0_LBN 22
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_PREFIX_LEN_0_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_PREFIX_LEN_14_LBN 23
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_PREFIX_LEN_14_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_TIMESTAMP_LBN 24
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_TIMESTAMP_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_BATCHING_LBN 25
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_BATCHING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_MCAST_FILTER_CHAINING_LBN 26
+#define MC_CMD_GET_CAPABILITIES_OUT_MCAST_FILTER_CHAINING_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_PM_AND_RXDP_COUNTERS_LBN 27
+#define MC_CMD_GET_CAPABILITIES_OUT_PM_AND_RXDP_COUNTERS_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_DISABLE_SCATTER_LBN 28
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_DISABLE_SCATTER_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_MCAST_UDP_LOOPBACK_LBN 29
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_MCAST_UDP_LOOPBACK_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_EVB_LBN 30
+#define MC_CMD_GET_CAPABILITIES_OUT_EVB_WIDTH 1
+#define MC_CMD_GET_CAPABILITIES_OUT_VXLAN_NVGRE_LBN 31
+#define MC_CMD_GET_CAPABILITIES_OUT_VXLAN_NVGRE_WIDTH 1
+/* RxDPCPU firmware id. */
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_DPCPU_FW_ID_OFST 4
+#define MC_CMD_GET_CAPABILITIES_OUT_RX_DPCPU_FW_ID_LEN 2
+/* enum: Standard RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP 0x0
+/* enum: Low latency RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_LOW_LATENCY 0x1
+/* enum: Packed stream RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_PACKED_STREAM 0x2
+/* enum: BIST RXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_BIST 0x10a
+/* enum: RXDP Test firmware image 1 */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_TO_MC_CUT_THROUGH 0x101
+/* enum: RXDP Test firmware image 2 */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD 0x102
+/* enum: RXDP Test firmware image 3 */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_TO_MC_STORE_FORWARD_FIRST 0x103
+/* enum: RXDP Test firmware image 4 */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_EVERY_EVENT_BATCHABLE 0x104
+/* enum: RXDP Test firmware image 5 */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_BACKPRESSURE 0x105
+/* enum: RXDP Test firmware image 6 */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_PACKET_EDITS 0x106
+/* enum: RXDP Test firmware image 7 */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_RX_HDR_SPLIT 0x107
+/* enum: RXDP Test firmware image 8 */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXDP_TEST_FW_DISABLE_DL 0x108
+/* TxDPCPU firmware id. */
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_DPCPU_FW_ID_OFST 6
+#define MC_CMD_GET_CAPABILITIES_OUT_TX_DPCPU_FW_ID_LEN 2
+/* enum: Standard TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXDP 0x0
+/* enum: Low latency TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_LOW_LATENCY 0x1
+/* enum: High packet rate TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_HIGH_PACKET_RATE 0x3
+/* enum: BIST TXDP firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_BIST 0x12d
+/* enum: TXDP Test firmware image 1 */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_TEST_FW_TSO_EDIT 0x101
+/* enum: TXDP Test firmware image 2 */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXDP_TEST_FW_PACKET_EDITS 0x102
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_OFST 8
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_LEN 2
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_REV_LBN 0
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_REV_WIDTH 12
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_TYPE_LBN 12
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_VERSION_TYPE_WIDTH 4
+/* enum: reserved value - do not use (may indicate alternative interpretation
+ * of REV field in future)
+ */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_RESERVED 0x0
+/* enum: Trivial RX PD firmware for early Huntington development (Huntington
+ * development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_FIRST_PKT 0x1
+/* enum: RX PD firmware with approximately Siena-compatible behaviour
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_SIENA_COMPAT 0x2
+/* enum: Virtual switching (full feature) RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_VSWITCH 0x3
+/* enum: siena_compat variant RX PD firmware using PM rather than MAC
+ * (Huntington development only)
*/
-#define MC_CMD_V2_EXTN 0x7f
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_SIENA_COMPAT_PM 0x4
+/* enum: Low latency RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_LOW_LATENCY 0x5
+/* enum: Packed stream RX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_PACKED_STREAM 0x6
+/* enum: RX PD firmware handling layer 2 only for high packet rate performance
+ * tests (Medford development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_LAYER2_PERF 0x7
+/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe
+/* enum: RX PD firmware parsing but not filtering network overlay tunnel
+ * encapsulations (Medford development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_OUT_RXPD_FW_TYPE_TESTFW_ENCAP_PARSING_ONLY 0xf
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_OFST 10
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_LEN 2
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_REV_LBN 0
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_REV_WIDTH 12
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_TYPE_LBN 12
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_VERSION_TYPE_WIDTH 4
+/* enum: reserved value - do not use (may indicate alternative interpretation
+ * of REV field in future)
+ */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_RESERVED 0x0
+/* enum: Trivial TX PD firmware for early Huntington development (Huntington
+ * development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_FIRST_PKT 0x1
+/* enum: TX PD firmware with approximately Siena-compatible behaviour
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_SIENA_COMPAT 0x2
+/* enum: Virtual switching (full feature) TX PD production firmware */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_VSWITCH 0x3
+/* enum: siena_compat variant TX PD firmware using PM rather than MAC
+ * (Huntington development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_SIENA_COMPAT_PM 0x4
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_LOW_LATENCY 0x5 /* enum */
+/* enum: TX PD firmware handling layer 2 only for high packet rate performance
+ * tests (Medford development only)
+ */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_LAYER2_PERF 0x7
+/* enum: RX PD firmware for GUE parsing prototype (Medford development only) */
+#define MC_CMD_GET_CAPABILITIES_OUT_TXPD_FW_TYPE_TESTFW_GUE_PROTOTYPE 0xe
+/* Hardware capabilities of NIC */
+#define MC_CMD_GET_CAPABILITIES_OUT_HW_CAPABILITIES_OFST 12
+/* Licensed capabilities */
+#define MC_CMD_GET_CAPABILITIES_OUT_LICENSE_CAPABILITIES_OFST 16
+
+
+/***********************************/
+/* MC_CMD_V2_EXTN
+ * Encapsulation for a v2 extended command
+ */
+#define MC_CMD_V2_EXTN 0x7f
/* MC_CMD_V2_EXTN_IN msgrequest */
#define MC_CMD_V2_EXTN_IN_LEN 4
+/* the extended command number */
#define MC_CMD_V2_EXTN_IN_EXTENDED_CMD_LBN 0
#define MC_CMD_V2_EXTN_IN_EXTENDED_CMD_WIDTH 15
#define MC_CMD_V2_EXTN_IN_UNUSED_LBN 15
#define MC_CMD_V2_EXTN_IN_UNUSED_WIDTH 1
+/* the actual length of the encapsulated command (which is not in the v1
+ * header)
+ */
#define MC_CMD_V2_EXTN_IN_ACTUAL_LEN_LBN 16
#define MC_CMD_V2_EXTN_IN_ACTUAL_LEN_WIDTH 10
#define MC_CMD_V2_EXTN_IN_UNUSED2_LBN 26
@@ -5035,25 +9619,35 @@
/***********************************/
-/* MC_CMD_TCM_BUCKET_ALLOC
+/* MC_CMD_TCM_BUCKET_ALLOC
+ * Allocate a pacer bucket (for qau rp or a snapper test)
*/
-#define MC_CMD_TCM_BUCKET_ALLOC 0x80
+#define MC_CMD_TCM_BUCKET_ALLOC 0xb2
+#undef MC_CMD_0xb2_PRIVILEGE_CTG
+
+#define MC_CMD_0xb2_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_TCM_BUCKET_ALLOC_IN msgrequest */
#define MC_CMD_TCM_BUCKET_ALLOC_IN_LEN 0
/* MC_CMD_TCM_BUCKET_ALLOC_OUT msgresponse */
#define MC_CMD_TCM_BUCKET_ALLOC_OUT_LEN 4
+/* the bucket id */
#define MC_CMD_TCM_BUCKET_ALLOC_OUT_BUCKET_OFST 0
/***********************************/
-/* MC_CMD_TCM_BUCKET_FREE
+/* MC_CMD_TCM_BUCKET_FREE
+ * Free a pacer bucket
*/
-#define MC_CMD_TCM_BUCKET_FREE 0x81
+#define MC_CMD_TCM_BUCKET_FREE 0xb3
+#undef MC_CMD_0xb3_PRIVILEGE_CTG
+
+#define MC_CMD_0xb3_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_TCM_BUCKET_FREE_IN msgrequest */
#define MC_CMD_TCM_BUCKET_FREE_IN_LEN 4
+/* the bucket id */
#define MC_CMD_TCM_BUCKET_FREE_IN_BUCKET_OFST 0
/* MC_CMD_TCM_BUCKET_FREE_OUT msgresponse */
@@ -5061,35 +9655,2865 @@
/***********************************/
-/* MC_CMD_TCM_BUCKET_INIT
+/* MC_CMD_TCM_BUCKET_INIT
+ * Initialise pacer bucket with a given rate
*/
-#define MC_CMD_TCM_BUCKET_INIT 0x82
+#define MC_CMD_TCM_BUCKET_INIT 0xb4
+#undef MC_CMD_0xb4_PRIVILEGE_CTG
+
+#define MC_CMD_0xb4_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_TCM_BUCKET_INIT_IN msgrequest */
#define MC_CMD_TCM_BUCKET_INIT_IN_LEN 8
+/* the bucket id */
#define MC_CMD_TCM_BUCKET_INIT_IN_BUCKET_OFST 0
+/* the rate in mbps */
#define MC_CMD_TCM_BUCKET_INIT_IN_RATE_OFST 4
+/* MC_CMD_TCM_BUCKET_INIT_EXT_IN msgrequest */
+#define MC_CMD_TCM_BUCKET_INIT_EXT_IN_LEN 12
+/* the bucket id */
+#define MC_CMD_TCM_BUCKET_INIT_EXT_IN_BUCKET_OFST 0
+/* the rate in mbps */
+#define MC_CMD_TCM_BUCKET_INIT_EXT_IN_RATE_OFST 4
+/* the desired maximum fill level */
+#define MC_CMD_TCM_BUCKET_INIT_EXT_IN_MAX_FILL_OFST 8
+
/* MC_CMD_TCM_BUCKET_INIT_OUT msgresponse */
#define MC_CMD_TCM_BUCKET_INIT_OUT_LEN 0
/***********************************/
-/* MC_CMD_TCM_TXQ_INIT
+/* MC_CMD_TCM_TXQ_INIT
+ * Initialise txq in pacer with given options or set options
*/
-#define MC_CMD_TCM_TXQ_INIT 0x83
+#define MC_CMD_TCM_TXQ_INIT 0xb5
+#undef MC_CMD_0xb5_PRIVILEGE_CTG
+
+#define MC_CMD_0xb5_PRIVILEGE_CTG SRIOV_CTG_GENERAL
/* MC_CMD_TCM_TXQ_INIT_IN msgrequest */
#define MC_CMD_TCM_TXQ_INIT_IN_LEN 28
+/* the txq id */
#define MC_CMD_TCM_TXQ_INIT_IN_QID_OFST 0
+/* the static priority associated with the txq */
#define MC_CMD_TCM_TXQ_INIT_IN_LABEL_OFST 4
+/* bitmask of the priority queues this txq is inserted into when inserted. */
#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAGS_OFST 8
+#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_GUARANTEED_LBN 0
+#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_GUARANTEED_WIDTH 1
+#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_NORMAL_LBN 1
+#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_NORMAL_WIDTH 1
+#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_LOW_LBN 2
+#define MC_CMD_TCM_TXQ_INIT_IN_PQ_FLAG_LOW_WIDTH 1
+/* the reaction point (RP) bucket */
#define MC_CMD_TCM_TXQ_INIT_IN_RP_BKT_OFST 12
+/* an already reserved bucket (typically set to bucket associated with outer
+ * vswitch)
+ */
#define MC_CMD_TCM_TXQ_INIT_IN_MAX_BKT1_OFST 16
+/* an already reserved bucket (typically set to bucket associated with inner
+ * vswitch)
+ */
#define MC_CMD_TCM_TXQ_INIT_IN_MAX_BKT2_OFST 20
+/* the min bucket (typically for ETS/minimum bandwidth) */
#define MC_CMD_TCM_TXQ_INIT_IN_MIN_BKT_OFST 24
+/* MC_CMD_TCM_TXQ_INIT_EXT_IN msgrequest */
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_LEN 32
+/* the txq id */
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_QID_OFST 0
+/* the static priority associated with the txq */
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_LABEL_NORMAL_OFST 4
+/* bitmask of the priority queues this txq is inserted into when inserted. */
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAGS_OFST 8
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_GUARANTEED_LBN 0
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_GUARANTEED_WIDTH 1
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_NORMAL_LBN 1
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_NORMAL_WIDTH 1
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_LOW_LBN 2
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_PQ_FLAG_LOW_WIDTH 1
+/* the reaction point (RP) bucket */
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_RP_BKT_OFST 12
+/* an already reserved bucket (typically set to bucket associated with outer
+ * vswitch)
+ */
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_MAX_BKT1_OFST 16
+/* an already reserved bucket (typically set to bucket associated with inner
+ * vswitch)
+ */
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_MAX_BKT2_OFST 20
+/* the min bucket (typically for ETS/minimum bandwidth) */
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_MIN_BKT_OFST 24
+/* the static priority associated with the txq */
+#define MC_CMD_TCM_TXQ_INIT_EXT_IN_LABEL_GUARANTEED_OFST 28
+
/* MC_CMD_TCM_TXQ_INIT_OUT msgresponse */
#define MC_CMD_TCM_TXQ_INIT_OUT_LEN 0
+
+/***********************************/
+/* MC_CMD_LINK_PIOBUF
+ * Link a push I/O buffer to a TxQ
+ */
+#define MC_CMD_LINK_PIOBUF 0x92
+#undef MC_CMD_0x92_PRIVILEGE_CTG
+
+#define MC_CMD_0x92_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
+
+/* MC_CMD_LINK_PIOBUF_IN msgrequest */
+#define MC_CMD_LINK_PIOBUF_IN_LEN 8
+/* Handle for allocated push I/O buffer. */
+#define MC_CMD_LINK_PIOBUF_IN_PIOBUF_HANDLE_OFST 0
+/* Function Local Instance (VI) number. */
+#define MC_CMD_LINK_PIOBUF_IN_TXQ_INSTANCE_OFST 4
+
+/* MC_CMD_LINK_PIOBUF_OUT msgresponse */
+#define MC_CMD_LINK_PIOBUF_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_UNLINK_PIOBUF
+ * Unlink a push I/O buffer from a TxQ
+ */
+#define MC_CMD_UNLINK_PIOBUF 0x93
+#undef MC_CMD_0x93_PRIVILEGE_CTG
+
+#define MC_CMD_0x93_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
+
+/* MC_CMD_UNLINK_PIOBUF_IN msgrequest */
+#define MC_CMD_UNLINK_PIOBUF_IN_LEN 4
+/* Function Local Instance (VI) number. */
+#define MC_CMD_UNLINK_PIOBUF_IN_TXQ_INSTANCE_OFST 0
+
+/* MC_CMD_UNLINK_PIOBUF_OUT msgresponse */
+#define MC_CMD_UNLINK_PIOBUF_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_VSWITCH_ALLOC
+ * allocate and initialise a v-switch.
+ */
+#define MC_CMD_VSWITCH_ALLOC 0x94
+#undef MC_CMD_0x94_PRIVILEGE_CTG
+
+#define MC_CMD_0x94_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VSWITCH_ALLOC_IN msgrequest */
+#define MC_CMD_VSWITCH_ALLOC_IN_LEN 16
+/* The port to connect to the v-switch's upstream port. */
+#define MC_CMD_VSWITCH_ALLOC_IN_UPSTREAM_PORT_ID_OFST 0
+/* The type of v-switch to create. */
+#define MC_CMD_VSWITCH_ALLOC_IN_TYPE_OFST 4
+/* enum: VLAN */
+#define MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VLAN 0x1
+/* enum: VEB */
+#define MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VEB 0x2
+/* enum: VEPA (obsolete) */
+#define MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_VEPA 0x3
+/* enum: MUX */
+#define MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_MUX 0x4
+/* enum: Snapper specific; semantics TBD */
+#define MC_CMD_VSWITCH_ALLOC_IN_VSWITCH_TYPE_TEST 0x5
+/* Flags controlling v-port creation */
+#define MC_CMD_VSWITCH_ALLOC_IN_FLAGS_OFST 8
+#define MC_CMD_VSWITCH_ALLOC_IN_FLAG_AUTO_PORT_LBN 0
+#define MC_CMD_VSWITCH_ALLOC_IN_FLAG_AUTO_PORT_WIDTH 1
+/* The number of VLAN tags to allow for attached v-ports. For VLAN aggregators,
+ * this must be one or greated, and the attached v-ports must have exactly this
+ * number of tags. For other v-switch types, this must be zero of greater, and
+ * is an upper limit on the number of VLAN tags for attached v-ports. An error
+ * will be returned if existing configuration means we can't support attached
+ * v-ports with this number of tags.
+ */
+#define MC_CMD_VSWITCH_ALLOC_IN_NUM_VLAN_TAGS_OFST 12
+
+/* MC_CMD_VSWITCH_ALLOC_OUT msgresponse */
+#define MC_CMD_VSWITCH_ALLOC_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_VSWITCH_FREE
+ * de-allocate a v-switch.
+ */
+#define MC_CMD_VSWITCH_FREE 0x95
+#undef MC_CMD_0x95_PRIVILEGE_CTG
+
+#define MC_CMD_0x95_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VSWITCH_FREE_IN msgrequest */
+#define MC_CMD_VSWITCH_FREE_IN_LEN 4
+/* The port to which the v-switch is connected. */
+#define MC_CMD_VSWITCH_FREE_IN_UPSTREAM_PORT_ID_OFST 0
+
+/* MC_CMD_VSWITCH_FREE_OUT msgresponse */
+#define MC_CMD_VSWITCH_FREE_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_VPORT_ALLOC
+ * allocate a v-port.
+ */
+#define MC_CMD_VPORT_ALLOC 0x96
+#undef MC_CMD_0x96_PRIVILEGE_CTG
+
+#define MC_CMD_0x96_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VPORT_ALLOC_IN msgrequest */
+#define MC_CMD_VPORT_ALLOC_IN_LEN 20
+/* The port to which the v-switch is connected. */
+#define MC_CMD_VPORT_ALLOC_IN_UPSTREAM_PORT_ID_OFST 0
+/* The type of the new v-port. */
+#define MC_CMD_VPORT_ALLOC_IN_TYPE_OFST 4
+/* enum: VLAN (obsolete) */
+#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_VLAN 0x1
+/* enum: VEB (obsolete) */
+#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_VEB 0x2
+/* enum: VEPA (obsolete) */
+#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_VEPA 0x3
+/* enum: A normal v-port receives packets which match a specified MAC and/or
+ * VLAN.
+ */
+#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_NORMAL 0x4
+/* enum: An expansion v-port packets traffic which don't match any other
+ * v-port.
+ */
+#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_EXPANSION 0x5
+/* enum: An test v-port receives packets which match any filters installed by
+ * its downstream components.
+ */
+#define MC_CMD_VPORT_ALLOC_IN_VPORT_TYPE_TEST 0x6
+/* Flags controlling v-port creation */
+#define MC_CMD_VPORT_ALLOC_IN_FLAGS_OFST 8
+#define MC_CMD_VPORT_ALLOC_IN_FLAG_AUTO_PORT_LBN 0
+#define MC_CMD_VPORT_ALLOC_IN_FLAG_AUTO_PORT_WIDTH 1
+/* The number of VLAN tags to insert/remove. An error will be returned if
+ * incompatible with the number of VLAN tags specified for the upstream
+ * v-switch.
+ */
+#define MC_CMD_VPORT_ALLOC_IN_NUM_VLAN_TAGS_OFST 12
+/* The actual VLAN tags to insert/remove */
+#define MC_CMD_VPORT_ALLOC_IN_VLAN_TAGS_OFST 16
+#define MC_CMD_VPORT_ALLOC_IN_VLAN_TAG_0_LBN 0
+#define MC_CMD_VPORT_ALLOC_IN_VLAN_TAG_0_WIDTH 16
+#define MC_CMD_VPORT_ALLOC_IN_VLAN_TAG_1_LBN 16
+#define MC_CMD_VPORT_ALLOC_IN_VLAN_TAG_1_WIDTH 16
+
+/* MC_CMD_VPORT_ALLOC_OUT msgresponse */
+#define MC_CMD_VPORT_ALLOC_OUT_LEN 4
+/* The handle of the new v-port */
+#define MC_CMD_VPORT_ALLOC_OUT_VPORT_ID_OFST 0
+
+
+/***********************************/
+/* MC_CMD_VPORT_FREE
+ * de-allocate a v-port.
+ */
+#define MC_CMD_VPORT_FREE 0x97
+#undef MC_CMD_0x97_PRIVILEGE_CTG
+
+#define MC_CMD_0x97_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VPORT_FREE_IN msgrequest */
+#define MC_CMD_VPORT_FREE_IN_LEN 4
+/* The handle of the v-port */
+#define MC_CMD_VPORT_FREE_IN_VPORT_ID_OFST 0
+
+/* MC_CMD_VPORT_FREE_OUT msgresponse */
+#define MC_CMD_VPORT_FREE_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_VADAPTOR_ALLOC
+ * allocate a v-adaptor.
+ */
+#define MC_CMD_VADAPTOR_ALLOC 0x98
+#undef MC_CMD_0x98_PRIVILEGE_CTG
+
+#define MC_CMD_0x98_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VADAPTOR_ALLOC_IN msgrequest */
+#define MC_CMD_VADAPTOR_ALLOC_IN_LEN 30
+/* The port to connect to the v-adaptor's port. */
+#define MC_CMD_VADAPTOR_ALLOC_IN_UPSTREAM_PORT_ID_OFST 0
+/* Flags controlling v-adaptor creation */
+#define MC_CMD_VADAPTOR_ALLOC_IN_FLAGS_OFST 8
+#define MC_CMD_VADAPTOR_ALLOC_IN_FLAG_AUTO_VADAPTOR_LBN 0
+#define MC_CMD_VADAPTOR_ALLOC_IN_FLAG_AUTO_VADAPTOR_WIDTH 1
+/* The number of VLAN tags to strip on receive */
+#define MC_CMD_VADAPTOR_ALLOC_IN_NUM_VLANS_OFST 12
+/* The number of VLAN tags to transparently insert/remove. */
+#define MC_CMD_VADAPTOR_ALLOC_IN_NUM_VLAN_TAGS_OFST 16
+/* The actual VLAN tags to insert/remove */
+#define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAGS_OFST 20
+#define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAG_0_LBN 0
+#define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAG_0_WIDTH 16
+#define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAG_1_LBN 16
+#define MC_CMD_VADAPTOR_ALLOC_IN_VLAN_TAG_1_WIDTH 16
+/* The MAC address to assign to this v-adaptor */
+#define MC_CMD_VADAPTOR_ALLOC_IN_MACADDR_OFST 24
+#define MC_CMD_VADAPTOR_ALLOC_IN_MACADDR_LEN 6
+/* enum: Derive the MAC address from the upstream port */
+#define MC_CMD_VADAPTOR_ALLOC_IN_AUTO_MAC 0x0
+
+/* MC_CMD_VADAPTOR_ALLOC_OUT msgresponse */
+#define MC_CMD_VADAPTOR_ALLOC_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_VADAPTOR_FREE
+ * de-allocate a v-adaptor.
+ */
+#define MC_CMD_VADAPTOR_FREE 0x99
+#undef MC_CMD_0x99_PRIVILEGE_CTG
+
+#define MC_CMD_0x99_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VADAPTOR_FREE_IN msgrequest */
+#define MC_CMD_VADAPTOR_FREE_IN_LEN 4
+/* The port to which the v-adaptor is connected. */
+#define MC_CMD_VADAPTOR_FREE_IN_UPSTREAM_PORT_ID_OFST 0
+
+/* MC_CMD_VADAPTOR_FREE_OUT msgresponse */
+#define MC_CMD_VADAPTOR_FREE_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_VADAPTOR_SET_MAC
+ * assign a new MAC address to a v-adaptor.
+ */
+#define MC_CMD_VADAPTOR_SET_MAC 0x5d
+#undef MC_CMD_0x5d_PRIVILEGE_CTG
+
+#define MC_CMD_0x5d_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VADAPTOR_SET_MAC_IN msgrequest */
+#define MC_CMD_VADAPTOR_SET_MAC_IN_LEN 10
+/* The port to which the v-adaptor is connected. */
+#define MC_CMD_VADAPTOR_SET_MAC_IN_UPSTREAM_PORT_ID_OFST 0
+/* The new MAC address to assign to this v-adaptor */
+#define MC_CMD_VADAPTOR_SET_MAC_IN_MACADDR_OFST 4
+#define MC_CMD_VADAPTOR_SET_MAC_IN_MACADDR_LEN 6
+
+/* MC_CMD_VADAPTOR_SET_MAC_OUT msgresponse */
+#define MC_CMD_VADAPTOR_SET_MAC_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_VADAPTOR_GET_MAC
+ * read the MAC address assigned to a v-adaptor.
+ */
+#define MC_CMD_VADAPTOR_GET_MAC 0x5e
+#undef MC_CMD_0x5e_PRIVILEGE_CTG
+
+#define MC_CMD_0x5e_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VADAPTOR_GET_MAC_IN msgrequest */
+#define MC_CMD_VADAPTOR_GET_MAC_IN_LEN 4
+/* The port to which the v-adaptor is connected. */
+#define MC_CMD_VADAPTOR_GET_MAC_IN_UPSTREAM_PORT_ID_OFST 0
+
+/* MC_CMD_VADAPTOR_GET_MAC_OUT msgresponse */
+#define MC_CMD_VADAPTOR_GET_MAC_OUT_LEN 6
+/* The MAC address assigned to this v-adaptor */
+#define MC_CMD_VADAPTOR_GET_MAC_OUT_MACADDR_OFST 0
+#define MC_CMD_VADAPTOR_GET_MAC_OUT_MACADDR_LEN 6
+
+
+/***********************************/
+/* MC_CMD_EVB_PORT_ASSIGN
+ * assign a port to a PCI function.
+ */
+#define MC_CMD_EVB_PORT_ASSIGN 0x9a
+#undef MC_CMD_0x9a_PRIVILEGE_CTG
+
+#define MC_CMD_0x9a_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_EVB_PORT_ASSIGN_IN msgrequest */
+#define MC_CMD_EVB_PORT_ASSIGN_IN_LEN 8
+/* The port to assign. */
+#define MC_CMD_EVB_PORT_ASSIGN_IN_PORT_ID_OFST 0
+/* The target function to modify. */
+#define MC_CMD_EVB_PORT_ASSIGN_IN_FUNCTION_OFST 4
+#define MC_CMD_EVB_PORT_ASSIGN_IN_PF_LBN 0
+#define MC_CMD_EVB_PORT_ASSIGN_IN_PF_WIDTH 16
+#define MC_CMD_EVB_PORT_ASSIGN_IN_VF_LBN 16
+#define MC_CMD_EVB_PORT_ASSIGN_IN_VF_WIDTH 16
+
+/* MC_CMD_EVB_PORT_ASSIGN_OUT msgresponse */
+#define MC_CMD_EVB_PORT_ASSIGN_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_RDWR_A64_REGIONS
+ * Assign the 64 bit region addresses.
+ */
+#define MC_CMD_RDWR_A64_REGIONS 0x9b
+#undef MC_CMD_0x9b_PRIVILEGE_CTG
+
+#define MC_CMD_0x9b_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_RDWR_A64_REGIONS_IN msgrequest */
+#define MC_CMD_RDWR_A64_REGIONS_IN_LEN 17
+#define MC_CMD_RDWR_A64_REGIONS_IN_REGION0_OFST 0
+#define MC_CMD_RDWR_A64_REGIONS_IN_REGION1_OFST 4
+#define MC_CMD_RDWR_A64_REGIONS_IN_REGION2_OFST 8
+#define MC_CMD_RDWR_A64_REGIONS_IN_REGION3_OFST 12
+/* Write enable bits 0-3, set to write, clear to read. */
+#define MC_CMD_RDWR_A64_REGIONS_IN_WRITE_MASK_LBN 128
+#define MC_CMD_RDWR_A64_REGIONS_IN_WRITE_MASK_WIDTH 4
+#define MC_CMD_RDWR_A64_REGIONS_IN_WRITE_MASK_BYTE_OFST 16
+#define MC_CMD_RDWR_A64_REGIONS_IN_WRITE_MASK_BYTE_LEN 1
+
+/* MC_CMD_RDWR_A64_REGIONS_OUT msgresponse: This data always included
+ * regardless of state of write bits in the request.
+ */
+#define MC_CMD_RDWR_A64_REGIONS_OUT_LEN 16
+#define MC_CMD_RDWR_A64_REGIONS_OUT_REGION0_OFST 0
+#define MC_CMD_RDWR_A64_REGIONS_OUT_REGION1_OFST 4
+#define MC_CMD_RDWR_A64_REGIONS_OUT_REGION2_OFST 8
+#define MC_CMD_RDWR_A64_REGIONS_OUT_REGION3_OFST 12
+
+
+/***********************************/
+/* MC_CMD_ONLOAD_STACK_ALLOC
+ * Allocate an Onload stack ID.
+ */
+#define MC_CMD_ONLOAD_STACK_ALLOC 0x9c
+#undef MC_CMD_0x9c_PRIVILEGE_CTG
+
+#define MC_CMD_0x9c_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
+
+/* MC_CMD_ONLOAD_STACK_ALLOC_IN msgrequest */
+#define MC_CMD_ONLOAD_STACK_ALLOC_IN_LEN 4
+/* The handle of the owning upstream port */
+#define MC_CMD_ONLOAD_STACK_ALLOC_IN_UPSTREAM_PORT_ID_OFST 0
+
+/* MC_CMD_ONLOAD_STACK_ALLOC_OUT msgresponse */
+#define MC_CMD_ONLOAD_STACK_ALLOC_OUT_LEN 4
+/* The handle of the new Onload stack */
+#define MC_CMD_ONLOAD_STACK_ALLOC_OUT_ONLOAD_STACK_ID_OFST 0
+
+
+/***********************************/
+/* MC_CMD_ONLOAD_STACK_FREE
+ * Free an Onload stack ID.
+ */
+#define MC_CMD_ONLOAD_STACK_FREE 0x9d
+#undef MC_CMD_0x9d_PRIVILEGE_CTG
+
+#define MC_CMD_0x9d_PRIVILEGE_CTG SRIOV_CTG_ONLOAD
+
+/* MC_CMD_ONLOAD_STACK_FREE_IN msgrequest */
+#define MC_CMD_ONLOAD_STACK_FREE_IN_LEN 4
+/* The handle of the Onload stack */
+#define MC_CMD_ONLOAD_STACK_FREE_IN_ONLOAD_STACK_ID_OFST 0
+
+/* MC_CMD_ONLOAD_STACK_FREE_OUT msgresponse */
+#define MC_CMD_ONLOAD_STACK_FREE_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_RSS_CONTEXT_ALLOC
+ * Allocate an RSS context.
+ */
+#define MC_CMD_RSS_CONTEXT_ALLOC 0x9e
+#undef MC_CMD_0x9e_PRIVILEGE_CTG
+
+#define MC_CMD_0x9e_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_RSS_CONTEXT_ALLOC_IN msgrequest */
+#define MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN 12
+/* The handle of the owning upstream port */
+#define MC_CMD_RSS_CONTEXT_ALLOC_IN_UPSTREAM_PORT_ID_OFST 0
+/* The type of context to allocate */
+#define MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_OFST 4
+/* enum: Allocate a context for exclusive use. The key and indirection table
+ * must be explicitly configured.
+ */
+#define MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_EXCLUSIVE 0x0
+/* enum: Allocate a context for shared use; this will spread across a range of
+ * queues, but the key and indirection table are pre-configured and may not be
+ * changed. For this mode, NUM_QUEUES must 2, 4, 8, 16, 32 or 64.
+ */
+#define MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_SHARED 0x1
+/* Number of queues spanned by this context, in the range 1-64; valid offsets
+ * in the indirection table will be in the range 0 to NUM_QUEUES-1.
+ */
+#define MC_CMD_RSS_CONTEXT_ALLOC_IN_NUM_QUEUES_OFST 8
+
+/* MC_CMD_RSS_CONTEXT_ALLOC_OUT msgresponse */
+#define MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN 4
+/* The handle of the new RSS context. This should be considered opaque to the
+ * host, although a value of 0xFFFFFFFF is guaranteed never to be a valid
+ * handle.
+ */
+#define MC_CMD_RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID_OFST 0
+/* enum: guaranteed invalid RSS context handle value */
+#define MC_CMD_RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID_INVALID 0xffffffff
+
+
+/***********************************/
+/* MC_CMD_RSS_CONTEXT_FREE
+ * Free an RSS context.
+ */
+#define MC_CMD_RSS_CONTEXT_FREE 0x9f
+#undef MC_CMD_0x9f_PRIVILEGE_CTG
+
+#define MC_CMD_0x9f_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_RSS_CONTEXT_FREE_IN msgrequest */
+#define MC_CMD_RSS_CONTEXT_FREE_IN_LEN 4
+/* The handle of the RSS context */
+#define MC_CMD_RSS_CONTEXT_FREE_IN_RSS_CONTEXT_ID_OFST 0
+
+/* MC_CMD_RSS_CONTEXT_FREE_OUT msgresponse */
+#define MC_CMD_RSS_CONTEXT_FREE_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_RSS_CONTEXT_SET_KEY
+ * Set the Toeplitz hash key for an RSS context.
+ */
+#define MC_CMD_RSS_CONTEXT_SET_KEY 0xa0
+#undef MC_CMD_0xa0_PRIVILEGE_CTG
+
+#define MC_CMD_0xa0_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_RSS_CONTEXT_SET_KEY_IN msgrequest */
+#define MC_CMD_RSS_CONTEXT_SET_KEY_IN_LEN 44
+/* The handle of the RSS context */
+#define MC_CMD_RSS_CONTEXT_SET_KEY_IN_RSS_CONTEXT_ID_OFST 0
+/* The 40-byte Toeplitz hash key (TBD endianness issues?) */
+#define MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_OFST 4
+#define MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_LEN 40
+
+/* MC_CMD_RSS_CONTEXT_SET_KEY_OUT msgresponse */
+#define MC_CMD_RSS_CONTEXT_SET_KEY_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_RSS_CONTEXT_GET_KEY
+ * Get the Toeplitz hash key for an RSS context.
+ */
+#define MC_CMD_RSS_CONTEXT_GET_KEY 0xa1
+#undef MC_CMD_0xa1_PRIVILEGE_CTG
+
+#define MC_CMD_0xa1_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_RSS_CONTEXT_GET_KEY_IN msgrequest */
+#define MC_CMD_RSS_CONTEXT_GET_KEY_IN_LEN 4
+/* The handle of the RSS context */
+#define MC_CMD_RSS_CONTEXT_GET_KEY_IN_RSS_CONTEXT_ID_OFST 0
+
+/* MC_CMD_RSS_CONTEXT_GET_KEY_OUT msgresponse */
+#define MC_CMD_RSS_CONTEXT_GET_KEY_OUT_LEN 44
+/* The 40-byte Toeplitz hash key (TBD endianness issues?) */
+#define MC_CMD_RSS_CONTEXT_GET_KEY_OUT_TOEPLITZ_KEY_OFST 4
+#define MC_CMD_RSS_CONTEXT_GET_KEY_OUT_TOEPLITZ_KEY_LEN 40
+
+
+/***********************************/
+/* MC_CMD_RSS_CONTEXT_SET_TABLE
+ * Set the indirection table for an RSS context.
+ */
+#define MC_CMD_RSS_CONTEXT_SET_TABLE 0xa2
+#undef MC_CMD_0xa2_PRIVILEGE_CTG
+
+#define MC_CMD_0xa2_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_RSS_CONTEXT_SET_TABLE_IN msgrequest */
+#define MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN 132
+/* The handle of the RSS context */
+#define MC_CMD_RSS_CONTEXT_SET_TABLE_IN_RSS_CONTEXT_ID_OFST 0
+/* The 128-byte indirection table (1 byte per entry) */
+#define MC_CMD_RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE_OFST 4
+#define MC_CMD_RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE_LEN 128
+
+/* MC_CMD_RSS_CONTEXT_SET_TABLE_OUT msgresponse */
+#define MC_CMD_RSS_CONTEXT_SET_TABLE_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_RSS_CONTEXT_GET_TABLE
+ * Get the indirection table for an RSS context.
+ */
+#define MC_CMD_RSS_CONTEXT_GET_TABLE 0xa3
+#undef MC_CMD_0xa3_PRIVILEGE_CTG
+
+#define MC_CMD_0xa3_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_RSS_CONTEXT_GET_TABLE_IN msgrequest */
+#define MC_CMD_RSS_CONTEXT_GET_TABLE_IN_LEN 4
+/* The handle of the RSS context */
+#define MC_CMD_RSS_CONTEXT_GET_TABLE_IN_RSS_CONTEXT_ID_OFST 0
+
+/* MC_CMD_RSS_CONTEXT_GET_TABLE_OUT msgresponse */
+#define MC_CMD_RSS_CONTEXT_GET_TABLE_OUT_LEN 132
+/* The 128-byte indirection table (1 byte per entry) */
+#define MC_CMD_RSS_CONTEXT_GET_TABLE_OUT_INDIRECTION_TABLE_OFST 4
+#define MC_CMD_RSS_CONTEXT_GET_TABLE_OUT_INDIRECTION_TABLE_LEN 128
+
+
+/***********************************/
+/* MC_CMD_RSS_CONTEXT_SET_FLAGS
+ * Set various control flags for an RSS context.
+ */
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS 0xe1
+#undef MC_CMD_0xe1_PRIVILEGE_CTG
+
+#define MC_CMD_0xe1_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_RSS_CONTEXT_SET_FLAGS_IN msgrequest */
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN 8
+/* The handle of the RSS context */
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_RSS_CONTEXT_ID_OFST 0
+/* Hash control flags. The _EN bits are always supported. The _MODE bits only
+ * work when the firmware reports ADDITIONAL_RSS_MODES in
+ * MC_CMD_GET_CAPABILITIES and override the _EN bits if any of them are not 0.
+ * See the RSS_MODE structure for the meaning of the mode bits.
+ */
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_FLAGS_OFST 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN_LBN 0
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN_LBN 1
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN_LBN 2
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN_LBN 3
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_RESERVED_LBN 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_RESERVED_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE_LBN 8
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV4_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV4_RSS_MODE_LBN 12
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV4_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE_LBN 16
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV4_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE_LBN 20
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_TCP_IPV6_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV6_RSS_MODE_LBN 24
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_UDP_IPV6_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE_LBN 28
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_OTHER_IPV6_RSS_MODE_WIDTH 4
+
+/* MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT msgresponse */
+#define MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_RSS_CONTEXT_GET_FLAGS
+ * Get various control flags for an RSS context.
+ */
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS 0xe2
+#undef MC_CMD_0xe2_PRIVILEGE_CTG
+
+#define MC_CMD_0xe2_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_RSS_CONTEXT_GET_FLAGS_IN msgrequest */
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_IN_LEN 4
+/* The handle of the RSS context */
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_IN_RSS_CONTEXT_ID_OFST 0
+
+/* MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT msgresponse */
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_LEN 8
+/* Hash control flags. If any _MODE bits are non-zero (which will only be true
+ * when the firmware reports ADDITIONAL_RSS_MODES) then the _EN bits should be
+ * disregarded (but are guaranteed to be consistent with the _MODE bits if
+ * RSS_CONTEXT_SET_FLAGS has never been called for this context since it was
+ * allocated).
+ */
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_FLAGS_OFST 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_IPV4_EN_LBN 0
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_IPV4_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_TCPV4_EN_LBN 1
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_TCPV4_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_IPV6_EN_LBN 2
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_IPV6_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_TCPV6_EN_LBN 3
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TOEPLITZ_TCPV6_EN_WIDTH 1
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_RESERVED_LBN 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_RESERVED_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TCP_IPV4_RSS_MODE_LBN 8
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TCP_IPV4_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV4_RSS_MODE_LBN 12
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV4_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_OTHER_IPV4_RSS_MODE_LBN 16
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_OTHER_IPV4_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TCP_IPV6_RSS_MODE_LBN 20
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_TCP_IPV6_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV6_RSS_MODE_LBN 24
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_UDP_IPV6_RSS_MODE_WIDTH 4
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_OTHER_IPV6_RSS_MODE_LBN 28
+#define MC_CMD_RSS_CONTEXT_GET_FLAGS_OUT_OTHER_IPV6_RSS_MODE_WIDTH 4
+
+
+/***********************************/
+/* MC_CMD_DOT1P_MAPPING_ALLOC
+ * Allocate a .1p mapping.
+ */
+#define MC_CMD_DOT1P_MAPPING_ALLOC 0xa4
+#undef MC_CMD_0xa4_PRIVILEGE_CTG
+
+#define MC_CMD_0xa4_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DOT1P_MAPPING_ALLOC_IN msgrequest */
+#define MC_CMD_DOT1P_MAPPING_ALLOC_IN_LEN 8
+/* The handle of the owning upstream port */
+#define MC_CMD_DOT1P_MAPPING_ALLOC_IN_UPSTREAM_PORT_ID_OFST 0
+/* Number of queues spanned by this mapping, in the range 1-64; valid fixed
+ * offsets in the mapping table will be in the range 0 to NUM_QUEUES-1, and
+ * referenced RSS contexts must span no more than this number.
+ */
+#define MC_CMD_DOT1P_MAPPING_ALLOC_IN_NUM_QUEUES_OFST 4
+
+/* MC_CMD_DOT1P_MAPPING_ALLOC_OUT msgresponse */
+#define MC_CMD_DOT1P_MAPPING_ALLOC_OUT_LEN 4
+/* The handle of the new .1p mapping. This should be considered opaque to the
+ * host, although a value of 0xFFFFFFFF is guaranteed never to be a valid
+ * handle.
+ */
+#define MC_CMD_DOT1P_MAPPING_ALLOC_OUT_DOT1P_MAPPING_ID_OFST 0
+/* enum: guaranteed invalid .1p mapping handle value */
+#define MC_CMD_DOT1P_MAPPING_ALLOC_OUT_DOT1P_MAPPING_ID_INVALID 0xffffffff
+
+
+/***********************************/
+/* MC_CMD_DOT1P_MAPPING_FREE
+ * Free a .1p mapping.
+ */
+#define MC_CMD_DOT1P_MAPPING_FREE 0xa5
+#undef MC_CMD_0xa5_PRIVILEGE_CTG
+
+#define MC_CMD_0xa5_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DOT1P_MAPPING_FREE_IN msgrequest */
+#define MC_CMD_DOT1P_MAPPING_FREE_IN_LEN 4
+/* The handle of the .1p mapping */
+#define MC_CMD_DOT1P_MAPPING_FREE_IN_DOT1P_MAPPING_ID_OFST 0
+
+/* MC_CMD_DOT1P_MAPPING_FREE_OUT msgresponse */
+#define MC_CMD_DOT1P_MAPPING_FREE_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_DOT1P_MAPPING_SET_TABLE
+ * Set the mapping table for a .1p mapping.
+ */
+#define MC_CMD_DOT1P_MAPPING_SET_TABLE 0xa6
+#undef MC_CMD_0xa6_PRIVILEGE_CTG
+
+#define MC_CMD_0xa6_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DOT1P_MAPPING_SET_TABLE_IN msgrequest */
+#define MC_CMD_DOT1P_MAPPING_SET_TABLE_IN_LEN 36
+/* The handle of the .1p mapping */
+#define MC_CMD_DOT1P_MAPPING_SET_TABLE_IN_DOT1P_MAPPING_ID_OFST 0
+/* Per-priority mappings (1 32-bit word per entry - an offset or RSS context
+ * handle)
+ */
+#define MC_CMD_DOT1P_MAPPING_SET_TABLE_IN_MAPPING_TABLE_OFST 4
+#define MC_CMD_DOT1P_MAPPING_SET_TABLE_IN_MAPPING_TABLE_LEN 32
+
+/* MC_CMD_DOT1P_MAPPING_SET_TABLE_OUT msgresponse */
+#define MC_CMD_DOT1P_MAPPING_SET_TABLE_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_DOT1P_MAPPING_GET_TABLE
+ * Get the mapping table for a .1p mapping.
+ */
+#define MC_CMD_DOT1P_MAPPING_GET_TABLE 0xa7
+#undef MC_CMD_0xa7_PRIVILEGE_CTG
+
+#define MC_CMD_0xa7_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DOT1P_MAPPING_GET_TABLE_IN msgrequest */
+#define MC_CMD_DOT1P_MAPPING_GET_TABLE_IN_LEN 4
+/* The handle of the .1p mapping */
+#define MC_CMD_DOT1P_MAPPING_GET_TABLE_IN_DOT1P_MAPPING_ID_OFST 0
+
+/* MC_CMD_DOT1P_MAPPING_GET_TABLE_OUT msgresponse */
+#define MC_CMD_DOT1P_MAPPING_GET_TABLE_OUT_LEN 36
+/* Per-priority mappings (1 32-bit word per entry - an offset or RSS context
+ * handle)
+ */
+#define MC_CMD_DOT1P_MAPPING_GET_TABLE_OUT_MAPPING_TABLE_OFST 4
+#define MC_CMD_DOT1P_MAPPING_GET_TABLE_OUT_MAPPING_TABLE_LEN 32
+
+
+/***********************************/
+/* MC_CMD_GET_VECTOR_CFG
+ * Get Interrupt Vector config for this PF.
+ */
+#define MC_CMD_GET_VECTOR_CFG 0xbf
+#undef MC_CMD_0xbf_PRIVILEGE_CTG
+
+#define MC_CMD_0xbf_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_VECTOR_CFG_IN msgrequest */
+#define MC_CMD_GET_VECTOR_CFG_IN_LEN 0
+
+/* MC_CMD_GET_VECTOR_CFG_OUT msgresponse */
+#define MC_CMD_GET_VECTOR_CFG_OUT_LEN 12
+/* Base absolute interrupt vector number. */
+#define MC_CMD_GET_VECTOR_CFG_OUT_VEC_BASE_OFST 0
+/* Number of interrupt vectors allocate to this PF. */
+#define MC_CMD_GET_VECTOR_CFG_OUT_VECS_PER_PF_OFST 4
+/* Number of interrupt vectors to allocate per VF. */
+#define MC_CMD_GET_VECTOR_CFG_OUT_VECS_PER_VF_OFST 8
+
+
+/***********************************/
+/* MC_CMD_SET_VECTOR_CFG
+ * Set Interrupt Vector config for this PF.
+ */
+#define MC_CMD_SET_VECTOR_CFG 0xc0
+#undef MC_CMD_0xc0_PRIVILEGE_CTG
+
+#define MC_CMD_0xc0_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_SET_VECTOR_CFG_IN msgrequest */
+#define MC_CMD_SET_VECTOR_CFG_IN_LEN 12
+/* Base absolute interrupt vector number, or MC_CMD_RESOURCE_INSTANCE_ANY to
+ * let the system find a suitable base.
+ */
+#define MC_CMD_SET_VECTOR_CFG_IN_VEC_BASE_OFST 0
+/* Number of interrupt vectors allocate to this PF. */
+#define MC_CMD_SET_VECTOR_CFG_IN_VECS_PER_PF_OFST 4
+/* Number of interrupt vectors to allocate per VF. */
+#define MC_CMD_SET_VECTOR_CFG_IN_VECS_PER_VF_OFST 8
+
+/* MC_CMD_SET_VECTOR_CFG_OUT msgresponse */
+#define MC_CMD_SET_VECTOR_CFG_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_VPORT_ADD_MAC_ADDRESS
+ * Add a MAC address to a v-port
+ */
+#define MC_CMD_VPORT_ADD_MAC_ADDRESS 0xa8
+#undef MC_CMD_0xa8_PRIVILEGE_CTG
+
+#define MC_CMD_0xa8_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VPORT_ADD_MAC_ADDRESS_IN msgrequest */
+#define MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_LEN 10
+/* The handle of the v-port */
+#define MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_VPORT_ID_OFST 0
+/* MAC address to add */
+#define MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_MACADDR_OFST 4
+#define MC_CMD_VPORT_ADD_MAC_ADDRESS_IN_MACADDR_LEN 6
+
+/* MC_CMD_VPORT_ADD_MAC_ADDRESS_OUT msgresponse */
+#define MC_CMD_VPORT_ADD_MAC_ADDRESS_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_VPORT_DEL_MAC_ADDRESS
+ * Delete a MAC address from a v-port
+ */
+#define MC_CMD_VPORT_DEL_MAC_ADDRESS 0xa9
+#undef MC_CMD_0xa9_PRIVILEGE_CTG
+
+#define MC_CMD_0xa9_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VPORT_DEL_MAC_ADDRESS_IN msgrequest */
+#define MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_LEN 10
+/* The handle of the v-port */
+#define MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_VPORT_ID_OFST 0
+/* MAC address to add */
+#define MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_MACADDR_OFST 4
+#define MC_CMD_VPORT_DEL_MAC_ADDRESS_IN_MACADDR_LEN 6
+
+/* MC_CMD_VPORT_DEL_MAC_ADDRESS_OUT msgresponse */
+#define MC_CMD_VPORT_DEL_MAC_ADDRESS_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_VPORT_GET_MAC_ADDRESSES
+ * Delete a MAC address from a v-port
+ */
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES 0xaa
+#undef MC_CMD_0xaa_PRIVILEGE_CTG
+
+#define MC_CMD_0xaa_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_VPORT_GET_MAC_ADDRESSES_IN msgrequest */
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN 4
+/* The handle of the v-port */
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_VPORT_ID_OFST 0
+
+/* MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT msgresponse */
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMIN 4
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX 250
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LEN(num) (4+6*(num))
+/* The number of MAC addresses returned */
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_COUNT_OFST 0
+/* Array of MAC addresses */
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_OFST 4
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_LEN 6
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_MINNUM 0
+#define MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_MAXNUM 41
+
+
+/***********************************/
+/* MC_CMD_DUMP_BUFTBL_ENTRIES
+ * Dump buffer table entries, mainly for command client debug use. Dumps
+ * absolute entries, and does not use chunk handles. All entries must be in
+ * range, and used for q page mapping, Although the latter restriction may be
+ * lifted in future.
+ */
+#define MC_CMD_DUMP_BUFTBL_ENTRIES 0xab
+#undef MC_CMD_0xab_PRIVILEGE_CTG
+
+#define MC_CMD_0xab_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DUMP_BUFTBL_ENTRIES_IN msgrequest */
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_IN_LEN 8
+/* Index of the first buffer table entry. */
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_IN_FIRSTID_OFST 0
+/* Number of buffer table entries to dump. */
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_IN_NUMENTRIES_OFST 4
+
+/* MC_CMD_DUMP_BUFTBL_ENTRIES_OUT msgresponse */
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_LENMIN 12
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_LENMAX 252
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_LEN(num) (0+12*(num))
+/* Raw buffer table entries, layed out as BUFTBL_ENTRY. */
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_ENTRY_OFST 0
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_ENTRY_LEN 12
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_ENTRY_MINNUM 1
+#define MC_CMD_DUMP_BUFTBL_ENTRIES_OUT_ENTRY_MAXNUM 21
+
+
+/***********************************/
+/* MC_CMD_SET_RXDP_CONFIG
+ * Set global RXDP configuration settings
+ */
+#define MC_CMD_SET_RXDP_CONFIG 0xc1
+#undef MC_CMD_0xc1_PRIVILEGE_CTG
+
+#define MC_CMD_0xc1_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_SET_RXDP_CONFIG_IN msgrequest */
+#define MC_CMD_SET_RXDP_CONFIG_IN_LEN 4
+#define MC_CMD_SET_RXDP_CONFIG_IN_DATA_OFST 0
+#define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_DMA_LBN 0
+#define MC_CMD_SET_RXDP_CONFIG_IN_PAD_HOST_DMA_WIDTH 1
+
+/* MC_CMD_SET_RXDP_CONFIG_OUT msgresponse */
+#define MC_CMD_SET_RXDP_CONFIG_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_GET_RXDP_CONFIG
+ * Get global RXDP configuration settings
+ */
+#define MC_CMD_GET_RXDP_CONFIG 0xc2
+#undef MC_CMD_0xc2_PRIVILEGE_CTG
+
+#define MC_CMD_0xc2_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_GET_RXDP_CONFIG_IN msgrequest */
+#define MC_CMD_GET_RXDP_CONFIG_IN_LEN 0
+
+/* MC_CMD_GET_RXDP_CONFIG_OUT msgresponse */
+#define MC_CMD_GET_RXDP_CONFIG_OUT_LEN 4
+#define MC_CMD_GET_RXDP_CONFIG_OUT_DATA_OFST 0
+#define MC_CMD_GET_RXDP_CONFIG_OUT_PAD_HOST_DMA_LBN 0
+#define MC_CMD_GET_RXDP_CONFIG_OUT_PAD_HOST_DMA_WIDTH 1
+
+
+/***********************************/
+/* MC_CMD_GET_CLOCK
+ * Return the system and PDCPU clock frequencies.
+ */
+#define MC_CMD_GET_CLOCK 0xac
+#undef MC_CMD_0xac_PRIVILEGE_CTG
+
+#define MC_CMD_0xac_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_CLOCK_IN msgrequest */
+#define MC_CMD_GET_CLOCK_IN_LEN 0
+
+/* MC_CMD_GET_CLOCK_OUT msgresponse */
+#define MC_CMD_GET_CLOCK_OUT_LEN 8
+/* System frequency, MHz */
+#define MC_CMD_GET_CLOCK_OUT_SYS_FREQ_OFST 0
+/* DPCPU frequency, MHz */
+#define MC_CMD_GET_CLOCK_OUT_DPCPU_FREQ_OFST 4
+
+
+/***********************************/
+/* MC_CMD_SET_CLOCK
+ * Control the system and DPCPU clock frequencies. Changes are lost reboot.
+ */
+#define MC_CMD_SET_CLOCK 0xad
+#undef MC_CMD_0xad_PRIVILEGE_CTG
+
+#define MC_CMD_0xad_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_SET_CLOCK_IN msgrequest */
+#define MC_CMD_SET_CLOCK_IN_LEN 28
+/* Requested frequency in MHz for system clock domain */
+#define MC_CMD_SET_CLOCK_IN_SYS_FREQ_OFST 0
+/* enum: Leave the system clock domain frequency unchanged */
+#define MC_CMD_SET_CLOCK_IN_SYS_DOMAIN_DONT_CHANGE 0x0
+/* Requested frequency in MHz for inter-core clock domain */
+#define MC_CMD_SET_CLOCK_IN_ICORE_FREQ_OFST 4
+/* enum: Leave the inter-core clock domain frequency unchanged */
+#define MC_CMD_SET_CLOCK_IN_ICORE_DOMAIN_DONT_CHANGE 0x0
+/* Requested frequency in MHz for DPCPU clock domain */
+#define MC_CMD_SET_CLOCK_IN_DPCPU_FREQ_OFST 8
+/* enum: Leave the DPCPU clock domain frequency unchanged */
+#define MC_CMD_SET_CLOCK_IN_DPCPU_DOMAIN_DONT_CHANGE 0x0
+/* Requested frequency in MHz for PCS clock domain */
+#define MC_CMD_SET_CLOCK_IN_PCS_FREQ_OFST 12
+/* enum: Leave the PCS clock domain frequency unchanged */
+#define MC_CMD_SET_CLOCK_IN_PCS_DOMAIN_DONT_CHANGE 0x0
+/* Requested frequency in MHz for MC clock domain */
+#define MC_CMD_SET_CLOCK_IN_MC_FREQ_OFST 16
+/* enum: Leave the MC clock domain frequency unchanged */
+#define MC_CMD_SET_CLOCK_IN_MC_DOMAIN_DONT_CHANGE 0x0
+/* Requested frequency in MHz for rmon clock domain */
+#define MC_CMD_SET_CLOCK_IN_RMON_FREQ_OFST 20
+/* enum: Leave the rmon clock domain frequency unchanged */
+#define MC_CMD_SET_CLOCK_IN_RMON_DOMAIN_DONT_CHANGE 0x0
+/* Requested frequency in MHz for vswitch clock domain */
+#define MC_CMD_SET_CLOCK_IN_VSWITCH_FREQ_OFST 24
+/* enum: Leave the vswitch clock domain frequency unchanged */
+#define MC_CMD_SET_CLOCK_IN_VSWITCH_DOMAIN_DONT_CHANGE 0x0
+
+/* MC_CMD_SET_CLOCK_OUT msgresponse */
+#define MC_CMD_SET_CLOCK_OUT_LEN 28
+/* Resulting system frequency in MHz */
+#define MC_CMD_SET_CLOCK_OUT_SYS_FREQ_OFST 0
+/* enum: The system clock domain doesn't exist */
+#define MC_CMD_SET_CLOCK_OUT_SYS_DOMAIN_UNSUPPORTED 0x0
+/* Resulting inter-core frequency in MHz */
+#define MC_CMD_SET_CLOCK_OUT_ICORE_FREQ_OFST 4
+/* enum: The inter-core clock domain doesn't exist / isn't used */
+#define MC_CMD_SET_CLOCK_OUT_ICORE_DOMAIN_UNSUPPORTED 0x0
+/* Resulting DPCPU frequency in MHz */
+#define MC_CMD_SET_CLOCK_OUT_DPCPU_FREQ_OFST 8
+/* enum: The dpcpu clock domain doesn't exist */
+#define MC_CMD_SET_CLOCK_OUT_DPCPU_DOMAIN_UNSUPPORTED 0x0
+/* Resulting PCS frequency in MHz */
+#define MC_CMD_SET_CLOCK_OUT_PCS_FREQ_OFST 12
+/* enum: The PCS clock domain doesn't exist / isn't controlled */
+#define MC_CMD_SET_CLOCK_OUT_PCS_DOMAIN_UNSUPPORTED 0x0
+/* Resulting MC frequency in MHz */
+#define MC_CMD_SET_CLOCK_OUT_MC_FREQ_OFST 16
+/* enum: The MC clock domain doesn't exist / isn't controlled */
+#define MC_CMD_SET_CLOCK_OUT_MC_DOMAIN_UNSUPPORTED 0x0
+/* Resulting rmon frequency in MHz */
+#define MC_CMD_SET_CLOCK_OUT_RMON_FREQ_OFST 20
+/* enum: The rmon clock domain doesn't exist / isn't controlled */
+#define MC_CMD_SET_CLOCK_OUT_RMON_DOMAIN_UNSUPPORTED 0x0
+/* Resulting vswitch frequency in MHz */
+#define MC_CMD_SET_CLOCK_OUT_VSWITCH_FREQ_OFST 24
+/* enum: The vswitch clock domain doesn't exist / isn't controlled */
+#define MC_CMD_SET_CLOCK_OUT_VSWITCH_DOMAIN_UNSUPPORTED 0x0
+
+
+/***********************************/
+/* MC_CMD_DPCPU_RPC
+ * Send an arbitrary DPCPU message.
+ */
+#define MC_CMD_DPCPU_RPC 0xae
+#undef MC_CMD_0xae_PRIVILEGE_CTG
+
+#define MC_CMD_0xae_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DPCPU_RPC_IN msgrequest */
+#define MC_CMD_DPCPU_RPC_IN_LEN 36
+#define MC_CMD_DPCPU_RPC_IN_CPU_OFST 0
+/* enum: RxDPCPU0 */
+#define MC_CMD_DPCPU_RPC_IN_DPCPU_RX0 0x0
+/* enum: TxDPCPU0 */
+#define MC_CMD_DPCPU_RPC_IN_DPCPU_TX0 0x1
+/* enum: TxDPCPU1 */
+#define MC_CMD_DPCPU_RPC_IN_DPCPU_TX1 0x2
+/* enum: RxDPCPU1 (Medford only) */
+#define MC_CMD_DPCPU_RPC_IN_DPCPU_RX1 0x3
+/* enum: RxDPCPU (will be for the calling function; for now, just an alias of
+ * DPCPU_RX0)
+ */
+#define MC_CMD_DPCPU_RPC_IN_DPCPU_RX 0x80
+/* enum: TxDPCPU (will be for the calling function; for now, just an alias of
+ * DPCPU_TX0)
+ */
+#define MC_CMD_DPCPU_RPC_IN_DPCPU_TX 0x81
+/* First 8 bits [39:32] of DATA are consumed by MC-DPCPU protocol and must be
+ * initialised to zero
+ */
+#define MC_CMD_DPCPU_RPC_IN_DATA_OFST 4
+#define MC_CMD_DPCPU_RPC_IN_DATA_LEN 32
+#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_CMDNUM_LBN 8
+#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_CMDNUM_WIDTH 8
+#define MC_CMD_DPCPU_RPC_IN_CMDNUM_TXDPCPU_READ 0x6 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CMDNUM_TXDPCPU_WRITE 0x7 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CMDNUM_TXDPCPU_SELF_TEST 0xc /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CMDNUM_TXDPCPU_CSR_ACCESS 0xe /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_READ 0x46 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_WRITE 0x47 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_SELF_TEST 0x4a /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_CSR_ACCESS 0x4c /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CMDNUM_RXDPCPU_SET_MC_REPLAY_CNTXT 0x4d /* enum */
+#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_OBJID_LBN 16
+#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_OBJID_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_ADDR_LBN 16
+#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_ADDR_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_COUNT_LBN 48
+#define MC_CMD_DPCPU_RPC_IN_HDR_CMD_REQ_COUNT_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_INFO_LBN 16
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_INFO_WIDTH 240
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_LBN 16
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_STOP_RETURN_RESULT 0x0 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_START_READ 0x1 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_START_WRITE 0x2 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_START_WRITE_READ 0x3 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_CMD_START_PIPELINED_READ 0x4 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_START_DELAY_LBN 48
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_START_DELAY_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_RPT_COUNT_LBN 64
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_RPT_COUNT_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_GAP_DELAY_LBN 80
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_GAP_DELAY_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_LBN 16
+#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_CUT_THROUGH 0x1 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_STORE_FORWARD 0x2 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_MODE_STORE_FORWARD_FIRST 0x3 /* enum */
+#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_CNTXT_LBN 64
+#define MC_CMD_DPCPU_RPC_IN_MC_REPLAY_CNTXT_WIDTH 16
+#define MC_CMD_DPCPU_RPC_IN_WDATA_OFST 12
+#define MC_CMD_DPCPU_RPC_IN_WDATA_LEN 24
+/* Register data to write. Only valid in write/write-read. */
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_DATA_OFST 16
+/* Register address. */
+#define MC_CMD_DPCPU_RPC_IN_CSR_ACCESS_ADDRESS_OFST 20
+
+/* MC_CMD_DPCPU_RPC_OUT msgresponse */
+#define MC_CMD_DPCPU_RPC_OUT_LEN 36
+#define MC_CMD_DPCPU_RPC_OUT_RC_OFST 0
+/* DATA */
+#define MC_CMD_DPCPU_RPC_OUT_DATA_OFST 4
+#define MC_CMD_DPCPU_RPC_OUT_DATA_LEN 32
+#define MC_CMD_DPCPU_RPC_OUT_HDR_CMD_RESP_ERRCODE_LBN 32
+#define MC_CMD_DPCPU_RPC_OUT_HDR_CMD_RESP_ERRCODE_WIDTH 16
+#define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_COUNT_LBN 48
+#define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_COUNT_WIDTH 16
+#define MC_CMD_DPCPU_RPC_OUT_RDATA_OFST 12
+#define MC_CMD_DPCPU_RPC_OUT_RDATA_LEN 24
+#define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_VAL_1_OFST 12
+#define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_VAL_2_OFST 16
+#define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_VAL_3_OFST 20
+#define MC_CMD_DPCPU_RPC_OUT_CSR_ACCESS_READ_VAL_4_OFST 24
+
+
+/***********************************/
+/* MC_CMD_TRIGGER_INTERRUPT
+ * Trigger an interrupt by prodding the BIU.
+ */
+#define MC_CMD_TRIGGER_INTERRUPT 0xe3
+#undef MC_CMD_0xe3_PRIVILEGE_CTG
+
+#define MC_CMD_0xe3_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_TRIGGER_INTERRUPT_IN msgrequest */
+#define MC_CMD_TRIGGER_INTERRUPT_IN_LEN 4
+/* Interrupt level relative to base for function. */
+#define MC_CMD_TRIGGER_INTERRUPT_IN_INTR_LEVEL_OFST 0
+
+/* MC_CMD_TRIGGER_INTERRUPT_OUT msgresponse */
+#define MC_CMD_TRIGGER_INTERRUPT_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_SHMBOOT_OP
+ * Special operations to support (for now) shmboot.
+ */
+#define MC_CMD_SHMBOOT_OP 0xe6
+#undef MC_CMD_0xe6_PRIVILEGE_CTG
+
+#define MC_CMD_0xe6_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_SHMBOOT_OP_IN msgrequest */
+#define MC_CMD_SHMBOOT_OP_IN_LEN 4
+/* Identifies the operation to perform */
+#define MC_CMD_SHMBOOT_OP_IN_SHMBOOT_OP_OFST 0
+/* enum: Copy slave_data section to the slave core. (Greenport only) */
+#define MC_CMD_SHMBOOT_OP_IN_PUSH_SLAVE_DATA 0x0
+
+/* MC_CMD_SHMBOOT_OP_OUT msgresponse */
+#define MC_CMD_SHMBOOT_OP_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_CAP_BLK_READ
+ * Read multiple 64bit words from capture block memory
+ */
+#define MC_CMD_CAP_BLK_READ 0xe7
+#undef MC_CMD_0xe7_PRIVILEGE_CTG
+
+#define MC_CMD_0xe7_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_CAP_BLK_READ_IN msgrequest */
+#define MC_CMD_CAP_BLK_READ_IN_LEN 12
+#define MC_CMD_CAP_BLK_READ_IN_CAP_REG_OFST 0
+#define MC_CMD_CAP_BLK_READ_IN_ADDR_OFST 4
+#define MC_CMD_CAP_BLK_READ_IN_COUNT_OFST 8
+
+/* MC_CMD_CAP_BLK_READ_OUT msgresponse */
+#define MC_CMD_CAP_BLK_READ_OUT_LENMIN 8
+#define MC_CMD_CAP_BLK_READ_OUT_LENMAX 248
+#define MC_CMD_CAP_BLK_READ_OUT_LEN(num) (0+8*(num))
+#define MC_CMD_CAP_BLK_READ_OUT_BUFFER_OFST 0
+#define MC_CMD_CAP_BLK_READ_OUT_BUFFER_LEN 8
+#define MC_CMD_CAP_BLK_READ_OUT_BUFFER_LO_OFST 0
+#define MC_CMD_CAP_BLK_READ_OUT_BUFFER_HI_OFST 4
+#define MC_CMD_CAP_BLK_READ_OUT_BUFFER_MINNUM 1
+#define MC_CMD_CAP_BLK_READ_OUT_BUFFER_MAXNUM 31
+
+
+/***********************************/
+/* MC_CMD_DUMP_DO
+ * Take a dump of the DUT state
+ */
+#define MC_CMD_DUMP_DO 0xe8
+#undef MC_CMD_0xe8_PRIVILEGE_CTG
+
+#define MC_CMD_0xe8_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DUMP_DO_IN msgrequest */
+#define MC_CMD_DUMP_DO_IN_LEN 52
+#define MC_CMD_DUMP_DO_IN_PADDING_OFST 0
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_OFST 4
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM 0x0 /* enum */
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_DEFAULT 0x1 /* enum */
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_TYPE_OFST 8
+#define MC_CMD_DUMP_DO_IN_DUMP_LOCATION_NVRAM 0x1 /* enum */
+#define MC_CMD_DUMP_DO_IN_DUMP_LOCATION_HOST_MEMORY 0x2 /* enum */
+#define MC_CMD_DUMP_DO_IN_DUMP_LOCATION_HOST_MEMORY_MLI 0x3 /* enum */
+#define MC_CMD_DUMP_DO_IN_DUMP_LOCATION_UART 0x4 /* enum */
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_NVRAM_PARTITION_TYPE_ID_OFST 12
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_NVRAM_OFFSET_OFST 16
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_ADDR_LO_OFST 12
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_ADDR_HI_OFST 16
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_LO_OFST 12
+#define MC_CMD_DUMP_DO_IN_HOST_MEMORY_MLI_PAGE_SIZE 0x1000 /* enum */
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_HI_OFST 16
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_DEPTH_OFST 20
+#define MC_CMD_DUMP_DO_IN_HOST_MEMORY_MLI_MAX_DEPTH 0x2 /* enum */
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_UART_PORT_OFST 12
+/* enum: The uart port this command was received over (if using a uart
+ * transport)
+ */
+#define MC_CMD_DUMP_DO_IN_UART_PORT_SRC 0xff
+#define MC_CMD_DUMP_DO_IN_DUMPSPEC_SRC_CUSTOM_SIZE_OFST 24
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_OFST 28
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM 0x0 /* enum */
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_NVRAM_DUMP_PARTITION 0x1 /* enum */
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_TYPE_OFST 32
+/* Enum values, see field(s): */
+/* MC_CMD_DUMP_DO_IN/DUMPSPEC_SRC_CUSTOM_TYPE */
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_NVRAM_PARTITION_TYPE_ID_OFST 36
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_NVRAM_OFFSET_OFST 40
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_ADDR_LO_OFST 36
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_ADDR_HI_OFST 40
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_LO_OFST 36
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_HI_OFST 40
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_DEPTH_OFST 44
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_UART_PORT_OFST 36
+#define MC_CMD_DUMP_DO_IN_DUMPFILE_DST_CUSTOM_SIZE_OFST 48
+
+/* MC_CMD_DUMP_DO_OUT msgresponse */
+#define MC_CMD_DUMP_DO_OUT_LEN 4
+#define MC_CMD_DUMP_DO_OUT_DUMPFILE_SIZE_OFST 0
+
+
+/***********************************/
+/* MC_CMD_DUMP_CONFIGURE_UNSOLICITED
+ * Configure unsolicited dumps
+ */
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED 0xe9
+#undef MC_CMD_0xe9_PRIVILEGE_CTG
+
+#define MC_CMD_0xe9_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN msgrequest */
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_LEN 52
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_ENABLE_OFST 0
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_OFST 4
+/* Enum values, see field(s): */
+/* MC_CMD_DUMP_DO/MC_CMD_DUMP_DO_IN/DUMPSPEC_SRC */
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_TYPE_OFST 8
+/* Enum values, see field(s): */
+/* MC_CMD_DUMP_DO/MC_CMD_DUMP_DO_IN/DUMPSPEC_SRC_CUSTOM_TYPE */
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_NVRAM_PARTITION_TYPE_ID_OFST 12
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_NVRAM_OFFSET_OFST 16
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_ADDR_LO_OFST 12
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_ADDR_HI_OFST 16
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_LO_OFST 12
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_HI_OFST 16
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_HOST_MEMORY_MLI_DEPTH_OFST 20
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_UART_PORT_OFST 12
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPSPEC_SRC_CUSTOM_SIZE_OFST 24
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_OFST 28
+/* Enum values, see field(s): */
+/* MC_CMD_DUMP_DO/MC_CMD_DUMP_DO_IN/DUMPFILE_DST */
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_TYPE_OFST 32
+/* Enum values, see field(s): */
+/* MC_CMD_DUMP_DO/MC_CMD_DUMP_DO_IN/DUMPSPEC_SRC_CUSTOM_TYPE */
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_NVRAM_PARTITION_TYPE_ID_OFST 36
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_NVRAM_OFFSET_OFST 40
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_ADDR_LO_OFST 36
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_ADDR_HI_OFST 40
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_LO_OFST 36
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_ROOT_ADDR_HI_OFST 40
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_HOST_MEMORY_MLI_DEPTH_OFST 44
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_UART_PORT_OFST 36
+#define MC_CMD_DUMP_CONFIGURE_UNSOLICITED_IN_DUMPFILE_DST_CUSTOM_SIZE_OFST 48
+
+
+/***********************************/
+/* MC_CMD_SET_PSU
+ * Adjusts power supply parameters. This is a warranty-voiding operation.
+ * Returns: ENOENT if the parameter or rail specified does not exist, EINVAL if
+ * the parameter is out of range.
+ */
+#define MC_CMD_SET_PSU 0xea
+#undef MC_CMD_0xea_PRIVILEGE_CTG
+
+#define MC_CMD_0xea_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_SET_PSU_IN msgrequest */
+#define MC_CMD_SET_PSU_IN_LEN 12
+#define MC_CMD_SET_PSU_IN_PARAM_OFST 0
+#define MC_CMD_SET_PSU_IN_PARAM_SUPPLY_VOLTAGE 0x0 /* enum */
+#define MC_CMD_SET_PSU_IN_RAIL_OFST 4
+#define MC_CMD_SET_PSU_IN_RAIL_0V9 0x0 /* enum */
+#define MC_CMD_SET_PSU_IN_RAIL_1V2 0x1 /* enum */
+/* desired value, eg voltage in mV */
+#define MC_CMD_SET_PSU_IN_VALUE_OFST 8
+
+/* MC_CMD_SET_PSU_OUT msgresponse */
+#define MC_CMD_SET_PSU_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_GET_FUNCTION_INFO
+ * Get function information. PF and VF number.
+ */
+#define MC_CMD_GET_FUNCTION_INFO 0xec
+#undef MC_CMD_0xec_PRIVILEGE_CTG
+
+#define MC_CMD_0xec_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_FUNCTION_INFO_IN msgrequest */
+#define MC_CMD_GET_FUNCTION_INFO_IN_LEN 0
+
+/* MC_CMD_GET_FUNCTION_INFO_OUT msgresponse */
+#define MC_CMD_GET_FUNCTION_INFO_OUT_LEN 8
+#define MC_CMD_GET_FUNCTION_INFO_OUT_PF_OFST 0
+#define MC_CMD_GET_FUNCTION_INFO_OUT_VF_OFST 4
+
+
+/***********************************/
+/* MC_CMD_ENABLE_OFFLINE_BIST
+ * Enters offline BIST mode. All queues are torn down, chip enters quiescent
+ * mode, calling function gets exclusive MCDI ownership. The only way out is
+ * reboot.
+ */
+#define MC_CMD_ENABLE_OFFLINE_BIST 0xed
+#undef MC_CMD_0xed_PRIVILEGE_CTG
+
+#define MC_CMD_0xed_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_ENABLE_OFFLINE_BIST_IN msgrequest */
+#define MC_CMD_ENABLE_OFFLINE_BIST_IN_LEN 0
+
+/* MC_CMD_ENABLE_OFFLINE_BIST_OUT msgresponse */
+#define MC_CMD_ENABLE_OFFLINE_BIST_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_UART_SEND_DATA
+ * Send checksummed[sic] block of data over the uart. Response is a placeholder
+ * should we wish to make this reliable; currently requests are fire-and-
+ * forget.
+ */
+#define MC_CMD_UART_SEND_DATA 0xee
+#undef MC_CMD_0xee_PRIVILEGE_CTG
+
+#define MC_CMD_0xee_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_UART_SEND_DATA_OUT msgrequest */
+#define MC_CMD_UART_SEND_DATA_OUT_LENMIN 16
+#define MC_CMD_UART_SEND_DATA_OUT_LENMAX 252
+#define MC_CMD_UART_SEND_DATA_OUT_LEN(num) (16+1*(num))
+/* CRC32 over OFFSET, LENGTH, RESERVED, DATA */
+#define MC_CMD_UART_SEND_DATA_OUT_CHECKSUM_OFST 0
+/* Offset at which to write the data */
+#define MC_CMD_UART_SEND_DATA_OUT_OFFSET_OFST 4
+/* Length of data */
+#define MC_CMD_UART_SEND_DATA_OUT_LENGTH_OFST 8
+/* Reserved for future use */
+#define MC_CMD_UART_SEND_DATA_OUT_RESERVED_OFST 12
+#define MC_CMD_UART_SEND_DATA_OUT_DATA_OFST 16
+#define MC_CMD_UART_SEND_DATA_OUT_DATA_LEN 1
+#define MC_CMD_UART_SEND_DATA_OUT_DATA_MINNUM 0
+#define MC_CMD_UART_SEND_DATA_OUT_DATA_MAXNUM 236
+
+/* MC_CMD_UART_SEND_DATA_IN msgresponse */
+#define MC_CMD_UART_SEND_DATA_IN_LEN 0
+
+
+/***********************************/
+/* MC_CMD_UART_RECV_DATA
+ * Request checksummed[sic] block of data over the uart. Only a placeholder,
+ * subject to change and not currently implemented.
+ */
+#define MC_CMD_UART_RECV_DATA 0xef
+#undef MC_CMD_0xef_PRIVILEGE_CTG
+
+#define MC_CMD_0xef_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_UART_RECV_DATA_OUT msgrequest */
+#define MC_CMD_UART_RECV_DATA_OUT_LEN 16
+/* CRC32 over OFFSET, LENGTH, RESERVED */
+#define MC_CMD_UART_RECV_DATA_OUT_CHECKSUM_OFST 0
+/* Offset from which to read the data */
+#define MC_CMD_UART_RECV_DATA_OUT_OFFSET_OFST 4
+/* Length of data */
+#define MC_CMD_UART_RECV_DATA_OUT_LENGTH_OFST 8
+/* Reserved for future use */
+#define MC_CMD_UART_RECV_DATA_OUT_RESERVED_OFST 12
+
+/* MC_CMD_UART_RECV_DATA_IN msgresponse */
+#define MC_CMD_UART_RECV_DATA_IN_LENMIN 16
+#define MC_CMD_UART_RECV_DATA_IN_LENMAX 252
+#define MC_CMD_UART_RECV_DATA_IN_LEN(num) (16+1*(num))
+/* CRC32 over RESERVED1, RESERVED2, RESERVED3, DATA */
+#define MC_CMD_UART_RECV_DATA_IN_CHECKSUM_OFST 0
+/* Offset at which to write the data */
+#define MC_CMD_UART_RECV_DATA_IN_RESERVED1_OFST 4
+/* Length of data */
+#define MC_CMD_UART_RECV_DATA_IN_RESERVED2_OFST 8
+/* Reserved for future use */
+#define MC_CMD_UART_RECV_DATA_IN_RESERVED3_OFST 12
+#define MC_CMD_UART_RECV_DATA_IN_DATA_OFST 16
+#define MC_CMD_UART_RECV_DATA_IN_DATA_LEN 1
+#define MC_CMD_UART_RECV_DATA_IN_DATA_MINNUM 0
+#define MC_CMD_UART_RECV_DATA_IN_DATA_MAXNUM 236
+
+
+/***********************************/
+/* MC_CMD_READ_FUSES
+ * Read data programmed into the device One-Time-Programmable (OTP) Fuses
+ */
+#define MC_CMD_READ_FUSES 0xf0
+#undef MC_CMD_0xf0_PRIVILEGE_CTG
+
+#define MC_CMD_0xf0_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_READ_FUSES_IN msgrequest */
+#define MC_CMD_READ_FUSES_IN_LEN 8
+/* Offset in OTP to read */
+#define MC_CMD_READ_FUSES_IN_OFFSET_OFST 0
+/* Length of data to read in bytes */
+#define MC_CMD_READ_FUSES_IN_LENGTH_OFST 4
+
+/* MC_CMD_READ_FUSES_OUT msgresponse */
+#define MC_CMD_READ_FUSES_OUT_LENMIN 4
+#define MC_CMD_READ_FUSES_OUT_LENMAX 252
+#define MC_CMD_READ_FUSES_OUT_LEN(num) (4+1*(num))
+/* Length of returned OTP data in bytes */
+#define MC_CMD_READ_FUSES_OUT_LENGTH_OFST 0
+/* Returned data */
+#define MC_CMD_READ_FUSES_OUT_DATA_OFST 4
+#define MC_CMD_READ_FUSES_OUT_DATA_LEN 1
+#define MC_CMD_READ_FUSES_OUT_DATA_MINNUM 0
+#define MC_CMD_READ_FUSES_OUT_DATA_MAXNUM 248
+
+
+/***********************************/
+/* MC_CMD_KR_TUNE
+ * Get or set KR Serdes RXEQ and TX Driver settings
+ */
+#define MC_CMD_KR_TUNE 0xf1
+#undef MC_CMD_0xf1_PRIVILEGE_CTG
+
+#define MC_CMD_0xf1_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_KR_TUNE_IN msgrequest */
+#define MC_CMD_KR_TUNE_IN_LENMIN 4
+#define MC_CMD_KR_TUNE_IN_LENMAX 252
+#define MC_CMD_KR_TUNE_IN_LEN(num) (4+4*(num))
+/* Requested operation */
+#define MC_CMD_KR_TUNE_IN_KR_TUNE_OP_OFST 0
+#define MC_CMD_KR_TUNE_IN_KR_TUNE_OP_LEN 1
+/* enum: Get current RXEQ settings */
+#define MC_CMD_KR_TUNE_IN_RXEQ_GET 0x0
+/* enum: Override RXEQ settings */
+#define MC_CMD_KR_TUNE_IN_RXEQ_SET 0x1
+/* enum: Get current TX Driver settings */
+#define MC_CMD_KR_TUNE_IN_TXEQ_GET 0x2
+/* enum: Override TX Driver settings */
+#define MC_CMD_KR_TUNE_IN_TXEQ_SET 0x3
+/* enum: Force KR Serdes reset / recalibration */
+#define MC_CMD_KR_TUNE_IN_RECAL 0x4
+/* enum: Start KR Serdes Eye diagram plot on a given lane. Lane must have valid
+ * signal.
+ */
+#define MC_CMD_KR_TUNE_IN_START_EYE_PLOT 0x5
+/* enum: Poll KR Serdes Eye diagram plot. Returns one row of BER data. The
+ * caller should call this command repeatedly after starting eye plot, until no
+ * more data is returned.
+ */
+#define MC_CMD_KR_TUNE_IN_POLL_EYE_PLOT 0x6
+/* enum: Read Figure Of Merit (eye quality, higher is better). */
+#define MC_CMD_KR_TUNE_IN_READ_FOM 0x7
+/* Align the arguments to 32 bits */
+#define MC_CMD_KR_TUNE_IN_KR_TUNE_RSVD_OFST 1
+#define MC_CMD_KR_TUNE_IN_KR_TUNE_RSVD_LEN 3
+/* Arguments specific to the operation */
+#define MC_CMD_KR_TUNE_IN_KR_TUNE_ARGS_OFST 4
+#define MC_CMD_KR_TUNE_IN_KR_TUNE_ARGS_LEN 4
+#define MC_CMD_KR_TUNE_IN_KR_TUNE_ARGS_MINNUM 0
+#define MC_CMD_KR_TUNE_IN_KR_TUNE_ARGS_MAXNUM 62
+
+/* MC_CMD_KR_TUNE_OUT msgresponse */
+#define MC_CMD_KR_TUNE_OUT_LEN 0
+
+/* MC_CMD_KR_TUNE_RXEQ_GET_IN msgrequest */
+#define MC_CMD_KR_TUNE_RXEQ_GET_IN_LEN 4
+/* Requested operation */
+#define MC_CMD_KR_TUNE_RXEQ_GET_IN_KR_TUNE_OP_OFST 0
+#define MC_CMD_KR_TUNE_RXEQ_GET_IN_KR_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_KR_TUNE_RXEQ_GET_IN_KR_TUNE_RSVD_OFST 1
+#define MC_CMD_KR_TUNE_RXEQ_GET_IN_KR_TUNE_RSVD_LEN 3
+
+/* MC_CMD_KR_TUNE_RXEQ_GET_OUT msgresponse */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LENMIN 4
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LENMAX 252
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LEN(num) (0+4*(num))
+/* RXEQ Parameter */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_OFST 0
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_LEN 4
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_MINNUM 1
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_MAXNUM 63
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_ID_LBN 0
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_ID_WIDTH 8
+/* enum: Attenuation (0-15, TBD for Medford) */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_ATT 0x0
+/* enum: CTLE Boost (0-15, TBD for Medford) */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_BOOST 0x1
+/* enum: Edge DFE Tap1 (0 - max negative, 64 - zero, 127 - max positive, TBD
+ * for Medford)
+ */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_TAP1 0x2
+/* enum: Edge DFE Tap2 (0 - max negative, 32 - zero, 63 - max positive, TBD for
+ * Medford)
+ */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_TAP2 0x3
+/* enum: Edge DFE Tap3 (0 - max negative, 32 - zero, 63 - max positive, TBD for
+ * Medford)
+ */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_TAP3 0x4
+/* enum: Edge DFE Tap4 (0 - max negative, 32 - zero, 63 - max positive, TBD for
+ * Medford)
+ */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_TAP4 0x5
+/* enum: Edge DFE Tap5 (0 - max negative, 32 - zero, 63 - max positive, TBD for
+ * Medford)
+ */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_TAP5 0x6
+/* enum: Edge DFE DLEV (TBD for Medford) */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_EDFE_DLEV 0x7
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_LANE_LBN 8
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_LANE_WIDTH 3
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_0 0x0 /* enum */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_1 0x1 /* enum */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_2 0x2 /* enum */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_3 0x3 /* enum */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_LANE_ALL 0x4 /* enum */
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_AUTOCAL_LBN 11
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_AUTOCAL_WIDTH 1
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_RESERVED_LBN 12
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_RESERVED_WIDTH 4
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_INITIAL_LBN 16
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_INITIAL_WIDTH 8
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_CURRENT_LBN 24
+#define MC_CMD_KR_TUNE_RXEQ_GET_OUT_PARAM_CURRENT_WIDTH 8
+
+/* MC_CMD_KR_TUNE_RXEQ_SET_IN msgrequest */
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_LENMIN 8
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_LENMAX 252
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_LEN(num) (4+4*(num))
+/* Requested operation */
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_KR_TUNE_OP_OFST 0
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_KR_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_KR_TUNE_RSVD_OFST 1
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_KR_TUNE_RSVD_LEN 3
+/* RXEQ Parameter */
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_OFST 4
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_LEN 4
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_MINNUM 1
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_MAXNUM 62
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_ID_LBN 0
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_ID_WIDTH 8
+/* Enum values, see field(s): */
+/* MC_CMD_KR_TUNE_RXEQ_GET_OUT/PARAM_ID */
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_LANE_LBN 8
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_LANE_WIDTH 3
+/* Enum values, see field(s): */
+/* MC_CMD_KR_TUNE_RXEQ_GET_OUT/PARAM_LANE */
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_AUTOCAL_LBN 11
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_AUTOCAL_WIDTH 1
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_RESERVED_LBN 12
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_RESERVED_WIDTH 4
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_INITIAL_LBN 16
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_PARAM_INITIAL_WIDTH 8
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_RESERVED2_LBN 24
+#define MC_CMD_KR_TUNE_RXEQ_SET_IN_RESERVED2_WIDTH 8
+
+/* MC_CMD_KR_TUNE_RXEQ_SET_OUT msgresponse */
+#define MC_CMD_KR_TUNE_RXEQ_SET_OUT_LEN 0
+
+/* MC_CMD_KR_TUNE_TXEQ_GET_IN msgrequest */
+#define MC_CMD_KR_TUNE_TXEQ_GET_IN_LEN 4
+/* Requested operation */
+#define MC_CMD_KR_TUNE_TXEQ_GET_IN_KR_TUNE_OP_OFST 0
+#define MC_CMD_KR_TUNE_TXEQ_GET_IN_KR_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_KR_TUNE_TXEQ_GET_IN_KR_TUNE_RSVD_OFST 1
+#define MC_CMD_KR_TUNE_TXEQ_GET_IN_KR_TUNE_RSVD_LEN 3
+
+/* MC_CMD_KR_TUNE_TXEQ_GET_OUT msgresponse */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LENMIN 4
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LENMAX 252
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LEN(num) (0+4*(num))
+/* TXEQ Parameter */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_OFST 0
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_LEN 4
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_MINNUM 1
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_MAXNUM 63
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_ID_LBN 0
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_ID_WIDTH 8
+/* enum: TX Amplitude */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_LEV 0x0
+/* enum: De-Emphasis Tap1 Magnitude (0-7) */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_MODE 0x1
+/* enum: De-Emphasis Tap1 Fine */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_DTLEV 0x2
+/* enum: De-Emphasis Tap2 Magnitude (0-6) */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_D2 0x3
+/* enum: De-Emphasis Tap2 Fine */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_D2TLEV 0x4
+/* enum: Pre-Emphasis Magnitude */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_E 0x5
+/* enum: Pre-Emphasis Fine */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_ETLEV 0x6
+/* enum: TX Slew Rate Coarse control */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_PREDRV_DLY 0x7
+/* enum: TX Slew Rate Fine control */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_SR_SET 0x8
+/* enum: TX Termination Impedance control */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_TX_RT_SET 0x9
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_LANE_LBN 8
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_LANE_WIDTH 3
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_0 0x0 /* enum */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_1 0x1 /* enum */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_2 0x2 /* enum */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_3 0x3 /* enum */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_LANE_ALL 0x4 /* enum */
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_RESERVED_LBN 11
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_RESERVED_WIDTH 5
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_INITIAL_LBN 16
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_PARAM_INITIAL_WIDTH 8
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_RESERVED2_LBN 24
+#define MC_CMD_KR_TUNE_TXEQ_GET_OUT_RESERVED2_WIDTH 8
+
+/* MC_CMD_KR_TUNE_TXEQ_SET_IN msgrequest */
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_LENMIN 8
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_LENMAX 252
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_LEN(num) (4+4*(num))
+/* Requested operation */
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_KR_TUNE_OP_OFST 0
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_KR_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_KR_TUNE_RSVD_OFST 1
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_KR_TUNE_RSVD_LEN 3
+/* TXEQ Parameter */
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_OFST 4
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_LEN 4
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_MINNUM 1
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_MAXNUM 62
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_ID_LBN 0
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_ID_WIDTH 8
+/* Enum values, see field(s): */
+/* MC_CMD_KR_TUNE_TXEQ_GET_OUT/PARAM_ID */
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_LANE_LBN 8
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_LANE_WIDTH 3
+/* Enum values, see field(s): */
+/* MC_CMD_KR_TUNE_TXEQ_GET_OUT/PARAM_LANE */
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_RESERVED_LBN 11
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_RESERVED_WIDTH 5
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_INITIAL_LBN 16
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_PARAM_INITIAL_WIDTH 8
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_RESERVED2_LBN 24
+#define MC_CMD_KR_TUNE_TXEQ_SET_IN_RESERVED2_WIDTH 8
+
+/* MC_CMD_KR_TUNE_TXEQ_SET_OUT msgresponse */
+#define MC_CMD_KR_TUNE_TXEQ_SET_OUT_LEN 0
+
+/* MC_CMD_KR_TUNE_RECAL_IN msgrequest */
+#define MC_CMD_KR_TUNE_RECAL_IN_LEN 4
+/* Requested operation */
+#define MC_CMD_KR_TUNE_RECAL_IN_KR_TUNE_OP_OFST 0
+#define MC_CMD_KR_TUNE_RECAL_IN_KR_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_KR_TUNE_RECAL_IN_KR_TUNE_RSVD_OFST 1
+#define MC_CMD_KR_TUNE_RECAL_IN_KR_TUNE_RSVD_LEN 3
+
+/* MC_CMD_KR_TUNE_RECAL_OUT msgresponse */
+#define MC_CMD_KR_TUNE_RECAL_OUT_LEN 0
+
+/* MC_CMD_KR_TUNE_START_EYE_PLOT_IN msgrequest */
+#define MC_CMD_KR_TUNE_START_EYE_PLOT_IN_LEN 8
+/* Requested operation */
+#define MC_CMD_KR_TUNE_START_EYE_PLOT_IN_KR_TUNE_OP_OFST 0
+#define MC_CMD_KR_TUNE_START_EYE_PLOT_IN_KR_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_KR_TUNE_START_EYE_PLOT_IN_KR_TUNE_RSVD_OFST 1
+#define MC_CMD_KR_TUNE_START_EYE_PLOT_IN_KR_TUNE_RSVD_LEN 3
+#define MC_CMD_KR_TUNE_START_EYE_PLOT_IN_LANE_OFST 4
+
+/* MC_CMD_KR_TUNE_START_EYE_PLOT_OUT msgresponse */
+#define MC_CMD_KR_TUNE_START_EYE_PLOT_OUT_LEN 0
+
+/* MC_CMD_KR_TUNE_POLL_EYE_PLOT_IN msgrequest */
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_IN_LEN 4
+/* Requested operation */
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_IN_KR_TUNE_OP_OFST 0
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_IN_KR_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_IN_KR_TUNE_RSVD_OFST 1
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_IN_KR_TUNE_RSVD_LEN 3
+
+/* MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT msgresponse */
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_LENMIN 0
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_LENMAX 252
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_LEN(num) (0+2*(num))
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_OFST 0
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_LEN 2
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_MINNUM 0
+#define MC_CMD_KR_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_MAXNUM 126
+
+/* MC_CMD_KR_TUNE_READ_FOM_IN msgrequest */
+#define MC_CMD_KR_TUNE_READ_FOM_IN_LEN 8
+/* Requested operation */
+#define MC_CMD_KR_TUNE_READ_FOM_IN_KR_TUNE_OP_OFST 0
+#define MC_CMD_KR_TUNE_READ_FOM_IN_KR_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_KR_TUNE_READ_FOM_IN_KR_TUNE_RSVD_OFST 1
+#define MC_CMD_KR_TUNE_READ_FOM_IN_KR_TUNE_RSVD_LEN 3
+#define MC_CMD_KR_TUNE_READ_FOM_IN_LANE_OFST 4
+
+/* MC_CMD_KR_TUNE_READ_FOM_OUT msgresponse */
+#define MC_CMD_KR_TUNE_READ_FOM_OUT_LEN 4
+#define MC_CMD_KR_TUNE_READ_FOM_OUT_FOM_OFST 0
+
+
+/***********************************/
+/* MC_CMD_PCIE_TUNE
+ * Get or set PCIE Serdes RXEQ and TX Driver settings
+ */
+#define MC_CMD_PCIE_TUNE 0xf2
+#undef MC_CMD_0xf2_PRIVILEGE_CTG
+
+#define MC_CMD_0xf2_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_PCIE_TUNE_IN msgrequest */
+#define MC_CMD_PCIE_TUNE_IN_LENMIN 4
+#define MC_CMD_PCIE_TUNE_IN_LENMAX 252
+#define MC_CMD_PCIE_TUNE_IN_LEN(num) (4+4*(num))
+/* Requested operation */
+#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_OP_OFST 0
+#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_OP_LEN 1
+/* enum: Get current RXEQ settings */
+#define MC_CMD_PCIE_TUNE_IN_RXEQ_GET 0x0
+/* enum: Override RXEQ settings */
+#define MC_CMD_PCIE_TUNE_IN_RXEQ_SET 0x1
+/* enum: Get current TX Driver settings */
+#define MC_CMD_PCIE_TUNE_IN_TXEQ_GET 0x2
+/* enum: Override TX Driver settings */
+#define MC_CMD_PCIE_TUNE_IN_TXEQ_SET 0x3
+/* enum: Start PCIe Serdes Eye diagram plot on a given lane. */
+#define MC_CMD_PCIE_TUNE_IN_START_EYE_PLOT 0x5
+/* enum: Poll PCIe Serdes Eye diagram plot. Returns one row of BER data. The
+ * caller should call this command repeatedly after starting eye plot, until no
+ * more data is returned.
+ */
+#define MC_CMD_PCIE_TUNE_IN_POLL_EYE_PLOT 0x6
+/* Align the arguments to 32 bits */
+#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_RSVD_OFST 1
+#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_RSVD_LEN 3
+/* Arguments specific to the operation */
+#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_ARGS_OFST 4
+#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_ARGS_LEN 4
+#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_ARGS_MINNUM 0
+#define MC_CMD_PCIE_TUNE_IN_PCIE_TUNE_ARGS_MAXNUM 62
+
+/* MC_CMD_PCIE_TUNE_OUT msgresponse */
+#define MC_CMD_PCIE_TUNE_OUT_LEN 0
+
+/* MC_CMD_PCIE_TUNE_RXEQ_GET_IN msgrequest */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_IN_LEN 4
+/* Requested operation */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_IN_PCIE_TUNE_OP_OFST 0
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_IN_PCIE_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_IN_PCIE_TUNE_RSVD_OFST 1
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_IN_PCIE_TUNE_RSVD_LEN 3
+
+/* MC_CMD_PCIE_TUNE_RXEQ_GET_OUT msgresponse */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LENMIN 4
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LENMAX 252
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LEN(num) (0+4*(num))
+/* RXEQ Parameter */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_OFST 0
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_LEN 4
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_MINNUM 1
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_MAXNUM 63
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_ID_LBN 0
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_ID_WIDTH 8
+/* enum: Attenuation (0-15) */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_ATT 0x0
+/* enum: CTLE Boost (0-15) */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_BOOST 0x1
+/* enum: DFE Tap1 (0 - max negative, 64 - zero, 127 - max positive) */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_DFE_TAP1 0x2
+/* enum: DFE Tap2 (0 - max negative, 32 - zero, 63 - max positive) */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_DFE_TAP2 0x3
+/* enum: DFE Tap3 (0 - max negative, 32 - zero, 63 - max positive) */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_DFE_TAP3 0x4
+/* enum: DFE Tap4 (0 - max negative, 32 - zero, 63 - max positive) */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_DFE_TAP4 0x5
+/* enum: DFE Tap5 (0 - max negative, 32 - zero, 63 - max positive) */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_DFE_TAP5 0x6
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_LANE_LBN 8
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_LANE_WIDTH 4
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_0 0x0 /* enum */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_1 0x1 /* enum */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_2 0x2 /* enum */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_3 0x3 /* enum */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_4 0x4 /* enum */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_5 0x5 /* enum */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_6 0x6 /* enum */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_7 0x7 /* enum */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_LANE_ALL 0x8 /* enum */
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_RESERVED_LBN 12
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_RESERVED_WIDTH 12
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_CURRENT_LBN 24
+#define MC_CMD_PCIE_TUNE_RXEQ_GET_OUT_PARAM_CURRENT_WIDTH 8
+
+/* MC_CMD_PCIE_TUNE_TXEQ_GET_IN msgrequest */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_IN_LEN 4
+/* Requested operation */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_IN_PCIE_TUNE_OP_OFST 0
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_IN_PCIE_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_IN_PCIE_TUNE_RSVD_OFST 1
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_IN_PCIE_TUNE_RSVD_LEN 3
+
+/* MC_CMD_PCIE_TUNE_TXEQ_GET_OUT msgresponse */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_LENMIN 4
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_LENMAX 252
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_LEN(num) (0+4*(num))
+/* RXEQ Parameter */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_OFST 0
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_LEN 4
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_MINNUM 1
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_MAXNUM 63
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_ID_LBN 0
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_ID_WIDTH 8
+/* enum: TxMargin (PIPE) */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_TXMARGIN 0x0
+/* enum: TxSwing (PIPE) */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_TXSWING 0x1
+/* enum: De-emphasis coefficient C(-1) (PIPE) */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_CM1 0x2
+/* enum: De-emphasis coefficient C(0) (PIPE) */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_C0 0x3
+/* enum: De-emphasis coefficient C(+1) (PIPE) */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_CP1 0x4
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_LANE_LBN 8
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_LANE_WIDTH 4
+/* Enum values, see field(s): */
+/* MC_CMD_PCIE_TUNE_RXEQ_GET_OUT/PARAM_LANE */
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_RESERVED_LBN 12
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_RESERVED_WIDTH 12
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_CURRENT_LBN 24
+#define MC_CMD_PCIE_TUNE_TXEQ_GET_OUT_PARAM_CURRENT_WIDTH 8
+
+/* MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN msgrequest */
+#define MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN_LEN 8
+/* Requested operation */
+#define MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN_PCIE_TUNE_OP_OFST 0
+#define MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN_PCIE_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN_PCIE_TUNE_RSVD_OFST 1
+#define MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN_PCIE_TUNE_RSVD_LEN 3
+#define MC_CMD_PCIE_TUNE_START_EYE_PLOT_IN_LANE_OFST 4
+
+/* MC_CMD_PCIE_TUNE_START_EYE_PLOT_OUT msgresponse */
+#define MC_CMD_PCIE_TUNE_START_EYE_PLOT_OUT_LEN 0
+
+/* MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_IN msgrequest */
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_IN_LEN 4
+/* Requested operation */
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_IN_PCIE_TUNE_OP_OFST 0
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_IN_PCIE_TUNE_OP_LEN 1
+/* Align the arguments to 32 bits */
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_IN_PCIE_TUNE_RSVD_OFST 1
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_IN_PCIE_TUNE_RSVD_LEN 3
+
+/* MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT msgresponse */
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_LENMIN 0
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_LENMAX 252
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_LEN(num) (0+2*(num))
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_OFST 0
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_LEN 2
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_MINNUM 0
+#define MC_CMD_PCIE_TUNE_POLL_EYE_PLOT_OUT_SAMPLES_MAXNUM 126
+
+
+/***********************************/
+/* MC_CMD_LICENSING
+ * Operations on the NVRAM_PARTITION_TYPE_LICENSE application license partition
+ */
+#define MC_CMD_LICENSING 0xf3
+#undef MC_CMD_0xf3_PRIVILEGE_CTG
+
+#define MC_CMD_0xf3_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_LICENSING_IN msgrequest */
+#define MC_CMD_LICENSING_IN_LEN 4
+/* identifies the type of operation requested */
+#define MC_CMD_LICENSING_IN_OP_OFST 0
+/* enum: re-read and apply licenses after a license key partition update; note
+ * that this operation returns a zero-length response
+ */
+#define MC_CMD_LICENSING_IN_OP_UPDATE_LICENSE 0x0
+/* enum: report counts of installed licenses */
+#define MC_CMD_LICENSING_IN_OP_GET_KEY_STATS 0x1
+
+/* MC_CMD_LICENSING_OUT msgresponse */
+#define MC_CMD_LICENSING_OUT_LEN 28
+/* count of application keys which are valid */
+#define MC_CMD_LICENSING_OUT_VALID_APP_KEYS_OFST 0
+/* sum of UNVERIFIABLE_APP_KEYS + WRONG_NODE_APP_KEYS (for compatibility with
+ * MC_CMD_FC_OP_LICENSE)
+ */
+#define MC_CMD_LICENSING_OUT_INVALID_APP_KEYS_OFST 4
+/* count of application keys which are invalid due to being blacklisted */
+#define MC_CMD_LICENSING_OUT_BLACKLISTED_APP_KEYS_OFST 8
+/* count of application keys which are invalid due to being unverifiable */
+#define MC_CMD_LICENSING_OUT_UNVERIFIABLE_APP_KEYS_OFST 12
+/* count of application keys which are invalid due to being for the wrong node
+ */
+#define MC_CMD_LICENSING_OUT_WRONG_NODE_APP_KEYS_OFST 16
+/* licensing state (for diagnostics; the exact meaning of the bits in this
+ * field are private to the firmware)
+ */
+#define MC_CMD_LICENSING_OUT_LICENSING_STATE_OFST 20
+/* licensing subsystem self-test report (for manftest) */
+#define MC_CMD_LICENSING_OUT_LICENSING_SELF_TEST_OFST 24
+/* enum: licensing subsystem self-test failed */
+#define MC_CMD_LICENSING_OUT_SELF_TEST_FAIL 0x0
+/* enum: licensing subsystem self-test passed */
+#define MC_CMD_LICENSING_OUT_SELF_TEST_PASS 0x1
+
+
+/***********************************/
+/* MC_CMD_MC2MC_PROXY
+ * Execute an arbitrary MCDI command on the slave MC of a dual-core device.
+ * This will fail on a single-core system.
+ */
+#define MC_CMD_MC2MC_PROXY 0xf4
+#undef MC_CMD_0xf4_PRIVILEGE_CTG
+
+#define MC_CMD_0xf4_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_MC2MC_PROXY_IN msgrequest */
+#define MC_CMD_MC2MC_PROXY_IN_LEN 0
+
+/* MC_CMD_MC2MC_PROXY_OUT msgresponse */
+#define MC_CMD_MC2MC_PROXY_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_GET_LICENSED_APP_STATE
+ * Query the state of an individual licensed application. (Note that the actual
+ * state may be invalidated by the MC_CMD_LICENSING OP_UPDATE_LICENSE operation
+ * or a reboot of the MC.)
+ */
+#define MC_CMD_GET_LICENSED_APP_STATE 0xf5
+#undef MC_CMD_0xf5_PRIVILEGE_CTG
+
+#define MC_CMD_0xf5_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_LICENSED_APP_STATE_IN msgrequest */
+#define MC_CMD_GET_LICENSED_APP_STATE_IN_LEN 4
+/* application ID to query (LICENSED_APP_ID_xxx) */
+#define MC_CMD_GET_LICENSED_APP_STATE_IN_APP_ID_OFST 0
+
+/* MC_CMD_GET_LICENSED_APP_STATE_OUT msgresponse */
+#define MC_CMD_GET_LICENSED_APP_STATE_OUT_LEN 4
+/* state of this application */
+#define MC_CMD_GET_LICENSED_APP_STATE_OUT_STATE_OFST 0
+/* enum: no (or invalid) license is present for the application */
+#define MC_CMD_GET_LICENSED_APP_STATE_OUT_NOT_LICENSED 0x0
+/* enum: a valid license is present for the application */
+#define MC_CMD_GET_LICENSED_APP_STATE_OUT_LICENSED 0x1
+
+
+/***********************************/
+/* MC_CMD_LICENSED_APP_OP
+ * Perform an action for an individual licensed application.
+ */
+#define MC_CMD_LICENSED_APP_OP 0xf6
+#undef MC_CMD_0xf6_PRIVILEGE_CTG
+
+#define MC_CMD_0xf6_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_LICENSED_APP_OP_IN msgrequest */
+#define MC_CMD_LICENSED_APP_OP_IN_LENMIN 8
+#define MC_CMD_LICENSED_APP_OP_IN_LENMAX 252
+#define MC_CMD_LICENSED_APP_OP_IN_LEN(num) (8+4*(num))
+/* application ID */
+#define MC_CMD_LICENSED_APP_OP_IN_APP_ID_OFST 0
+/* the type of operation requested */
+#define MC_CMD_LICENSED_APP_OP_IN_OP_OFST 4
+/* enum: validate application */
+#define MC_CMD_LICENSED_APP_OP_IN_OP_VALIDATE 0x0
+/* enum: mask application */
+#define MC_CMD_LICENSED_APP_OP_IN_OP_MASK 0x1
+/* arguments specific to this particular operation */
+#define MC_CMD_LICENSED_APP_OP_IN_ARGS_OFST 8
+#define MC_CMD_LICENSED_APP_OP_IN_ARGS_LEN 4
+#define MC_CMD_LICENSED_APP_OP_IN_ARGS_MINNUM 0
+#define MC_CMD_LICENSED_APP_OP_IN_ARGS_MAXNUM 61
+
+/* MC_CMD_LICENSED_APP_OP_OUT msgresponse */
+#define MC_CMD_LICENSED_APP_OP_OUT_LENMIN 0
+#define MC_CMD_LICENSED_APP_OP_OUT_LENMAX 252
+#define MC_CMD_LICENSED_APP_OP_OUT_LEN(num) (0+4*(num))
+/* result specific to this particular operation */
+#define MC_CMD_LICENSED_APP_OP_OUT_RESULT_OFST 0
+#define MC_CMD_LICENSED_APP_OP_OUT_RESULT_LEN 4
+#define MC_CMD_LICENSED_APP_OP_OUT_RESULT_MINNUM 0
+#define MC_CMD_LICENSED_APP_OP_OUT_RESULT_MAXNUM 63
+
+/* MC_CMD_LICENSED_APP_OP_VALIDATE_IN msgrequest */
+#define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_LEN 72
+/* application ID */
+#define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_APP_ID_OFST 0
+/* the type of operation requested */
+#define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_OP_OFST 4
+/* validation challenge */
+#define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_CHALLENGE_OFST 8
+#define MC_CMD_LICENSED_APP_OP_VALIDATE_IN_CHALLENGE_LEN 64
+
+/* MC_CMD_LICENSED_APP_OP_VALIDATE_OUT msgresponse */
+#define MC_CMD_LICENSED_APP_OP_VALIDATE_OUT_LEN 68
+/* feature expiry (time_t) */
+#define MC_CMD_LICENSED_APP_OP_VALIDATE_OUT_EXPIRY_OFST 0
+/* validation response */
+#define MC_CMD_LICENSED_APP_OP_VALIDATE_OUT_RESPONSE_OFST 4
+#define MC_CMD_LICENSED_APP_OP_VALIDATE_OUT_RESPONSE_LEN 64
+
+/* MC_CMD_LICENSED_APP_OP_MASK_IN msgrequest */
+#define MC_CMD_LICENSED_APP_OP_MASK_IN_LEN 12
+/* application ID */
+#define MC_CMD_LICENSED_APP_OP_MASK_IN_APP_ID_OFST 0
+/* the type of operation requested */
+#define MC_CMD_LICENSED_APP_OP_MASK_IN_OP_OFST 4
+/* flag */
+#define MC_CMD_LICENSED_APP_OP_MASK_IN_FLAG_OFST 8
+
+/* MC_CMD_LICENSED_APP_OP_MASK_OUT msgresponse */
+#define MC_CMD_LICENSED_APP_OP_MASK_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_SET_PORT_SNIFF_CONFIG
+ * Configure RX port sniffing for the physical port associated with the calling
+ * function. Only a privileged function may change the port sniffing
+ * configuration. A copy of all traffic delivered to the host (non-promiscuous
+ * mode) or all traffic arriving at the port (promiscuous mode) may be
+ * delivered to a specific queue, or a set of queues with RSS.
+ */
+#define MC_CMD_SET_PORT_SNIFF_CONFIG 0xf7
+#undef MC_CMD_0xf7_PRIVILEGE_CTG
+
+#define MC_CMD_0xf7_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_SET_PORT_SNIFF_CONFIG_IN msgrequest */
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_LEN 16
+/* configuration flags */
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_FLAGS_OFST 0
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_ENABLE_LBN 0
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_ENABLE_WIDTH 1
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_PROMISCUOUS_LBN 1
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_PROMISCUOUS_WIDTH 1
+/* receive queue handle (for RSS mode, this is the base queue) */
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_QUEUE_OFST 4
+/* receive mode */
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_MODE_OFST 8
+/* enum: receive to just the specified queue */
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_MODE_SIMPLE 0x0
+/* enum: receive to multiple queues using RSS context */
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_MODE_RSS 0x1
+/* RSS context (for RX_MODE_RSS) as returned by MC_CMD_RSS_CONTEXT_ALLOC. Note
+ * that these handles should be considered opaque to the host, although a value
+ * of 0xFFFFFFFF is guaranteed never to be a valid handle.
+ */
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_IN_RX_CONTEXT_OFST 12
+
+/* MC_CMD_SET_PORT_SNIFF_CONFIG_OUT msgresponse */
+#define MC_CMD_SET_PORT_SNIFF_CONFIG_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_GET_PORT_SNIFF_CONFIG
+ * Obtain the current RX port sniffing configuration for the physical port
+ * associated with the calling function. Only a privileged function may read
+ * the configuration.
+ */
+#define MC_CMD_GET_PORT_SNIFF_CONFIG 0xf8
+#undef MC_CMD_0xf8_PRIVILEGE_CTG
+
+#define MC_CMD_0xf8_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_GET_PORT_SNIFF_CONFIG_IN msgrequest */
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_IN_LEN 0
+
+/* MC_CMD_GET_PORT_SNIFF_CONFIG_OUT msgresponse */
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_LEN 16
+/* configuration flags */
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_FLAGS_OFST 0
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_ENABLE_LBN 0
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_ENABLE_WIDTH 1
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_PROMISCUOUS_LBN 1
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_PROMISCUOUS_WIDTH 1
+/* receiving queue handle (for RSS mode, this is the base queue) */
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_QUEUE_OFST 4
+/* receive mode */
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_MODE_OFST 8
+/* enum: receiving to just the specified queue */
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_MODE_SIMPLE 0x0
+/* enum: receiving to multiple queues using RSS context */
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_MODE_RSS 0x1
+/* RSS context (for RX_MODE_RSS) */
+#define MC_CMD_GET_PORT_SNIFF_CONFIG_OUT_RX_CONTEXT_OFST 12
+
+
+/***********************************/
+/* MC_CMD_SET_PARSER_DISP_CONFIG
+ * Change configuration related to the parser-dispatcher subsystem.
+ */
+#define MC_CMD_SET_PARSER_DISP_CONFIG 0xf9
+#undef MC_CMD_0xf9_PRIVILEGE_CTG
+
+#define MC_CMD_0xf9_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_SET_PARSER_DISP_CONFIG_IN msgrequest */
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_LENMIN 12
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_LENMAX 252
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_LEN(num) (8+4*(num))
+/* the type of configuration setting to change */
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_TYPE_OFST 0
+/* enum: Per-TXQ enable for multicast UDP destination lookup for possible
+ * internal loopback. (ENTITY is a queue handle, VALUE is a single boolean.)
+ */
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_TXQ_MCAST_UDP_DST_LOOKUP_EN 0x0
+/* enum: Per-v-adaptor enable for suppression of self-transmissions on the
+ * internal loopback path. (ENTITY is an EVB_PORT_ID, VALUE is a single
+ * boolean.)
+ */
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_VADAPTOR_SUPPRESS_SELF_TX 0x1
+/* handle for the entity to update: queue handle, EVB port ID, etc. depending
+ * on the type of configuration setting being changed
+ */
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_ENTITY_OFST 4
+/* new value: the details depend on the type of configuration setting being
+ * changed
+ */
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_VALUE_OFST 8
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_VALUE_LEN 4
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_VALUE_MINNUM 1
+#define MC_CMD_SET_PARSER_DISP_CONFIG_IN_VALUE_MAXNUM 61
+
+/* MC_CMD_SET_PARSER_DISP_CONFIG_OUT msgresponse */
+#define MC_CMD_SET_PARSER_DISP_CONFIG_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_GET_PARSER_DISP_CONFIG
+ * Read configuration related to the parser-dispatcher subsystem.
+ */
+#define MC_CMD_GET_PARSER_DISP_CONFIG 0xfa
+#undef MC_CMD_0xfa_PRIVILEGE_CTG
+
+#define MC_CMD_0xfa_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_PARSER_DISP_CONFIG_IN msgrequest */
+#define MC_CMD_GET_PARSER_DISP_CONFIG_IN_LEN 8
+/* the type of configuration setting to read */
+#define MC_CMD_GET_PARSER_DISP_CONFIG_IN_TYPE_OFST 0
+/* Enum values, see field(s): */
+/* MC_CMD_SET_PARSER_DISP_CONFIG/MC_CMD_SET_PARSER_DISP_CONFIG_IN/TYPE */
+/* handle for the entity to query: queue handle, EVB port ID, etc. depending on
+ * the type of configuration setting being read
+ */
+#define MC_CMD_GET_PARSER_DISP_CONFIG_IN_ENTITY_OFST 4
+
+/* MC_CMD_GET_PARSER_DISP_CONFIG_OUT msgresponse */
+#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_LENMIN 4
+#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_LENMAX 252
+#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_LEN(num) (0+4*(num))
+/* current value: the details depend on the type of configuration setting being
+ * read
+ */
+#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_VALUE_OFST 0
+#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_VALUE_LEN 4
+#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_VALUE_MINNUM 1
+#define MC_CMD_GET_PARSER_DISP_CONFIG_OUT_VALUE_MAXNUM 63
+
+
+/***********************************/
+/* MC_CMD_SET_TX_PORT_SNIFF_CONFIG
+ * Configure TX port sniffing for the physical port associated with the calling
+ * function. Only a privileged function may change the port sniffing
+ * configuration. A copy of all traffic transmitted through the port may be
+ * delivered to a specific queue, or a set of queues with RSS. Note that these
+ * packets are delivered with transmit timestamps in the packet prefix, not
+ * receive timestamps, so it is likely that the queue(s) will need to be
+ * dedicated as TX sniff receivers.
+ */
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG 0xfb
+#undef MC_CMD_0xfb_PRIVILEGE_CTG
+
+#define MC_CMD_0xfb_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN msgrequest */
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_LEN 16
+/* configuration flags */
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_FLAGS_OFST 0
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_ENABLE_LBN 0
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_ENABLE_WIDTH 1
+/* receive queue handle (for RSS mode, this is the base queue) */
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_QUEUE_OFST 4
+/* receive mode */
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_MODE_OFST 8
+/* enum: receive to just the specified queue */
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_MODE_SIMPLE 0x0
+/* enum: receive to multiple queues using RSS context */
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_MODE_RSS 0x1
+/* RSS context (for RX_MODE_RSS) as returned by MC_CMD_RSS_CONTEXT_ALLOC. Note
+ * that these handles should be considered opaque to the host, although a value
+ * of 0xFFFFFFFF is guaranteed never to be a valid handle.
+ */
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_IN_RX_CONTEXT_OFST 12
+
+/* MC_CMD_SET_TX_PORT_SNIFF_CONFIG_OUT msgresponse */
+#define MC_CMD_SET_TX_PORT_SNIFF_CONFIG_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_GET_TX_PORT_SNIFF_CONFIG
+ * Obtain the current TX port sniffing configuration for the physical port
+ * associated with the calling function. Only a privileged function may read
+ * the configuration.
+ */
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG 0xfc
+#undef MC_CMD_0xfc_PRIVILEGE_CTG
+
+#define MC_CMD_0xfc_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_GET_TX_PORT_SNIFF_CONFIG_IN msgrequest */
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_IN_LEN 0
+
+/* MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT msgresponse */
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_LEN 16
+/* configuration flags */
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_FLAGS_OFST 0
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_ENABLE_LBN 0
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_ENABLE_WIDTH 1
+/* receiving queue handle (for RSS mode, this is the base queue) */
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_QUEUE_OFST 4
+/* receive mode */
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_MODE_OFST 8
+/* enum: receiving to just the specified queue */
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_MODE_SIMPLE 0x0
+/* enum: receiving to multiple queues using RSS context */
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_MODE_RSS 0x1
+/* RSS context (for RX_MODE_RSS) */
+#define MC_CMD_GET_TX_PORT_SNIFF_CONFIG_OUT_RX_CONTEXT_OFST 12
+
+
+/***********************************/
+/* MC_CMD_RMON_STATS_RX_ERRORS
+ * Per queue rx error stats.
+ */
+#define MC_CMD_RMON_STATS_RX_ERRORS 0xfe
+#undef MC_CMD_0xfe_PRIVILEGE_CTG
+
+#define MC_CMD_0xfe_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_RMON_STATS_RX_ERRORS_IN msgrequest */
+#define MC_CMD_RMON_STATS_RX_ERRORS_IN_LEN 8
+/* The rx queue to get stats for. */
+#define MC_CMD_RMON_STATS_RX_ERRORS_IN_RX_QUEUE_OFST 0
+#define MC_CMD_RMON_STATS_RX_ERRORS_IN_FLAGS_OFST 4
+#define MC_CMD_RMON_STATS_RX_ERRORS_IN_RST_LBN 0
+#define MC_CMD_RMON_STATS_RX_ERRORS_IN_RST_WIDTH 1
+
+/* MC_CMD_RMON_STATS_RX_ERRORS_OUT msgresponse */
+#define MC_CMD_RMON_STATS_RX_ERRORS_OUT_LEN 16
+#define MC_CMD_RMON_STATS_RX_ERRORS_OUT_CRC_ERRORS_OFST 0
+#define MC_CMD_RMON_STATS_RX_ERRORS_OUT_TRUNC_ERRORS_OFST 4
+#define MC_CMD_RMON_STATS_RX_ERRORS_OUT_RX_NO_DESC_DROPS_OFST 8
+#define MC_CMD_RMON_STATS_RX_ERRORS_OUT_RX_ABORT_OFST 12
+
+
+/***********************************/
+/* MC_CMD_GET_PCIE_RESOURCE_INFO
+ * Find out about available PCIE resources
+ */
+#define MC_CMD_GET_PCIE_RESOURCE_INFO 0xfd
+
+/* MC_CMD_GET_PCIE_RESOURCE_INFO_IN msgrequest */
+#define MC_CMD_GET_PCIE_RESOURCE_INFO_IN_LEN 0
+
+/* MC_CMD_GET_PCIE_RESOURCE_INFO_OUT msgresponse */
+#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_LEN 28
+/* The maximum number of PFs the device can expose */
+#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_MAX_PFS_OFST 0
+/* The maximum number of VFs the device can expose in total */
+#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_MAX_VFS_OFST 4
+/* The maximum number of MSI-X vectors the device can provide in total */
+#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_MAX_VECTORS_OFST 8
+/* the number of MSI-X vectors the device will allocate by default to each PF
+ */
+#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_DEFAULT_PF_VECTORS_OFST 12
+/* the number of MSI-X vectors the device will allocate by default to each VF
+ */
+#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_DEFAULT_VF_VECTORS_OFST 16
+/* the maximum number of MSI-X vectors the device can allocate to any one PF */
+#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_MAX_PF_VECTORS_OFST 20
+/* the maximum number of MSI-X vectors the device can allocate to any one VF */
+#define MC_CMD_GET_PCIE_RESOURCE_INFO_OUT_MAX_VF_VECTORS_OFST 24
+
+
+/***********************************/
+/* MC_CMD_GET_PORT_MODES
+ * Find out about available port modes
+ */
+#define MC_CMD_GET_PORT_MODES 0xff
+#undef MC_CMD_0xff_PRIVILEGE_CTG
+
+#define MC_CMD_0xff_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_PORT_MODES_IN msgrequest */
+#define MC_CMD_GET_PORT_MODES_IN_LEN 0
+
+/* MC_CMD_GET_PORT_MODES_OUT msgresponse */
+#define MC_CMD_GET_PORT_MODES_OUT_LEN 12
+/* Bitmask of port modes available on the board (indexed by TLV_PORT_MODE_*) */
+#define MC_CMD_GET_PORT_MODES_OUT_MODES_OFST 0
+/* Default (canonical) board mode */
+#define MC_CMD_GET_PORT_MODES_OUT_DEFAULT_MODE_OFST 4
+/* Current board mode */
+#define MC_CMD_GET_PORT_MODES_OUT_CURRENT_MODE_OFST 8
+
+
+/***********************************/
+/* MC_CMD_READ_ATB
+ * Sample voltages on the ATB
+ */
+#define MC_CMD_READ_ATB 0x100
+#undef MC_CMD_0x100_PRIVILEGE_CTG
+
+#define MC_CMD_0x100_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_READ_ATB_IN msgrequest */
+#define MC_CMD_READ_ATB_IN_LEN 16
+#define MC_CMD_READ_ATB_IN_SIGNAL_BUS_OFST 0
+#define MC_CMD_READ_ATB_IN_BUS_CCOM 0x0 /* enum */
+#define MC_CMD_READ_ATB_IN_BUS_CKR 0x1 /* enum */
+#define MC_CMD_READ_ATB_IN_BUS_CPCIE 0x8 /* enum */
+#define MC_CMD_READ_ATB_IN_SIGNAL_EN_BITNO_OFST 4
+#define MC_CMD_READ_ATB_IN_SIGNAL_SEL_OFST 8
+#define MC_CMD_READ_ATB_IN_SETTLING_TIME_US_OFST 12
+
+/* MC_CMD_READ_ATB_OUT msgresponse */
+#define MC_CMD_READ_ATB_OUT_LEN 4
+#define MC_CMD_READ_ATB_OUT_SAMPLE_MV_OFST 0
+
+
+/***********************************/
+/* MC_CMD_GET_WORKAROUNDS
+ * Read the list of all implemented and all currently enabled workarounds. The
+ * enums here must correspond with those in MC_CMD_WORKAROUND.
+ */
+#define MC_CMD_GET_WORKAROUNDS 0x59
+#undef MC_CMD_0x59_PRIVILEGE_CTG
+
+#define MC_CMD_0x59_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_WORKAROUNDS_OUT msgresponse */
+#define MC_CMD_GET_WORKAROUNDS_OUT_LEN 8
+/* Each workaround is represented by a single bit according to the enums below.
+ */
+#define MC_CMD_GET_WORKAROUNDS_OUT_IMPLEMENTED_OFST 0
+#define MC_CMD_GET_WORKAROUNDS_OUT_ENABLED_OFST 4
+/* enum: Bug 17230 work around. */
+#define MC_CMD_GET_WORKAROUNDS_OUT_BUG17230 0x2
+/* enum: Bug 35388 work around (unsafe EVQ writes). */
+#define MC_CMD_GET_WORKAROUNDS_OUT_BUG35388 0x4
+/* enum: Bug35017 workaround (A64 tables must be identity map) */
+#define MC_CMD_GET_WORKAROUNDS_OUT_BUG35017 0x8
+/* enum: Bug 41750 present (MC_CMD_TRIGGER_INTERRUPT won't work) */
+#define MC_CMD_GET_WORKAROUNDS_OUT_BUG41750 0x10
+/* enum: Bug 42008 present (Interrupts can overtake associated events). Caution
+ * - before adding code that queries this workaround, remember that there's
+ * released Monza firmware that doesn't understand MC_CMD_WORKAROUND_BUG42008,
+ * and will hence (incorrectly) report that the bug doesn't exist.
+ */
+#define MC_CMD_GET_WORKAROUNDS_OUT_BUG42008 0x20
+/* enum: Bug 26807 features present in firmware (multicast filter chaining) */
+#define MC_CMD_GET_WORKAROUNDS_OUT_BUG26807 0x40
+
+
+/***********************************/
+/* MC_CMD_PRIVILEGE_MASK
+ * Read/set privileges of an arbitrary PCIe function
+ */
+#define MC_CMD_PRIVILEGE_MASK 0x5a
+#undef MC_CMD_0x5a_PRIVILEGE_CTG
+
+#define MC_CMD_0x5a_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_PRIVILEGE_MASK_IN msgrequest */
+#define MC_CMD_PRIVILEGE_MASK_IN_LEN 8
+/* The target function to have its mask read or set e.g. PF 0 = 0xFFFF0000, VF
+ * 1,3 = 0x00030001
+ */
+#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_OFST 0
+#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_PF_LBN 0
+#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_PF_WIDTH 16
+#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_VF_LBN 16
+#define MC_CMD_PRIVILEGE_MASK_IN_FUNCTION_VF_WIDTH 16
+#define MC_CMD_PRIVILEGE_MASK_IN_VF_NULL 0xffff /* enum */
+/* New privilege mask to be set. The mask will only be changed if the MSB is
+ * set to 1.
+ */
+#define MC_CMD_PRIVILEGE_MASK_IN_NEW_MASK_OFST 4
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN 0x1 /* enum */
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_LINK 0x2 /* enum */
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_ONLOAD 0x4 /* enum */
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_PTP 0x8 /* enum */
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_INSECURE_FILTERS 0x10 /* enum */
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING 0x20 /* enum */
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_UNICAST 0x40 /* enum */
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_MULTICAST 0x80 /* enum */
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_BROADCAST 0x100 /* enum */
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_ALL_MULTICAST 0x200 /* enum */
+#define MC_CMD_PRIVILEGE_MASK_IN_GRP_PROMISCUOUS 0x400 /* enum */
+/* enum: Set this bit to indicate that a new privilege mask is to be set,
+ * otherwise the command will only read the existing mask.
+ */
+#define MC_CMD_PRIVILEGE_MASK_IN_DO_CHANGE 0x80000000
+
+/* MC_CMD_PRIVILEGE_MASK_OUT msgresponse */
+#define MC_CMD_PRIVILEGE_MASK_OUT_LEN 4
+/* For an admin function, always all the privileges are reported. */
+#define MC_CMD_PRIVILEGE_MASK_OUT_OLD_MASK_OFST 0
+
+
+/***********************************/
+/* MC_CMD_LINK_STATE_MODE
+ * Read/set link state mode of a VF
+ */
+#define MC_CMD_LINK_STATE_MODE 0x5c
+#undef MC_CMD_0x5c_PRIVILEGE_CTG
+
+#define MC_CMD_0x5c_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_LINK_STATE_MODE_IN msgrequest */
+#define MC_CMD_LINK_STATE_MODE_IN_LEN 8
+/* The target function to have its link state mode read or set, must be a VF
+ * e.g. VF 1,3 = 0x00030001
+ */
+#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_OFST 0
+#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_PF_LBN 0
+#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_PF_WIDTH 16
+#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_VF_LBN 16
+#define MC_CMD_LINK_STATE_MODE_IN_FUNCTION_VF_WIDTH 16
+/* New link state mode to be set */
+#define MC_CMD_LINK_STATE_MODE_IN_NEW_MODE_OFST 4
+#define MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_AUTO 0x0 /* enum */
+#define MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_UP 0x1 /* enum */
+#define MC_CMD_LINK_STATE_MODE_IN_LINK_STATE_DOWN 0x2 /* enum */
+/* enum: Use this value to just read the existing setting without modifying it.
+ */
+#define MC_CMD_LINK_STATE_MODE_IN_DO_NOT_CHANGE 0xffffffff
+
+/* MC_CMD_LINK_STATE_MODE_OUT msgresponse */
+#define MC_CMD_LINK_STATE_MODE_OUT_LEN 4
+#define MC_CMD_LINK_STATE_MODE_OUT_OLD_MODE_OFST 0
+
+
+/***********************************/
+/* MC_CMD_GET_SNAPSHOT_LENGTH
+ * Obtain the curent range of allowable values for the SNAPSHOT_LENGTH
+ * parameter to MC_CMD_INIT_RXQ.
+ */
+#define MC_CMD_GET_SNAPSHOT_LENGTH 0x101
+#undef MC_CMD_0x101_PRIVILEGE_CTG
+
+#define MC_CMD_0x101_PRIVILEGE_CTG SRIOV_CTG_GENERAL
+
+/* MC_CMD_GET_SNAPSHOT_LENGTH_IN msgrequest */
+#define MC_CMD_GET_SNAPSHOT_LENGTH_IN_LEN 0
+
+/* MC_CMD_GET_SNAPSHOT_LENGTH_OUT msgresponse */
+#define MC_CMD_GET_SNAPSHOT_LENGTH_OUT_LEN 8
+/* Minimum acceptable snapshot length. */
+#define MC_CMD_GET_SNAPSHOT_LENGTH_OUT_RX_SNAPLEN_MIN_OFST 0
+/* Maximum acceptable snapshot length. */
+#define MC_CMD_GET_SNAPSHOT_LENGTH_OUT_RX_SNAPLEN_MAX_OFST 4
+
+
+/***********************************/
+/* MC_CMD_FUSE_DIAGS
+ * Additional fuse diagnostics
+ */
+#define MC_CMD_FUSE_DIAGS 0x102
+#undef MC_CMD_0x102_PRIVILEGE_CTG
+
+#define MC_CMD_0x102_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_FUSE_DIAGS_IN msgrequest */
+#define MC_CMD_FUSE_DIAGS_IN_LEN 0
+
+/* MC_CMD_FUSE_DIAGS_OUT msgresponse */
+#define MC_CMD_FUSE_DIAGS_OUT_LEN 48
+/* Total number of mismatched bits between pairs in area 0 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA0_MISMATCH_BITS_OFST 0
+/* Total number of unexpectedly clear (set in B but not A) bits in area 0 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA0_PAIR_A_BAD_BITS_OFST 4
+/* Total number of unexpectedly clear (set in A but not B) bits in area 0 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA0_PAIR_B_BAD_BITS_OFST 8
+/* Checksum of data after logical OR of pairs in area 0 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA0_CHECKSUM_OFST 12
+/* Total number of mismatched bits between pairs in area 1 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA1_MISMATCH_BITS_OFST 16
+/* Total number of unexpectedly clear (set in B but not A) bits in area 1 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA1_PAIR_A_BAD_BITS_OFST 20
+/* Total number of unexpectedly clear (set in A but not B) bits in area 1 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA1_PAIR_B_BAD_BITS_OFST 24
+/* Checksum of data after logical OR of pairs in area 1 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA1_CHECKSUM_OFST 28
+/* Total number of mismatched bits between pairs in area 2 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA2_MISMATCH_BITS_OFST 32
+/* Total number of unexpectedly clear (set in B but not A) bits in area 2 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA2_PAIR_A_BAD_BITS_OFST 36
+/* Total number of unexpectedly clear (set in A but not B) bits in area 2 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA2_PAIR_B_BAD_BITS_OFST 40
+/* Checksum of data after logical OR of pairs in area 2 */
+#define MC_CMD_FUSE_DIAGS_OUT_AREA2_CHECKSUM_OFST 44
+
+
+/***********************************/
+/* MC_CMD_PRIVILEGE_MODIFY
+ * Modify the privileges of a set of PCIe functions. Note that this operation
+ * only effects non-admin functions unless the admin privilege itself is
+ * included in one of the masks provided.
+ */
+#define MC_CMD_PRIVILEGE_MODIFY 0x60
+#undef MC_CMD_0x60_PRIVILEGE_CTG
+
+#define MC_CMD_0x60_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_PRIVILEGE_MODIFY_IN msgrequest */
+#define MC_CMD_PRIVILEGE_MODIFY_IN_LEN 16
+/* The groups of functions to have their privilege masks modified. */
+#define MC_CMD_PRIVILEGE_MODIFY_IN_FN_GROUP_OFST 0
+#define MC_CMD_PRIVILEGE_MODIFY_IN_NONE 0x0 /* enum */
+#define MC_CMD_PRIVILEGE_MODIFY_IN_ALL 0x1 /* enum */
+#define MC_CMD_PRIVILEGE_MODIFY_IN_PFS_ONLY 0x2 /* enum */
+#define MC_CMD_PRIVILEGE_MODIFY_IN_VFS_ONLY 0x3 /* enum */
+#define MC_CMD_PRIVILEGE_MODIFY_IN_VFS_OF_PF 0x4 /* enum */
+#define MC_CMD_PRIVILEGE_MODIFY_IN_ONE 0x5 /* enum */
+/* For VFS_OF_PF specify the PF, for ONE specify the target function */
+#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_OFST 4
+#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_PF_LBN 0
+#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_PF_WIDTH 16
+#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_VF_LBN 16
+#define MC_CMD_PRIVILEGE_MODIFY_IN_FUNCTION_VF_WIDTH 16
+/* Privileges to be added to the target functions. For privilege definitions
+ * refer to the command MC_CMD_PRIVILEGE_MASK
+ */
+#define MC_CMD_PRIVILEGE_MODIFY_IN_ADD_MASK_OFST 8
+/* Privileges to be removed from the target functions. For privilege
+ * definitions refer to the command MC_CMD_PRIVILEGE_MASK
+ */
+#define MC_CMD_PRIVILEGE_MODIFY_IN_REMOVE_MASK_OFST 12
+
+/* MC_CMD_PRIVILEGE_MODIFY_OUT msgresponse */
+#define MC_CMD_PRIVILEGE_MODIFY_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_XPM_READ_BYTES
+ * Read XPM memory
+ */
+#define MC_CMD_XPM_READ_BYTES 0x103
+#undef MC_CMD_0x103_PRIVILEGE_CTG
+
+#define MC_CMD_0x103_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_XPM_READ_BYTES_IN msgrequest */
+#define MC_CMD_XPM_READ_BYTES_IN_LEN 8
+/* Start address (byte) */
+#define MC_CMD_XPM_READ_BYTES_IN_ADDR_OFST 0
+/* Count (bytes) */
+#define MC_CMD_XPM_READ_BYTES_IN_COUNT_OFST 4
+
+/* MC_CMD_XPM_READ_BYTES_OUT msgresponse */
+#define MC_CMD_XPM_READ_BYTES_OUT_LENMIN 0
+#define MC_CMD_XPM_READ_BYTES_OUT_LENMAX 252
+#define MC_CMD_XPM_READ_BYTES_OUT_LEN(num) (0+1*(num))
+/* Data */
+#define MC_CMD_XPM_READ_BYTES_OUT_DATA_OFST 0
+#define MC_CMD_XPM_READ_BYTES_OUT_DATA_LEN 1
+#define MC_CMD_XPM_READ_BYTES_OUT_DATA_MINNUM 0
+#define MC_CMD_XPM_READ_BYTES_OUT_DATA_MAXNUM 252
+
+
+/***********************************/
+/* MC_CMD_XPM_WRITE_BYTES
+ * Write XPM memory
+ */
+#define MC_CMD_XPM_WRITE_BYTES 0x104
+#undef MC_CMD_0x104_PRIVILEGE_CTG
+
+#define MC_CMD_0x104_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_XPM_WRITE_BYTES_IN msgrequest */
+#define MC_CMD_XPM_WRITE_BYTES_IN_LENMIN 8
+#define MC_CMD_XPM_WRITE_BYTES_IN_LENMAX 252
+#define MC_CMD_XPM_WRITE_BYTES_IN_LEN(num) (8+1*(num))
+/* Start address (byte) */
+#define MC_CMD_XPM_WRITE_BYTES_IN_ADDR_OFST 0
+/* Count (bytes) */
+#define MC_CMD_XPM_WRITE_BYTES_IN_COUNT_OFST 4
+/* Data */
+#define MC_CMD_XPM_WRITE_BYTES_IN_DATA_OFST 8
+#define MC_CMD_XPM_WRITE_BYTES_IN_DATA_LEN 1
+#define MC_CMD_XPM_WRITE_BYTES_IN_DATA_MINNUM 0
+#define MC_CMD_XPM_WRITE_BYTES_IN_DATA_MAXNUM 244
+
+/* MC_CMD_XPM_WRITE_BYTES_OUT msgresponse */
+#define MC_CMD_XPM_WRITE_BYTES_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_XPM_READ_SECTOR
+ * Read XPM sector
+ */
+#define MC_CMD_XPM_READ_SECTOR 0x105
+#undef MC_CMD_0x105_PRIVILEGE_CTG
+
+#define MC_CMD_0x105_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_XPM_READ_SECTOR_IN msgrequest */
+#define MC_CMD_XPM_READ_SECTOR_IN_LEN 8
+/* Sector index */
+#define MC_CMD_XPM_READ_SECTOR_IN_INDEX_OFST 0
+/* Sector size */
+#define MC_CMD_XPM_READ_SECTOR_IN_SIZE_OFST 4
+
+/* MC_CMD_XPM_READ_SECTOR_OUT msgresponse */
+#define MC_CMD_XPM_READ_SECTOR_OUT_LENMIN 4
+#define MC_CMD_XPM_READ_SECTOR_OUT_LENMAX 36
+#define MC_CMD_XPM_READ_SECTOR_OUT_LEN(num) (4+1*(num))
+/* Sector type */
+#define MC_CMD_XPM_READ_SECTOR_OUT_TYPE_OFST 0
+#define MC_CMD_XPM_READ_SECTOR_OUT_BLANK 0x0 /* enum */
+#define MC_CMD_XPM_READ_SECTOR_OUT_CRYPTO_KEY_128 0x1 /* enum */
+#define MC_CMD_XPM_READ_SECTOR_OUT_CRYPTO_KEY_256 0x2 /* enum */
+#define MC_CMD_XPM_READ_SECTOR_OUT_INVALID 0xff /* enum */
+/* Sector data */
+#define MC_CMD_XPM_READ_SECTOR_OUT_DATA_OFST 4
+#define MC_CMD_XPM_READ_SECTOR_OUT_DATA_LEN 1
+#define MC_CMD_XPM_READ_SECTOR_OUT_DATA_MINNUM 0
+#define MC_CMD_XPM_READ_SECTOR_OUT_DATA_MAXNUM 32
+
+
+/***********************************/
+/* MC_CMD_XPM_WRITE_SECTOR
+ * Write XPM sector
+ */
+#define MC_CMD_XPM_WRITE_SECTOR 0x106
+#undef MC_CMD_0x106_PRIVILEGE_CTG
+
+#define MC_CMD_0x106_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_XPM_WRITE_SECTOR_IN msgrequest */
+#define MC_CMD_XPM_WRITE_SECTOR_IN_LENMIN 12
+#define MC_CMD_XPM_WRITE_SECTOR_IN_LENMAX 44
+#define MC_CMD_XPM_WRITE_SECTOR_IN_LEN(num) (12+1*(num))
+/* If writing fails due to an uncorrectable error, try up to RETRIES following
+ * sectors (or until no more space available). If 0, only one write attempt is
+ * made. Note that uncorrectable errors are unlikely, thanks to XPM self-repair
+ * mechanism.
+ */
+#define MC_CMD_XPM_WRITE_SECTOR_IN_RETRIES_OFST 0
+#define MC_CMD_XPM_WRITE_SECTOR_IN_RETRIES_LEN 1
+#define MC_CMD_XPM_WRITE_SECTOR_IN_RESERVED_OFST 1
+#define MC_CMD_XPM_WRITE_SECTOR_IN_RESERVED_LEN 3
+/* Sector type */
+#define MC_CMD_XPM_WRITE_SECTOR_IN_TYPE_OFST 4
+/* Enum values, see field(s): */
+/* MC_CMD_XPM_READ_SECTOR_OUT/TYPE */
+/* Sector size */
+#define MC_CMD_XPM_WRITE_SECTOR_IN_SIZE_OFST 8
+/* Sector data */
+#define MC_CMD_XPM_WRITE_SECTOR_IN_DATA_OFST 12
+#define MC_CMD_XPM_WRITE_SECTOR_IN_DATA_LEN 1
+#define MC_CMD_XPM_WRITE_SECTOR_IN_DATA_MINNUM 0
+#define MC_CMD_XPM_WRITE_SECTOR_IN_DATA_MAXNUM 32
+
+/* MC_CMD_XPM_WRITE_SECTOR_OUT msgresponse */
+#define MC_CMD_XPM_WRITE_SECTOR_OUT_LEN 4
+/* New sector index */
+#define MC_CMD_XPM_WRITE_SECTOR_OUT_INDEX_OFST 0
+
+
+/***********************************/
+/* MC_CMD_XPM_INVALIDATE_SECTOR
+ * Invalidate XPM sector
+ */
+#define MC_CMD_XPM_INVALIDATE_SECTOR 0x107
+#undef MC_CMD_0x107_PRIVILEGE_CTG
+
+#define MC_CMD_0x107_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_XPM_INVALIDATE_SECTOR_IN msgrequest */
+#define MC_CMD_XPM_INVALIDATE_SECTOR_IN_LEN 4
+/* Sector index */
+#define MC_CMD_XPM_INVALIDATE_SECTOR_IN_INDEX_OFST 0
+
+/* MC_CMD_XPM_INVALIDATE_SECTOR_OUT msgresponse */
+#define MC_CMD_XPM_INVALIDATE_SECTOR_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_XPM_BLANK_CHECK
+ * Blank-check XPM memory and report bad locations
+ */
+#define MC_CMD_XPM_BLANK_CHECK 0x108
+#undef MC_CMD_0x108_PRIVILEGE_CTG
+
+#define MC_CMD_0x108_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_XPM_BLANK_CHECK_IN msgrequest */
+#define MC_CMD_XPM_BLANK_CHECK_IN_LEN 8
+/* Start address (byte) */
+#define MC_CMD_XPM_BLANK_CHECK_IN_ADDR_OFST 0
+/* Count (bytes) */
+#define MC_CMD_XPM_BLANK_CHECK_IN_COUNT_OFST 4
+
+/* MC_CMD_XPM_BLANK_CHECK_OUT msgresponse */
+#define MC_CMD_XPM_BLANK_CHECK_OUT_LENMIN 4
+#define MC_CMD_XPM_BLANK_CHECK_OUT_LENMAX 252
+#define MC_CMD_XPM_BLANK_CHECK_OUT_LEN(num) (4+2*(num))
+/* Total number of bad (non-blank) locations */
+#define MC_CMD_XPM_BLANK_CHECK_OUT_BAD_COUNT_OFST 0
+/* Addresses of bad locations (may be less than BAD_COUNT, if all cannot fit
+ * into MCDI response)
+ */
+#define MC_CMD_XPM_BLANK_CHECK_OUT_BAD_ADDR_OFST 4
+#define MC_CMD_XPM_BLANK_CHECK_OUT_BAD_ADDR_LEN 2
+#define MC_CMD_XPM_BLANK_CHECK_OUT_BAD_ADDR_MINNUM 0
+#define MC_CMD_XPM_BLANK_CHECK_OUT_BAD_ADDR_MAXNUM 124
+
+
+/***********************************/
+/* MC_CMD_XPM_REPAIR
+ * Blank-check and repair XPM memory
+ */
+#define MC_CMD_XPM_REPAIR 0x109
+#undef MC_CMD_0x109_PRIVILEGE_CTG
+
+#define MC_CMD_0x109_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_XPM_REPAIR_IN msgrequest */
+#define MC_CMD_XPM_REPAIR_IN_LEN 8
+/* Start address (byte) */
+#define MC_CMD_XPM_REPAIR_IN_ADDR_OFST 0
+/* Count (bytes) */
+#define MC_CMD_XPM_REPAIR_IN_COUNT_OFST 4
+
+/* MC_CMD_XPM_REPAIR_OUT msgresponse */
+#define MC_CMD_XPM_REPAIR_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_XPM_DECODER_TEST
+ * Test XPM memory address decoders for gross manufacturing defects. Can only
+ * be performed on an unprogrammed part.
+ */
+#define MC_CMD_XPM_DECODER_TEST 0x10a
+#undef MC_CMD_0x10a_PRIVILEGE_CTG
+
+#define MC_CMD_0x10a_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_XPM_DECODER_TEST_IN msgrequest */
+#define MC_CMD_XPM_DECODER_TEST_IN_LEN 0
+
+/* MC_CMD_XPM_DECODER_TEST_OUT msgresponse */
+#define MC_CMD_XPM_DECODER_TEST_OUT_LEN 0
+
+
+/***********************************/
+/* MC_CMD_XPM_WRITE_TEST
+ * XPM memory write test. Test XPM write logic for gross manufacturing defects
+ * by writing to a dedicated test row. There are 16 locations in the test row
+ * and the test can only be performed on locations that have not been
+ * previously used (i.e. can be run at most 16 times). The test will pick the
+ * first available location to use, or fail with ENOSPC if none left.
+ */
+#define MC_CMD_XPM_WRITE_TEST 0x10b
+#undef MC_CMD_0x10b_PRIVILEGE_CTG
+
+#define MC_CMD_0x10b_PRIVILEGE_CTG SRIOV_CTG_ADMIN
+
+/* MC_CMD_XPM_WRITE_TEST_IN msgrequest */
+#define MC_CMD_XPM_WRITE_TEST_IN_LEN 0
+
+/* MC_CMD_XPM_WRITE_TEST_OUT msgresponse */
+#define MC_CMD_XPM_WRITE_TEST_OUT_LEN 0
+
#endif /* _SIENA_MC_DRIVER_PCOL_H */
diff --git a/sys/dev/sfxge/common/efx_regs_pci.h b/sys/dev/sfxge/common/efx_regs_pci.h
index 3a3a827..a5fd45b 100644
--- a/sys/dev/sfxge/common/efx_regs_pci.h
+++ b/sys/dev/sfxge/common/efx_regs_pci.h
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2010 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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.
*
* $FreeBSD$
*/
@@ -366,6 +371,10 @@ extern "C" {
#define PCRF_AZ_INT_PIN_LBN 0
#define PCRF_AZ_INT_PIN_WIDTH 8
+#define PCFE_DZ_INTPIN_INTD 4
+#define PCFE_DZ_INTPIN_INTC 3
+#define PCFE_DZ_INTPIN_INTB 2
+#define PCFE_DZ_INTPIN_INTA 1
/*
@@ -373,11 +382,8 @@ extern "C" {
* Power management capability ID
*/
-#define PCR_AC_PM_CAP_ID_REG 0x00000040
-/* falcona0,falconb0,sienaa0=pci_f0_config */
-
-#define PCR_DZ_PM_CAP_ID_REG 0x00000080
-/* hunta0=pci_f0_config */
+#define PCR_AZ_PM_CAP_ID_REG 0x00000040
+/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_PM_CAP_ID_LBN 0
#define PCRF_AZ_PM_CAP_ID_WIDTH 8
@@ -388,11 +394,8 @@ extern "C" {
* Power management next item pointer
*/
-#define PCR_AC_PM_NXT_PTR_REG 0x00000041
-/* falcona0,falconb0,sienaa0=pci_f0_config */
-
-#define PCR_DZ_PM_NXT_PTR_REG 0x00000081
-/* hunta0=pci_f0_config */
+#define PCR_AZ_PM_NXT_PTR_REG 0x00000041
+/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_PM_NXT_PTR_LBN 0
#define PCRF_AZ_PM_NXT_PTR_WIDTH 8
@@ -403,11 +406,8 @@ extern "C" {
* Power management capabilities register
*/
-#define PCR_AC_PM_CAP_REG 0x00000042
-/* falcona0,falconb0,sienaa0=pci_f0_config */
-
-#define PCR_DZ_PM_CAP_REG 0x00000082
-/* hunta0=pci_f0_config */
+#define PCR_AZ_PM_CAP_REG 0x00000042
+/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_PM_PME_SUPT_LBN 11
#define PCRF_AZ_PM_PME_SUPT_WIDTH 5
@@ -430,11 +430,8 @@ extern "C" {
* Power management control & status register
*/
-#define PCR_AC_PM_CS_REG 0x00000044
-/* falcona0,falconb0,sienaa0=pci_f0_config */
-
-#define PCR_DZ_PM_CS_REG 0x00000084
-/* hunta0=pci_f0_config */
+#define PCR_AZ_PM_CS_REG 0x00000044
+/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_PM_PME_STAT_LBN 15
#define PCRF_AZ_PM_PME_STAT_WIDTH 1
@@ -455,11 +452,8 @@ extern "C" {
* MSI capability ID
*/
-#define PCR_AC_MSI_CAP_ID_REG 0x00000050
-/* falcona0,falconb0,sienaa0=pci_f0_config */
-
-#define PCR_DZ_MSI_CAP_ID_REG 0x00000090
-/* hunta0=pci_f0_config */
+#define PCR_AZ_MSI_CAP_ID_REG 0x00000050
+/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_MSI_CAP_ID_LBN 0
#define PCRF_AZ_MSI_CAP_ID_WIDTH 8
@@ -470,11 +464,8 @@ extern "C" {
* MSI next item pointer
*/
-#define PCR_AC_MSI_NXT_PTR_REG 0x00000051
-/* falcona0,falconb0,sienaa0=pci_f0_config */
-
-#define PCR_DZ_MSI_NXT_PTR_REG 0x00000091
-/* hunta0=pci_f0_config */
+#define PCR_AZ_MSI_NXT_PTR_REG 0x00000051
+/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_MSI_NXT_PTR_LBN 0
#define PCRF_AZ_MSI_NXT_PTR_WIDTH 8
@@ -485,11 +476,8 @@ extern "C" {
* MSI control register
*/
-#define PCR_AC_MSI_CTL_REG 0x00000052
-/* falcona0,falconb0,sienaa0=pci_f0_config */
-
-#define PCR_DZ_MSI_CTL_REG 0x00000092
-/* hunta0=pci_f0_config */
+#define PCR_AZ_MSI_CTL_REG 0x00000052
+/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_MSI_64_EN_LBN 7
#define PCRF_AZ_MSI_64_EN_WIDTH 1
@@ -506,65 +494,20 @@ extern "C" {
* MSI low 32 bits address register
*/
-#define PCR_AC_MSI_ADR_LO_REG 0x00000054
-/* falcona0,falconb0,sienaa0=pci_f0_config */
-
-#define PCR_DZ_MSI_ADR_LO_REG 0x00000094
-/* hunta0=pci_f0_config */
+#define PCR_AZ_MSI_ADR_LO_REG 0x00000054
+/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_MSI_ADR_LO_LBN 2
#define PCRF_AZ_MSI_ADR_LO_WIDTH 30
/*
- * PC_VPD_CAP_CTL_REG(8bit):
- * VPD control and capabilities register
- */
-
-#define PCR_DZ_VPD_CAP_CTL_REG 0x00000054
-/* hunta0=pci_f0_config */
-
-#define PCR_CC_VPD_CAP_CTL_REG 0x000000d0
-/* sienaa0=pci_f0_config */
-
-#define PCRF_CZ_VPD_FLAG_LBN 31
-#define PCRF_CZ_VPD_FLAG_WIDTH 1
-#define PCRF_CZ_VPD_ADDR_LBN 16
-#define PCRF_CZ_VPD_ADDR_WIDTH 15
-#define PCRF_CZ_VPD_NXT_PTR_LBN 8
-#define PCRF_CZ_VPD_NXT_PTR_WIDTH 8
-#define PCRF_CZ_VPD_CAP_ID_LBN 0
-#define PCRF_CZ_VPD_CAP_ID_WIDTH 8
-
-
-/*
- * PC_VPD_CAP_DATA_REG(32bit):
- * documentation to be written for sum_PC_VPD_CAP_DATA_REG
- */
-
-#define PCR_DZ_VPD_CAP_DATA_REG 0x00000058
-/* hunta0=pci_f0_config */
-
-#define PCR_AB_VPD_CAP_DATA_REG 0x000000b4
-/* falcona0,falconb0=pci_f0_config */
-
-#define PCR_CC_VPD_CAP_DATA_REG 0x000000d4
-/* sienaa0=pci_f0_config */
-
-#define PCRF_AZ_VPD_DATA_LBN 0
-#define PCRF_AZ_VPD_DATA_WIDTH 32
-
-
-/*
* PC_MSI_ADR_HI_REG(32bit):
* MSI high 32 bits address register
*/
-#define PCR_AC_MSI_ADR_HI_REG 0x00000058
-/* falcona0,falconb0,sienaa0=pci_f0_config */
-
-#define PCR_DZ_MSI_ADR_HI_REG 0x00000098
-/* hunta0=pci_f0_config */
+#define PCR_AZ_MSI_ADR_HI_REG 0x00000058
+/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_MSI_ADR_HI_LBN 0
#define PCRF_AZ_MSI_ADR_HI_WIDTH 32
@@ -575,11 +518,8 @@ extern "C" {
* MSI data register
*/
-#define PCR_AC_MSI_DAT_REG 0x0000005c
-/* falcona0,falconb0,sienaa0=pci_f0_config */
-
-#define PCR_DZ_MSI_DAT_REG 0x0000009c
-/* hunta0=pci_f0_config */
+#define PCR_AZ_MSI_DAT_REG 0x0000005c
+/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_MSI_DAT_LBN 0
#define PCRF_AZ_MSI_DAT_WIDTH 16
@@ -593,11 +533,8 @@ extern "C" {
#define PCR_AB_PCIE_CAP_LIST_REG 0x00000060
/* falcona0,falconb0=pci_f0_config */
-#define PCR_CC_PCIE_CAP_LIST_REG 0x00000070
-/* sienaa0=pci_f0_config */
-
-#define PCR_DZ_PCIE_CAP_LIST_REG 0x000000c0
-/* hunta0=pci_f0_config */
+#define PCR_CZ_PCIE_CAP_LIST_REG 0x00000070
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_PCIE_NXT_PTR_LBN 8
#define PCRF_AZ_PCIE_NXT_PTR_WIDTH 8
@@ -613,11 +550,8 @@ extern "C" {
#define PCR_AB_PCIE_CAP_REG 0x00000062
/* falcona0,falconb0=pci_f0_config */
-#define PCR_CC_PCIE_CAP_REG 0x00000072
-/* sienaa0=pci_f0_config */
-
-#define PCR_DZ_PCIE_CAP_REG 0x000000c2
-/* hunta0=pci_f0_config */
+#define PCR_CZ_PCIE_CAP_REG 0x00000072
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_PCIE_INT_MSG_NUM_LBN 9
#define PCRF_AZ_PCIE_INT_MSG_NUM_WIDTH 5
@@ -637,11 +571,8 @@ extern "C" {
#define PCR_AB_DEV_CAP_REG 0x00000064
/* falcona0,falconb0=pci_f0_config */
-#define PCR_CC_DEV_CAP_REG 0x00000074
-/* sienaa0=pci_f0_config */
-
-#define PCR_DZ_DEV_CAP_REG 0x000000c4
-/* hunta0=pci_f0_config */
+#define PCR_CZ_DEV_CAP_REG 0x00000074
+/* sienaa0=pci_f0_config,hunta0=pci_f0_config */
#define PCRF_CZ_CAP_FN_LEVEL_RESET_LBN 28
#define PCRF_CZ_CAP_FN_LEVEL_RESET_WIDTH 1
@@ -677,11 +608,8 @@ extern "C" {
#define PCR_AB_DEV_CTL_REG 0x00000068
/* falcona0,falconb0=pci_f0_config */
-#define PCR_CC_DEV_CTL_REG 0x00000078
-/* sienaa0=pci_f0_config */
-
-#define PCR_DZ_DEV_CTL_REG 0x000000c8
-/* hunta0=pci_f0_config */
+#define PCR_CZ_DEV_CTL_REG 0x00000078
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_CZ_FN_LEVEL_RESET_LBN 15
#define PCRF_CZ_FN_LEVEL_RESET_WIDTH 1
@@ -693,7 +621,6 @@ extern "C" {
#define PCFE_AZ_MAX_RD_REQ_SIZE_512 2
#define PCFE_AZ_MAX_RD_REQ_SIZE_256 1
#define PCFE_AZ_MAX_RD_REQ_SIZE_128 0
-#define PCFE_DZ_OTHER other
#define PCRF_AZ_EN_NO_SNOOP_LBN 11
#define PCRF_AZ_EN_NO_SNOOP_WIDTH 1
#define PCRF_AZ_AUX_PWR_PM_EN_LBN 10
@@ -712,7 +639,6 @@ extern "C" {
#define PCFE_AZ_MAX_PAYL_SIZE_512 2
#define PCFE_AZ_MAX_PAYL_SIZE_256 1
#define PCFE_AZ_MAX_PAYL_SIZE_128 0
-#define PCFE_DZ_OTHER other
#define PCRF_AZ_EN_RELAX_ORDER_LBN 4
#define PCRF_AZ_EN_RELAX_ORDER_WIDTH 1
#define PCRF_AZ_UNSUP_REQ_RPT_EN_LBN 3
@@ -733,11 +659,8 @@ extern "C" {
#define PCR_AB_DEV_STAT_REG 0x0000006a
/* falcona0,falconb0=pci_f0_config */
-#define PCR_CC_DEV_STAT_REG 0x0000007a
-/* sienaa0=pci_f0_config */
-
-#define PCR_DZ_DEV_STAT_REG 0x000000ca
-/* hunta0=pci_f0_config */
+#define PCR_CZ_DEV_STAT_REG 0x0000007a
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_TRNS_PEND_LBN 5
#define PCRF_AZ_TRNS_PEND_WIDTH 1
@@ -761,14 +684,13 @@ extern "C" {
#define PCR_AB_LNK_CAP_REG 0x0000006c
/* falcona0,falconb0=pci_f0_config */
-#define PCR_CC_LNK_CAP_REG 0x0000007c
-/* sienaa0=pci_f0_config */
-
-#define PCR_DZ_LNK_CAP_REG 0x000000cc
-/* hunta0=pci_f0_config */
+#define PCR_CZ_LNK_CAP_REG 0x0000007c
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_PORT_NUM_LBN 24
#define PCRF_AZ_PORT_NUM_WIDTH 8
+#define PCRF_DZ_ASPM_OPTIONALITY_CAP_LBN 22
+#define PCRF_DZ_ASPM_OPTIONALITY_CAP_WIDTH 1
#define PCRF_CZ_LINK_BWDITH_NOTIF_CAP_LBN 21
#define PCRF_CZ_LINK_BWDITH_NOTIF_CAP_WIDTH 1
#define PCRF_CZ_DATA_LINK_ACTIVE_RPT_CAP_LBN 20
@@ -797,11 +719,8 @@ extern "C" {
#define PCR_AB_LNK_CTL_REG 0x00000070
/* falcona0,falconb0=pci_f0_config */
-#define PCR_CC_LNK_CTL_REG 0x00000080
-/* sienaa0=pci_f0_config */
-
-#define PCR_DZ_LNK_CTL_REG 0x000000d0
-/* hunta0=pci_f0_config */
+#define PCR_CZ_LNK_CTL_REG 0x00000080
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_EXT_SYNC_LBN 7
#define PCRF_AZ_EXT_SYNC_WIDTH 1
@@ -827,11 +746,8 @@ extern "C" {
#define PCR_AB_LNK_STAT_REG 0x00000072
/* falcona0,falconb0=pci_f0_config */
-#define PCR_CC_LNK_STAT_REG 0x00000082
-/* sienaa0=pci_f0_config */
-
-#define PCR_DZ_LNK_STAT_REG 0x000000d2
-/* hunta0=pci_f0_config */
+#define PCR_CZ_LNK_STAT_REG 0x00000082
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_AZ_SLOT_CLK_CFG_LBN 12
#define PCRF_AZ_SLOT_CLK_CFG_WIDTH 1
@@ -977,18 +893,40 @@ extern "C" {
/*
- * PC_DEV_CAP2_REG(16bit):
- * PCIe Device Capabilities 2
+ * PC_MSIX_TBL_BASE_REG(32bit):
+ * MSIX Capability Vector Table Base
*/
-#define PCR_CC_DEV_CAP2_REG 0x00000094
-/* sienaa0=pci_f0_config */
+#define PCR_BB_MSIX_TBL_BASE_REG 0x00000094
+/* falconb0=pci_f0_config */
-#define PCR_DZ_DEV_CAP2_REG 0x000000e4
-/* hunta0=pci_f0_config */
+#define PCR_CZ_MSIX_TBL_BASE_REG 0x000000b4
+/* sienaa0,hunta0=pci_f0_config */
-#define PCRF_CZ_CMPL_TIMEOUT_DIS_LBN 4
-#define PCRF_CZ_CMPL_TIMEOUT_DIS_WIDTH 1
+#define PCRF_BZ_MSIX_TBL_OFF_LBN 3
+#define PCRF_BZ_MSIX_TBL_OFF_WIDTH 29
+#define PCRF_BZ_MSIX_TBL_BIR_LBN 0
+#define PCRF_BZ_MSIX_TBL_BIR_WIDTH 3
+
+
+/*
+ * PC_DEV_CAP2_REG(32bit):
+ * PCIe Device Capabilities 2
+ */
+
+#define PCR_CZ_DEV_CAP2_REG 0x00000094
+/* sienaa0=pci_f0_config,hunta0=pci_f0_config */
+
+#define PCRF_DZ_OBFF_SUPPORTED_LBN 18
+#define PCRF_DZ_OBFF_SUPPORTED_WIDTH 2
+#define PCRF_DZ_TPH_CMPL_SUPPORTED_LBN 12
+#define PCRF_DZ_TPH_CMPL_SUPPORTED_WIDTH 2
+#define PCRF_DZ_LTR_M_SUPPORTED_LBN 11
+#define PCRF_DZ_LTR_M_SUPPORTED_WIDTH 1
+#define PCRF_CC_CMPL_TIMEOUT_DIS_LBN 4
+#define PCRF_CC_CMPL_TIMEOUT_DIS_WIDTH 1
+#define PCRF_DZ_CMPL_TIMEOUT_DIS_SUPPORTED_LBN 4
+#define PCRF_DZ_CMPL_TIMEOUT_DIS_SUPPORTED_WIDTH 1
#define PCRF_CZ_CMPL_TIMEOUT_LBN 0
#define PCRF_CZ_CMPL_TIMEOUT_WIDTH 4
#define PCFE_CZ_CMPL_TIMEOUT_17000_TO_6400MS 14
@@ -1003,33 +941,21 @@ extern "C" {
/*
- * PC_MSIX_TBL_BASE_REG(32bit):
- * MSIX Capability Vector Table Base
- */
-
-#define PCR_BB_MSIX_TBL_BASE_REG 0x00000094
-/* falconb0=pci_f0_config */
-
-#define PCR_CZ_MSIX_TBL_BASE_REG 0x000000b4
-/* sienaa0,hunta0=pci_f0_config */
-
-#define PCRF_BZ_MSIX_TBL_OFF_LBN 3
-#define PCRF_BZ_MSIX_TBL_OFF_WIDTH 29
-#define PCRF_BZ_MSIX_TBL_BIR_LBN 0
-#define PCRF_BZ_MSIX_TBL_BIR_WIDTH 3
-
-
-/*
* PC_DEV_CTL2_REG(16bit):
* PCIe Device Control 2
*/
-#define PCR_CC_DEV_CTL2_REG 0x00000098
-/* sienaa0=pci_f0_config */
-
-#define PCR_DZ_DEV_CTL2_REG 0x000000e8
-/* hunta0=pci_f0_config */
+#define PCR_CZ_DEV_CTL2_REG 0x00000098
+/* sienaa0,hunta0=pci_f0_config */
+#define PCRF_DZ_OBFF_ENABLE_LBN 13
+#define PCRF_DZ_OBFF_ENABLE_WIDTH 2
+#define PCRF_DZ_LTR_ENABLE_LBN 10
+#define PCRF_DZ_LTR_ENABLE_WIDTH 1
+#define PCRF_DZ_IDO_COMPLETION_ENABLE_LBN 9
+#define PCRF_DZ_IDO_COMPLETION_ENABLE_WIDTH 1
+#define PCRF_DZ_IDO_REQUEST_ENABLE_LBN 8
+#define PCRF_DZ_IDO_REQUEST_ENABLE_WIDTH 1
#define PCRF_CZ_CMPL_TIMEOUT_DIS_CTL_LBN 4
#define PCRF_CZ_CMPL_TIMEOUT_DIS_CTL_WIDTH 1
#define PCRF_CZ_CMPL_TIMEOUT_CTL_LBN 0
@@ -1054,15 +980,24 @@ extern "C" {
/*
+ * PC_LNK_CAP2_REG(32bit):
+ * PCIe Link Capability 2
+ */
+
+#define PCR_DZ_LNK_CAP2_REG 0x0000009c
+/* hunta0=pci_f0_config */
+
+#define PCRF_DZ_LNK_SPEED_SUP_LBN 1
+#define PCRF_DZ_LNK_SPEED_SUP_WIDTH 7
+
+
+/*
* PC_LNK_CTL2_REG(16bit):
* PCIe Link Control 2
*/
-#define PCR_CC_LNK_CTL2_REG 0x000000a0
-/* sienaa0=pci_f0_config */
-
-#define PCR_DZ_LNK_CTL2_REG 0x000000f0
-/* hunta0=pci_f0_config */
+#define PCR_CZ_LNK_CTL2_REG 0x000000a0
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_CZ_POLLING_DEEMPH_LVL_LBN 12
#define PCRF_CZ_POLLING_DEEMPH_LVL_WIDTH 1
@@ -1080,6 +1015,9 @@ extern "C" {
#define PCRF_CZ_ENTER_COMPLIANCE_CTL_WIDTH 1
#define PCRF_CZ_TGT_LNK_SPEED_CTL_LBN 0
#define PCRF_CZ_TGT_LNK_SPEED_CTL_WIDTH 4
+#define PCFE_DZ_LCTL2_TGT_SPEED_GEN3 3
+#define PCFE_DZ_LCTL2_TGT_SPEED_GEN2 2
+#define PCFE_DZ_LCTL2_TGT_SPEED_GEN1 1
/*
@@ -1087,11 +1025,8 @@ extern "C" {
* PCIe Link Status 2
*/
-#define PCR_CC_LNK_STAT2_REG 0x000000a2
-/* sienaa0=pci_f0_config */
-
-#define PCR_DZ_LNK_STAT2_REG 0x000000f2
-/* hunta0=pci_f0_config */
+#define PCR_CZ_LNK_STAT2_REG 0x000000a2
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_CZ_CURRENT_DEEMPH_LBN 0
#define PCRF_CZ_CURRENT_DEEMPH_WIDTH 1
@@ -1136,6 +1071,39 @@ extern "C" {
/*
+ * PC_VPD_CAP_DATA_REG(32bit):
+ * documentation to be written for sum_PC_VPD_CAP_DATA_REG
+ */
+
+#define PCR_AB_VPD_CAP_DATA_REG 0x000000b4
+/* falcona0,falconb0=pci_f0_config */
+
+#define PCR_CZ_VPD_CAP_DATA_REG 0x000000d4
+/* sienaa0,hunta0=pci_f0_config */
+
+#define PCRF_AZ_VPD_DATA_LBN 0
+#define PCRF_AZ_VPD_DATA_WIDTH 32
+
+
+/*
+ * PC_VPD_CAP_CTL_REG(8bit):
+ * VPD control and capabilities register
+ */
+
+#define PCR_CZ_VPD_CAP_CTL_REG 0x000000d0
+/* sienaa0,hunta0=pci_f0_config */
+
+#define PCRF_CZ_VPD_FLAG_LBN 31
+#define PCRF_CZ_VPD_FLAG_WIDTH 1
+#define PCRF_CZ_VPD_ADDR_LBN 16
+#define PCRF_CZ_VPD_ADDR_WIDTH 15
+#define PCRF_CZ_VPD_NXT_PTR_LBN 8
+#define PCRF_CZ_VPD_NXT_PTR_WIDTH 8
+#define PCRF_CZ_VPD_CAP_ID_LBN 0
+#define PCRF_CZ_VPD_CAP_ID_WIDTH 8
+
+
+/*
* PC_AER_CAP_HDR_REG(32bit):
* AER capability header register
*/
@@ -1191,6 +1159,10 @@ extern "C" {
#define PCR_AZ_AER_UNCORR_ERR_MASK_REG 0x00000108
/* falcona0,falconb0,sienaa0,hunta0=pci_f0_config */
+#define PCRF_DZ_ATOMIC_OP_EGR_BLOCKED_MASK_LBN 24
+#define PCRF_DZ_ATOMIC_OP_EGR_BLOCKED_MASK_WIDTH 1
+#define PCRF_DZ_UNCORR_INT_ERR_MASK_LBN 22
+#define PCRF_DZ_UNCORR_INT_ERR_MASK_WIDTH 1
#define PCRF_AZ_UNSUPT_REQ_ERR_MASK_LBN 20
#define PCRF_AZ_UNSUPT_REQ_ERR_MASK_WIDTH 1
#define PCRF_AZ_ECRC_ERR_MASK_LBN 19
@@ -1328,11 +1300,8 @@ extern "C" {
* Device serial number capability header register
*/
-#define PCR_DZ_DEVSN_CAP_HDR_REG 0x00000130
-/* hunta0=pci_f0_config */
-
-#define PCR_CC_DEVSN_CAP_HDR_REG 0x00000140
-/* sienaa0=pci_f0_config */
+#define PCR_CZ_DEVSN_CAP_HDR_REG 0x00000140
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_CZ_DEVSNCAPHDR_NXT_PTR_LBN 20
#define PCRF_CZ_DEVSNCAPHDR_NXT_PTR_WIDTH 12
@@ -1347,11 +1316,8 @@ extern "C" {
* Device serial number DWORD0
*/
-#define PCR_DZ_DEVSN_DWORD0_REG 0x00000134
-/* hunta0=pci_f0_config */
-
-#define PCR_CC_DEVSN_DWORD0_REG 0x00000144
-/* sienaa0=pci_f0_config */
+#define PCR_CZ_DEVSN_DWORD0_REG 0x00000144
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_CZ_DEVSN_DWORD0_LBN 0
#define PCRF_CZ_DEVSN_DWORD0_WIDTH 32
@@ -1362,11 +1328,8 @@ extern "C" {
* Device serial number DWORD0
*/
-#define PCR_DZ_DEVSN_DWORD1_REG 0x00000138
-/* hunta0=pci_f0_config */
-
-#define PCR_CC_DEVSN_DWORD1_REG 0x00000148
-/* sienaa0=pci_f0_config */
+#define PCR_CZ_DEVSN_DWORD1_REG 0x00000148
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_CZ_DEVSN_DWORD1_LBN 0
#define PCRF_CZ_DEVSN_DWORD1_WIDTH 32
@@ -1377,11 +1340,8 @@ extern "C" {
* ARI capability header register
*/
-#define PCR_DZ_ARI_CAP_HDR_REG 0x00000140
-/* hunta0=pci_f0_config */
-
-#define PCR_CC_ARI_CAP_HDR_REG 0x00000150
-/* sienaa0=pci_f0_config */
+#define PCR_CZ_ARI_CAP_HDR_REG 0x00000150
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_CZ_ARICAPHDR_NXT_PTR_LBN 20
#define PCRF_CZ_ARICAPHDR_NXT_PTR_WIDTH 12
@@ -1396,11 +1356,8 @@ extern "C" {
* ARI Capabilities
*/
-#define PCR_DZ_ARI_CAP_REG 0x00000144
-/* hunta0=pci_f0_config */
-
-#define PCR_CC_ARI_CAP_REG 0x00000154
-/* sienaa0=pci_f0_config */
+#define PCR_CZ_ARI_CAP_REG 0x00000154
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_CZ_ARI_NXT_FN_NUM_LBN 8
#define PCRF_CZ_ARI_NXT_FN_NUM_WIDTH 8
@@ -1415,11 +1372,8 @@ extern "C" {
* ARI Control
*/
-#define PCR_DZ_ARI_CTL_REG 0x00000146
-/* hunta0=pci_f0_config */
-
-#define PCR_CC_ARI_CTL_REG 0x00000156
-/* sienaa0=pci_f0_config */
+#define PCR_CZ_ARI_CTL_REG 0x00000156
+/* sienaa0,hunta0=pci_f0_config */
#define PCRF_CZ_ARI_FN_GRP_LBN 4
#define PCRF_CZ_ARI_FN_GRP_WIDTH 3
@@ -1430,6 +1384,22 @@ extern "C" {
/*
+ * PC_SEC_PCIE_CAP_REG(32bit):
+ * Secondary PCIE Capability Register
+ */
+
+#define PCR_DZ_SEC_PCIE_CAP_REG 0x00000160
+/* hunta0=pci_f0_config */
+
+#define PCRF_DZ_SEC_NXT_PTR_LBN 20
+#define PCRF_DZ_SEC_NXT_PTR_WIDTH 12
+#define PCRF_DZ_SEC_VERSION_LBN 16
+#define PCRF_DZ_SEC_VERSION_WIDTH 4
+#define PCRF_DZ_SEC_EXT_CAP_ID_LBN 0
+#define PCRF_DZ_SEC_EXT_CAP_ID_WIDTH 16
+
+
+/*
* PC_SRIOV_CAP_HDR_REG(32bit):
* SRIOV capability header register
*/
@@ -1437,7 +1407,7 @@ extern "C" {
#define PCR_CC_SRIOV_CAP_HDR_REG 0x00000160
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_CAP_HDR_REG 0x00000200
+#define PCR_DZ_SRIOV_CAP_HDR_REG 0x00000180
/* hunta0=pci_f0_config */
#define PCRF_CZ_SRIOVCAPHDR_NXT_PTR_LBN 20
@@ -1456,16 +1426,44 @@ extern "C" {
#define PCR_CC_SRIOV_CAP_REG 0x00000164
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_CAP_REG 0x00000204
+#define PCR_DZ_SRIOV_CAP_REG 0x00000184
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_MIGR_INT_MSG_NUM_LBN 21
#define PCRF_CZ_VF_MIGR_INT_MSG_NUM_WIDTH 11
+#define PCRF_DZ_VF_ARI_CAP_PRESV_LBN 1
+#define PCRF_DZ_VF_ARI_CAP_PRESV_WIDTH 1
#define PCRF_CZ_VF_MIGR_CAP_LBN 0
#define PCRF_CZ_VF_MIGR_CAP_WIDTH 1
/*
+ * PC_LINK_CONTROL3_REG(32bit):
+ * Link Control 3.
+ */
+
+#define PCR_DZ_LINK_CONTROL3_REG 0x00000164
+/* hunta0=pci_f0_config */
+
+#define PCRF_DZ_LINK_EQ_INT_EN_LBN 1
+#define PCRF_DZ_LINK_EQ_INT_EN_WIDTH 1
+#define PCRF_DZ_PERFORM_EQL_LBN 0
+#define PCRF_DZ_PERFORM_EQL_WIDTH 1
+
+
+/*
+ * PC_LANE_ERROR_STAT_REG(32bit):
+ * Lane Error Status Register.
+ */
+
+#define PCR_DZ_LANE_ERROR_STAT_REG 0x00000168
+/* hunta0=pci_f0_config */
+
+#define PCRF_DZ_LANE_STATUS_LBN 0
+#define PCRF_DZ_LANE_STATUS_WIDTH 8
+
+
+/*
* PC_SRIOV_CTL_REG(16bit):
* SRIOV Control
*/
@@ -1473,7 +1471,7 @@ extern "C" {
#define PCR_CC_SRIOV_CTL_REG 0x00000168
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_CTL_REG 0x00000208
+#define PCR_DZ_SRIOV_CTL_REG 0x00000188
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_ARI_CAP_HRCHY_LBN 4
@@ -1496,7 +1494,7 @@ extern "C" {
#define PCR_CC_SRIOV_STAT_REG 0x0000016a
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_STAT_REG 0x0000020a
+#define PCR_DZ_SRIOV_STAT_REG 0x0000018a
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_MIGR_STAT_LBN 0
@@ -1504,6 +1502,20 @@ extern "C" {
/*
+ * PC_LANE01_EQU_CONTROL_REG(32bit):
+ * Lanes 0,1 Equalization Control Register.
+ */
+
+#define PCR_DZ_LANE01_EQU_CONTROL_REG 0x0000016c
+/* hunta0=pci_f0_config */
+
+#define PCRF_DZ_LANE1_EQ_CTRL_LBN 16
+#define PCRF_DZ_LANE1_EQ_CTRL_WIDTH 16
+#define PCRF_DZ_LANE0_EQ_CTRL_LBN 0
+#define PCRF_DZ_LANE0_EQ_CTRL_WIDTH 16
+
+
+/*
* PC_SRIOV_INITIALVFS_REG(16bit):
* SRIOV Initial VFs
*/
@@ -1511,7 +1523,7 @@ extern "C" {
#define PCR_CC_SRIOV_INITIALVFS_REG 0x0000016c
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_INITIALVFS_REG 0x0000020c
+#define PCR_DZ_SRIOV_INITIALVFS_REG 0x0000018c
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_INITIALVFS_LBN 0
@@ -1526,7 +1538,7 @@ extern "C" {
#define PCR_CC_SRIOV_TOTALVFS_REG 0x0000016e
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_TOTALVFS_REG 0x0000020e
+#define PCR_DZ_SRIOV_TOTALVFS_REG 0x0000018e
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_TOTALVFS_LBN 0
@@ -1541,7 +1553,7 @@ extern "C" {
#define PCR_CC_SRIOV_NUMVFS_REG 0x00000170
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_NUMVFS_REG 0x00000210
+#define PCR_DZ_SRIOV_NUMVFS_REG 0x00000190
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_NUMVFS_LBN 0
@@ -1549,6 +1561,20 @@ extern "C" {
/*
+ * PC_LANE23_EQU_CONTROL_REG(32bit):
+ * Lanes 2,3 Equalization Control Register.
+ */
+
+#define PCR_DZ_LANE23_EQU_CONTROL_REG 0x00000170
+/* hunta0=pci_f0_config */
+
+#define PCRF_DZ_LANE3_EQ_CTRL_LBN 16
+#define PCRF_DZ_LANE3_EQ_CTRL_WIDTH 16
+#define PCRF_DZ_LANE2_EQ_CTRL_LBN 0
+#define PCRF_DZ_LANE2_EQ_CTRL_WIDTH 16
+
+
+/*
* PC_SRIOV_FN_DPND_LNK_REG(16bit):
* SRIOV Function dependency link
*/
@@ -1556,7 +1582,7 @@ extern "C" {
#define PCR_CC_SRIOV_FN_DPND_LNK_REG 0x00000172
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_FN_DPND_LNK_REG 0x00000212
+#define PCR_DZ_SRIOV_FN_DPND_LNK_REG 0x00000192
/* hunta0=pci_f0_config */
#define PCRF_CZ_SRIOV_FN_DPND_LNK_LBN 0
@@ -1571,7 +1597,7 @@ extern "C" {
#define PCR_CC_SRIOV_1STVF_OFFSET_REG 0x00000174
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_1STVF_OFFSET_REG 0x00000214
+#define PCR_DZ_SRIOV_1STVF_OFFSET_REG 0x00000194
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_1STVF_OFFSET_LBN 0
@@ -1579,6 +1605,20 @@ extern "C" {
/*
+ * PC_LANE45_EQU_CONTROL_REG(32bit):
+ * Lanes 4,5 Equalization Control Register.
+ */
+
+#define PCR_DZ_LANE45_EQU_CONTROL_REG 0x00000174
+/* hunta0=pci_f0_config */
+
+#define PCRF_DZ_LANE5_EQ_CTRL_LBN 16
+#define PCRF_DZ_LANE5_EQ_CTRL_WIDTH 16
+#define PCRF_DZ_LANE4_EQ_CTRL_LBN 0
+#define PCRF_DZ_LANE4_EQ_CTRL_WIDTH 16
+
+
+/*
* PC_SRIOV_VFSTRIDE_REG(16bit):
* SRIOV VF Stride
*/
@@ -1586,7 +1626,7 @@ extern "C" {
#define PCR_CC_SRIOV_VFSTRIDE_REG 0x00000176
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_VFSTRIDE_REG 0x00000216
+#define PCR_DZ_SRIOV_VFSTRIDE_REG 0x00000196
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_VFSTRIDE_LBN 0
@@ -1594,6 +1634,20 @@ extern "C" {
/*
+ * PC_LANE67_EQU_CONTROL_REG(32bit):
+ * Lanes 6,7 Equalization Control Register.
+ */
+
+#define PCR_DZ_LANE67_EQU_CONTROL_REG 0x00000178
+/* hunta0=pci_f0_config */
+
+#define PCRF_DZ_LANE7_EQ_CTRL_LBN 16
+#define PCRF_DZ_LANE7_EQ_CTRL_WIDTH 16
+#define PCRF_DZ_LANE6_EQ_CTRL_LBN 0
+#define PCRF_DZ_LANE6_EQ_CTRL_WIDTH 16
+
+
+/*
* PC_SRIOV_DEVID_REG(16bit):
* SRIOV VF Device ID
*/
@@ -1601,7 +1655,7 @@ extern "C" {
#define PCR_CC_SRIOV_DEVID_REG 0x0000017a
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_DEVID_REG 0x0000021a
+#define PCR_DZ_SRIOV_DEVID_REG 0x0000019a
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_DEVID_LBN 0
@@ -1616,7 +1670,7 @@ extern "C" {
#define PCR_CC_SRIOV_SUP_PAGESZ_REG 0x0000017c
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_SUP_PAGESZ_REG 0x0000021c
+#define PCR_DZ_SRIOV_SUP_PAGESZ_REG 0x0000019c
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_SUP_PAGESZ_LBN 0
@@ -1631,7 +1685,7 @@ extern "C" {
#define PCR_CC_SRIOV_SYS_PAGESZ_REG 0x00000180
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_SYS_PAGESZ_REG 0x00000220
+#define PCR_DZ_SRIOV_SYS_PAGESZ_REG 0x000001a0
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_SYS_PAGESZ_LBN 0
@@ -1646,13 +1700,19 @@ extern "C" {
#define PCR_CC_SRIOV_BAR0_REG 0x00000184
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_BAR0_REG 0x00000224
+#define PCR_DZ_SRIOV_BAR0_REG 0x000001a4
/* hunta0=pci_f0_config */
#define PCRF_CC_VF_BAR_ADDRESS_LBN 0
#define PCRF_CC_VF_BAR_ADDRESS_WIDTH 32
-#define PCRF_DZ_VF_BAR0_ADDRESS_LBN 0
-#define PCRF_DZ_VF_BAR0_ADDRESS_WIDTH 32
+#define PCRF_DZ_VF_BAR0_ADDRESS_LBN 4
+#define PCRF_DZ_VF_BAR0_ADDRESS_WIDTH 28
+#define PCRF_DZ_VF_BAR0_PREF_LBN 3
+#define PCRF_DZ_VF_BAR0_PREF_WIDTH 1
+#define PCRF_DZ_VF_BAR0_TYPE_LBN 1
+#define PCRF_DZ_VF_BAR0_TYPE_WIDTH 2
+#define PCRF_DZ_VF_BAR0_IOM_LBN 0
+#define PCRF_DZ_VF_BAR0_IOM_WIDTH 1
/*
@@ -1663,7 +1723,7 @@ extern "C" {
#define PCR_CC_SRIOV_BAR1_REG 0x00000188
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_BAR1_REG 0x00000228
+#define PCR_DZ_SRIOV_BAR1_REG 0x000001a8
/* hunta0=pci_f0_config */
/* defined as PCRF_CC_VF_BAR_ADDRESS_LBN 0; */
@@ -1680,13 +1740,19 @@ extern "C" {
#define PCR_CC_SRIOV_BAR2_REG 0x0000018c
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_BAR2_REG 0x0000022c
+#define PCR_DZ_SRIOV_BAR2_REG 0x000001ac
/* hunta0=pci_f0_config */
/* defined as PCRF_CC_VF_BAR_ADDRESS_LBN 0; */
/* defined as PCRF_CC_VF_BAR_ADDRESS_WIDTH 32 */
-#define PCRF_DZ_VF_BAR2_ADDRESS_LBN 0
-#define PCRF_DZ_VF_BAR2_ADDRESS_WIDTH 32
+#define PCRF_DZ_VF_BAR2_ADDRESS_LBN 4
+#define PCRF_DZ_VF_BAR2_ADDRESS_WIDTH 28
+#define PCRF_DZ_VF_BAR2_PREF_LBN 3
+#define PCRF_DZ_VF_BAR2_PREF_WIDTH 1
+#define PCRF_DZ_VF_BAR2_TYPE_LBN 1
+#define PCRF_DZ_VF_BAR2_TYPE_WIDTH 2
+#define PCRF_DZ_VF_BAR2_IOM_LBN 0
+#define PCRF_DZ_VF_BAR2_IOM_WIDTH 1
/*
@@ -1697,7 +1763,7 @@ extern "C" {
#define PCR_CC_SRIOV_BAR3_REG 0x00000190
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_BAR3_REG 0x00000230
+#define PCR_DZ_SRIOV_BAR3_REG 0x000001b0
/* hunta0=pci_f0_config */
/* defined as PCRF_CC_VF_BAR_ADDRESS_LBN 0; */
@@ -1714,7 +1780,7 @@ extern "C" {
#define PCR_CC_SRIOV_BAR4_REG 0x00000194
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_BAR4_REG 0x00000234
+#define PCR_DZ_SRIOV_BAR4_REG 0x000001b4
/* hunta0=pci_f0_config */
/* defined as PCRF_CC_VF_BAR_ADDRESS_LBN 0; */
@@ -1731,7 +1797,7 @@ extern "C" {
#define PCR_CC_SRIOV_BAR5_REG 0x00000198
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_BAR5_REG 0x00000238
+#define PCR_DZ_SRIOV_BAR5_REG 0x000001b8
/* hunta0=pci_f0_config */
/* defined as PCRF_CC_VF_BAR_ADDRESS_LBN 0; */
@@ -1741,6 +1807,18 @@ extern "C" {
/*
+ * PC_SRIOV_RSVD_REG(16bit):
+ * Reserved register
+ */
+
+#define PCR_DZ_SRIOV_RSVD_REG 0x00000198
+/* hunta0=pci_f0_config */
+
+#define PCRF_DZ_VF_RSVD_LBN 0
+#define PCRF_DZ_VF_RSVD_WIDTH 16
+
+
+/*
* PC_SRIOV_MIBR_SARRAY_OFFSET_REG(32bit):
* SRIOV VF Migration State Array Offset
*/
@@ -1748,7 +1826,7 @@ extern "C" {
#define PCR_CC_SRIOV_MIBR_SARRAY_OFFSET_REG 0x0000019c
/* sienaa0=pci_f0_config */
-#define PCR_DZ_SRIOV_MIBR_SARRAY_OFFSET_REG 0x0000023c
+#define PCR_DZ_SRIOV_MIBR_SARRAY_OFFSET_REG 0x000001bc
/* hunta0=pci_f0_config */
#define PCRF_CZ_VF_MIGR_OFFSET_LBN 3
@@ -1758,45 +1836,11 @@ extern "C" {
/*
- * PC_LTR_CAP_HDR_REG(32bit):
- * Latency Tolerance Reporting Cap Header Reg
- */
-
-#define PCR_DZ_LTR_CAP_HDR_REG 0x00000240
-/* hunta0=pci_f0_config */
-
-#define PCRF_DZ_LTR_NXT_PTR_LBN 20
-#define PCRF_DZ_LTR_NXT_PTR_WIDTH 12
-#define PCRF_DZ_LTR_VERSION_LBN 16
-#define PCRF_DZ_LTR_VERSION_WIDTH 4
-#define PCRF_DZ_LTR_EXT_CAP_ID_LBN 0
-#define PCRF_DZ_LTR_EXT_CAP_ID_WIDTH 16
-
-
-/*
- * PC_LTR_MAX_SNOOP_REG(32bit):
- * LTR Maximum Snoop/No Snoop Register
- */
-
-#define PCR_DZ_LTR_MAX_SNOOP_REG 0x00000244
-/* hunta0=pci_f0_config */
-
-#define PCRF_DZ_LTR_MAX_NOSNOOP_SCALE_LBN 26
-#define PCRF_DZ_LTR_MAX_NOSNOOP_SCALE_WIDTH 3
-#define PCRF_DZ_LTR_MAX_NOSNOOP_LAT_LBN 16
-#define PCRF_DZ_LTR_MAX_NOSNOOP_LAT_WIDTH 10
-#define PCRF_DZ_LTR_MAX_SNOOP_SCALE_LBN 10
-#define PCRF_DZ_LTR_MAX_SNOOP_SCALE_WIDTH 3
-#define PCRF_DZ_LTR_MAX_SNOOP_LAT_LBN 0
-#define PCRF_DZ_LTR_MAX_SNOOP_LAT_WIDTH 10
-
-
-/*
* PC_TPH_CAP_HDR_REG(32bit):
* TPH Capability Header Register
*/
-#define PCR_DZ_TPH_CAP_HDR_REG 0x00000274
+#define PCR_DZ_TPH_CAP_HDR_REG 0x000001c0
/* hunta0=pci_f0_config */
#define PCRF_DZ_TPH_NXT_PTR_LBN 20
@@ -1812,7 +1856,7 @@ extern "C" {
* TPH Requester Capability Register
*/
-#define PCR_DZ_TPH_REQ_CAP_REG 0x00000278
+#define PCR_DZ_TPH_REQ_CAP_REG 0x000001c4
/* hunta0=pci_f0_config */
#define PCRF_DZ_ST_TBLE_SIZE_LBN 16
@@ -1834,7 +1878,7 @@ extern "C" {
* TPH Requester Control Register
*/
-#define PCR_DZ_TPH_REQ_CTL_REG 0x0000027c
+#define PCR_DZ_TPH_REQ_CTL_REG 0x000001c8
/* hunta0=pci_f0_config */
#define PCRF_DZ_TPH_REQ_ENABLE_LBN 8
@@ -1844,101 +1888,37 @@ extern "C" {
/*
- * PC_SEC_PCIE_CAP_REG(32bit):
- * Secondary PCIE Capability Register
- */
-
-#define PCR_DZ_SEC_PCIE_CAP_REG 0x00000300
-/* hunta0=pci_f0_config */
-
-#define PCRF_DZ_SEC_NXT_PTR_LBN 20
-#define PCRF_DZ_SEC_NXT_PTR_WIDTH 12
-#define PCRF_DZ_SEC_VERSION_LBN 16
-#define PCRF_DZ_SEC_VERSION_WIDTH 4
-#define PCRF_DZ_SEC_EXT_CAP_ID_LBN 0
-#define PCRF_DZ_SEC_EXT_CAP_ID_WIDTH 16
-
-
-/*
- * PC_LINK_CONTROL3_REG(32bit):
- * Link Control 3.
- */
-
-#define PCR_DZ_LINK_CONTROL3_REG 0x00000304
-/* hunta0=pci_f0_config */
-
-#define PCRF_DZ_LINK_EQ_INT_EN_LBN 1
-#define PCRF_DZ_LINK_EQ_INT_EN_WIDTH 1
-#define PCRF_DZ_PERFORM_EQL_LBN 0
-#define PCRF_DZ_PERFORM_EQL_WIDTH 1
-
-
-/*
- * PC_LANE_ERROR_STAT_REG(32bit):
- * Lane Error Status Register.
- */
-
-#define PCR_DZ_LANE_ERROR_STAT_REG 0x00000308
-/* hunta0=pci_f0_config */
-
-#define PCRF_DZ_LANE_STATUS_LBN 0
-#define PCRF_DZ_LANE_STATUS_WIDTH 8
-
-
-/*
- * PC_LANE01_EQU_CONTROL_REG(32bit):
- * Lanes 0,1 Equalization Control Register.
- */
-
-#define PCR_DZ_LANE01_EQU_CONTROL_REG 0x0000030c
-/* hunta0=pci_f0_config */
-
-#define PCRF_DZ_LANE1_EQ_CTRL_LBN 16
-#define PCRF_DZ_LANE1_EQ_CTRL_WIDTH 16
-#define PCRF_DZ_LANE0_EQ_CTRL_LBN 0
-#define PCRF_DZ_LANE0_EQ_CTRL_WIDTH 16
-
-
-/*
- * PC_LANE23_EQU_CONTROL_REG(32bit):
- * Lanes 2,3 Equalization Control Register.
- */
-
-#define PCR_DZ_LANE23_EQU_CONTROL_REG 0x00000310
-/* hunta0=pci_f0_config */
-
-#define PCRF_DZ_LANE3_EQ_CTRL_LBN 16
-#define PCRF_DZ_LANE3_EQ_CTRL_WIDTH 16
-#define PCRF_DZ_LANE2_EQ_CTRL_LBN 0
-#define PCRF_DZ_LANE2_EQ_CTRL_WIDTH 16
-
-
-/*
- * PC_LANE45_EQU_CONTROL_REG(32bit):
- * Lanes 4,5 Equalization Control Register.
+ * PC_LTR_CAP_HDR_REG(32bit):
+ * Latency Tolerance Reporting Cap Header Reg
*/
-#define PCR_DZ_LANE45_EQU_CONTROL_REG 0x00000314
+#define PCR_DZ_LTR_CAP_HDR_REG 0x00000290
/* hunta0=pci_f0_config */
-#define PCRF_DZ_LANE5_EQ_CTRL_LBN 16
-#define PCRF_DZ_LANE5_EQ_CTRL_WIDTH 16
-#define PCRF_DZ_LANE4_EQ_CTRL_LBN 0
-#define PCRF_DZ_LANE4_EQ_CTRL_WIDTH 16
+#define PCRF_DZ_LTR_NXT_PTR_LBN 20
+#define PCRF_DZ_LTR_NXT_PTR_WIDTH 12
+#define PCRF_DZ_LTR_VERSION_LBN 16
+#define PCRF_DZ_LTR_VERSION_WIDTH 4
+#define PCRF_DZ_LTR_EXT_CAP_ID_LBN 0
+#define PCRF_DZ_LTR_EXT_CAP_ID_WIDTH 16
/*
- * PC_LANE67_EQU_CONTROL_REG(32bit):
- * Lanes 6,7 Equalization Control Register.
+ * PC_LTR_MAX_SNOOP_REG(32bit):
+ * LTR Maximum Snoop/No Snoop Register
*/
-#define PCR_DZ_LANE67_EQU_CONTROL_REG 0x00000318
+#define PCR_DZ_LTR_MAX_SNOOP_REG 0x00000294
/* hunta0=pci_f0_config */
-#define PCRF_DZ_LANE7_EQ_CTRL_LBN 16
-#define PCRF_DZ_LANE7_EQ_CTRL_WIDTH 16
-#define PCRF_DZ_LANE6_EQ_CTRL_LBN 0
-#define PCRF_DZ_LANE6_EQ_CTRL_WIDTH 16
+#define PCRF_DZ_LTR_MAX_NOSNOOP_SCALE_LBN 26
+#define PCRF_DZ_LTR_MAX_NOSNOOP_SCALE_WIDTH 3
+#define PCRF_DZ_LTR_MAX_NOSNOOP_LAT_LBN 16
+#define PCRF_DZ_LTR_MAX_NOSNOOP_LAT_WIDTH 10
+#define PCRF_DZ_LTR_MAX_SNOOP_SCALE_LBN 10
+#define PCRF_DZ_LTR_MAX_SNOOP_SCALE_WIDTH 3
+#define PCRF_DZ_LTR_MAX_SNOOP_LAT_LBN 0
+#define PCRF_DZ_LTR_MAX_SNOOP_LAT_WIDTH 10
/*
@@ -2140,6 +2120,18 @@ extern "C" {
/*
+ * PC_FLT_MSK_REG(32bit):
+ * Filter Mask Register 2
+ */
+
+#define PCR_CC_FLT_MSK_REG 0x00000720
+/* sienaa0=pci_f0_config */
+
+#define PCRF_CC_DEFAULT_FLT_MSK2_LBN 0
+#define PCRF_CC_DEFAULT_FLT_MSK2_WIDTH 32
+
+
+/*
* PC_PHY_STAT_REG(32bit):
* PHY status register
*/
@@ -2161,18 +2153,6 @@ extern "C" {
/*
- * PC_FLT_MSK_REG(32bit):
- * Filter Mask Register 2
- */
-
-#define PCR_CC_FLT_MSK_REG 0x00000720
-/* sienaa0=pci_f0_config */
-
-#define PCRF_CC_DEFAULT_FLT_MSK2_LBN 0
-#define PCRF_CC_DEFAULT_FLT_MSK2_WIDTH 32
-
-
-/*
* PC_PHY_CTL_REG(32bit):
* PHY control register
*/
diff --git a/sys/dev/sfxge/common/efx_rx.c b/sys/dev/sfxge/common/efx_rx.c
index c6e0d70..3501d6e 100644
--- a/sys/dev/sfxge/common/efx_rx.c
+++ b/sys/dev/sfxge/common/efx_rx.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -32,12 +37,174 @@ __FBSDID("$FreeBSD$");
#include "efx_regs.h"
#include "efx_impl.h"
+
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+static __checkReturn int
+falconsiena_rx_init(
+ __in efx_nic_t *enp);
+
+static void
+falconsiena_rx_fini(
+ __in efx_nic_t *enp);
+
+#if EFSYS_OPT_RX_HDR_SPLIT
+static __checkReturn int
+falconsiena_rx_hdr_split_enable(
+ __in efx_nic_t *enp,
+ __in unsigned int hdr_buf_size,
+ __in unsigned int pld_buf_size);
+#endif /* EFSYS_OPT_RX_HDR_SPLIT */
+
+#if EFSYS_OPT_RX_SCATTER
+static __checkReturn int
+falconsiena_rx_scatter_enable(
+ __in efx_nic_t *enp,
+ __in unsigned int buf_size);
+#endif /* EFSYS_OPT_RX_SCATTER */
+
+#if EFSYS_OPT_RX_SCALE
+static __checkReturn int
+falconsiena_rx_scale_mode_set(
+ __in efx_nic_t *enp,
+ __in efx_rx_hash_alg_t alg,
+ __in efx_rx_hash_type_t type,
+ __in boolean_t insert);
+
+static __checkReturn int
+falconsiena_rx_scale_key_set(
+ __in efx_nic_t *enp,
+ __in_ecount(n) uint8_t *key,
+ __in size_t n);
+
+static __checkReturn int
+falconsiena_rx_scale_tbl_set(
+ __in efx_nic_t *enp,
+ __in_ecount(n) unsigned int *table,
+ __in size_t n);
+
+#endif /* EFSYS_OPT_RX_SCALE */
+
+static void
+falconsiena_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);
+
+static void
+falconsiena_rx_qpush(
+ __in efx_rxq_t *erp,
+ __in unsigned int added,
+ __inout unsigned int *pushedp);
+
+static __checkReturn int
+falconsiena_rx_qflush(
+ __in efx_rxq_t *erp);
+
+static void
+falconsiena_rx_qenable(
+ __in efx_rxq_t *erp);
+
+static __checkReturn int
+falconsiena_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,
+ __in efx_rxq_t *erp);
+
+static void
+falconsiena_rx_qdestroy(
+ __in efx_rxq_t *erp);
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
+
+
+#if EFSYS_OPT_FALCON
+static efx_rx_ops_t __efx_rx_falcon_ops = {
+ falconsiena_rx_init, /* erxo_init */
+ falconsiena_rx_fini, /* erxo_fini */
+#if EFSYS_OPT_RX_HDR_SPLIT
+ falconsiena_rx_hdr_split_enable, /* erxo_hdr_split_enable */
+#endif
+#if EFSYS_OPT_RX_SCATTER
+ falconsiena_rx_scatter_enable, /* erxo_scatter_enable */
+#endif
+#if EFSYS_OPT_RX_SCALE
+ falconsiena_rx_scale_mode_set, /* erxo_scale_mode_set */
+ falconsiena_rx_scale_key_set, /* erxo_scale_key_set */
+ falconsiena_rx_scale_tbl_set, /* erxo_scale_tbl_set */
+#endif
+ falconsiena_rx_qpost, /* erxo_qpost */
+ falconsiena_rx_qpush, /* erxo_qpush */
+ falconsiena_rx_qflush, /* erxo_qflush */
+ falconsiena_rx_qenable, /* erxo_qenable */
+ falconsiena_rx_qcreate, /* erxo_qcreate */
+ falconsiena_rx_qdestroy, /* erxo_qdestroy */
+};
+#endif /* EFSYS_OPT_FALCON */
+
+#if EFSYS_OPT_SIENA
+static efx_rx_ops_t __efx_rx_siena_ops = {
+ falconsiena_rx_init, /* erxo_init */
+ falconsiena_rx_fini, /* erxo_fini */
+#if EFSYS_OPT_RX_HDR_SPLIT
+ falconsiena_rx_hdr_split_enable, /* erxo_hdr_split_enable */
+#endif
+#if EFSYS_OPT_RX_SCATTER
+ falconsiena_rx_scatter_enable, /* erxo_scatter_enable */
+#endif
+#if EFSYS_OPT_RX_SCALE
+ falconsiena_rx_scale_mode_set, /* erxo_scale_mode_set */
+ falconsiena_rx_scale_key_set, /* erxo_scale_key_set */
+ falconsiena_rx_scale_tbl_set, /* erxo_scale_tbl_set */
+#endif
+ falconsiena_rx_qpost, /* erxo_qpost */
+ falconsiena_rx_qpush, /* erxo_qpush */
+ falconsiena_rx_qflush, /* erxo_qflush */
+ falconsiena_rx_qenable, /* erxo_qenable */
+ falconsiena_rx_qcreate, /* erxo_qcreate */
+ falconsiena_rx_qdestroy, /* erxo_qdestroy */
+};
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+static efx_rx_ops_t __efx_rx_hunt_ops = {
+ hunt_rx_init, /* erxo_init */
+ hunt_rx_fini, /* erxo_fini */
+#if EFSYS_OPT_RX_HDR_SPLIT
+ hunt_rx_hdr_split_enable, /* erxo_hdr_split_enable */
+#endif
+#if EFSYS_OPT_RX_SCATTER
+ hunt_rx_scatter_enable, /* erxo_scatter_enable */
+#endif
+#if EFSYS_OPT_RX_SCALE
+ hunt_rx_scale_mode_set, /* erxo_scale_mode_set */
+ hunt_rx_scale_key_set, /* erxo_scale_key_set */
+ hunt_rx_scale_tbl_set, /* erxo_scale_tbl_set */
+#endif
+ hunt_rx_qpost, /* erxo_qpost */
+ hunt_rx_qpush, /* erxo_qpush */
+ hunt_rx_qflush, /* erxo_qflush */
+ hunt_rx_qenable, /* erxo_qenable */
+ hunt_rx_qcreate, /* erxo_qcreate */
+ hunt_rx_qdestroy, /* erxo_qdestroy */
+};
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+
__checkReturn int
efx_rx_init(
- __in efx_nic_t *enp)
+ __inout efx_nic_t *enp)
{
- efx_oword_t oword;
- unsigned int index;
+ efx_rx_ops_t *erxop;
int rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
@@ -53,6 +220,471 @@ efx_rx_init(
goto fail2;
}
+ switch (enp->en_family) {
+#if EFSYS_OPT_FALCON
+ case EFX_FAMILY_FALCON:
+ erxop = (efx_rx_ops_t *)&__efx_rx_falcon_ops;
+ break;
+#endif /* EFSYS_OPT_FALCON */
+
+#if EFSYS_OPT_SIENA
+ case EFX_FAMILY_SIENA:
+ erxop = (efx_rx_ops_t *)&__efx_rx_siena_ops;
+ break;
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ erxop = (efx_rx_ops_t *)&__efx_rx_hunt_ops;
+ break;
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+ 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, int, rc);
+
+ enp->en_erxop = NULL;
+ enp->en_mod_flags &= ~EFX_MOD_RX;
+ return (rc);
+}
+
+ void
+efx_rx_fini(
+ __in efx_nic_t *enp)
+{
+ 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;
+}
+
+#if EFSYS_OPT_RX_HDR_SPLIT
+ __checkReturn int
+efx_rx_hdr_split_enable(
+ __in efx_nic_t *enp,
+ __in unsigned int hdr_buf_size,
+ __in unsigned int pld_buf_size)
+{
+ efx_rx_ops_t *erxop = enp->en_erxop;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
+ EFSYS_ASSERT3U(enp->en_family, >=, EFX_FAMILY_SIENA);
+
+ if ((rc = erxop->erxo_hdr_split_enable(enp, hdr_buf_size,
+ pld_buf_size)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_HDR_SPLIT */
+
+#if EFSYS_OPT_RX_SCATTER
+ __checkReturn int
+efx_rx_scatter_enable(
+ __in efx_nic_t *enp,
+ __in unsigned int buf_size)
+{
+ efx_rx_ops_t *erxop = enp->en_erxop;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
+
+ if ((rc = erxop->erxo_scatter_enable(enp, buf_size)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCATTER */
+
+#if EFSYS_OPT_RX_SCALE
+ __checkReturn int
+efx_rx_hash_support_get(
+ __in efx_nic_t *enp,
+ __out efx_rx_hash_support_t *supportp)
+{
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
+
+ if (supportp == NULL) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ /* Report if resources are available to insert RX hash value */
+ *supportp = enp->en_hash_support;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_rx_scale_support_get(
+ __in efx_nic_t *enp,
+ __out efx_rx_scale_support_t *supportp)
+{
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
+
+ if (supportp == NULL) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ /* Report if resources are available to support RSS */
+ *supportp = enp->en_rss_support;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+efx_rx_scale_mode_set(
+ __in efx_nic_t *enp,
+ __in efx_rx_hash_alg_t alg,
+ __in efx_rx_hash_type_t type,
+ __in boolean_t insert)
+{
+ efx_rx_ops_t *erxop = enp->en_erxop;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
+
+ if (erxop->erxo_scale_mode_set != NULL) {
+ if ((rc = erxop->erxo_scale_mode_set(enp, alg,
+ type, insert)) != 0)
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+#if EFSYS_OPT_RX_SCALE
+ __checkReturn int
+efx_rx_scale_key_set(
+ __in efx_nic_t *enp,
+ __in_ecount(n) uint8_t *key,
+ __in size_t n)
+{
+ efx_rx_ops_t *erxop = enp->en_erxop;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
+
+ if ((rc = erxop->erxo_scale_key_set(enp, key, n)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+#if EFSYS_OPT_RX_SCALE
+ __checkReturn int
+efx_rx_scale_tbl_set(
+ __in efx_nic_t *enp,
+ __in_ecount(n) unsigned int *table,
+ __in size_t n)
+{
+ efx_rx_ops_t *erxop = enp->en_erxop;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
+
+ if ((rc = erxop->erxo_scale_tbl_set(enp, table, n)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+ 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;
+ 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;
+ efx_rx_ops_t *erxop = enp->en_erxop;
+
+ EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
+
+ erxop->erxo_qpush(erp, added, pushedp);
+}
+
+ __checkReturn int
+efx_rx_qflush(
+ __in efx_rxq_t *erp)
+{
+ efx_nic_t *enp = erp->er_enp;
+ efx_rx_ops_t *erxop = enp->en_erxop;
+ int rc;
+
+ EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
+
+ if ((rc = erxop->erxo_qflush(erp)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+efx_rx_qenable(
+ __in efx_rxq_t *erp)
+{
+ efx_nic_t *enp = erp->er_enp;
+ efx_rx_ops_t *erxop = enp->en_erxop;
+
+ EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
+
+ erxop->erxo_qenable(erp);
+}
+
+ __checkReturn int
+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)
+{
+ efx_rx_ops_t *erxop = enp->en_erxop;
+ efx_rxq_t *erp;
+ int 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, int, rc);
+
+ return (rc);
+}
+
+ void
+efx_rx_qdestroy(
+ __in efx_rxq_t *erp)
+{
+ efx_nic_t *enp = erp->er_enp;
+ efx_rx_ops_t *erxop = enp->en_erxop;
+
+ EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
+
+ erxop->erxo_qdestroy(erp);
+}
+
+/*
+ * Psuedo-header info for Siena/Falcon.
+ *
+ * The psuedo-header is a byte array of one of the forms:
+ *
+ * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+ * XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.TT.TT.TT.TT
+ * XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.XX.LL.LL
+ *
+ * where:
+ *
+ * TT.TT.TT.TT is a 32-bit Toeplitz hash
+ * LL.LL is a 16-bit LFSR hash
+ *
+ * Hash values are in network (big-endian) byte order.
+ *
+ *
+ * On Huntington the pseudo-header is laid out as:
+ * (See also SF-109306-TC section 9)
+ *
+ * Toeplitz hash (32 bits, little-endian)
+ * Out-of-band outer VLAN tag
+ * (16 bits, big-endian, 0 if the packet did not have an outer VLAN tag)
+ * Out-of-band inner VLAN tag
+ * (16 bits, big-endian, 0 if the packet did not have an inner VLAN tag)
+ * Packet length (16 bits, little-endian, may be 0)
+ * MAC timestamp (32 bits, little-endian, may be 0)
+ * VLAN tag
+ * (16 bits, big-endian, 0 if the packet did not have an outer VLAN tag)
+ * VLAN tag
+ * (16 bits, big-endian, 0 if the packet did not have an inner VLAN tag)
+ */
+
+ __checkReturn int
+efx_psuedo_hdr_pkt_length_get(
+ __in efx_nic_t *enp,
+ __in uint8_t *buffer,
+ __out uint16_t *pkt_lengthp)
+{
+ if (enp->en_family != EFX_FAMILY_HUNTINGTON) {
+ EFSYS_ASSERT(0);
+ return (ENOTSUP);
+ }
+
+ *pkt_lengthp = buffer[8] | (buffer[9] << 8);
+
+ return (0);
+}
+
+#if EFSYS_OPT_RX_SCALE
+
+uint32_t
+efx_psuedo_hdr_hash_get(
+ __in efx_nic_t *enp,
+ __in efx_rx_hash_alg_t func,
+ __in uint8_t *buffer)
+{
+ if (func == EFX_RX_HASHALG_TOEPLITZ) {
+ switch (enp->en_family) {
+ case EFX_FAMILY_FALCON:
+ case EFX_FAMILY_SIENA:
+ return ((buffer[12] << 24) |
+ (buffer[13] << 16) |
+ (buffer[14] << 8) |
+ buffer[15]);
+ case EFX_FAMILY_HUNTINGTON:
+ return (buffer[0] |
+ (buffer[1] << 8) |
+ (buffer[2] << 16) |
+ (buffer[3] << 24));
+ default:
+ EFSYS_ASSERT(0);
+ return (0);
+ }
+ } else if (func == EFX_RX_HASHALG_LFSR) {
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_FALCON ||
+ enp->en_family == EFX_FAMILY_SIENA);
+ return ((buffer[14] << 8) | buffer[15]);
+ } else {
+ EFSYS_ASSERT(0);
+ return (0);
+ }
+}
+
+#endif /* EFSYS_OPT_RX_SCALE */
+
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+static __checkReturn int
+falconsiena_rx_init(
+ __in efx_nic_t *enp)
+{
+ efx_oword_t oword;
+ unsigned int index;
+
EFX_BAR_READO(enp, FR_AZ_RX_CFG_REG, &oword);
EFX_SET_OWORD_FIELD(oword, FRF_BZ_RX_DESC_PUSH_EN, 0);
@@ -68,23 +700,23 @@ efx_rx_init(
index++) {
EFX_ZERO_OWORD(oword);
EFX_BAR_TBL_WRITEO(enp, FR_BZ_RX_INDIRECTION_TBL,
- index, &oword);
+ index, &oword, B_TRUE);
}
- enp->en_mod_flags |= EFX_MOD_RX;
- return (0);
+#if EFSYS_OPT_RX_SCALE
+ /* The RSS key and indirection table are writable. */
+ enp->en_rss_support = EFX_RX_SCALE_EXCLUSIVE;
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
+ /* Hardware can insert RX hash with/without RSS */
+ enp->en_hash_support = EFX_RX_HASH_AVAILABLE;
+#endif /* EFSYS_OPT_RX_SCALE */
- return (rc);
+ return (0);
}
#if EFSYS_OPT_RX_HDR_SPLIT
- __checkReturn int
-efx_rx_hdr_split_enable(
+static __checkReturn int
+falconsiena_rx_hdr_split_enable(
__in efx_nic_t *enp,
__in unsigned int hdr_buf_size,
__in unsigned int pld_buf_size)
@@ -94,10 +726,6 @@ efx_rx_hdr_split_enable(
efx_oword_t oword;
int rc;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
- EFSYS_ASSERT3U(enp->en_family, >=, EFX_FAMILY_SIENA);
-
nhdr32 = hdr_buf_size / 32;
if ((nhdr32 == 0) ||
(nhdr32 >= (1 << FRF_CZ_RX_HDR_SPLIT_HDR_BUF_SIZE_WIDTH)) ||
@@ -140,10 +768,9 @@ fail1:
}
#endif /* EFSYS_OPT_RX_HDR_SPLIT */
-
#if EFSYS_OPT_RX_SCATTER
- __checkReturn int
-efx_rx_scatter_enable(
+static __checkReturn int
+falconsiena_rx_scatter_enable(
__in efx_nic_t *enp,
__in unsigned int buf_size)
{
@@ -151,10 +778,6 @@ efx_rx_scatter_enable(
efx_oword_t oword;
int rc;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
- EFSYS_ASSERT3U(enp->en_family, >=, EFX_FAMILY_FALCON);
-
nbuf32 = buf_size / 32;
if ((nbuf32 == 0) ||
(nbuf32 >= (1 << FRF_BZ_RX_USR_BUF_SIZE_WIDTH)) ||
@@ -191,7 +814,7 @@ fail1:
#define EFX_RX_LFSR_HASH(_enp, _insert) \
- do { \
+ do { \
efx_oword_t oword; \
\
EFX_BAR_READO((_enp), FR_AZ_RX_CFG_REG, &oword); \
@@ -215,7 +838,7 @@ fail1:
} while (B_FALSE)
#define EFX_RX_TOEPLITZ_IPV4_HASH(_enp, _insert, _ip, _tcp) \
- do { \
+ do { \
efx_oword_t oword; \
\
EFX_BAR_READO((_enp), FR_AZ_RX_CFG_REG, &oword); \
@@ -232,7 +855,7 @@ fail1:
} while (B_FALSE)
#define EFX_RX_TOEPLITZ_IPV6_HASH(_enp, _ip, _tcp, _rc) \
- do { \
+ do { \
efx_oword_t oword; \
\
if ((_enp)->en_family == EFX_FAMILY_FALCON) { \
@@ -256,8 +879,9 @@ fail1:
#if EFSYS_OPT_RX_SCALE
- __checkReturn int
-efx_rx_scale_mode_set(
+
+static __checkReturn int
+falconsiena_rx_scale_mode_set(
__in efx_nic_t *enp,
__in efx_rx_hash_alg_t alg,
__in efx_rx_hash_type_t type,
@@ -265,10 +889,6 @@ efx_rx_scale_mode_set(
{
int rc;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
- EFSYS_ASSERT3U(enp->en_family, >=, EFX_FAMILY_FALCON);
-
switch (alg) {
case EFX_RX_HASHALG_LFSR:
EFX_RX_LFSR_HASH(enp, insert);
@@ -307,8 +927,8 @@ fail1:
#endif
#if EFSYS_OPT_RX_SCALE
- __checkReturn int
-efx_rx_scale_toeplitz_ipv4_key_set(
+static __checkReturn int
+falconsiena_rx_scale_key_set(
__in efx_nic_t *enp,
__in_ecount(n) uint8_t *key,
__in size_t n)
@@ -318,12 +938,9 @@ efx_rx_scale_toeplitz_ipv4_key_set(
unsigned int offset;
int rc;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
-
byte = 0;
- /* Write toeplitz hash key */
+ /* Write Toeplitz IPv4 hash key */
EFX_ZERO_OWORD(oword);
for (offset = (FRF_BZ_RX_RSS_TKEY_LBN + FRF_BZ_RX_RSS_TKEY_WIDTH) / 8;
offset > 0 && byte < n;
@@ -334,7 +951,7 @@ efx_rx_scale_toeplitz_ipv4_key_set(
byte = 0;
- /* Verify toeplitz hash key */
+ /* Verify Toeplitz IPv4 hash key */
EFX_BAR_READO(enp, FR_BZ_RX_RSS_TKEY_REG, &oword);
for (offset = (FRF_BZ_RX_RSS_TKEY_LBN + FRF_BZ_RX_RSS_TKEY_WIDTH) / 8;
offset > 0 && byte < n;
@@ -345,33 +962,14 @@ efx_rx_scale_toeplitz_ipv4_key_set(
}
}
- return (0);
+ if ((enp->en_features & EFX_FEATURE_IPV6) == 0)
+ goto done;
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-#endif
-
-#if EFSYS_OPT_RX_SCALE
- __checkReturn int
-efx_rx_scale_toeplitz_ipv6_key_set(
- __in efx_nic_t *enp,
- __in_ecount(n) uint8_t *key,
- __in size_t n)
-{
- efx_oword_t oword;
- unsigned int byte;
- int offset;
- int rc;
-
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
+ EFSYS_ASSERT3U(enp->en_family, !=, EFX_FAMILY_FALCON);
byte = 0;
- /* Write toeplitz hash key 3 */
+ /* Write Toeplitz IPv6 hash key 3 */
EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN +
FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH) / 8;
@@ -381,7 +979,7 @@ efx_rx_scale_toeplitz_ipv6_key_set(
EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
- /* Write toeplitz hash key 2 */
+ /* Write Toeplitz IPv6 hash key 2 */
EFX_ZERO_OWORD(oword);
for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN +
FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH) / 8;
@@ -391,7 +989,7 @@ efx_rx_scale_toeplitz_ipv6_key_set(
EFX_BAR_WRITEO(enp, FR_CZ_RX_RSS_IPV6_REG2, &oword);
- /* Write toeplitz hash key 1 */
+ /* Write Toeplitz IPv6 hash key 1 */
EFX_ZERO_OWORD(oword);
for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN +
FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH) / 8;
@@ -403,7 +1001,7 @@ efx_rx_scale_toeplitz_ipv6_key_set(
byte = 0;
- /* Verify toeplitz hash key 3 */
+ /* Verify Toeplitz IPv6 hash key 3 */
EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG3, &oword);
for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_HI_LBN +
FRF_CZ_RX_RSS_IPV6_TKEY_HI_WIDTH) / 8;
@@ -411,11 +1009,11 @@ efx_rx_scale_toeplitz_ipv6_key_set(
--offset) {
if (oword.eo_u8[offset - 1] != key[byte++]) {
rc = EFAULT;
- goto fail1;
+ goto fail2;
}
}
- /* Verify toeplitz hash key 2 */
+ /* Verify Toeplitz IPv6 hash key 2 */
EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG2, &oword);
for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_MID_LBN +
FRF_CZ_RX_RSS_IPV6_TKEY_MID_WIDTH) / 8;
@@ -423,11 +1021,11 @@ efx_rx_scale_toeplitz_ipv6_key_set(
--offset) {
if (oword.eo_u8[offset - 1] != key[byte++]) {
rc = EFAULT;
- goto fail2;
+ goto fail3;
}
}
- /* Verify toeplitz hash key 1 */
+ /* Verify Toeplitz IPv6 hash key 1 */
EFX_BAR_READO(enp, FR_CZ_RX_RSS_IPV6_REG1, &oword);
for (offset = (FRF_CZ_RX_RSS_IPV6_TKEY_LO_LBN +
FRF_CZ_RX_RSS_IPV6_TKEY_LO_WIDTH) / 8;
@@ -435,12 +1033,15 @@ efx_rx_scale_toeplitz_ipv6_key_set(
--offset) {
if (oword.eo_u8[offset - 1] != key[byte++]) {
rc = EFAULT;
- goto fail3;
+ goto fail4;
}
}
+done:
return (0);
+fail4:
+ EFSYS_PROBE(fail4);
fail3:
EFSYS_PROBE(fail3);
fail2:
@@ -453,8 +1054,8 @@ fail1:
#endif
#if EFSYS_OPT_RX_SCALE
- __checkReturn int
-efx_rx_scale_tbl_set(
+static __checkReturn int
+falconsiena_rx_scale_tbl_set(
__in efx_nic_t *enp,
__in_ecount(n) unsigned int *table,
__in size_t n)
@@ -463,9 +1064,6 @@ efx_rx_scale_tbl_set(
int index;
int rc;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
-
EFX_STATIC_ASSERT(EFX_RSS_TBL_SIZE == FR_BZ_RX_INDIRECTION_TBL_ROWS);
EFX_STATIC_ASSERT(EFX_MAXRSS == (1 << FRF_BZ_IT_QUEUE_WIDTH));
@@ -478,7 +1076,7 @@ efx_rx_scale_tbl_set(
uint32_t byte;
/* Calculate the entry to place in the table */
- byte = (uint32_t)table[index % n];
+ byte = (n > 0) ? (uint32_t)table[index % n] : 0;
EFSYS_PROBE2(table, int, index, uint32_t, byte);
@@ -486,18 +1084,18 @@ efx_rx_scale_tbl_set(
/* Write the table */
EFX_BAR_TBL_WRITEO(enp, FR_BZ_RX_INDIRECTION_TBL,
- index, &oword);
+ index, &oword, B_TRUE);
}
for (index = FR_BZ_RX_INDIRECTION_TBL_ROWS - 1; index >= 0; --index) {
uint32_t byte;
/* Determine if we're starting a new batch */
- byte = (uint32_t)table[index % n];
+ byte = (n > 0) ? (uint32_t)table[index % n] : 0;
/* Read the table */
EFX_BAR_TBL_READO(enp, FR_BZ_RX_INDIRECTION_TBL,
- index, &oword);
+ index, &oword, B_TRUE);
/* Verify the entry */
if (EFX_OWORD_FIELD(oword, FRF_BZ_IT_QUEUE) != byte) {
@@ -517,36 +1115,8 @@ fail1:
}
#endif
-#if EFSYS_OPT_FILTER
-extern __checkReturn int
-efx_rx_filter_insert(
- __in efx_rxq_t *erp,
- __inout efx_filter_spec_t *spec)
-{
- EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
- EFSYS_ASSERT3P(spec, !=, NULL);
-
- spec->efs_dmaq_id = (uint16_t)erp->er_index;
- return (efx_filter_insert_filter(erp->er_enp, spec, B_FALSE));
-}
-#endif
-
-#if EFSYS_OPT_FILTER
-extern __checkReturn int
-efx_rx_filter_remove(
- __in efx_rxq_t *erp,
- __inout efx_filter_spec_t *spec)
-{
- EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
- EFSYS_ASSERT3P(spec, !=, NULL);
-
- spec->efs_dmaq_id = (uint16_t)erp->er_index;
- return (efx_filter_remove_filter(erp->er_enp, spec));
-}
-#endif
-
-extern void
-efx_rx_qpost(
+static void
+falconsiena_rx_qpost(
__in efx_rxq_t *erp,
__in_ecount(n) efsys_dma_addr_t *addrp,
__in size_t size,
@@ -559,8 +1129,6 @@ efx_rx_qpost(
unsigned int offset;
unsigned int id;
- EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
-
/* The client driver must not overfill the queue */
EFSYS_ASSERT3U(added - completed + n, <=,
EFX_RXQ_LIMIT(erp->er_mask + 1));
@@ -585,20 +1153,20 @@ efx_rx_qpost(
}
}
- void
-efx_rx_qpush(
+static void
+falconsiena_rx_qpush(
__in efx_rxq_t *erp,
- __in unsigned int added)
+ __in unsigned int added,
+ __inout unsigned int *pushedp)
{
efx_nic_t *enp = erp->er_enp;
+ unsigned int pushed = *pushedp;
uint32_t wptr;
efx_oword_t oword;
efx_dword_t dword;
- EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
-
- /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
- EFSYS_PIO_WRITE_BARRIER();
+ /* All descriptors are pushed */
+ *pushedp = added;
/* Push the populated descriptors out */
wptr = added & erp->er_mask;
@@ -608,30 +1176,35 @@ efx_rx_qpush(
/* Only write the third DWORD */
EFX_POPULATE_DWORD_1(dword,
EFX_DWORD_0, EFX_OWORD_FIELD(oword, EFX_DWORD_3));
+
+ /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
+ EFX_DMA_SYNC_QUEUE_FOR_DEVICE(erp->er_esmp, erp->er_mask + 1,
+ wptr, pushed & erp->er_mask);
+ EFSYS_PIO_WRITE_BARRIER();
EFX_BAR_TBL_WRITED3(enp, FR_BZ_RX_DESC_UPD_REGP0,
erp->er_index, &dword, B_FALSE);
}
- void
-efx_rx_qflush(
+static __checkReturn int
+falconsiena_rx_qflush(
__in efx_rxq_t *erp)
{
efx_nic_t *enp = erp->er_enp;
efx_oword_t oword;
uint32_t label;
- EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
-
label = erp->er_index;
/* Flush the queue */
EFX_POPULATE_OWORD_2(oword, FRF_AZ_RX_FLUSH_DESCQ_CMD, 1,
FRF_AZ_RX_FLUSH_DESCQ, label);
EFX_BAR_WRITEO(enp, FR_AZ_RX_FLUSH_DESCQ_REG, &oword);
+
+ return (0);
}
- void
-efx_rx_qenable(
+static void
+falconsiena_rx_qenable(
__in efx_rxq_t *erp)
{
efx_nic_t *enp = erp->er_enp;
@@ -640,18 +1213,18 @@ efx_rx_qenable(
EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
EFX_BAR_TBL_READO(enp, FR_AZ_RX_DESC_PTR_TBL,
- erp->er_index, &oword);
+ erp->er_index, &oword, B_TRUE);
EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DC_HW_RPTR, 0);
EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DESCQ_HW_RPTR, 0);
EFX_SET_OWORD_FIELD(oword, FRF_AZ_RX_DESCQ_EN, 1);
EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
- erp->er_index, &oword);
+ erp->er_index, &oword, B_TRUE);
}
- __checkReturn int
-efx_rx_qcreate(
+static __checkReturn int
+falconsiena_rx_qcreate(
__in efx_nic_t *enp,
__in unsigned int index,
__in unsigned int label,
@@ -660,25 +1233,24 @@ efx_rx_qcreate(
__in size_t n,
__in uint32_t id,
__in efx_evq_t *eep,
- __deref_out efx_rxq_t **erpp)
+ __in efx_rxq_t *erp)
{
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- efx_rxq_t *erp;
efx_oword_t oword;
uint32_t size;
boolean_t split;
boolean_t jumbo;
int rc;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_RX);
-
EFX_STATIC_ASSERT(EFX_EV_RX_NLABELS ==
(1 << FRF_AZ_RX_DESCQ_LABEL_WIDTH));
EFSYS_ASSERT3U(label, <, EFX_EV_RX_NLABELS);
EFSYS_ASSERT3U(enp->en_rx_qcount + 1, <, encp->enc_rxq_limit);
- if (!ISP2(n) || !(n & EFX_RXQ_NDESCS_MASK)) {
+ EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MAXNDESCS));
+ EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MINNDESCS));
+
+ if (!ISP2(n) || (n < EFX_RXQ_MINNDESCS) || (n > EFX_RXQ_MAXNDESCS)) {
rc = EINVAL;
goto fail1;
}
@@ -737,20 +1309,6 @@ efx_rx_qcreate(
goto fail4;
}
- /* Allocate an RXQ object */
- EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_rxq_t), erp);
-
- if (erp == NULL) {
- rc = ENOMEM;
- goto fail5;
- }
-
- erp->er_magic = EFX_RXQ_MAGIC;
- erp->er_enp = enp;
- erp->er_index = index;
- erp->er_mask = n - 1;
- erp->er_esmp = esmp;
-
/* Set up the new descriptor queue */
EFX_POPULATE_OWORD_10(oword,
FRF_CZ_RX_HDR_SPLIT, split,
@@ -765,14 +1323,10 @@ efx_rx_qcreate(
FRF_AZ_RX_DESCQ_JUMBO, jumbo);
EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
- erp->er_index, &oword);
+ erp->er_index, &oword, B_TRUE);
- enp->en_rx_qcount++;
- *erpp = erp;
return (0);
-fail5:
- EFSYS_PROBE(fail5);
fail4:
EFSYS_PROBE(fail4);
fail3:
@@ -785,15 +1339,13 @@ fail1:
return (rc);
}
- void
-efx_rx_qdestroy(
+static void
+falconsiena_rx_qdestroy(
__in efx_rxq_t *erp)
{
efx_nic_t *enp = erp->er_enp;
efx_oword_t oword;
- EFSYS_ASSERT3U(erp->er_magic, ==, EFX_RXQ_MAGIC);
-
EFSYS_ASSERT(enp->en_rx_qcount != 0);
--enp->en_rx_qcount;
@@ -801,20 +1353,17 @@ efx_rx_qdestroy(
EFX_ZERO_OWORD(oword);
EFX_BAR_TBL_WRITEO(enp, FR_AZ_RX_DESC_PTR_TBL,
- erp->er_index, &oword);
+ erp->er_index, &oword, B_TRUE);
/* Free the RXQ object */
EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp);
}
- void
-efx_rx_fini(
+static void
+falconsiena_rx_fini(
__in efx_nic_t *enp)
{
- 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);
-
- enp->en_mod_flags &= ~EFX_MOD_RX;
+ _NOTE(ARGUNUSED(enp))
}
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
diff --git a/sys/dev/sfxge/common/efx_sram.c b/sys/dev/sfxge/common/efx_sram.c
index f081adf..4bd951b 100644
--- a/sys/dev/sfxge/common/efx_sram.c
+++ b/sys/dev/sfxge/common/efx_sram.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -50,6 +55,21 @@ efx_sram_buf_tbl_set(
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
+#if EFSYS_OPT_HUNTINGTON
+ if (enp->en_family == EFX_FAMILY_HUNTINGTON) {
+ /*
+ * FIXME: the efx_sram_buf_tbl_*() functionality needs to be
+ * pulled inside the Falcon/Siena queue create/destroy code,
+ * and then the original functions can be removed (see bug30834
+ * comment #1). But, for now, we just ensure that they are
+ * no-ops for Huntington, to allow bringing up existing drivers
+ * without modification.
+ */
+
+ return (0);
+ }
+#endif /* EFSYS_OPT_HUNTINGTON */
+
if (stop >= EFX_BUF_TBL_SIZE) {
rc = EFBIG;
goto fail1;
@@ -156,6 +176,21 @@ efx_sram_buf_tbl_clear(
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_NIC);
+#if EFSYS_OPT_HUNTINGTON
+ if (enp->en_family == EFX_FAMILY_HUNTINGTON) {
+ /*
+ * FIXME: the efx_sram_buf_tbl_*() functionality needs to be
+ * pulled inside the Falcon/Siena queue create/destroy code,
+ * and then the original functions can be removed (see bug30834
+ * comment #1). But, for now, we just ensure that they are
+ * no-ops for Huntington, to allow bringing up existing drivers
+ * without modification.
+ */
+
+ return;
+ }
+#endif /* EFSYS_OPT_HUNTINGTON */
+
EFSYS_ASSERT3U(stop, <, EFX_BUF_TBL_SIZE);
EFSYS_PROBE2(buf, uint32_t, start, uint32_t, stop - 1);
@@ -262,7 +297,7 @@ efx_sram_bit_sweep_set(
}
}
-efx_sram_pattern_fn_t __cs __efx_sram_pattern_fns[] = {
+efx_sram_pattern_fn_t __efx_sram_pattern_fns[] = {
efx_sram_byte_increment_set,
efx_sram_all_the_same_set,
efx_sram_bit_alternate_set,
diff --git a/sys/dev/sfxge/common/efx_tx.c b/sys/dev/sfxge/common/efx_tx.c
index 2b0f5e5..a2e8769 100644
--- a/sys/dev/sfxge/common/efx_tx.c
+++ b/sys/dev/sfxge/common/efx_tx.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -42,11 +47,166 @@ __FBSDID("$FreeBSD$");
#define EFX_TX_QSTAT_INCR(_etp, _stat)
#endif
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+static __checkReturn int
+falconsiena_tx_init(
+ __in efx_nic_t *enp);
+
+static void
+falconsiena_tx_fini(
+ __in efx_nic_t *enp);
+
+static __checkReturn int
+falconsiena_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,
+ __in efx_txq_t *etp,
+ __out unsigned int *addedp);
+
+static void
+falconsiena_tx_qdestroy(
+ __in efx_txq_t *etp);
+
+static __checkReturn int
+falconsiena_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);
+
+static void
+falconsiena_tx_qpush(
+ __in efx_txq_t *etp,
+ __in unsigned int added,
+ __in unsigned int pushed);
+
+static __checkReturn int
+falconsiena_tx_qpace(
+ __in efx_txq_t *etp,
+ __in unsigned int ns);
+
+static __checkReturn int
+falconsiena_tx_qflush(
+ __in efx_txq_t *etp);
+
+static void
+falconsiena_tx_qenable(
+ __in efx_txq_t *etp);
+
+ __checkReturn int
+falconsiena_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);
+
+ void
+falconsiena_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);
+
+#if EFSYS_OPT_QSTATS
+static void
+falconsiena_tx_qstats_update(
+ __in efx_txq_t *etp,
+ __inout_ecount(TX_NQSTATS) efsys_stat_t *stat);
+#endif
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
+
+
+#if EFSYS_OPT_FALCON
+static efx_tx_ops_t __efx_tx_falcon_ops = {
+ falconsiena_tx_init, /* etxo_init */
+ falconsiena_tx_fini, /* etxo_fini */
+ falconsiena_tx_qcreate, /* etxo_qcreate */
+ falconsiena_tx_qdestroy, /* etxo_qdestroy */
+ falconsiena_tx_qpost, /* etxo_qpost */
+ falconsiena_tx_qpush, /* etxo_qpush */
+ falconsiena_tx_qpace, /* etxo_qpace */
+ falconsiena_tx_qflush, /* etxo_qflush */
+ falconsiena_tx_qenable, /* etxo_qenable */
+ NULL, /* etxo_qpio_enable */
+ NULL, /* etxo_qpio_disable */
+ NULL, /* etxo_qpio_write */
+ NULL, /* etxo_qpio_post */
+ falconsiena_tx_qdesc_post, /* etxo_qdesc_post */
+ falconsiena_tx_qdesc_dma_create, /* etxo_qdesc_dma_create */
+ NULL, /* etxo_qdesc_tso_create */
+ NULL, /* etxo_qdesc_vlantci_create */
+#if EFSYS_OPT_QSTATS
+ falconsiena_tx_qstats_update, /* etxo_qstats_update */
+#endif
+};
+#endif /* EFSYS_OPT_FALCON */
+
+#if EFSYS_OPT_SIENA
+static efx_tx_ops_t __efx_tx_siena_ops = {
+ falconsiena_tx_init, /* etxo_init */
+ falconsiena_tx_fini, /* etxo_fini */
+ falconsiena_tx_qcreate, /* etxo_qcreate */
+ falconsiena_tx_qdestroy, /* etxo_qdestroy */
+ falconsiena_tx_qpost, /* etxo_qpost */
+ falconsiena_tx_qpush, /* etxo_qpush */
+ falconsiena_tx_qpace, /* etxo_qpace */
+ falconsiena_tx_qflush, /* etxo_qflush */
+ falconsiena_tx_qenable, /* etxo_qenable */
+ NULL, /* etxo_qpio_enable */
+ NULL, /* etxo_qpio_disable */
+ NULL, /* etxo_qpio_write */
+ NULL, /* etxo_qpio_post */
+ falconsiena_tx_qdesc_post, /* etxo_qdesc_post */
+ falconsiena_tx_qdesc_dma_create, /* etxo_qdesc_dma_create */
+ NULL, /* etxo_qdesc_tso_create */
+ NULL, /* etxo_qdesc_vlantci_create */
+#if EFSYS_OPT_QSTATS
+ falconsiena_tx_qstats_update, /* etxo_qstats_update */
+#endif
+};
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+static efx_tx_ops_t __efx_tx_hunt_ops = {
+ hunt_tx_init, /* etxo_init */
+ hunt_tx_fini, /* etxo_fini */
+ hunt_tx_qcreate, /* etxo_qcreate */
+ hunt_tx_qdestroy, /* etxo_qdestroy */
+ hunt_tx_qpost, /* etxo_qpost */
+ hunt_tx_qpush, /* etxo_qpush */
+ hunt_tx_qpace, /* etxo_qpace */
+ hunt_tx_qflush, /* etxo_qflush */
+ hunt_tx_qenable, /* etxo_qenable */
+ hunt_tx_qpio_enable, /* etxo_qpio_enable */
+ hunt_tx_qpio_disable, /* etxo_qpio_disable */
+ hunt_tx_qpio_write, /* etxo_qpio_write */
+ hunt_tx_qpio_post, /* etxo_qpio_post */
+ hunt_tx_qdesc_post, /* etxo_qdesc_post */
+ hunt_tx_qdesc_dma_create, /* etxo_qdesc_dma_create */
+ hunt_tx_qdesc_tso_create, /* etxo_qdesc_tso_create */
+ hunt_tx_qdesc_vlantci_create, /* etxo_qdesc_vlantci_create */
+#if EFSYS_OPT_QSTATS
+ hunt_tx_qstats_update, /* etxo_qstats_update */
+#endif
+};
+#endif /* EFSYS_OPT_HUNTINGTON */
+
__checkReturn int
efx_tx_init(
__in efx_nic_t *enp)
{
- efx_oword_t oword;
+ efx_tx_ops_t *etxop;
int rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
@@ -62,8 +222,436 @@ efx_tx_init(
goto fail2;
}
+ switch (enp->en_family) {
+#if EFSYS_OPT_FALCON
+ case EFX_FAMILY_FALCON:
+ etxop = (efx_tx_ops_t *)&__efx_tx_falcon_ops;
+ break;
+#endif /* EFSYS_OPT_FALCON */
+
+#if EFSYS_OPT_SIENA
+ case EFX_FAMILY_SIENA:
+ etxop = (efx_tx_ops_t *)&__efx_tx_siena_ops;
+ break;
+#endif /* EFSYS_OPT_SIENA */
+
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ etxop = (efx_tx_ops_t *)&__efx_tx_hunt_ops;
+ break;
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+ 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, int, rc);
+
+ enp->en_etxop = NULL;
+ enp->en_mod_flags &= ~EFX_MOD_TX;
+ return (rc);
+}
+
+ void
+efx_tx_fini(
+ __in efx_nic_t *enp)
+{
+ 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 int
+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)
+{
+ efx_tx_ops_t *etxop = enp->en_etxop;
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_txq_t *etp;
+ int 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, int, rc);
+ return (rc);
+}
+
+ void
+efx_tx_qdestroy(
+ __in efx_txq_t *etp)
+{
+ efx_nic_t *enp = etp->et_enp;
+ 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 int
+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;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+ int 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, int, 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;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+
+ EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+ etxop->etxo_qpush(etp, added, pushed);
+}
+
+ __checkReturn int
+efx_tx_qpace(
+ __in efx_txq_t *etp,
+ __in unsigned int ns)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+ int 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, int, rc);
+ return (rc);
+}
+
+ __checkReturn int
+efx_tx_qflush(
+ __in efx_txq_t *etp)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+ int rc;
+
+ EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+ if ((rc = etxop->etxo_qflush(etp)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+
+ void
+efx_tx_qenable(
+ __in efx_txq_t *etp)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+
+ EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+ etxop->etxo_qenable(etp);
+}
+
+ __checkReturn int
+efx_tx_qpio_enable(
+ __in efx_txq_t *etp)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+ int 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, int, rc);
+ return (rc);
+}
+
+ void
+efx_tx_qpio_disable(
+ __in efx_txq_t *etp)
+{
+ efx_nic_t *enp = etp->et_enp;
+ 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 int
+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;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+ int 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, int, rc);
+ return (rc);
+}
+
+ __checkReturn int
+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;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+ int 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, int, rc);
+ return (rc);
+}
+
+ __checkReturn int
+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;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+ int 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, int, 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;
+ 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;
+ 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_vlantci_create(
+ __in efx_txq_t *etp,
+ __in uint16_t tci,
+ __out efx_desc_t *edp)
+{
+ efx_nic_t *enp = etp->et_enp;
+ 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);
+}
+
+
+#if EFSYS_OPT_QSTATS
+ void
+efx_tx_qstats_update(
+ __in efx_txq_t *etp,
+ __inout_ecount(TX_NQSTATS) efsys_stat_t *stat)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_tx_ops_t *etxop = enp->en_etxop;
+
+ EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
+
+ etxop->etxo_qstats_update(etp, stat);
+}
+#endif
+
+
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
+
+static __checkReturn int
+falconsiena_tx_init(
+ __in efx_nic_t *enp)
+{
+ efx_oword_t oword;
+
/*
* Disable the timer-based TX DMA backoff and allow TX DMA to be
* controlled by the RX FIFO fill level (although always allow a
@@ -93,44 +681,8 @@ efx_tx_init(
EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_NO_EOP_DISC_EN, 0);
EFX_BAR_WRITEO(enp, FR_AZ_TX_CFG_REG, &oword);
- enp->en_mod_flags |= EFX_MOD_TX;
return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
-#if EFSYS_OPT_FILTER
-extern __checkReturn int
-efx_tx_filter_insert(
- __in efx_txq_t *etp,
- __inout efx_filter_spec_t *spec)
-{
- EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
- EFSYS_ASSERT3P(spec, !=, NULL);
-
- spec->efs_dmaq_id = (uint16_t)etp->et_index;
- return (efx_filter_insert_filter(etp->et_enp, spec, B_FALSE));
-}
-#endif
-
-#if EFSYS_OPT_FILTER
-extern __checkReturn int
-efx_tx_filter_remove(
- __in efx_txq_t *etp,
- __inout efx_filter_spec_t *spec)
-{
- EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
- EFSYS_ASSERT3P(spec, !=, NULL);
-
- spec->efs_dmaq_id = (uint16_t)etp->et_index;
- return (efx_filter_remove_filter(etp->et_enp, spec));
}
-#endif
#define EFX_TX_DESC(_etp, _addr, _size, _eop, _added) \
do { \
@@ -157,8 +709,8 @@ efx_tx_filter_remove(
_NOTE(CONSTANTCONDITION) \
} while (B_FALSE)
- __checkReturn int
-efx_tx_qpost(
+static __checkReturn int
+falconsiena_tx_qpost(
__in efx_txq_t *etp,
__in_ecount(n) efx_buffer_t *eb,
__in unsigned int n,
@@ -169,8 +721,6 @@ efx_tx_qpost(
unsigned int i;
int rc = ENOSPC;
- EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
-
if (added - completed + n > EFX_TXQ_LIMIT(etp->et_mask + 1))
goto fail1;
@@ -197,21 +747,17 @@ fail1:
return (rc);
}
- void
-efx_tx_qpush(
+static void
+falconsiena_tx_qpush(
__in efx_txq_t *etp,
- __in unsigned int added)
+ __in unsigned int added,
+ __in unsigned int pushed)
{
efx_nic_t *enp = etp->et_enp;
uint32_t wptr;
efx_dword_t dword;
efx_oword_t oword;
- EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
-
- /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
- EFSYS_PIO_WRITE_BARRIER();
-
/* Push the populated descriptors out */
wptr = added & etp->et_mask;
@@ -220,6 +766,11 @@ efx_tx_qpush(
/* Only write the third DWORD */
EFX_POPULATE_DWORD_1(dword,
EFX_DWORD_0, EFX_OWORD_FIELD(oword, EFX_DWORD_3));
+
+ /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
+ EFX_DMA_SYNC_QUEUE_FOR_DEVICE(etp->et_esmp, etp->et_mask + 1,
+ wptr, pushed & etp->et_mask);
+ EFSYS_PIO_WRITE_BARRIER();
EFX_BAR_TBL_WRITED3(enp, FR_BZ_TX_DESC_UPD_REGP0,
etp->et_index, &dword, B_FALSE);
}
@@ -227,8 +778,8 @@ efx_tx_qpush(
#define EFX_MAX_PACE_VALUE 20
#define EFX_TX_PACE_CLOCK_BASE 104
- __checkReturn int
-efx_tx_qpace(
+static __checkReturn int
+falconsiena_tx_qpace(
__in efx_txq_t *etp,
__in unsigned int ns)
{
@@ -239,8 +790,6 @@ efx_tx_qpace(
unsigned int timer_period;
int rc;
- EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
-
if (ns == 0) {
pace_val = 0;
} else {
@@ -261,7 +810,8 @@ efx_tx_qpace(
/* Update the pacing table */
EFX_POPULATE_OWORD_1(oword, FRF_AZ_TX_PACE, pace_val);
- EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_PACE_TBL, etp->et_index, &oword);
+ EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_PACE_TBL, etp->et_index,
+ &oword, B_TRUE);
return (0);
@@ -271,16 +821,14 @@ fail1:
return (rc);
}
- void
-efx_tx_qflush(
- __in efx_txq_t *etp)
+static __checkReturn int
+falconsiena_tx_qflush(
+ __in efx_txq_t *etp)
{
efx_nic_t *enp = etp->et_enp;
efx_oword_t oword;
uint32_t label;
- EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
-
efx_tx_qpace(etp, 0);
label = etp->et_index;
@@ -289,19 +837,19 @@ efx_tx_qflush(
EFX_POPULATE_OWORD_2(oword, FRF_AZ_TX_FLUSH_DESCQ_CMD, 1,
FRF_AZ_TX_FLUSH_DESCQ, label);
EFX_BAR_WRITEO(enp, FR_AZ_TX_FLUSH_DESCQ_REG, &oword);
+
+ return (0);
}
- void
-efx_tx_qenable(
+static void
+falconsiena_tx_qenable(
__in efx_txq_t *etp)
{
efx_nic_t *enp = etp->et_enp;
efx_oword_t oword;
- EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
-
EFX_BAR_TBL_READO(enp, FR_AZ_TX_DESC_PTR_TBL,
- etp->et_index, &oword);
+ etp->et_index, &oword, B_TRUE);
EFSYS_PROBE5(tx_descq_ptr, unsigned int, etp->et_index,
uint32_t, EFX_OWORD_FIELD(oword, EFX_DWORD_3),
@@ -314,11 +862,11 @@ efx_tx_qenable(
EFX_SET_OWORD_FIELD(oword, FRF_AZ_TX_DESCQ_EN, 1);
EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
- etp->et_index, &oword);
+ etp->et_index, &oword, B_TRUE);
}
- __checkReturn int
-efx_tx_qcreate(
+static __checkReturn int
+falconsiena_tx_qcreate(
__in efx_nic_t *enp,
__in unsigned int index,
__in unsigned int label,
@@ -327,23 +875,22 @@ efx_tx_qcreate(
__in uint32_t id,
__in uint16_t flags,
__in efx_evq_t *eep,
- __deref_out efx_txq_t **etpp)
+ __in efx_txq_t *etp,
+ __out unsigned int *addedp)
{
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- efx_txq_t *etp;
efx_oword_t oword;
uint32_t size;
int rc;
- EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
- EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_TX);
-
EFX_STATIC_ASSERT(EFX_EV_TX_NLABELS ==
(1 << FRF_AZ_TX_DESCQ_LABEL_WIDTH));
EFSYS_ASSERT3U(label, <, EFX_EV_TX_NLABELS);
- EFSYS_ASSERT3U(enp->en_tx_qcount + 1, <, encp->enc_txq_limit);
- if (!ISP2(n) || !(n & EFX_TXQ_NDESCS_MASK)) {
+ EFSYS_ASSERT(ISP2(EFX_TXQ_MAXNDESCS(encp)));
+ EFX_STATIC_ASSERT(ISP2(EFX_TXQ_MINNDESCS));
+
+ if (!ISP2(n) || (n < EFX_TXQ_MINNDESCS) || (n > EFX_EVQ_MAXNEVS)) {
rc = EINVAL;
goto fail1;
}
@@ -351,7 +898,8 @@ efx_tx_qcreate(
rc = EINVAL;
goto fail2;
}
- for (size = 0; (1 << size) <= (EFX_TXQ_MAXNDESCS / EFX_TXQ_MINNDESCS);
+ for (size = 0;
+ (1 << size) <= (EFX_TXQ_MAXNDESCS(encp) / EFX_TXQ_MINNDESCS);
size++)
if ((1 << size) == (int)(n / EFX_TXQ_MINNDESCS))
break;
@@ -360,20 +908,6 @@ efx_tx_qcreate(
goto fail3;
}
- /* Allocate an TXQ object */
- EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (efx_txq_t), etp);
-
- if (etp == NULL) {
- rc = ENOMEM;
- goto fail4;
- }
-
- etp->et_magic = EFX_TXQ_MAGIC;
- etp->et_enp = enp;
- etp->et_index = index;
- etp->et_mask = n - 1;
- etp->et_esmp = esmp;
-
/* Set up the new descriptor queue */
EFX_POPULATE_OWORD_6(oword,
FRF_AZ_TX_DESCQ_BUF_BASE_ID, id,
@@ -390,14 +924,10 @@ efx_tx_qcreate(
(flags & EFX_CKSUM_TCPUDP) ? 0 : 1);
EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
- etp->et_index, &oword);
+ etp->et_index, &oword, B_TRUE);
- enp->en_tx_qcount++;
- *etpp = etp;
return (0);
-fail4:
- EFSYS_PROBE(fail4);
fail3:
EFSYS_PROBE(fail3);
fail2:
@@ -408,16 +938,83 @@ fail1:
return (rc);
}
+ __checkReturn int
+falconsiena_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)
+{
+ unsigned int added = *addedp;
+ unsigned int i;
+ int rc;
+
+ if (added - completed + n > EFX_TXQ_LIMIT(etp->et_mask + 1)) {
+ rc = ENOSPC;
+ goto fail1;
+ }
+
+ for (i = 0; i < n; i++) {
+ efx_desc_t *edp = &ed[i];
+ unsigned int id;
+ size_t offset;
+
+ id = added++ & etp->et_mask;
+ offset = id * sizeof (efx_desc_t);
+
+ EFSYS_MEM_WRITEQ(etp->et_esmp, offset, &edp->ed_eq);
+ }
+
+ EFSYS_PROBE3(tx_desc_post, unsigned int, etp->et_index,
+ unsigned int, added, unsigned int, n);
+
+ EFX_TX_QSTAT_INCR(etp, TX_POST);
+
+ *addedp = added;
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+
+ void
+falconsiena_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)
+{
+ /* Fragments must not span 4k boundaries. */
+ EFSYS_ASSERT(P2ROUNDUP(addr + 1, 4096) >= addr + size);
+
+ EFSYS_PROBE4(tx_desc_dma_create, unsigned int, etp->et_index,
+ efsys_dma_addr_t, addr,
+ size_t, size, boolean_t, eop);
+
+ EFX_POPULATE_QWORD_4(edp->ed_eq,
+ FSF_AZ_TX_KER_CONT, eop ? 0 : 1,
+ FSF_AZ_TX_KER_BYTE_COUNT, (uint32_t)size,
+ FSF_AZ_TX_KER_BUF_ADDR_DW0,
+ (uint32_t)(addr & 0xffffffff),
+ FSF_AZ_TX_KER_BUF_ADDR_DW1,
+ (uint32_t)(addr >> 32));
+}
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
+
#if EFSYS_OPT_QSTATS
#if EFSYS_OPT_NAMES
-/* START MKCONFIG GENERATED EfxTransmitQueueStatNamesBlock 78ca9ab00287fffb */
-static const char __cs * __cs __efx_tx_qstat_name[] = {
+/* START MKCONFIG GENERATED EfxTransmitQueueStatNamesBlock 9d8d26a0a5e2c453 */
+static const char *__efx_tx_qstat_name[] = {
"post",
- "unaligned_split",
+ "post_pio",
};
/* END MKCONFIG GENERATED EfxTransmitQueueStatNamesBlock */
- const char __cs *
+ const char *
efx_tx_qstat_name(
__in efx_nic_t *enp,
__in unsigned int id)
@@ -429,18 +1026,18 @@ efx_tx_qstat_name(
return (__efx_tx_qstat_name[id]);
}
#endif /* EFSYS_OPT_NAMES */
-#endif /* EFSYS_OPT_QSTATS */
+#endif /* EFSYS_OPT_QSTATS */
+
+#if EFSYS_OPT_FALCON || EFSYS_OPT_SIENA
#if EFSYS_OPT_QSTATS
- void
-efx_tx_qstats_update(
+static void
+falconsiena_tx_qstats_update(
__in efx_txq_t *etp,
__inout_ecount(TX_NQSTATS) efsys_stat_t *stat)
{
unsigned int id;
- EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
-
for (id = 0; id < TX_NQSTATS; id++) {
efsys_stat_t *essp = &stat[id];
@@ -450,36 +1047,25 @@ efx_tx_qstats_update(
}
#endif /* EFSYS_OPT_QSTATS */
- void
-efx_tx_qdestroy(
+static void
+falconsiena_tx_qdestroy(
__in efx_txq_t *etp)
{
efx_nic_t *enp = etp->et_enp;
efx_oword_t oword;
- EFSYS_ASSERT3U(etp->et_magic, ==, EFX_TXQ_MAGIC);
-
- EFSYS_ASSERT(enp->en_tx_qcount != 0);
- --enp->en_tx_qcount;
-
/* Purge descriptor queue */
EFX_ZERO_OWORD(oword);
EFX_BAR_TBL_WRITEO(enp, FR_AZ_TX_DESC_PTR_TBL,
- etp->et_index, &oword);
-
- /* Free the TXQ object */
- EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_txq_t), etp);
+ etp->et_index, &oword, B_TRUE);
}
- void
-efx_tx_fini(
+static void
+falconsiena_tx_fini(
__in efx_nic_t *enp)
{
- 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);
-
- enp->en_mod_flags &= ~EFX_MOD_TX;
+ _NOTE(ARGUNUSED(enp))
}
+
+#endif /* EFSYS_OPT_FALCON || EFSYS_OPT_SIENA */
diff --git a/sys/dev/sfxge/common/efx_types.h b/sys/dev/sfxge/common/efx_types.h
index 9fbaea1..ee357b1 100644
--- a/sys/dev/sfxge/common/efx_types.h
+++ b/sys/dev/sfxge/common/efx_types.h
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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.
*
@@ -113,11 +118,10 @@ extern "C" {
#define EFX_DWORD_3_LBN 96
#define EFX_DWORD_3_WIDTH 32
-#define EFX_QWORD_0_LBN 0
-#define EFX_QWORD_0_WIDTH 64
-
-#define EFX_QWORD_1_LBN 64
-#define EFX_QWORD_1_WIDTH 64
+/* 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) \
@@ -229,6 +233,9 @@ typedef union efx_oword_u {
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
@@ -891,11 +898,7 @@ extern int fix_lint;
#define EFX_ZERO_OWORD(_oword) \
EFX_POPULATE_OWORD_1(_oword, EFX_DUMMY_FIELD, 0)
-#define EFX_SET_OWORD64(_oword) \
- EFX_POPULATE_OWORD_2(_oword, \
- EFX_QWORD_0, (uint64_t)-1, EFX_QWORD_1, (uint64_t)-1)
-
-#define EFX_SET_OWORD32(_oword) \
+#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)
@@ -969,11 +972,7 @@ extern int fix_lint;
#define EFX_ZERO_QWORD(_qword) \
EFX_POPULATE_QWORD_1(_qword, EFX_DUMMY_FIELD, 0)
-#define EFX_SET_QWORD64(_qword) \
- EFX_POPULATE_QWORD_1(_qword, \
- EFX_QWORD_0, (uint64_t)-1)
-
-#define EFX_SET_QWORD32(_qword) \
+#define EFX_SET_QWORD(_qword) \
EFX_POPULATE_QWORD_2(_qword, \
EFX_DWORD_0, 0xffffffff, EFX_DWORD_1, 0xffffffff)
@@ -1380,6 +1379,23 @@ extern int fix_lint;
_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) \
@@ -1416,6 +1432,17 @@ extern int fix_lint;
_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] |= \
@@ -1430,6 +1457,11 @@ extern int fix_lint;
_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] |= \
@@ -1444,6 +1476,11 @@ extern int fix_lint;
_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] |= \
@@ -1458,6 +1495,11 @@ extern int fix_lint;
_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]; \
@@ -1563,18 +1605,18 @@ extern int fix_lint;
#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 EFX_SET_OWORD64
-#define EFX_SET_QWORD EFX_SET_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_OR_QWORD64
+#define EFX_AND_QWORD EFX_AND_QWORD64
#else
#define EFX_OWORD_FIELD EFX_OWORD_FIELD32
#define EFX_QWORD_FIELD EFX_QWORD_FIELD32
@@ -1586,18 +1628,18 @@ extern int fix_lint;
#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 EFX_SET_OWORD32
-#define EFX_SET_QWORD EFX_SET_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_OR_QWORD32
+#define EFX_AND_QWORD EFX_AND_QWORD32
#endif
#ifdef __cplusplus
diff --git a/sys/dev/sfxge/common/efx_vpd.c b/sys/dev/sfxge/common/efx_vpd.c
index 399c056..812070a 100644
--- a/sys/dev/sfxge/common/efx_vpd.c
+++ b/sys/dev/sfxge/common/efx_vpd.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -54,7 +59,7 @@ __FBSDID("$FreeBSD$");
#if EFSYS_OPT_FALCON
-static efx_vpd_ops_t __cs __efx_vpd_falcon_ops = {
+static efx_vpd_ops_t __efx_vpd_falcon_ops = {
NULL, /* evpdo_init */
falcon_vpd_size, /* evpdo_size */
falcon_vpd_read, /* evpdo_read */
@@ -71,7 +76,7 @@ static efx_vpd_ops_t __cs __efx_vpd_falcon_ops = {
#if EFSYS_OPT_SIENA
-static efx_vpd_ops_t __cs __efx_vpd_siena_ops = {
+static efx_vpd_ops_t __efx_vpd_siena_ops = {
siena_vpd_init, /* evpdo_init */
siena_vpd_size, /* evpdo_size */
siena_vpd_read, /* evpdo_read */
@@ -86,6 +91,23 @@ static efx_vpd_ops_t __cs __efx_vpd_siena_ops = {
#endif /* EFSYS_OPT_SIENA */
+#if EFSYS_OPT_HUNTINGTON
+
+static efx_vpd_ops_t __efx_vpd_hunt_ops = {
+ hunt_vpd_init, /* evpdo_init */
+ hunt_vpd_size, /* evpdo_size */
+ hunt_vpd_read, /* evpdo_read */
+ hunt_vpd_verify, /* evpdo_verify */
+ hunt_vpd_reinit, /* evpdo_reinit */
+ hunt_vpd_get, /* evpdo_get */
+ hunt_vpd_set, /* evpdo_set */
+ hunt_vpd_next, /* evpdo_next */
+ hunt_vpd_write, /* evpdo_write */
+ hunt_vpd_fini, /* evpdo_fini */
+};
+
+#endif /* EFSYS_OPT_HUNTINGTON */
+
__checkReturn int
efx_vpd_init(
__in efx_nic_t *enp)
@@ -110,6 +132,12 @@ efx_vpd_init(
break;
#endif /* EFSYS_OPT_SIENA */
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ evpdop = (efx_vpd_ops_t *)&__efx_vpd_hunt_ops;
+ break;
+#endif /* EFSYS_OPT_HUNTINGTON */
+
default:
EFSYS_ASSERT(0);
rc = ENOTSUP;
@@ -566,14 +594,14 @@ fail1:
return (rc);
}
-static uint8_t __cs __efx_vpd_blank_pid[] = {
+static uint8_t __efx_vpd_blank_pid[] = {
/* Large resource type ID length 1 */
0x82, 0x01, 0x00,
/* Product name ' ' */
0x32,
};
-static uint8_t __cs __efx_vpd_blank_r[] = {
+static uint8_t __efx_vpd_blank_r[] = {
/* Large resource type VPD-R length 4 */
0x90, 0x04, 0x00,
/* RV keyword length 1 */
@@ -584,7 +612,7 @@ static uint8_t __cs __efx_vpd_blank_r[] = {
__checkReturn int
efx_vpd_hunk_reinit(
- __in caddr_t data,
+ __in_bcount(size) caddr_t data,
__in size_t size,
__in boolean_t wantpid)
{
diff --git a/sys/dev/sfxge/common/efx_wol.c b/sys/dev/sfxge/common/efx_wol.c
index 89a80c7..2e1b4a1 100644
--- a/sys/dev/sfxge/common/efx_wol.c
+++ b/sys/dev/sfxge/common/efx_wol.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -67,17 +72,19 @@ efx_wol_filter_clear(
__in efx_nic_t *enp)
{
efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_WOL_FILTER_RESET_IN_LEN];
+ uint8_t payload[MAX(MC_CMD_WOL_FILTER_RESET_IN_LEN,
+ MC_CMD_WOL_FILTER_RESET_OUT_LEN)];
int rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_WOL_FILTER_RESET;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_WOL_FILTER_RESET_IN_LEN;
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_WOL_FILTER_RESET_OUT_LEN;
MCDI_IN_SET_DWORD(req, WOL_FILTER_RESET_IN_MASK,
MC_CMD_WOL_FILTER_RESET_IN_WAKE_FILTERS |
@@ -114,8 +121,8 @@ efx_wol_filter_add(
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_WOL_FILTER_SET;
- (void) memset(payload, '\0', sizeof (payload));
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_WOL_FILTER_SET_IN_LEN;
req.emr_out_buf = payload;
@@ -226,18 +233,19 @@ efx_wol_filter_remove(
__in uint32_t filter_id)
{
efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_WOL_FILTER_REMOVE_IN_LEN];
+ uint8_t payload[MAX(MC_CMD_WOL_FILTER_REMOVE_IN_LEN,
+ MC_CMD_WOL_FILTER_REMOVE_OUT_LEN)];
int rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_WOL_FILTER_REMOVE;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_WOL_FILTER_REMOVE_IN_LEN;
- EFX_STATIC_ASSERT(MC_CMD_WOL_FILTER_REMOVE_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_WOL_FILTER_REMOVE_OUT_LEN;
MCDI_IN_SET_DWORD(req, WOL_FILTER_REMOVE_IN_FILTER_ID, filter_id);
@@ -273,6 +281,7 @@ efx_lightsout_offload_add(
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_ADD_LIGHTSOUT_OFFLOAD;
req.emr_in_buf = payload;
req.emr_in_length = sizeof (type);
@@ -282,6 +291,7 @@ efx_lightsout_offload_add(
switch (type) {
case EFX_LIGHTSOUT_OFFLOAD_TYPE_ARP:
req.emr_in_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_LEN;
+
MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL,
MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP);
EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t,
@@ -292,6 +302,7 @@ efx_lightsout_offload_add(
break;
case EFX_LIGHTSOUT_OFFLOAD_TYPE_NS:
req.emr_in_length = MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_LEN;
+
MCDI_IN_SET_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL,
MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS);
EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t,
@@ -305,25 +316,28 @@ efx_lightsout_offload_add(
paramp->elop_ns.ip, sizeof (paramp->elop_ns.ip));
break;
default:
- EFSYS_ASSERT3U(type, !=, type);
+ rc = EINVAL;
+ goto fail1;
}
efx_mcdi_execute(enp, &req);
if (req.emr_rc != 0) {
rc = req.emr_rc;
- goto fail1;
+ goto fail2;
}
if (req.emr_out_length_used < MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN) {
rc = EMSGSIZE;
- goto fail2;
+ goto fail3;
}
*filter_idp = MCDI_OUT_DWORD(req, ADD_LIGHTSOUT_OFFLOAD_OUT_FILTER_ID);
return (0);
+fail3:
+ EFSYS_PROBE(fail3);
fail2:
EFSYS_PROBE(fail2);
fail1:
@@ -340,18 +354,19 @@ efx_lightsout_offload_remove(
__in uint32_t filter_id)
{
efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN];
+ uint8_t payload[MAX(MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN,
+ MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN)];
int rc;
EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_WOL);
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD;
req.emr_in_buf = payload;
- req.emr_in_length = sizeof (payload);
- EFX_STATIC_ASSERT(MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
+ req.emr_in_length = MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN;
switch (type) {
case EFX_LIGHTSOUT_OFFLOAD_TYPE_ARP:
@@ -363,7 +378,8 @@ efx_lightsout_offload_remove(
MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS);
break;
default:
- EFSYS_ASSERT3U(type, !=, type);
+ rc = EINVAL;
+ goto fail1;
}
MCDI_IN_SET_DWORD(req, REMOVE_LIGHTSOUT_OFFLOAD_IN_FILTER_ID,
@@ -373,11 +389,13 @@ efx_lightsout_offload_remove(
if (req.emr_rc != 0) {
rc = req.emr_rc;
- goto fail1;
+ goto fail2;
}
return (0);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, int, rc);
diff --git a/sys/dev/sfxge/common/hunt_ev.c b/sys/dev/sfxge/common/hunt_ev.c
new file mode 100644
index 0000000..8e5cf89
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_ev.c
@@ -0,0 +1,1010 @@
+/*-
+ * Copyright (c) 2012-2015 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_types.h"
+#include "efx_regs.h"
+#include "efx_impl.h"
+#if EFSYS_OPT_MON_STATS
+#include "mcdi_mon.h"
+#endif
+
+#if EFSYS_OPT_HUNTINGTON
+
+#if EFSYS_OPT_QSTATS
+#define EFX_EV_QSTAT_INCR(_eep, _stat) \
+ do { \
+ (_eep)->ee_stat[_stat]++; \
+ _NOTE(CONSTANTCONDITION) \
+ } while (B_FALSE)
+#else
+#define EFX_EV_QSTAT_INCR(_eep, _stat)
+#endif
+
+
+static __checkReturn boolean_t
+hunt_ev_rx(
+ __in efx_evq_t *eep,
+ __in efx_qword_t *eqp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg);
+
+static __checkReturn boolean_t
+hunt_ev_tx(
+ __in efx_evq_t *eep,
+ __in efx_qword_t *eqp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg);
+
+static __checkReturn boolean_t
+hunt_ev_driver(
+ __in efx_evq_t *eep,
+ __in efx_qword_t *eqp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg);
+
+static __checkReturn boolean_t
+hunt_ev_drv_gen(
+ __in efx_evq_t *eep,
+ __in efx_qword_t *eqp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg);
+
+static __checkReturn boolean_t
+hunt_ev_mcdi(
+ __in efx_evq_t *eep,
+ __in efx_qword_t *eqp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg);
+
+
+static __checkReturn int
+efx_mcdi_init_evq(
+ __in efx_nic_t *enp,
+ __in unsigned int instance,
+ __in efsys_mem_t *esmp,
+ __in size_t nevs,
+ __in uint32_t irq,
+ __out_opt uint32_t *irqp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[
+ MAX(MC_CMD_INIT_EVQ_IN_LEN(EFX_EVQ_NBUFS(EFX_EVQ_MAXNEVS)),
+ MC_CMD_INIT_EVQ_OUT_LEN)];
+ efx_qword_t *dma_addr;
+ uint64_t addr;
+ int npages;
+ int i;
+ int supports_rx_batching;
+ int rc;
+
+ npages = EFX_EVQ_NBUFS(nevs);
+ if (MC_CMD_INIT_EVQ_IN_LEN(npages) > MC_CMD_INIT_EVQ_IN_LENMAX) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_INIT_EVQ;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_INIT_EVQ_IN_LEN(npages);
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_INIT_EVQ_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_SIZE, nevs);
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_INSTANCE, instance);
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_IRQ_NUM, irq);
+
+ /*
+ * On Huntington RX and TX event batching can only be requested
+ * together (even if the datapath firmware doesn't actually support RX
+ * batching).
+ * Cut through is incompatible with RX batching and so enabling cut
+ * through disables RX batching (but it does not affect TX batching).
+ *
+ * So always enable RX and TX event batching, and enable cut through
+ * if RX event batching isn't supported (i.e. on low latency firmware).
+ */
+ supports_rx_batching = enp->en_nic_cfg.enc_rx_batching_enabled ? 1 : 0;
+ MCDI_IN_POPULATE_DWORD_6(req, INIT_EVQ_IN_FLAGS,
+ INIT_EVQ_IN_FLAG_INTERRUPTING, 1,
+ INIT_EVQ_IN_FLAG_RPTR_DOS, 0,
+ INIT_EVQ_IN_FLAG_INT_ARMD, 0,
+ INIT_EVQ_IN_FLAG_CUT_THRU, !supports_rx_batching,
+ INIT_EVQ_IN_FLAG_RX_MERGE, 1,
+ INIT_EVQ_IN_FLAG_TX_MERGE, 1);
+
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_MODE,
+ MC_CMD_INIT_EVQ_IN_TMR_MODE_DIS);
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_LOAD, 0);
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_TMR_RELOAD, 0);
+
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_COUNT_MODE,
+ MC_CMD_INIT_EVQ_IN_COUNT_MODE_DIS);
+ MCDI_IN_SET_DWORD(req, INIT_EVQ_IN_COUNT_THRSHLD, 0);
+
+ dma_addr = MCDI_IN2(req, efx_qword_t, INIT_EVQ_IN_DMA_ADDR);
+ addr = EFSYS_MEM_ADDR(esmp);
+
+ for (i = 0; i < npages; i++) {
+ EFX_POPULATE_QWORD_2(*dma_addr,
+ EFX_DWORD_1, (uint32_t)(addr >> 32),
+ EFX_DWORD_0, (uint32_t)(addr & 0xffffffff));
+
+ dma_addr++;
+ addr += EFX_BUF_SIZE;
+ }
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_INIT_EVQ_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail3;
+ }
+
+ if (irqp != NULL)
+ *irqp = MCDI_OUT_DWORD(req, INIT_EVQ_OUT_IRQ);
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_fini_evq(
+ __in efx_nic_t *enp,
+ __in uint32_t instance)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_FINI_EVQ_IN_LEN,
+ MC_CMD_FINI_EVQ_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_FINI_EVQ;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_FINI_EVQ_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_FINI_EVQ_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, FINI_EVQ_IN_INSTANCE, instance);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+
+ __checkReturn int
+hunt_ev_init(
+ __in efx_nic_t *enp)
+{
+ _NOTE(ARGUNUSED(enp))
+ return (0);
+}
+
+ void
+hunt_ev_fini(
+ __in efx_nic_t *enp)
+{
+ _NOTE(ARGUNUSED(enp))
+}
+
+ __checkReturn int
+hunt_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 efx_evq_t *eep)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ uint32_t irq;
+ int rc;
+
+ _NOTE(ARGUNUSED(id)) /* buftbl id managed by MC */
+ EFX_STATIC_ASSERT(ISP2(EFX_EVQ_MAXNEVS));
+ EFX_STATIC_ASSERT(ISP2(EFX_EVQ_MINNEVS));
+
+ if (!ISP2(n) || (n < EFX_EVQ_MINNEVS) || (n > EFX_EVQ_MAXNEVS)) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ if (index >= encp->enc_evq_limit) {
+ rc = EINVAL;
+ goto fail2;
+ }
+
+ /* Set up the handler table */
+ eep->ee_rx = hunt_ev_rx;
+ eep->ee_tx = hunt_ev_tx;
+ eep->ee_driver = hunt_ev_driver;
+ eep->ee_drv_gen = hunt_ev_drv_gen;
+ eep->ee_mcdi = hunt_ev_mcdi;
+
+ /*
+ * Set up the event queue
+ * NOTE: ignore the returned IRQ param as firmware does not set it.
+ */
+ irq = index; /* INIT_EVQ expects function-relative vector number */
+ if ((rc = efx_mcdi_init_evq(enp, index, esmp, n, irq, NULL)) != 0)
+ goto fail3;
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_ev_qdestroy(
+ __in efx_evq_t *eep)
+{
+ efx_nic_t *enp = eep->ee_enp;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ (void) efx_mcdi_fini_evq(eep->ee_enp, eep->ee_index);
+}
+
+ __checkReturn int
+hunt_ev_qprime(
+ __in efx_evq_t *eep,
+ __in unsigned int count)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ uint32_t rptr;
+ efx_dword_t dword;
+
+ rptr = count & eep->ee_mask;
+
+ if (enp->en_nic_cfg.enc_bug35388_workaround) {
+ EFX_STATIC_ASSERT(EFX_EVQ_MINNEVS >
+ (1 << ERF_DD_EVQ_IND_RPTR_WIDTH));
+ EFX_STATIC_ASSERT(EFX_EVQ_MAXNEVS <
+ (1 << 2 * ERF_DD_EVQ_IND_RPTR_WIDTH));
+
+ EFX_POPULATE_DWORD_2(dword,
+ ERF_DD_EVQ_IND_RPTR_FLAGS,
+ EFE_DD_EVQ_IND_RPTR_FLAGS_HIGH,
+ ERF_DD_EVQ_IND_RPTR,
+ (rptr >> ERF_DD_EVQ_IND_RPTR_WIDTH));
+ EFX_BAR_TBL_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index,
+ &dword, B_FALSE);
+
+ EFX_POPULATE_DWORD_2(dword,
+ ERF_DD_EVQ_IND_RPTR_FLAGS,
+ EFE_DD_EVQ_IND_RPTR_FLAGS_LOW,
+ ERF_DD_EVQ_IND_RPTR,
+ rptr & ((1 << ERF_DD_EVQ_IND_RPTR_WIDTH) - 1));
+ EFX_BAR_TBL_WRITED(enp, ER_DD_EVQ_INDIRECT, eep->ee_index,
+ &dword, B_FALSE);
+ } else {
+ EFX_POPULATE_DWORD_1(dword, ERF_DZ_EVQ_RPTR, rptr);
+ EFX_BAR_TBL_WRITED(enp, ER_DZ_EVQ_RPTR_REG, eep->ee_index,
+ &dword, B_FALSE);
+ }
+
+ return (0);
+}
+
+static __checkReturn int
+efx_mcdi_driver_event(
+ __in efx_nic_t *enp,
+ __in uint32_t evq,
+ __in efx_qword_t data)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_DRIVER_EVENT_IN_LEN,
+ MC_CMD_DRIVER_EVENT_OUT_LEN)];
+ int rc;
+
+ req.emr_cmd = MC_CMD_DRIVER_EVENT;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_DRIVER_EVENT_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_DRIVER_EVENT_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, DRIVER_EVENT_IN_EVQ, evq);
+
+ MCDI_IN_SET_DWORD(req, DRIVER_EVENT_IN_DATA_LO,
+ EFX_QWORD_FIELD(data, EFX_DWORD_0));
+ MCDI_IN_SET_DWORD(req, DRIVER_EVENT_IN_DATA_HI,
+ EFX_QWORD_FIELD(data, EFX_DWORD_1));
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_ev_qpost(
+ __in efx_evq_t *eep,
+ __in uint16_t data)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ efx_qword_t event;
+
+ EFX_POPULATE_QWORD_3(event,
+ ESF_DZ_DRV_CODE, ESE_DZ_EV_CODE_DRV_GEN_EV,
+ ESF_DZ_DRV_SUB_CODE, 0,
+ ESF_DZ_DRV_SUB_DATA_DW0, (uint32_t)data);
+
+ (void) efx_mcdi_driver_event(enp, eep->ee_index, event);
+}
+
+ __checkReturn int
+hunt_ev_qmoderate(
+ __in efx_evq_t *eep,
+ __in unsigned int us)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_dword_t dword;
+ uint32_t timer_val, mode;
+ int rc;
+
+ if (us > encp->enc_evq_timer_max_us) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ /* If the value is zero then disable the timer */
+ if (us == 0) {
+ timer_val = 0;
+ mode = FFE_CZ_TIMER_MODE_DIS;
+ } else {
+ /* Calculate the timer value in quanta */
+ timer_val = us * 1000 / encp->enc_evq_timer_quantum_ns;
+
+ /* Moderation value is base 0 so we need to deduct 1 */
+ if (timer_val > 0)
+ timer_val--;
+
+ mode = FFE_CZ_TIMER_MODE_INT_HLDOFF;
+ }
+
+ if (encp->enc_bug35388_workaround) {
+ EFX_POPULATE_DWORD_3(dword,
+ ERF_DD_EVQ_IND_TIMER_FLAGS,
+ EFE_DD_EVQ_IND_TIMER_FLAGS,
+ ERF_DD_EVQ_IND_TIMER_MODE, mode,
+ ERF_DD_EVQ_IND_TIMER_VAL, timer_val);
+ EFX_BAR_TBL_WRITED(enp, ER_DD_EVQ_INDIRECT,
+ eep->ee_index, &dword, 0);
+ } else {
+ EFX_POPULATE_DWORD_2(dword,
+ FRF_CZ_TC_TIMER_MODE, mode,
+ FRF_CZ_TC_TIMER_VAL, timer_val);
+ EFX_BAR_TBL_WRITED(enp, FR_BZ_TIMER_COMMAND_REGP0,
+ eep->ee_index, &dword, 0);
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+#if EFSYS_OPT_QSTATS
+ void
+hunt_ev_qstats_update(
+ __in efx_evq_t *eep,
+ __inout_ecount(EV_NQSTATS) efsys_stat_t *stat)
+{
+ /*
+ * TBD: Consider a common Siena/Huntington function. The code is
+ * essentially identical.
+ */
+ unsigned int id;
+
+ for (id = 0; id < EV_NQSTATS; id++) {
+ efsys_stat_t *essp = &stat[id];
+
+ EFSYS_STAT_INCR(essp, eep->ee_stat[id]);
+ eep->ee_stat[id] = 0;
+ }
+}
+#endif /* EFSYS_OPT_QSTATS */
+
+
+static __checkReturn boolean_t
+hunt_ev_rx(
+ __in efx_evq_t *eep,
+ __in efx_qword_t *eqp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ uint32_t size;
+ boolean_t parse_err;
+ uint32_t label;
+ uint32_t mcast;
+ uint32_t eth_base_class;
+ uint32_t eth_tag_class;
+ uint32_t l3_class;
+ uint32_t l4_class;
+ uint32_t next_read_lbits;
+ boolean_t soft1, soft2;
+ uint16_t flags;
+ boolean_t should_abort;
+ efx_evq_rxq_state_t *eersp;
+ unsigned int desc_count;
+ unsigned int last_used_id;
+
+ EFX_EV_QSTAT_INCR(eep, EV_RX);
+
+ /* Discard events after RXQ/TXQ errors */
+ if (enp->en_reset_flags & (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR))
+ return (B_FALSE);
+
+ /*
+ * FIXME: likely to be incomplete, incorrect and inefficient.
+ * Improvements in all three areas are required.
+ */
+
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DROP_EVENT) != 0) {
+ /* Drop this event */
+ return (B_FALSE);
+ }
+ flags = 0;
+
+ size = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_BYTES);
+
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_CONT) != 0) {
+ /*
+ * FIXME: There is not yet any driver that supports scatter on
+ * Huntington. Scatter support is required for OSX.
+ */
+ EFSYS_ASSERT(0);
+ flags |= EFX_PKT_CONT;
+ }
+
+ parse_err = (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_PARSE_INCOMPLETE) != 0);
+ label = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_QLABEL);
+
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ECRC_ERR) != 0) {
+ /* Ethernet frame CRC bad */
+ flags |= EFX_DISCARD;
+ }
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_CRC0_ERR) != 0) {
+ /* IP+TCP, bad CRC in iSCSI header */
+ flags |= EFX_DISCARD;
+ }
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_CRC1_ERR) != 0) {
+ /* IP+TCP, bad CRC in iSCSI payload or FCoE or FCoIP */
+ flags |= EFX_DISCARD;
+ }
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ECC_ERR) != 0) {
+ /* ECC memory error */
+ flags |= EFX_DISCARD;
+ }
+
+ /* FIXME: do we need soft bits from RXDP firmware ? */
+ soft1 = (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_EV_SOFT1) != 0);
+ soft2 = (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_EV_SOFT2) != 0);
+
+ mcast = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_MAC_CLASS);
+ if (mcast == ESE_DZ_MAC_CLASS_UCAST)
+ flags |= EFX_PKT_UNICAST;
+
+ eth_base_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ETH_BASE_CLASS);
+ eth_tag_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_ETH_TAG_CLASS);
+ l3_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_L3_CLASS);
+ l4_class = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_L4_CLASS);
+
+ /* bottom 4 bits of incremented index (not last desc consumed) */
+ next_read_lbits = EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_DSC_PTR_LBITS);
+
+ /* Increment the count of descriptors read */
+ eersp = &eep->ee_rxq_state[label];
+ desc_count = (next_read_lbits - eersp->eers_rx_read_ptr) &
+ EFX_MASK32(ESF_DZ_RX_DSC_PTR_LBITS);
+ eersp->eers_rx_read_ptr += desc_count;
+
+ /*
+ * FIXME: add error checking to make sure this a batched event.
+ * This could also be an aborted scatter, see Bug36629.
+ */
+ if (desc_count > 1) {
+ EFX_EV_QSTAT_INCR(eep, EV_RX_BATCH);
+ flags |= EFX_PKT_PREFIX_LEN;
+ }
+
+ /* Calculate the index of the the last descriptor consumed */
+ last_used_id = (eersp->eers_rx_read_ptr - 1) & eersp->eers_rx_mask;
+
+ /* EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_OVERRIDE_HOLDOFF); */
+
+ switch (eth_base_class) {
+ case ESE_DZ_ETH_BASE_CLASS_LLC_SNAP:
+ case ESE_DZ_ETH_BASE_CLASS_LLC:
+ case ESE_DZ_ETH_BASE_CLASS_ETH2:
+ default:
+ break;
+ }
+
+ switch (eth_tag_class) {
+ case ESE_DZ_ETH_TAG_CLASS_RSVD7:
+ case ESE_DZ_ETH_TAG_CLASS_RSVD6:
+ case ESE_DZ_ETH_TAG_CLASS_RSVD5:
+ case ESE_DZ_ETH_TAG_CLASS_RSVD4:
+ break;
+
+ case ESE_DZ_ETH_TAG_CLASS_RSVD3: /* Triple tagged */
+ case ESE_DZ_ETH_TAG_CLASS_VLAN2: /* Double tagged */
+ case ESE_DZ_ETH_TAG_CLASS_VLAN1: /* VLAN tagged */
+ flags |= EFX_PKT_VLAN_TAGGED;
+ break;
+
+ case ESE_DZ_ETH_TAG_CLASS_NONE:
+ default:
+ break;
+ }
+
+ switch (l3_class) {
+ case ESE_DZ_L3_CLASS_RSVD7: /* Used by firmware for packet overrun */
+ parse_err = B_TRUE;
+ flags |= EFX_DISCARD;
+ break;
+
+ case ESE_DZ_L3_CLASS_ARP:
+ case ESE_DZ_L3_CLASS_FCOE:
+ break;
+
+ case ESE_DZ_L3_CLASS_IP6_FRAG:
+ case ESE_DZ_L3_CLASS_IP6:
+ flags |= EFX_PKT_IPV6;
+ break;
+
+ case ESE_DZ_L3_CLASS_IP4_FRAG:
+ case ESE_DZ_L3_CLASS_IP4:
+ flags |= EFX_PKT_IPV4;
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_IPCKSUM_ERR) == 0)
+ flags |= EFX_CKSUM_IPV4;
+ break;
+
+ case ESE_DZ_L3_CLASS_UNKNOWN:
+ default:
+ break;
+ }
+
+ switch (l4_class) {
+ case ESE_DZ_L4_CLASS_RSVD7:
+ case ESE_DZ_L4_CLASS_RSVD6:
+ case ESE_DZ_L4_CLASS_RSVD5:
+ case ESE_DZ_L4_CLASS_RSVD4:
+ case ESE_DZ_L4_CLASS_RSVD3:
+ break;
+
+ case ESE_DZ_L4_CLASS_UDP:
+ flags |= EFX_PKT_UDP;
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TCPUDP_CKSUM_ERR) == 0)
+ flags |= EFX_CKSUM_TCPUDP;
+ break;
+
+ case ESE_DZ_L4_CLASS_TCP:
+ flags |= EFX_PKT_TCP;
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_RX_TCPUDP_CKSUM_ERR) == 0)
+ flags |= EFX_CKSUM_TCPUDP;
+ break;
+
+ case ESE_DZ_L4_CLASS_UNKNOWN:
+ default:
+ break;
+ }
+
+ /* If we're not discarding the packet then it is ok */
+ if (~flags & EFX_DISCARD)
+ EFX_EV_QSTAT_INCR(eep, EV_RX_OK);
+
+ EFSYS_ASSERT(eecp->eec_rx != NULL);
+ should_abort = eecp->eec_rx(arg, label, last_used_id, size, flags);
+
+ return (should_abort);
+}
+
+static __checkReturn boolean_t
+hunt_ev_tx(
+ __in efx_evq_t *eep,
+ __in efx_qword_t *eqp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ uint32_t id;
+ uint32_t label;
+ boolean_t should_abort;
+
+ EFX_EV_QSTAT_INCR(eep, EV_TX);
+
+ /* Discard events after RXQ/TXQ errors */
+ if (enp->en_reset_flags & (EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR))
+ return (B_FALSE);
+
+ if (EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_DROP_EVENT) != 0) {
+ /* Drop this event */
+ return (B_FALSE);
+ }
+
+ /* Per-packet TX completion (was per-descriptor for Falcon/Siena) */
+ id = EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_DESCR_INDX);
+ label = EFX_QWORD_FIELD(*eqp, ESF_DZ_TX_QLABEL);
+
+ EFSYS_PROBE2(tx_complete, uint32_t, label, uint32_t, id);
+
+ EFSYS_ASSERT(eecp->eec_tx != NULL);
+ should_abort = eecp->eec_tx(arg, label, id);
+
+ return (should_abort);
+}
+
+static __checkReturn boolean_t
+hunt_ev_driver(
+ __in efx_evq_t *eep,
+ __in efx_qword_t *eqp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg)
+{
+ unsigned int code;
+ boolean_t should_abort;
+
+ EFX_EV_QSTAT_INCR(eep, EV_DRIVER);
+ should_abort = B_FALSE;
+
+ code = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_SUB_CODE);
+ switch (code) {
+ case ESE_DZ_DRV_TIMER_EV: {
+ uint32_t id;
+
+ id = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_TMR_ID);
+
+ EFSYS_ASSERT(eecp->eec_timer != NULL);
+ should_abort = eecp->eec_timer(arg, id);
+ break;
+ }
+
+ case ESE_DZ_DRV_WAKE_UP_EV: {
+ uint32_t id;
+
+ id = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_EVQ_ID);
+
+ EFSYS_ASSERT(eecp->eec_wake_up != NULL);
+ should_abort = eecp->eec_wake_up(arg, id);
+ break;
+ }
+
+ case ESE_DZ_DRV_START_UP_EV:
+ EFSYS_ASSERT(eecp->eec_initialized != NULL);
+ should_abort = eecp->eec_initialized(arg);
+ break;
+
+ default:
+ EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
+ uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
+ uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
+ break;
+ }
+
+ return (should_abort);
+}
+
+static __checkReturn boolean_t
+hunt_ev_drv_gen(
+ __in efx_evq_t *eep,
+ __in efx_qword_t *eqp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg)
+{
+ uint32_t data;
+ boolean_t should_abort;
+
+ EFX_EV_QSTAT_INCR(eep, EV_DRV_GEN);
+ should_abort = B_FALSE;
+
+ data = EFX_QWORD_FIELD(*eqp, ESF_DZ_DRV_SUB_DATA_DW0);
+ if (data >= ((uint32_t)1 << 16)) {
+ EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
+ uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
+ uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
+
+ return (B_TRUE);
+ }
+
+ EFSYS_ASSERT(eecp->eec_software != NULL);
+ should_abort = eecp->eec_software(arg, (uint16_t)data);
+
+ return (should_abort);
+}
+
+static __checkReturn boolean_t
+hunt_ev_mcdi(
+ __in efx_evq_t *eep,
+ __in efx_qword_t *eqp,
+ __in const efx_ev_callbacks_t *eecp,
+ __in_opt void *arg)
+{
+ efx_nic_t *enp = eep->ee_enp;
+ unsigned code;
+ boolean_t should_abort = B_FALSE;
+
+ EFX_EV_QSTAT_INCR(eep, EV_MCDI_RESPONSE);
+
+ code = EFX_QWORD_FIELD(*eqp, MCDI_EVENT_CODE);
+ switch (code) {
+ case MCDI_EVENT_CODE_BADSSERT:
+ efx_mcdi_ev_death(enp, EINTR);
+ break;
+
+ case MCDI_EVENT_CODE_CMDDONE:
+ efx_mcdi_ev_cpl(enp,
+ MCDI_EV_FIELD(eqp, CMDDONE_SEQ),
+ MCDI_EV_FIELD(eqp, CMDDONE_DATALEN),
+ MCDI_EV_FIELD(eqp, CMDDONE_ERRNO));
+ break;
+
+ case MCDI_EVENT_CODE_LINKCHANGE: {
+ efx_link_mode_t link_mode;
+
+ hunt_phy_link_ev(enp, eqp, &link_mode);
+ should_abort = eecp->eec_link_change(arg, link_mode);
+ break;
+ }
+
+ case MCDI_EVENT_CODE_SENSOREVT: {
+#if EFSYS_OPT_MON_STATS
+ efx_mon_stat_t id;
+ efx_mon_stat_value_t value;
+ int rc;
+
+ /* Decode monitor stat for MCDI sensor (if supported) */
+ if ((rc = mcdi_mon_ev(enp, eqp, &id, &value)) == 0) {
+ /* Report monitor stat change */
+ should_abort = eecp->eec_monitor(arg, id, value);
+ } else if (rc == ENOTSUP) {
+ should_abort = eecp->eec_exception(arg,
+ EFX_EXCEPTION_UNKNOWN_SENSOREVT,
+ MCDI_EV_FIELD(eqp, DATA));
+ } else {
+ EFSYS_ASSERT(rc == ENODEV); /* Wrong port */
+ }
+#endif
+ break;
+ }
+
+ case MCDI_EVENT_CODE_SCHEDERR:
+ /* Informational only */
+ break;
+
+ case MCDI_EVENT_CODE_REBOOT:
+ /* Falcon/Siena only (should not been seen with Huntington). */
+ efx_mcdi_ev_death(enp, EIO);
+ break;
+
+ case MCDI_EVENT_CODE_MC_REBOOT:
+ /* MC_REBOOT event is used for Huntington (EF10) and later. */
+ efx_mcdi_ev_death(enp, EIO);
+ break;
+
+ case MCDI_EVENT_CODE_MAC_STATS_DMA:
+#if EFSYS_OPT_MAC_STATS
+ if (eecp->eec_mac_stats != NULL) {
+ eecp->eec_mac_stats(arg,
+ MCDI_EV_FIELD(eqp, MAC_STATS_DMA_GENERATION));
+ }
+#endif
+ break;
+
+ case MCDI_EVENT_CODE_FWALERT: {
+ uint32_t reason = MCDI_EV_FIELD(eqp, FWALERT_REASON);
+
+ if (reason == MCDI_EVENT_FWALERT_REASON_SRAM_ACCESS)
+ should_abort = eecp->eec_exception(arg,
+ EFX_EXCEPTION_FWALERT_SRAM,
+ MCDI_EV_FIELD(eqp, FWALERT_DATA));
+ else
+ should_abort = eecp->eec_exception(arg,
+ EFX_EXCEPTION_UNKNOWN_FWALERT,
+ MCDI_EV_FIELD(eqp, DATA));
+ break;
+ }
+
+ case MCDI_EVENT_CODE_TX_ERR: {
+ /*
+ * After a TXQ error is detected, firmware sends a TX_ERR event.
+ * This may be followed by TX completions (which we discard),
+ * and then finally by a TX_FLUSH event. Firmware destroys the
+ * TXQ automatically after sending the TX_FLUSH event.
+ */
+ enp->en_reset_flags |= EFX_RESET_TXQ_ERR;
+
+ EFSYS_PROBE1(tx_descq_err, uint32_t, MCDI_EV_FIELD(eqp, DATA));
+
+ /* Inform the driver that a reset is required. */
+ eecp->eec_exception(arg, EFX_EXCEPTION_TX_ERROR,
+ MCDI_EV_FIELD(eqp, TX_ERR_DATA));
+ break;
+ }
+
+ case MCDI_EVENT_CODE_TX_FLUSH: {
+ uint32_t txq_index = MCDI_EV_FIELD(eqp, TX_FLUSH_TXQ);
+
+ /*
+ * EF10 firmware sends two TX_FLUSH events: one to the txq's
+ * event queue, and one to evq 0 (with TX_FLUSH_TO_DRIVER set).
+ * We want to wait for all completions, so ignore the events
+ * with TX_FLUSH_TO_DRIVER.
+ */
+ if (MCDI_EV_FIELD(eqp, TX_FLUSH_TO_DRIVER) != 0) {
+ should_abort = B_FALSE;
+ break;
+ }
+
+ EFX_EV_QSTAT_INCR(eep, EV_DRIVER_TX_DESCQ_FLS_DONE);
+
+ EFSYS_PROBE1(tx_descq_fls_done, uint32_t, txq_index);
+
+ EFSYS_ASSERT(eecp->eec_txq_flush_done != NULL);
+ should_abort = eecp->eec_txq_flush_done(arg, txq_index);
+ break;
+ }
+
+ case MCDI_EVENT_CODE_RX_ERR: {
+ /*
+ * After an RXQ error is detected, firmware sends an RX_ERR
+ * event. This may be followed by RX events (which we discard),
+ * and then finally by an RX_FLUSH event. Firmware destroys the
+ * RXQ automatically after sending the RX_FLUSH event.
+ */
+ enp->en_reset_flags |= EFX_RESET_RXQ_ERR;
+
+ EFSYS_PROBE1(rx_descq_err, uint32_t, MCDI_EV_FIELD(eqp, DATA));
+
+ /* Inform the driver that a reset is required. */
+ eecp->eec_exception(arg, EFX_EXCEPTION_RX_ERROR,
+ MCDI_EV_FIELD(eqp, RX_ERR_DATA));
+ break;
+ }
+
+ case MCDI_EVENT_CODE_RX_FLUSH: {
+ uint32_t rxq_index = MCDI_EV_FIELD(eqp, RX_FLUSH_RXQ);
+
+ /*
+ * EF10 firmware sends two RX_FLUSH events: one to the rxq's
+ * event queue, and one to evq 0 (with RX_FLUSH_TO_DRIVER set).
+ * We want to wait for all completions, so ignore the events
+ * with RX_FLUSH_TO_DRIVER.
+ */
+ if (MCDI_EV_FIELD(eqp, RX_FLUSH_TO_DRIVER) != 0) {
+ should_abort = B_FALSE;
+ break;
+ }
+
+ EFX_EV_QSTAT_INCR(eep, EV_DRIVER_RX_DESCQ_FLS_DONE);
+
+ EFSYS_PROBE1(rx_descq_fls_done, uint32_t, rxq_index);
+
+ EFSYS_ASSERT(eecp->eec_rxq_flush_done != NULL);
+ should_abort = eecp->eec_rxq_flush_done(arg, rxq_index);
+ break;
+ }
+
+ default:
+ EFSYS_PROBE3(bad_event, unsigned int, eep->ee_index,
+ uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_1),
+ uint32_t, EFX_QWORD_FIELD(*eqp, EFX_DWORD_0));
+ break;
+ }
+
+ return (should_abort);
+}
+
+ void
+hunt_ev_rxlabel_init(
+ __in efx_evq_t *eep,
+ __in efx_rxq_t *erp,
+ __in unsigned int label)
+{
+ efx_evq_rxq_state_t *eersp;
+
+ EFSYS_ASSERT3U(label, <, EFX_ARRAY_SIZE(eep->ee_rxq_state));
+ eersp = &eep->ee_rxq_state[label];
+
+ EFSYS_ASSERT3U(eersp->eers_rx_mask, ==, 0);
+
+ eersp->eers_rx_read_ptr = 0;
+ eersp->eers_rx_mask = erp->er_mask;
+}
+
+ void
+hunt_ev_rxlabel_fini(
+ __in efx_evq_t *eep,
+ __in unsigned int label)
+{
+ efx_evq_rxq_state_t *eersp;
+
+ EFSYS_ASSERT3U(label, <, EFX_ARRAY_SIZE(eep->ee_rxq_state));
+ eersp = &eep->ee_rxq_state[label];
+
+ EFSYS_ASSERT3U(eersp->eers_rx_mask, !=, 0);
+
+ eersp->eers_rx_read_ptr = 0;
+ eersp->eers_rx_mask = 0;
+}
+
+#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_filter.c b/sys/dev/sfxge/common/hunt_filter.c
new file mode 100644
index 0000000..27af7c3
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_filter.c
@@ -0,0 +1,1376 @@
+/*-
+ * Copyright (c) 2007-2015 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_types.h"
+#include "efx_regs_mcdi.h"
+#include "efx_impl.h"
+
+#if EFSYS_OPT_HUNTINGTON
+
+#if EFSYS_OPT_FILTER
+
+#define HFE_SPEC(hftp, index) ((hftp)->hft_entry[(index)].hfe_spec)
+
+static efx_filter_spec_t *
+hunt_filter_entry_spec(
+ __in const hunt_filter_table_t *hftp,
+ __in unsigned int index)
+{
+ return ((efx_filter_spec_t *)(HFE_SPEC(hftp, index) &
+ ~(uintptr_t)EFX_HUNT_FILTER_FLAGS));
+}
+
+static boolean_t
+hunt_filter_entry_is_busy(
+ __in const hunt_filter_table_t *hftp,
+ __in unsigned int index)
+{
+ if (HFE_SPEC(hftp, index) & EFX_HUNT_FILTER_FLAG_BUSY)
+ return (B_TRUE);
+ else
+ return (B_FALSE);
+}
+
+static boolean_t
+hunt_filter_entry_is_auto_old(
+ __in const hunt_filter_table_t *hftp,
+ __in unsigned int index)
+{
+ if (HFE_SPEC(hftp, index) & EFX_HUNT_FILTER_FLAG_AUTO_OLD)
+ return (B_TRUE);
+ else
+ return (B_FALSE);
+}
+
+static void
+hunt_filter_set_entry(
+ __inout hunt_filter_table_t *hftp,
+ __in unsigned int index,
+ __in_opt const efx_filter_spec_t *efsp)
+{
+ HFE_SPEC(hftp, index) = (uintptr_t)efsp;
+}
+
+static void
+hunt_filter_set_entry_busy(
+ __inout hunt_filter_table_t *hftp,
+ __in unsigned int index)
+{
+ HFE_SPEC(hftp, index) |= (uintptr_t)EFX_HUNT_FILTER_FLAG_BUSY;
+}
+
+static void
+hunt_filter_set_entry_not_busy(
+ __inout hunt_filter_table_t *hftp,
+ __in unsigned int index)
+{
+ HFE_SPEC(hftp, index) &= ~(uintptr_t)EFX_HUNT_FILTER_FLAG_BUSY;
+}
+
+static void
+hunt_filter_set_entry_auto_old(
+ __inout hunt_filter_table_t *hftp,
+ __in unsigned int index)
+{
+ EFSYS_ASSERT(hunt_filter_entry_spec(hftp, index) != NULL);
+ HFE_SPEC(hftp, index) |= (uintptr_t)EFX_HUNT_FILTER_FLAG_AUTO_OLD;
+}
+
+static void
+hunt_filter_set_entry_not_auto_old(
+ __inout hunt_filter_table_t *hftp,
+ __in unsigned int index)
+{
+ HFE_SPEC(hftp, index) &= ~(uintptr_t)EFX_HUNT_FILTER_FLAG_AUTO_OLD;
+ EFSYS_ASSERT(hunt_filter_entry_spec(hftp, index) != NULL);
+}
+
+ __checkReturn int
+hunt_filter_init(
+ __in efx_nic_t *enp)
+{
+ int rc;
+ hunt_filter_table_t *hftp;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+#define MATCH_MASK(match) (EFX_MASK32(match) << EFX_LOW_BIT(match))
+ EFX_STATIC_ASSERT(EFX_FILTER_MATCH_REM_HOST ==
+ MATCH_MASK(MC_CMD_FILTER_OP_IN_MATCH_SRC_IP));
+ EFX_STATIC_ASSERT(EFX_FILTER_MATCH_LOC_HOST ==
+ MATCH_MASK(MC_CMD_FILTER_OP_IN_MATCH_DST_IP));
+ EFX_STATIC_ASSERT(EFX_FILTER_MATCH_REM_MAC ==
+ MATCH_MASK(MC_CMD_FILTER_OP_IN_MATCH_SRC_MAC));
+ EFX_STATIC_ASSERT(EFX_FILTER_MATCH_REM_PORT ==
+ MATCH_MASK(MC_CMD_FILTER_OP_IN_MATCH_SRC_PORT));
+ EFX_STATIC_ASSERT(EFX_FILTER_MATCH_LOC_MAC ==
+ MATCH_MASK(MC_CMD_FILTER_OP_IN_MATCH_DST_MAC));
+ EFX_STATIC_ASSERT(EFX_FILTER_MATCH_LOC_PORT ==
+ MATCH_MASK(MC_CMD_FILTER_OP_IN_MATCH_DST_PORT));
+ EFX_STATIC_ASSERT(EFX_FILTER_MATCH_ETHER_TYPE ==
+ MATCH_MASK(MC_CMD_FILTER_OP_IN_MATCH_ETHER_TYPE));
+ EFX_STATIC_ASSERT(EFX_FILTER_MATCH_INNER_VID ==
+ MATCH_MASK(MC_CMD_FILTER_OP_IN_MATCH_INNER_VLAN));
+ EFX_STATIC_ASSERT(EFX_FILTER_MATCH_OUTER_VID ==
+ MATCH_MASK(MC_CMD_FILTER_OP_IN_MATCH_OUTER_VLAN));
+ EFX_STATIC_ASSERT(EFX_FILTER_MATCH_IP_PROTO ==
+ MATCH_MASK(MC_CMD_FILTER_OP_IN_MATCH_IP_PROTO));
+#undef MATCH_MASK
+
+ EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (hunt_filter_table_t), hftp);
+
+ if (!hftp) {
+ rc = ENOMEM;
+ goto fail1;
+ }
+
+ enp->en_filter.ef_hunt_filter_table = hftp;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_filter_fini(
+ __in efx_nic_t *enp)
+{
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ if (enp->en_filter.ef_hunt_filter_table != NULL) {
+ EFSYS_KMEM_FREE(enp->en_esip, sizeof (hunt_filter_table_t),
+ enp->en_filter.ef_hunt_filter_table);
+ }
+}
+
+static __checkReturn int
+efx_mcdi_filter_op_add(
+ __in efx_nic_t *enp,
+ __in efx_filter_spec_t *spec,
+ __in unsigned int filter_op,
+ __inout hunt_filter_handle_t *handle)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_FILTER_OP_IN_LEN,
+ MC_CMD_FILTER_OP_OUT_LEN)];
+ uint32_t match_fields = 0;
+ int rc;
+
+ memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_FILTER_OP;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_FILTER_OP_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_FILTER_OP_OUT_LEN;
+
+ switch (filter_op) {
+ case MC_CMD_FILTER_OP_IN_OP_REPLACE:
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_HANDLE_LO,
+ handle->hfh_lo);
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_HANDLE_HI,
+ handle->hfh_hi);
+ /* Fall through */
+ case MC_CMD_FILTER_OP_IN_OP_INSERT:
+ case MC_CMD_FILTER_OP_IN_OP_SUBSCRIBE:
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_OP, filter_op);
+ break;
+ default:
+ EFSYS_ASSERT(0);
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ if (spec->efs_match_flags & EFX_FILTER_MATCH_LOC_MAC_IG) {
+ /*
+ * The LOC_MAC_IG match flag can represent unknown unicast
+ * or multicast filters - use the MAC address to distinguish
+ * them.
+ */
+ if (EFX_MAC_ADDR_IS_MULTICAST(spec->efs_loc_mac))
+ match_fields |= 1U <<
+ MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_MCAST_DST_LBN;
+ else
+ match_fields |= 1U <<
+ MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_UCAST_DST_LBN;
+ }
+
+ match_fields |= spec->efs_match_flags & (~EFX_FILTER_MATCH_LOC_MAC_IG);
+
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_PORT_ID,
+ EVB_PORT_ID_ASSIGNED);
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_MATCH_FIELDS,
+ match_fields);
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_RX_DEST,
+ MC_CMD_FILTER_OP_IN_RX_DEST_HOST);
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_RX_QUEUE,
+ spec->efs_dmaq_id);
+ if (spec->efs_flags & EFX_FILTER_FLAG_RX_RSS) {
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_RX_CONTEXT,
+ spec->efs_rss_context);
+ }
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_RX_MODE,
+ spec->efs_flags & EFX_FILTER_FLAG_RX_RSS ?
+ MC_CMD_FILTER_OP_IN_RX_MODE_RSS :
+ MC_CMD_FILTER_OP_IN_RX_MODE_SIMPLE);
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_TX_DEST,
+ MC_CMD_FILTER_OP_IN_TX_DEST_DEFAULT);
+
+ if (filter_op != MC_CMD_FILTER_OP_IN_OP_REPLACE) {
+ /*
+ * NOTE: Unlike most MCDI requests, the filter fields
+ * are presented in network (big endian) byte order.
+ */
+ memcpy(MCDI_IN2(req, uint8_t, FILTER_OP_IN_SRC_MAC),
+ spec->efs_rem_mac, EFX_MAC_ADDR_LEN);
+ memcpy(MCDI_IN2(req, uint8_t, FILTER_OP_IN_DST_MAC),
+ spec->efs_loc_mac, EFX_MAC_ADDR_LEN);
+
+ MCDI_IN_SET_WORD(req, FILTER_OP_IN_SRC_PORT,
+ __CPU_TO_BE_16(spec->efs_rem_port));
+ MCDI_IN_SET_WORD(req, FILTER_OP_IN_DST_PORT,
+ __CPU_TO_BE_16(spec->efs_loc_port));
+
+ MCDI_IN_SET_WORD(req, FILTER_OP_IN_ETHER_TYPE,
+ __CPU_TO_BE_16(spec->efs_ether_type));
+
+ MCDI_IN_SET_WORD(req, FILTER_OP_IN_INNER_VLAN,
+ __CPU_TO_BE_16(spec->efs_inner_vid));
+ MCDI_IN_SET_WORD(req, FILTER_OP_IN_OUTER_VLAN,
+ __CPU_TO_BE_16(spec->efs_outer_vid));
+
+ /* IP protocol (in low byte, high byte is zero) */
+ MCDI_IN_SET_BYTE(req, FILTER_OP_IN_IP_PROTO,
+ spec->efs_ip_proto);
+
+ EFX_STATIC_ASSERT(sizeof (spec->efs_rem_host) ==
+ MC_CMD_FILTER_OP_IN_SRC_IP_LEN);
+ EFX_STATIC_ASSERT(sizeof (spec->efs_loc_host) ==
+ MC_CMD_FILTER_OP_IN_DST_IP_LEN);
+
+ memcpy(MCDI_IN2(req, uint8_t, FILTER_OP_IN_SRC_IP),
+ &spec->efs_rem_host.eo_byte[0],
+ MC_CMD_FILTER_OP_IN_SRC_IP_LEN);
+ memcpy(MCDI_IN2(req, uint8_t, FILTER_OP_IN_DST_IP),
+ &spec->efs_loc_host.eo_byte[0],
+ MC_CMD_FILTER_OP_IN_DST_IP_LEN);
+ }
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_FILTER_OP_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail3;
+ }
+
+ handle->hfh_lo = MCDI_OUT_DWORD(req, FILTER_OP_OUT_HANDLE_LO);
+ handle->hfh_hi = MCDI_OUT_DWORD(req, FILTER_OP_OUT_HANDLE_HI);
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+
+}
+
+static __checkReturn int
+efx_mcdi_filter_op_delete(
+ __in efx_nic_t *enp,
+ __in unsigned int filter_op,
+ __inout hunt_filter_handle_t *handle)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_FILTER_OP_IN_LEN,
+ MC_CMD_FILTER_OP_OUT_LEN)];
+ int rc;
+
+ memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_FILTER_OP;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_FILTER_OP_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_FILTER_OP_OUT_LEN;
+
+ switch (filter_op) {
+ case MC_CMD_FILTER_OP_IN_OP_REMOVE:
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_OP,
+ MC_CMD_FILTER_OP_IN_OP_REMOVE);
+ break;
+ case MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE:
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_OP,
+ MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE);
+ break;
+ default:
+ EFSYS_ASSERT(0);
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_HANDLE_LO, handle->hfh_lo);
+ MCDI_IN_SET_DWORD(req, FILTER_OP_IN_HANDLE_HI, handle->hfh_hi);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_FILTER_OP_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail3;
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn boolean_t
+hunt_filter_equal(
+ __in const efx_filter_spec_t *left,
+ __in const efx_filter_spec_t *right)
+{
+ /* FIXME: Consider rx vs tx filters (look at efs_flags) */
+ if (left->efs_match_flags != right->efs_match_flags)
+ return (B_FALSE);
+ if (!EFX_OWORD_IS_EQUAL(left->efs_rem_host, right->efs_rem_host))
+ return (B_FALSE);
+ if (!EFX_OWORD_IS_EQUAL(left->efs_loc_host, right->efs_loc_host))
+ return (B_FALSE);
+ if (memcmp(left->efs_rem_mac, right->efs_rem_mac, EFX_MAC_ADDR_LEN))
+ return (B_FALSE);
+ if (memcmp(left->efs_loc_mac, right->efs_loc_mac, EFX_MAC_ADDR_LEN))
+ return (B_FALSE);
+ if (left->efs_rem_port != right->efs_rem_port)
+ return (B_FALSE);
+ if (left->efs_loc_port != right->efs_loc_port)
+ return (B_FALSE);
+ if (left->efs_inner_vid != right->efs_inner_vid)
+ return (B_FALSE);
+ if (left->efs_outer_vid != right->efs_outer_vid)
+ return (B_FALSE);
+ if (left->efs_ether_type != right->efs_ether_type)
+ return (B_FALSE);
+ if (left->efs_ip_proto != right->efs_ip_proto)
+ return (B_FALSE);
+
+ return (B_TRUE);
+
+}
+
+static __checkReturn boolean_t
+hunt_filter_same_dest(
+ __in const efx_filter_spec_t *left,
+ __in const efx_filter_spec_t *right)
+{
+ if ((left->efs_flags & EFX_FILTER_FLAG_RX_RSS) &&
+ (right->efs_flags & EFX_FILTER_FLAG_RX_RSS)) {
+ if (left->efs_rss_context == right->efs_rss_context)
+ return (B_TRUE);
+ } else if ((~(left->efs_flags) & EFX_FILTER_FLAG_RX_RSS) &&
+ (~(right->efs_flags) & EFX_FILTER_FLAG_RX_RSS)) {
+ if (left->efs_dmaq_id == right->efs_dmaq_id)
+ return (B_TRUE);
+ }
+ return (B_FALSE);
+}
+
+static __checkReturn uint32_t
+hunt_filter_hash(
+ __in efx_filter_spec_t *spec)
+{
+ EFX_STATIC_ASSERT((sizeof (efx_filter_spec_t) % sizeof (uint32_t))
+ == 0);
+ EFX_STATIC_ASSERT((EFX_FIELD_OFFSET(efx_filter_spec_t, efs_outer_vid) %
+ sizeof (uint32_t)) == 0);
+
+ /*
+ * As the area of the efx_filter_spec_t we need to hash is DWORD
+ * aligned and an exact number of DWORDs in size we can use the
+ * optimised efx_hash_dwords() rather than efx_hash_bytes()
+ */
+ return (efx_hash_dwords((const uint32_t *)&spec->efs_outer_vid,
+ (sizeof (efx_filter_spec_t) -
+ EFX_FIELD_OFFSET(efx_filter_spec_t, efs_outer_vid)) /
+ sizeof (uint32_t), 0));
+}
+
+/*
+ * Decide whether a filter should be exclusive or else should allow
+ * delivery to additional recipients. Currently we decide that
+ * filters for specific local unicast MAC and IP addresses are
+ * exclusive.
+ */
+static __checkReturn boolean_t
+hunt_filter_is_exclusive(
+ __in efx_filter_spec_t *spec)
+{
+ if ((spec->efs_match_flags & EFX_FILTER_MATCH_LOC_MAC) &&
+ !EFX_MAC_ADDR_IS_MULTICAST(spec->efs_loc_mac))
+ return (B_TRUE);
+
+ if ((spec->efs_match_flags &
+ (EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_LOC_HOST)) ==
+ (EFX_FILTER_MATCH_ETHER_TYPE | EFX_FILTER_MATCH_LOC_HOST)) {
+ if ((spec->efs_ether_type == EFX_ETHER_TYPE_IPV4) &&
+ ((spec->efs_loc_host.eo_u8[0] & 0xf) != 0xe))
+ return (B_TRUE);
+ if ((spec->efs_ether_type == EFX_ETHER_TYPE_IPV6) &&
+ (spec->efs_loc_host.eo_u8[0] != 0xff))
+ return (B_TRUE);
+ }
+
+ return (B_FALSE);
+}
+
+ __checkReturn int
+hunt_filter_restore(
+ __in efx_nic_t *enp)
+{
+ int tbl_id;
+ efx_filter_spec_t *spec;
+ hunt_filter_table_t *hftp = enp->en_filter.ef_hunt_filter_table;
+ boolean_t restoring;
+ int state;
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ for (tbl_id = 0; tbl_id < EFX_HUNT_FILTER_TBL_ROWS; tbl_id++) {
+
+ EFSYS_LOCK(enp->en_eslp, state);
+
+ spec = hunt_filter_entry_spec(hftp, tbl_id);
+ if (spec == NULL) {
+ restoring = B_FALSE;
+ } else if (hunt_filter_entry_is_busy(hftp, tbl_id)) {
+ /* Ignore busy entries. */
+ restoring = B_FALSE;
+ } else {
+ hunt_filter_set_entry_busy(hftp, tbl_id);
+ restoring = B_TRUE;
+ }
+
+ EFSYS_UNLOCK(enp->en_eslp, state);
+
+ if (restoring == B_FALSE)
+ continue;
+
+ if (hunt_filter_is_exclusive(spec)) {
+ rc = efx_mcdi_filter_op_add(enp, spec,
+ MC_CMD_FILTER_OP_IN_OP_INSERT,
+ &hftp->hft_entry[tbl_id].hfe_handle);
+ } else {
+ rc = efx_mcdi_filter_op_add(enp, spec,
+ MC_CMD_FILTER_OP_IN_OP_SUBSCRIBE,
+ &hftp->hft_entry[tbl_id].hfe_handle);
+ }
+
+ if (rc != 0)
+ goto fail1;
+
+ EFSYS_LOCK(enp->en_eslp, state);
+
+ hunt_filter_set_entry_not_busy(hftp, tbl_id);
+
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+/*
+ * An arbitrary search limit for the software hash table. As per the linux net
+ * driver.
+ */
+#define EFX_HUNT_FILTER_SEARCH_LIMIT 200
+
+static __checkReturn int
+hunt_filter_add_internal(
+ __in efx_nic_t *enp,
+ __inout efx_filter_spec_t *spec,
+ __in boolean_t may_replace,
+ __out_opt uint32_t *filter_id)
+{
+ int rc;
+ hunt_filter_table_t *hftp = enp->en_filter.ef_hunt_filter_table;
+ efx_filter_spec_t *saved_spec;
+ uint32_t hash;
+ unsigned int depth;
+ int ins_index;
+ boolean_t replacing = B_FALSE;
+ unsigned int i;
+ int state;
+ boolean_t locked = B_FALSE;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+#if EFSYS_OPT_RX_SCALE
+ spec->efs_rss_context = enp->en_rss_context;
+#endif
+
+ hash = hunt_filter_hash(spec);
+
+ /*
+ * FIXME: Add support for inserting filters of different priorities
+ * and removing lower priority multicast filters (bug 42378)
+ */
+
+ /*
+ * Find any existing filters with the same match tuple or
+ * else a free slot to insert at. If any of them are busy,
+ * we have to wait and retry.
+ */
+ for (;;) {
+ ins_index = -1;
+ depth = 1;
+ EFSYS_LOCK(enp->en_eslp, state);
+ locked = B_TRUE;
+
+ for (;;) {
+ i = (hash + depth) & (EFX_HUNT_FILTER_TBL_ROWS - 1);
+ saved_spec = hunt_filter_entry_spec(hftp, i);
+
+ if (!saved_spec) {
+ if (ins_index < 0) {
+ ins_index = i;
+ }
+ } else if (hunt_filter_equal(spec, saved_spec)) {
+ if (hunt_filter_entry_is_busy(hftp, i))
+ break;
+ if (saved_spec->efs_priority
+ == EFX_FILTER_PRI_AUTO) {
+ ins_index = i;
+ goto found;
+ } else if (hunt_filter_is_exclusive(spec)) {
+ if (may_replace) {
+ ins_index = i;
+ goto found;
+ } else {
+ rc = EEXIST;
+ goto fail1;
+ }
+ }
+
+ /* Leave existing */
+ }
+
+ /*
+ * Once we reach the maximum search depth, use
+ * the first suitable slot or return EBUSY if
+ * there was none.
+ */
+ if (depth == EFX_HUNT_FILTER_SEARCH_LIMIT) {
+ if (ins_index < 0) {
+ rc = EBUSY;
+ goto fail2;
+ }
+ goto found;
+ }
+ depth++;
+ }
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ locked = B_FALSE;
+ }
+
+found:
+ /*
+ * Create a software table entry if necessary, and mark it
+ * busy. We might yet fail to insert, but any attempt to
+ * insert a conflicting filter while we're waiting for the
+ * firmware must find the busy entry.
+ */
+ saved_spec = hunt_filter_entry_spec(hftp, ins_index);
+ if (saved_spec) {
+ if (saved_spec->efs_priority == EFX_FILTER_PRI_AUTO) {
+ /* This is a filter we are refreshing */
+ hunt_filter_set_entry_not_auto_old(hftp, ins_index);
+ goto out_unlock;
+
+ }
+ replacing = B_TRUE;
+ } else {
+ EFSYS_KMEM_ALLOC(enp->en_esip, sizeof (*spec), saved_spec);
+ if (!saved_spec) {
+ rc = ENOMEM;
+ goto fail3;
+ }
+ *saved_spec = *spec;
+ hunt_filter_set_entry(hftp, ins_index, saved_spec);
+ }
+ hunt_filter_set_entry_busy(hftp, ins_index);
+
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ locked = B_FALSE;
+
+ /*
+ * On replacing the filter handle may change after after a successful
+ * replace operation.
+ */
+ if (replacing) {
+ rc = efx_mcdi_filter_op_add(enp, spec,
+ MC_CMD_FILTER_OP_IN_OP_REPLACE,
+ &hftp->hft_entry[ins_index].hfe_handle);
+ } else if (hunt_filter_is_exclusive(spec)) {
+ rc = efx_mcdi_filter_op_add(enp, spec,
+ MC_CMD_FILTER_OP_IN_OP_INSERT,
+ &hftp->hft_entry[ins_index].hfe_handle);
+ } else {
+ rc = efx_mcdi_filter_op_add(enp, spec,
+ MC_CMD_FILTER_OP_IN_OP_SUBSCRIBE,
+ &hftp->hft_entry[ins_index].hfe_handle);
+ }
+
+ if (rc != 0)
+ goto fail4;
+
+ EFSYS_LOCK(enp->en_eslp, state);
+ locked = B_TRUE;
+
+ if (replacing) {
+ /* Update the fields that may differ */
+ saved_spec->efs_priority = spec->efs_priority;
+ saved_spec->efs_flags = spec->efs_flags;
+ saved_spec->efs_rss_context = spec->efs_rss_context;
+ saved_spec->efs_dmaq_id = spec->efs_dmaq_id;
+ }
+
+ hunt_filter_set_entry_not_busy(hftp, ins_index);
+
+out_unlock:
+
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ locked = B_FALSE;
+
+ if (filter_id)
+ *filter_id = ins_index;
+
+ return (0);
+
+fail4:
+ EFSYS_PROBE(fail4);
+
+ if (!replacing) {
+ EFSYS_KMEM_FREE(enp->en_esip, sizeof (*spec), saved_spec);
+ saved_spec = NULL;
+ }
+ hunt_filter_set_entry_not_busy(hftp, ins_index);
+ hunt_filter_set_entry(hftp, ins_index, NULL);
+
+fail3:
+ EFSYS_PROBE(fail3);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ if (locked)
+ EFSYS_UNLOCK(enp->en_eslp, state);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_filter_add(
+ __in efx_nic_t *enp,
+ __inout efx_filter_spec_t *spec,
+ __in boolean_t may_replace)
+{
+ int rc;
+
+ rc = hunt_filter_add_internal(enp, spec, may_replace, NULL);
+ if (rc != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+static __checkReturn int
+hunt_filter_delete_internal(
+ __in efx_nic_t *enp,
+ __in uint32_t filter_id)
+{
+ int rc;
+ hunt_filter_table_t *table = enp->en_filter.ef_hunt_filter_table;
+ efx_filter_spec_t *spec;
+ int state;
+ uint32_t filter_idx = filter_id % EFX_HUNT_FILTER_TBL_ROWS;
+
+ /*
+ * Find the software table entry and mark it busy. Don't
+ * remove it yet; any attempt to update while we're waiting
+ * for the firmware must find the busy entry.
+ *
+ * FIXME: What if the busy flag is never cleared?
+ */
+ EFSYS_LOCK(enp->en_eslp, state);
+ while (hunt_filter_entry_is_busy(table, filter_idx)) {
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ EFSYS_SPIN(1);
+ EFSYS_LOCK(enp->en_eslp, state);
+ }
+ if ((spec = hunt_filter_entry_spec(table, filter_idx)) != NULL) {
+ hunt_filter_set_entry_busy(table, filter_idx);
+ }
+ EFSYS_UNLOCK(enp->en_eslp, state);
+
+ if (spec == NULL) {
+ rc = ENOENT;
+ goto fail1;
+ }
+
+ /*
+ * Try to remove the hardware filter. This may fail if the MC has
+ * rebooted (which frees all hardware filter resources).
+ */
+ if (hunt_filter_is_exclusive(spec)) {
+ rc = efx_mcdi_filter_op_delete(enp,
+ MC_CMD_FILTER_OP_IN_OP_REMOVE,
+ &table->hft_entry[filter_idx].hfe_handle);
+ } else {
+ rc = efx_mcdi_filter_op_delete(enp,
+ MC_CMD_FILTER_OP_IN_OP_UNSUBSCRIBE,
+ &table->hft_entry[filter_idx].hfe_handle);
+ }
+
+ /* Free the software table entry */
+ EFSYS_LOCK(enp->en_eslp, state);
+ hunt_filter_set_entry_not_busy(table, filter_idx);
+ hunt_filter_set_entry(table, filter_idx, NULL);
+ EFSYS_UNLOCK(enp->en_eslp, state);
+
+ EFSYS_KMEM_FREE(enp->en_esip, sizeof (*spec), spec);
+
+ /* Check result of hardware filter removal */
+ if (rc != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_filter_delete(
+ __in efx_nic_t *enp,
+ __inout efx_filter_spec_t *spec)
+{
+ int rc;
+ hunt_filter_table_t *table = enp->en_filter.ef_hunt_filter_table;
+ efx_filter_spec_t *saved_spec;
+ unsigned int hash;
+ unsigned int depth;
+ unsigned int i;
+ int state;
+ boolean_t locked = B_FALSE;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ hash = hunt_filter_hash(spec);
+
+ EFSYS_LOCK(enp->en_eslp, state);
+ locked = B_TRUE;
+
+ depth = 1;
+ for (;;) {
+ i = (hash + depth) & (EFX_HUNT_FILTER_TBL_ROWS - 1);
+ saved_spec = hunt_filter_entry_spec(table, i);
+ if (saved_spec && hunt_filter_equal(spec, saved_spec) &&
+ hunt_filter_same_dest(spec, saved_spec)) {
+ break;
+ }
+ if (depth == EFX_HUNT_FILTER_SEARCH_LIMIT) {
+ rc = ENOENT;
+ goto fail1;
+ }
+ depth++;
+ }
+
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ locked = B_FALSE;
+
+ rc = hunt_filter_delete_internal(enp, i);
+ if (rc != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ if (locked)
+ EFSYS_UNLOCK(enp->en_eslp, state);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_get_parser_disp_info(
+ __in efx_nic_t *enp,
+ __out uint32_t *list,
+ __out size_t *length)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_PARSER_DISP_INFO_IN_LEN,
+ MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMAX)];
+ int rc;
+ uint32_t i;
+ boolean_t support_unknown_ucast = B_FALSE;
+ boolean_t support_unknown_mcast = B_FALSE;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_PARSER_DISP_INFO;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_PARSER_DISP_INFO_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_PARSER_DISP_INFO_OUT_LENMAX;
+
+ MCDI_IN_SET_DWORD(req, GET_PARSER_DISP_INFO_OUT_OP,
+ MC_CMD_GET_PARSER_DISP_INFO_IN_OP_GET_SUPPORTED_RX_MATCHES);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ *length = MCDI_OUT_DWORD(req,
+ GET_PARSER_DISP_INFO_OUT_NUM_SUPPORTED_MATCHES);
+
+ if (req.emr_out_length_used <
+ MC_CMD_GET_PARSER_DISP_INFO_OUT_LEN(*length)) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ memcpy(list,
+ MCDI_OUT2(req,
+ uint32_t,
+ GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES),
+ (*length) * sizeof (uint32_t));
+ EFX_STATIC_ASSERT(sizeof (uint32_t) ==
+ MC_CMD_GET_PARSER_DISP_INFO_OUT_SUPPORTED_MATCHES_LEN);
+
+ /*
+ * Remove UNKNOWN UCAST and MCAST flags, and if both are present, change
+ * the lower priority one to LOC_MAC_IG.
+ */
+ for (i = 0; i < *length; i++) {
+ if (list[i] & MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_UCAST_DST_LBN) {
+ list[i] &=
+ (~MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_UCAST_DST_LBN);
+ support_unknown_ucast = B_TRUE;
+ }
+ if (list[i] & MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_MCAST_DST_LBN) {
+ list[i] &=
+ (~MC_CMD_FILTER_OP_IN_MATCH_UNKNOWN_MCAST_DST_LBN);
+ support_unknown_mcast = B_TRUE;
+ }
+
+ if (support_unknown_ucast && support_unknown_mcast) {
+ list[i] &= EFX_FILTER_MATCH_LOC_MAC_IG;
+ break;
+ }
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_filter_supported_filters(
+ __in efx_nic_t *enp,
+ __out uint32_t *list,
+ __out size_t *length)
+{
+ int rc;
+
+ if ((rc = efx_mcdi_get_parser_disp_info(enp, list, length) != 0))
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+hunt_filter_unicast_refresh(
+ __in efx_nic_t *enp,
+ __in_ecount(6) uint8_t const *addr,
+ __in boolean_t all_unicst,
+ __in efx_filter_flag_t filter_flags)
+{
+ hunt_filter_table_t *hftp = enp->en_filter.ef_hunt_filter_table;
+ efx_filter_spec_t spec;
+ int rc;
+
+ if (all_unicst == B_TRUE)
+ goto use_uc_def;
+
+ /* Insert the filter for the local station address */
+ efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
+ filter_flags,
+ hftp->hft_default_rxq);
+ efx_filter_spec_set_eth_local(&spec, EFX_FILTER_SPEC_VID_UNSPEC, addr);
+
+ rc = hunt_filter_add_internal(enp, &spec, B_TRUE,
+ &hftp->hft_unicst_filter_index);
+ if (rc != 0) {
+ /*
+ * Fall back to an unknown filter. We may be able to subscribe
+ * to it even if we couldn't insert the unicast filter.
+ */
+ goto use_uc_def;
+ }
+ hftp->hft_unicst_filter_set = B_TRUE;
+
+ return (0);
+
+use_uc_def:
+ /* Insert the unknown unicast filter */
+ efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
+ filter_flags,
+ hftp->hft_default_rxq);
+ efx_filter_spec_set_uc_def(&spec);
+ rc = hunt_filter_add_internal(enp, &spec, B_TRUE,
+ &hftp->hft_unicst_filter_index);
+ if (rc != 0)
+ goto fail1;
+
+ hftp->hft_unicst_filter_set = B_TRUE;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ if (hftp->hft_unicst_filter_set != B_FALSE) {
+ (void) hunt_filter_delete_internal(enp,
+ hftp->hft_unicst_filter_index);
+
+ hftp->hft_unicst_filter_set = B_FALSE;
+ }
+
+ return (rc);
+}
+
+static __checkReturn int
+hunt_filter_multicast_refresh(
+ __in efx_nic_t *enp,
+ __in boolean_t mulcst,
+ __in boolean_t all_mulcst,
+ __in boolean_t brdcst,
+ __in_ecount(6*count) uint8_t const *addrs,
+ __in int count,
+ __in efx_filter_flag_t filter_flags)
+{
+ hunt_filter_table_t *hftp = enp->en_filter.ef_hunt_filter_table;
+ efx_filter_spec_t spec;
+ uint8_t addr[6];
+ unsigned i;
+ int rc;
+
+ if (all_mulcst == B_TRUE)
+ goto use_mc_def;
+
+ if (mulcst == B_FALSE)
+ count = 0;
+
+ if (count + (brdcst ? 1 : 0) >
+ EFX_ARRAY_SIZE(hftp->hft_mulcst_filter_indexes)) {
+ /* Too many MAC addresses; use unknown multicast filter */
+ goto use_mc_def;
+ }
+
+ /* Insert/renew multicast address list filters */
+ hftp->hft_mulcst_filter_count = count;
+ for (i = 0; i < hftp->hft_mulcst_filter_count; i++) {
+ efx_filter_spec_init_rx(&spec,
+ EFX_FILTER_PRI_AUTO,
+ filter_flags,
+ hftp->hft_default_rxq);
+
+ efx_filter_spec_set_eth_local(&spec,
+ EFX_FILTER_SPEC_VID_UNSPEC,
+ &addrs[i * EFX_MAC_ADDR_LEN]);
+
+ rc = hunt_filter_add_internal(enp, &spec, B_TRUE,
+ &hftp->hft_mulcst_filter_indexes[i]);
+ if (rc != 0) {
+ /* Rollback, then use unknown multicast filter */
+ goto rollback;
+ }
+ }
+
+ if (brdcst == B_TRUE) {
+ /* Insert/renew broadcast address filter */
+ hftp->hft_mulcst_filter_count++;
+ efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
+ filter_flags,
+ hftp->hft_default_rxq);
+
+ EFX_MAC_BROADCAST_ADDR_SET(addr);
+ efx_filter_spec_set_eth_local(&spec, EFX_FILTER_SPEC_VID_UNSPEC,
+ addr);
+
+ rc = hunt_filter_add_internal(enp, &spec, B_TRUE,
+ &hftp->hft_mulcst_filter_indexes[
+ hftp->hft_mulcst_filter_count - 1]);
+ if (rc != 0) {
+ /* Rollback, then use unknown multicast filter */
+ goto rollback;
+ }
+ }
+
+ return (0);
+
+rollback:
+ /*
+ * Rollback by removing any filters we have inserted
+ * before inserting the unknown multicast filter.
+ */
+ while (i--) {
+ (void) hunt_filter_delete_internal(enp,
+ hftp->hft_mulcst_filter_indexes[i]);
+ }
+ hftp->hft_mulcst_filter_count = 0;
+
+use_mc_def:
+ /* Insert the unknown multicast filter */
+ efx_filter_spec_init_rx(&spec, EFX_FILTER_PRI_AUTO,
+ filter_flags,
+ hftp->hft_default_rxq);
+ efx_filter_spec_set_mc_def(&spec);
+
+ rc = hunt_filter_add_internal(enp, &spec, B_TRUE,
+ &hftp->hft_mulcst_filter_indexes[0]);
+ if (rc != 0)
+ goto fail1;
+
+ hftp->hft_mulcst_filter_count = 1;
+
+ /*
+ * FIXME: If brdcst == B_FALSE, add a filter to drop broadcast traffic.
+ */
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+
+}
+
+
+static __checkReturn int
+hunt_filter_get_workarounds(
+ __in efx_nic_t *enp)
+{
+ efx_nic_cfg_t *encp = &enp->en_nic_cfg;
+ uint32_t implemented = 0;
+ uint32_t enabled = 0;
+ int rc;
+
+ rc = efx_mcdi_get_workarounds(enp, &implemented, &enabled);
+ if (rc == 0) {
+ /* Check if chained multicast filter support is enabled */
+ if (implemented & enabled & MC_CMD_GET_WORKAROUNDS_OUT_BUG26807)
+ encp->enc_bug26807_workaround = B_TRUE;
+ else
+ encp->enc_bug26807_workaround = B_FALSE;
+ } else if (rc == ENOTSUP) {
+ /*
+ * Firmware is too old to support GET_WORKAROUNDS, and support
+ * for this workaround was implemented later.
+ */
+ encp->enc_bug26807_workaround = B_FALSE;
+ } else {
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+
+}
+
+
+/*
+ * Reconfigure all filters.
+ * If all_unicst and/or all mulcst filters cannot be applied then
+ * return ENOTSUP (Note the filters for the specified addresses are
+ * still applied in this case).
+ */
+ __checkReturn int
+hunt_filter_reconfigure(
+ __in efx_nic_t *enp,
+ __in_ecount(6) uint8_t const *mac_addr,
+ __in boolean_t all_unicst,
+ __in boolean_t mulcst,
+ __in boolean_t all_mulcst,
+ __in boolean_t brdcst,
+ __in_ecount(6*count) uint8_t const *addrs,
+ __in int count)
+{
+ hunt_filter_table_t *table = enp->en_filter.ef_hunt_filter_table;
+ efx_filter_flag_t filter_flags;
+ unsigned i;
+ int all_unicst_rc;
+ int all_mulcst_rc;
+ int rc;
+
+ if (table->hft_default_rxq == NULL) {
+ /*
+ * Filters direct traffic to the default RXQ, and so cannot be
+ * inserted until it is available. Any currently configured
+ * filters must be removed (ignore errors in case the MC
+ * has rebooted, which removes hardware filters).
+ */
+ if (table->hft_unicst_filter_set != B_FALSE) {
+ (void) hunt_filter_delete_internal(enp,
+ table->hft_unicst_filter_index);
+ table->hft_unicst_filter_set = B_FALSE;
+ }
+ for (i = 0; i < table->hft_mulcst_filter_count; i++) {
+ (void) hunt_filter_delete_internal(enp,
+ table->hft_mulcst_filter_indexes[i]);
+ }
+ table->hft_mulcst_filter_count = 0;
+
+ return (0);
+ }
+
+ if (table->hft_using_rss)
+ filter_flags = EFX_FILTER_FLAG_RX_RSS;
+ else
+ filter_flags = 0;
+
+ /* Mark old filters which may need to be removed */
+ if (table->hft_unicst_filter_set != B_FALSE) {
+ hunt_filter_set_entry_auto_old(table,
+ table->hft_unicst_filter_index);
+ }
+ for (i = 0; i < table->hft_mulcst_filter_count; i++) {
+ hunt_filter_set_entry_auto_old(table,
+ table->hft_mulcst_filter_indexes[i]);
+ }
+
+ /* Insert or renew unicast filters */
+ if ((all_unicst_rc = hunt_filter_unicast_refresh(enp, mac_addr,
+ all_unicst, filter_flags)) != 0) {
+ if (all_unicst == B_FALSE) {
+ rc = all_unicst_rc;
+ goto fail1;
+ }
+ /* Retry without all_unicast flag */
+ rc = hunt_filter_unicast_refresh(enp, mac_addr,
+ B_FALSE, filter_flags);
+ if (rc != 0)
+ goto fail2;
+ }
+
+ /*
+ * WORKAROUND_BUG26807 controls firmware support for chained multicast
+ * filters, and can only be enabled or disabled when the hardware filter
+ * table is empty.
+ *
+ * Firmware will reset (FLR) functions which have inserted filters in
+ * the hardware filter table when the workaround is enabled/disabled.
+ * Functions without any hardware filters are not reset.
+ *
+ * Re-check if the workaround is enabled after adding unicast hardware
+ * filters. This ensures that encp->enc_workaround_bug26807 matches the
+ * firmware state, and that later changes to enable/disable the
+ * workaround will result in this function seeing a reset (FLR).
+ */
+ if ((rc = hunt_filter_get_workarounds(enp)) != 0)
+ goto fail3;
+
+ /* Insert or renew multicast filters */
+ if ((all_mulcst_rc = hunt_filter_multicast_refresh(enp, mulcst,
+ all_mulcst, brdcst,
+ addrs, count, filter_flags)) != 0) {
+ if (all_mulcst == B_FALSE) {
+ rc = all_mulcst_rc;
+ goto fail4;
+ }
+ /* Retry without all_mulcast flag */
+ rc = hunt_filter_multicast_refresh(enp, mulcst,
+ B_FALSE, brdcst,
+ addrs, count, filter_flags);
+ if (rc != 0)
+ goto fail5;
+ }
+
+ /* Remove old filters which were not renewed */
+ for (i = 0; i < EFX_ARRAY_SIZE(table->hft_entry); i++) {
+ if (hunt_filter_entry_is_auto_old(table, i)) {
+ (void) hunt_filter_delete_internal(enp, i);
+ }
+ }
+
+ /* report if any optional flags were rejected */
+ if (((all_unicst != B_FALSE) && (all_unicst_rc != 0)) ||
+ ((all_mulcst != B_FALSE) && (all_mulcst_rc != 0))) {
+ rc = ENOTSUP;
+ }
+
+ return (rc);
+
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ /* Clear auto old flags */
+ for (i = 0; i < EFX_ARRAY_SIZE(table->hft_entry); i++) {
+ if (hunt_filter_entry_is_auto_old(table, i)) {
+ hunt_filter_set_entry_not_auto_old(table, i);
+ }
+ }
+
+ return (rc);
+}
+
+ void
+hunt_filter_get_default_rxq(
+ __in efx_nic_t *enp,
+ __out efx_rxq_t **erpp,
+ __out boolean_t *using_rss)
+{
+ hunt_filter_table_t *table = enp->en_filter.ef_hunt_filter_table;
+
+ *erpp = table->hft_default_rxq;
+ *using_rss = table->hft_using_rss;
+}
+
+
+ void
+hunt_filter_default_rxq_set(
+ __in efx_nic_t *enp,
+ __in efx_rxq_t *erp,
+ __in boolean_t using_rss)
+{
+ hunt_filter_table_t *table = enp->en_filter.ef_hunt_filter_table;
+
+#if EFSYS_OPT_RX_SCALE
+ EFSYS_ASSERT((using_rss == B_FALSE) ||
+ (enp->en_rss_context != HUNTINGTON_RSS_CONTEXT_INVALID));
+ table->hft_using_rss = using_rss;
+#else
+ EFSYS_ASSERT(using_rss == B_FALSE);
+ table->hft_using_rss = B_FALSE;
+#endif
+ table->hft_default_rxq = erp;
+}
+
+ void
+hunt_filter_default_rxq_clear(
+ __in efx_nic_t *enp)
+{
+ hunt_filter_table_t *table = enp->en_filter.ef_hunt_filter_table;
+
+ table->hft_default_rxq = NULL;
+ table->hft_using_rss = B_FALSE;
+}
+
+
+#endif /* EFSYS_OPT_FILTER */
+
+#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_impl.h b/sys/dev/sfxge/common/hunt_impl.h
new file mode 100644
index 0000000..d1a4c94
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_impl.h
@@ -0,0 +1,1015 @@
+/*-
+ * Copyright (c) 2012-2015 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_HUNT_IMPL_H
+#define _SYS_HUNT_IMPL_H
+
+#include "efx.h"
+#include "efx_regs.h"
+#include "efx_regs_ef10.h"
+#include "efx_mcdi.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define HUNTINGTON_NVRAM_CHUNK 0x80
+
+/* Alignment requirement for value written to RX WPTR:
+ * the WPTR must be aligned to an 8 descriptor boundary
+ */
+#define HUNTINGTON_RX_WPTR_ALIGN 8
+
+/* Invalid RSS context handle */
+#define HUNTINGTON_RSS_CONTEXT_INVALID (0xffffffff)
+
+
+/* EV */
+
+ __checkReturn int
+hunt_ev_init(
+ __in efx_nic_t *enp);
+
+ void
+hunt_ev_fini(
+ __in efx_nic_t *enp);
+
+ __checkReturn int
+hunt_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 efx_evq_t *eep);
+
+ void
+hunt_ev_qdestroy(
+ __in efx_evq_t *eep);
+
+ __checkReturn int
+hunt_ev_qprime(
+ __in efx_evq_t *eep,
+ __in unsigned int count);
+
+ void
+hunt_ev_qpost(
+ __in efx_evq_t *eep,
+ __in uint16_t data);
+
+ __checkReturn int
+hunt_ev_qmoderate(
+ __in efx_evq_t *eep,
+ __in unsigned int us);
+
+#if EFSYS_OPT_QSTATS
+ void
+hunt_ev_qstats_update(
+ __in efx_evq_t *eep,
+ __inout_ecount(EV_NQSTATS) efsys_stat_t *stat);
+#endif /* EFSYS_OPT_QSTATS */
+
+ void
+hunt_ev_rxlabel_init(
+ __in efx_evq_t *eep,
+ __in efx_rxq_t *erp,
+ __in unsigned int label);
+
+ void
+hunt_ev_rxlabel_fini(
+ __in efx_evq_t *eep,
+ __in unsigned int label);
+
+/* INTR */
+
+ __checkReturn int
+hunt_intr_init(
+ __in efx_nic_t *enp,
+ __in efx_intr_type_t type,
+ __in efsys_mem_t *esmp);
+
+ void
+hunt_intr_enable(
+ __in efx_nic_t *enp);
+
+ void
+hunt_intr_disable(
+ __in efx_nic_t *enp);
+
+ void
+hunt_intr_disable_unlocked(
+ __in efx_nic_t *enp);
+
+ __checkReturn int
+hunt_intr_trigger(
+ __in efx_nic_t *enp,
+ __in unsigned int level);
+
+ void
+hunt_intr_fini(
+ __in efx_nic_t *enp);
+
+/* NIC */
+
+extern __checkReturn int
+hunt_nic_probe(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+hunt_nic_set_drv_limits(
+ __inout efx_nic_t *enp,
+ __in efx_drv_limits_t *edlp);
+
+extern __checkReturn int
+hunt_nic_get_vi_pool(
+ __in efx_nic_t *enp,
+ __out uint32_t *vi_countp);
+
+extern __checkReturn int
+hunt_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 int
+hunt_nic_reset(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+hunt_nic_init(
+ __in efx_nic_t *enp);
+
+#if EFSYS_OPT_DIAG
+
+extern __checkReturn int
+hunt_nic_register_test(
+ __in efx_nic_t *enp);
+
+#endif /* EFSYS_OPT_DIAG */
+
+extern void
+hunt_nic_fini(
+ __in efx_nic_t *enp);
+
+extern void
+hunt_nic_unprobe(
+ __in efx_nic_t *enp);
+
+
+/* MAC */
+
+extern __checkReturn int
+hunt_mac_poll(
+ __in efx_nic_t *enp,
+ __out efx_link_mode_t *link_modep);
+
+extern __checkReturn int
+hunt_mac_up(
+ __in efx_nic_t *enp,
+ __out boolean_t *mac_upp);
+
+extern __checkReturn int
+hunt_mac_addr_set(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+hunt_mac_reconfigure(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+hunt_mac_multicast_list_set(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+hunt_mac_filter_default_rxq_set(
+ __in efx_nic_t *enp,
+ __in efx_rxq_t *erp,
+ __in boolean_t using_rss);
+
+extern void
+hunt_mac_filter_default_rxq_clear(
+ __in efx_nic_t *enp);
+
+#if EFSYS_OPT_LOOPBACK
+
+extern __checkReturn int
+hunt_mac_loopback_set(
+ __in efx_nic_t *enp,
+ __in efx_link_mode_t link_mode,
+ __in efx_loopback_type_t loopback_type);
+
+#endif /* EFSYS_OPT_LOOPBACK */
+
+#if EFSYS_OPT_MAC_STATS
+
+extern __checkReturn int
+hunt_mac_stats_update(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp,
+ __out_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat,
+ __out_opt uint32_t *generationp);
+
+#endif /* EFSYS_OPT_MAC_STATS */
+
+
+/* MCDI */
+
+#if EFSYS_OPT_MCDI
+
+extern __checkReturn int
+hunt_mcdi_init(
+ __in efx_nic_t *enp,
+ __in const efx_mcdi_transport_t *mtp);
+
+extern void
+hunt_mcdi_fini(
+ __in efx_nic_t *enp);
+
+extern void
+hunt_mcdi_request_copyin(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp,
+ __in unsigned int seq,
+ __in boolean_t ev_cpl,
+ __in boolean_t new_epoch);
+
+extern __checkReturn boolean_t
+hunt_mcdi_request_poll(
+ __in efx_nic_t *enp);
+
+extern void
+hunt_mcdi_request_copyout(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp);
+
+extern int
+hunt_mcdi_poll_reboot(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+hunt_mcdi_fw_update_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp);
+
+extern __checkReturn int
+hunt_mcdi_macaddr_change_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp);
+
+#endif /* EFSYS_OPT_MCDI */
+
+/* NVRAM */
+
+#if EFSYS_OPT_NVRAM || EFSYS_OPT_VPD
+
+extern __checkReturn int
+hunt_nvram_buf_read_tlv(
+ __in efx_nic_t *enp,
+ __in_bcount(partn_size) caddr_t partn_data,
+ __in size_t partn_size,
+ __in uint32_t tag,
+ __deref_out_bcount_opt(*sizep) caddr_t *datap,
+ __out size_t *sizep);
+
+extern __checkReturn int
+hunt_nvram_buf_write_tlv(
+ __inout_bcount(partn_size) caddr_t partn_data,
+ __in size_t partn_size,
+ __in uint32_t tag,
+ __in_bcount(tag_size) caddr_t tag_data,
+ __in size_t tag_size,
+ __out size_t *total_lengthp);
+
+extern __checkReturn int
+hunt_nvram_partn_read_tlv(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in uint32_t tag,
+ __deref_out_bcount_opt(*sizep) caddr_t *datap,
+ __out size_t *sizep);
+
+extern __checkReturn int
+hunt_nvram_partn_write_tlv(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in uint32_t tag,
+ __in_bcount(size) caddr_t data,
+ __in size_t size);
+
+extern __checkReturn int
+hunt_nvram_partn_size(
+ __in efx_nic_t *enp,
+ __in unsigned int partn,
+ __out size_t *sizep);
+
+extern __checkReturn int
+hunt_nvram_partn_lock(
+ __in efx_nic_t *enp,
+ __in unsigned int partn);
+
+extern __checkReturn int
+hunt_nvram_partn_read(
+ __in efx_nic_t *enp,
+ __in unsigned int partn,
+ __in unsigned int offset,
+ __out_bcount(size) caddr_t data,
+ __in size_t size);
+
+extern __checkReturn int
+hunt_nvram_partn_erase(
+ __in efx_nic_t *enp,
+ __in unsigned int partn,
+ __in unsigned int offset,
+ __in size_t size);
+
+extern __checkReturn int
+hunt_nvram_partn_write(
+ __in efx_nic_t *enp,
+ __in unsigned int partn,
+ __in unsigned int offset,
+ __out_bcount(size) caddr_t data,
+ __in size_t size);
+
+extern void
+hunt_nvram_partn_unlock(
+ __in efx_nic_t *enp,
+ __in unsigned int partn);
+
+#endif /* EFSYS_OPT_NVRAM || EFSYS_OPT_VPD */
+
+#if EFSYS_OPT_NVRAM
+
+#if EFSYS_OPT_DIAG
+
+extern __checkReturn int
+hunt_nvram_test(
+ __in efx_nic_t *enp);
+
+#endif /* EFSYS_OPT_DIAG */
+
+extern __checkReturn int
+hunt_nvram_size(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __out size_t *sizep);
+
+extern __checkReturn int
+hunt_nvram_get_version(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __out uint32_t *subtypep,
+ __out_ecount(4) uint16_t version[4]);
+
+extern __checkReturn int
+hunt_nvram_rw_start(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __out size_t *pref_chunkp);
+
+extern __checkReturn int
+hunt_nvram_read_chunk(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __in unsigned int offset,
+ __out_bcount(size) caddr_t data,
+ __in size_t size);
+
+extern __checkReturn int
+hunt_nvram_erase(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type);
+
+extern __checkReturn int
+hunt_nvram_write_chunk(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __in unsigned int offset,
+ __in_bcount(size) caddr_t data,
+ __in size_t size);
+
+extern void
+hunt_nvram_rw_finish(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type);
+
+extern __checkReturn int
+hunt_nvram_partn_set_version(
+ __in efx_nic_t *enp,
+ __in unsigned int partn,
+ __in_ecount(4) uint16_t version[4]);
+
+extern __checkReturn int
+hunt_nvram_set_version(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __in_ecount(4) uint16_t version[4]);
+
+#endif /* EFSYS_OPT_NVRAM */
+
+
+/* PHY */
+
+typedef struct hunt_link_state_s {
+ uint32_t hls_adv_cap_mask;
+ uint32_t hls_lp_cap_mask;
+ unsigned int hls_fcntl;
+ efx_link_mode_t hls_link_mode;
+#if EFSYS_OPT_LOOPBACK
+ efx_loopback_type_t hls_loopback;
+#endif
+ boolean_t hls_mac_up;
+} hunt_link_state_t;
+
+extern void
+hunt_phy_link_ev(
+ __in efx_nic_t *enp,
+ __in efx_qword_t *eqp,
+ __out efx_link_mode_t *link_modep);
+
+extern __checkReturn int
+hunt_phy_get_link(
+ __in efx_nic_t *enp,
+ __out hunt_link_state_t *hlsp);
+
+extern __checkReturn int
+hunt_phy_power(
+ __in efx_nic_t *enp,
+ __in boolean_t on);
+
+extern __checkReturn int
+hunt_phy_reconfigure(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+hunt_phy_verify(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+hunt_phy_oui_get(
+ __in efx_nic_t *enp,
+ __out uint32_t *ouip);
+
+#if EFSYS_OPT_PHY_STATS
+
+extern __checkReturn int
+hunt_phy_stats_update(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp,
+ __out_ecount(EFX_PHY_NSTATS) uint32_t *stat);
+
+#endif /* EFSYS_OPT_PHY_STATS */
+
+#if EFSYS_OPT_PHY_PROPS
+
+#if EFSYS_OPT_NAMES
+
+extern const char *
+hunt_phy_prop_name(
+ __in efx_nic_t *enp,
+ __in unsigned int id);
+
+#endif /* EFSYS_OPT_NAMES */
+
+extern __checkReturn int
+hunt_phy_prop_get(
+ __in efx_nic_t *enp,
+ __in unsigned int id,
+ __in uint32_t flags,
+ __out uint32_t *valp);
+
+extern __checkReturn int
+hunt_phy_prop_set(
+ __in efx_nic_t *enp,
+ __in unsigned int id,
+ __in uint32_t val);
+
+#endif /* EFSYS_OPT_PHY_PROPS */
+
+#if EFSYS_OPT_BIST
+
+extern __checkReturn int
+hunt_bist_enable_offline(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+hunt_bist_start(
+ __in efx_nic_t *enp,
+ __in efx_bist_type_t type);
+
+extern __checkReturn int
+hunt_bist_poll(
+ __in efx_nic_t *enp,
+ __in efx_bist_type_t type,
+ __out efx_bist_result_t *resultp,
+ __out_opt __drv_when(count > 0, __notnull)
+ uint32_t *value_maskp,
+ __out_ecount_opt(count) __drv_when(count > 0, __notnull)
+ unsigned long *valuesp,
+ __in size_t count);
+
+extern void
+hunt_bist_stop(
+ __in efx_nic_t *enp,
+ __in efx_bist_type_t type);
+
+#endif /* EFSYS_OPT_BIST */
+
+
+/* SRAM */
+
+#if EFSYS_OPT_DIAG
+
+extern __checkReturn int
+hunt_sram_test(
+ __in efx_nic_t *enp,
+ __in efx_sram_pattern_fn_t func);
+
+#endif /* EFSYS_OPT_DIAG */
+
+
+/* TX */
+
+extern __checkReturn int
+hunt_tx_init(
+ __in efx_nic_t *enp);
+
+extern void
+hunt_tx_fini(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+hunt_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,
+ __in efx_txq_t *etp,
+ __out unsigned int *addedp);
+
+extern void
+hunt_tx_qdestroy(
+ __in efx_txq_t *etp);
+
+extern __checkReturn int
+hunt_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 void
+hunt_tx_qpush(
+ __in efx_txq_t *etp,
+ __in unsigned int added,
+ __in unsigned int pushed);
+
+extern __checkReturn int
+hunt_tx_qpace(
+ __in efx_txq_t *etp,
+ __in unsigned int ns);
+
+extern __checkReturn int
+hunt_tx_qflush(
+ __in efx_txq_t *etp);
+
+extern void
+hunt_tx_qenable(
+ __in efx_txq_t *etp);
+
+extern __checkReturn int
+hunt_tx_qpio_enable(
+ __in efx_txq_t *etp);
+
+extern void
+hunt_tx_qpio_disable(
+ __in efx_txq_t *etp);
+
+extern __checkReturn int
+hunt_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 int
+hunt_tx_qpio_post(
+ __in efx_txq_t *etp,
+ __in size_t pkt_length,
+ __in unsigned int completed,
+ __inout unsigned int *addedp);
+
+extern __checkReturn int
+hunt_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
+hunt_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
+hunt_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);
+
+extern void
+hunt_tx_qdesc_vlantci_create(
+ __in efx_txq_t *etp,
+ __in uint16_t vlan_tci,
+ __out efx_desc_t *edp);
+
+
+#if EFSYS_OPT_QSTATS
+
+extern void
+hunt_tx_qstats_update(
+ __in efx_txq_t *etp,
+ __inout_ecount(TX_NQSTATS) efsys_stat_t *stat);
+
+#endif /* EFSYS_OPT_QSTATS */
+
+/* PIO */
+
+/* Missing register definitions */
+#ifndef ER_DZ_TX_PIOBUF_OFST
+#define ER_DZ_TX_PIOBUF_OFST 0x00001000
+#endif
+#ifndef ER_DZ_TX_PIOBUF_STEP
+#define ER_DZ_TX_PIOBUF_STEP 8192
+#endif
+#ifndef ER_DZ_TX_PIOBUF_ROWS
+#define ER_DZ_TX_PIOBUF_ROWS 2048
+#endif
+
+#ifndef ER_DZ_TX_PIOBUF_SIZE
+#define ER_DZ_TX_PIOBUF_SIZE 2048
+#endif
+
+#define HUNT_PIOBUF_NBUFS (16)
+#define HUNT_PIOBUF_SIZE (ER_DZ_TX_PIOBUF_SIZE)
+
+#define HUNT_MIN_PIO_ALLOC_SIZE (HUNT_PIOBUF_SIZE / 32)
+
+typedef uint32_t efx_piobuf_handle_t;
+
+#define EFX_PIOBUF_HANDLE_INVALID ((efx_piobuf_handle_t) -1)
+
+extern __checkReturn int
+hunt_nic_pio_alloc(
+ __inout efx_nic_t *enp,
+ __out uint32_t *bufnump,
+ __out efx_piobuf_handle_t *handlep,
+ __out uint32_t *blknump,
+ __out uint32_t *offsetp,
+ __out size_t *sizep);
+
+extern __checkReturn int
+hunt_nic_pio_free(
+ __inout efx_nic_t *enp,
+ __in uint32_t bufnum,
+ __in uint32_t blknum);
+
+extern __checkReturn int
+hunt_nic_pio_link(
+ __inout efx_nic_t *enp,
+ __in uint32_t vi_index,
+ __in efx_piobuf_handle_t handle);
+
+extern __checkReturn int
+hunt_nic_pio_unlink(
+ __inout efx_nic_t *enp,
+ __in uint32_t vi_index);
+
+
+/* VPD */
+
+#if EFSYS_OPT_VPD
+
+extern __checkReturn int
+hunt_vpd_init(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+hunt_vpd_size(
+ __in efx_nic_t *enp,
+ __out size_t *sizep);
+
+extern __checkReturn int
+hunt_vpd_read(
+ __in efx_nic_t *enp,
+ __out_bcount(size) caddr_t data,
+ __in size_t size);
+
+extern __checkReturn int
+hunt_vpd_verify(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size);
+
+extern __checkReturn int
+hunt_vpd_reinit(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size);
+
+extern __checkReturn int
+hunt_vpd_get(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size,
+ __inout efx_vpd_value_t *evvp);
+
+extern __checkReturn int
+hunt_vpd_set(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size,
+ __in efx_vpd_value_t *evvp);
+
+extern __checkReturn int
+hunt_vpd_next(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size,
+ __out efx_vpd_value_t *evvp,
+ __inout unsigned int *contp);
+
+extern __checkReturn int
+hunt_vpd_write(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size);
+
+extern void
+hunt_vpd_fini(
+ __in efx_nic_t *enp);
+
+#endif /* EFSYS_OPT_VPD */
+
+
+/* RX */
+
+extern __checkReturn int
+hunt_rx_init(
+ __in efx_nic_t *enp);
+
+#if EFSYS_OPT_RX_HDR_SPLIT
+extern __checkReturn int
+hunt_rx_hdr_split_enable(
+ __in efx_nic_t *enp,
+ __in unsigned int hdr_buf_size,
+ __in unsigned int pld_buf_size);
+#endif /* EFSYS_OPT_RX_HDR_SPLIT */
+
+#if EFSYS_OPT_RX_SCATTER
+extern __checkReturn int
+hunt_rx_scatter_enable(
+ __in efx_nic_t *enp,
+ __in unsigned int buf_size);
+#endif /* EFSYS_OPT_RX_SCATTER */
+
+
+#if EFSYS_OPT_RX_SCALE
+
+extern __checkReturn int
+hunt_rx_scale_mode_set(
+ __in efx_nic_t *enp,
+ __in efx_rx_hash_alg_t alg,
+ __in efx_rx_hash_type_t type,
+ __in boolean_t insert);
+
+extern __checkReturn int
+hunt_rx_scale_key_set(
+ __in efx_nic_t *enp,
+ __in_ecount(n) uint8_t *key,
+ __in size_t n);
+
+extern __checkReturn int
+hunt_rx_scale_tbl_set(
+ __in efx_nic_t *enp,
+ __in_ecount(n) unsigned int *table,
+ __in size_t n);
+
+#endif /* EFSYS_OPT_RX_SCALE */
+
+extern void
+hunt_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
+hunt_rx_qpush(
+ __in efx_rxq_t *erp,
+ __in unsigned int added,
+ __inout unsigned int *pushedp);
+
+extern __checkReturn int
+hunt_rx_qflush(
+ __in efx_rxq_t *erp);
+
+extern void
+hunt_rx_qenable(
+ __in efx_rxq_t *erp);
+
+extern __checkReturn int
+hunt_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,
+ __in efx_rxq_t *erp);
+
+extern void
+hunt_rx_qdestroy(
+ __in efx_rxq_t *erp);
+
+extern void
+hunt_rx_fini(
+ __in efx_nic_t *enp);
+
+#if EFSYS_OPT_FILTER
+
+typedef struct hunt_filter_handle_s {
+ uint32_t hfh_lo;
+ uint32_t hfh_hi;
+} hunt_filter_handle_t;
+
+typedef struct hunt_filter_entry_s {
+ uintptr_t hfe_spec; /* pointer to filter spec plus busy bit */
+ hunt_filter_handle_t hfe_handle;
+} hunt_filter_entry_t;
+
+/*
+ * BUSY flag indicates that an update is in progress.
+ * AUTO_OLD flag is used to mark and sweep MAC packet filters.
+ */
+#define EFX_HUNT_FILTER_FLAG_BUSY 1U
+#define EFX_HUNT_FILTER_FLAG_AUTO_OLD 2U
+#define EFX_HUNT_FILTER_FLAGS 3U
+
+#define EFX_HUNT_FILTER_TBL_ROWS 8192
+
+/* Allow for the broadcast address to be added to the multicast list */
+#define EFX_HUNT_FILTER_MULTICAST_FILTERS_MAX (EFX_MAC_MULTICAST_LIST_MAX + 1)
+
+typedef struct hunt_filter_table_s {
+ hunt_filter_entry_t hft_entry[EFX_HUNT_FILTER_TBL_ROWS];
+ efx_rxq_t * hft_default_rxq;
+ boolean_t hft_using_rss;
+ uint32_t hft_unicst_filter_index;
+ boolean_t hft_unicst_filter_set;
+ uint32_t hft_mulcst_filter_indexes[
+ EFX_HUNT_FILTER_MULTICAST_FILTERS_MAX];
+ uint32_t hft_mulcst_filter_count;
+} hunt_filter_table_t;
+
+ __checkReturn int
+hunt_filter_init(
+ __in efx_nic_t *enp);
+
+ void
+hunt_filter_fini(
+ __in efx_nic_t *enp);
+
+ __checkReturn int
+hunt_filter_restore(
+ __in efx_nic_t *enp);
+
+ __checkReturn int
+hunt_filter_add(
+ __in efx_nic_t *enp,
+ __inout efx_filter_spec_t *spec,
+ __in boolean_t may_replace);
+
+ __checkReturn int
+hunt_filter_delete(
+ __in efx_nic_t *enp,
+ __inout efx_filter_spec_t *spec);
+
+extern __checkReturn int
+hunt_filter_supported_filters(
+ __in efx_nic_t *enp,
+ __out uint32_t *list,
+ __out size_t *length);
+
+extern __checkReturn int
+hunt_filter_reconfigure(
+ __in efx_nic_t *enp,
+ __in_ecount(6) uint8_t const *mac_addr,
+ __in boolean_t all_unicst,
+ __in boolean_t mulcst,
+ __in boolean_t all_mulcst,
+ __in boolean_t brdcst,
+ __in_ecount(6*count) uint8_t const *addrs,
+ __in int count);
+
+extern void
+hunt_filter_get_default_rxq(
+ __in efx_nic_t *enp,
+ __out efx_rxq_t **erpp,
+ __out boolean_t *using_rss);
+
+extern void
+hunt_filter_default_rxq_set(
+ __in efx_nic_t *enp,
+ __in efx_rxq_t *erp,
+ __in boolean_t using_rss);
+
+extern void
+hunt_filter_default_rxq_clear(
+ __in efx_nic_t *enp);
+
+
+#endif /* EFSYS_OPT_FILTER */
+
+extern __checkReturn int
+hunt_pktfilter_set(
+ __in efx_nic_t *enp,
+ __in boolean_t unicst,
+ __in boolean_t brdcst);
+
+#if EFSYS_OPT_MCAST_FILTER_LIST
+
+extern __checkReturn int
+hunt_pktfilter_mcast_set(
+ __in efx_nic_t *enp,
+ __in uint8_t const *addrs,
+ __in int count);
+
+#endif /* EFSYS_OPT_MCAST_FILTER_LIST */
+
+extern __checkReturn int
+hunt_pktfilter_mcast_all(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+efx_mcdi_get_function_info(
+ __in efx_nic_t *enp,
+ __out uint32_t *pfp,
+ __out_opt uint32_t *vfp);
+
+extern __checkReturn int
+efx_mcdi_privilege_mask(
+ __in efx_nic_t *enp,
+ __in uint32_t pf,
+ __in uint32_t vf,
+ __out uint32_t *maskp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_HUNT_IMPL_H */
diff --git a/sys/dev/sfxge/common/hunt_intr.c b/sys/dev/sfxge/common/hunt_intr.c
new file mode 100644
index 0000000..b68135c
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_intr.c
@@ -0,0 +1,155 @@
+/*-
+ * Copyright (c) 2012-2015 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_impl.h"
+
+
+#if EFSYS_OPT_HUNTINGTON
+
+ __checkReturn int
+hunt_intr_init(
+ __in efx_nic_t *enp,
+ __in efx_intr_type_t type,
+ __in efsys_mem_t *esmp)
+{
+ _NOTE(ARGUNUSED(enp, type, esmp))
+ return (0);
+}
+
+
+ void
+hunt_intr_enable(
+ __in efx_nic_t *enp)
+{
+ _NOTE(ARGUNUSED(enp))
+}
+
+
+ void
+hunt_intr_disable(
+ __in efx_nic_t *enp)
+{
+ _NOTE(ARGUNUSED(enp))
+}
+
+
+ void
+hunt_intr_disable_unlocked(
+ __in efx_nic_t *enp)
+{
+ _NOTE(ARGUNUSED(enp))
+}
+
+
+static __checkReturn int
+efx_mcdi_trigger_interrupt(
+ __in efx_nic_t *enp,
+ __in unsigned int level)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_TRIGGER_INTERRUPT_IN_LEN,
+ MC_CMD_TRIGGER_INTERRUPT_OUT_LEN)];
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ if (level >= enp->en_nic_cfg.enc_intr_limit) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_TRIGGER_INTERRUPT;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_TRIGGER_INTERRUPT_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_TRIGGER_INTERRUPT_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, TRIGGER_INTERRUPT_IN_INTR_LEVEL, level);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_intr_trigger(
+ __in efx_nic_t *enp,
+ __in unsigned int level)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ int rc;
+
+ if (encp->enc_bug41750_workaround) {
+ /* bug 41750: Test interrupts don't work on Greenport */
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+ if ((rc = efx_mcdi_trigger_interrupt(enp, level)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+ void
+hunt_intr_fini(
+ __in efx_nic_t *enp)
+{
+ _NOTE(ARGUNUSED(enp))
+}
+
+#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_mac.c b/sys/dev/sfxge/common/hunt_mac.c
new file mode 100644
index 0000000..b9f7ca4
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_mac.c
@@ -0,0 +1,685 @@
+/*-
+ * Copyright (c) 2012-2015 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_impl.h"
+
+
+#if EFSYS_OPT_HUNTINGTON
+
+ __checkReturn int
+hunt_mac_poll(
+ __in efx_nic_t *enp,
+ __out efx_link_mode_t *link_modep)
+{
+ /*
+ * TBD: Consider a common Siena/Huntington function. The code is
+ * essentially identical.
+ */
+
+ efx_port_t *epp = &(enp->en_port);
+ hunt_link_state_t hls;
+ int rc;
+
+ if ((rc = hunt_phy_get_link(enp, &hls)) != 0)
+ goto fail1;
+
+ epp->ep_adv_cap_mask = hls.hls_adv_cap_mask;
+ epp->ep_fcntl = hls.hls_fcntl;
+
+ *link_modep = hls.hls_link_mode;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ *link_modep = EFX_LINK_UNKNOWN;
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_mac_up(
+ __in efx_nic_t *enp,
+ __out boolean_t *mac_upp)
+{
+ /*
+ * TBD: Consider a common Siena/Huntington function. The code is
+ * essentially identical.
+ */
+
+ hunt_link_state_t hls;
+ int rc;
+
+ /*
+ * Because Huntington doesn't *require* polling, we can't rely on
+ * hunt_mac_poll() being executed to populate epp->ep_mac_up.
+ */
+ if ((rc = hunt_phy_get_link(enp, &hls)) != 0)
+ goto fail1;
+
+ *mac_upp = hls.hls_mac_up;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+/*
+ * Huntington uses MC_CMD_VADAPTOR_SET_MAC to set the
+ * MAC address; the address field in MC_CMD_SET_MAC has no
+ * effect.
+ * MC_CMD_VADAPTOR_SET_MAC requires mac-spoofing privilege and
+ * the port to have no filters or queues active.
+ */
+static __checkReturn int
+efx_mcdi_vadapter_set_mac(
+ __in efx_nic_t *enp)
+{
+ efx_port_t *epp = &(enp->en_port);
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_VADAPTOR_SET_MAC_IN_LEN,
+ MC_CMD_VADAPTOR_SET_MAC_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_VADAPTOR_SET_MAC;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_VADAPTOR_SET_MAC_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_VADAPTOR_SET_MAC_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, VADAPTOR_SET_MAC_IN_UPSTREAM_PORT_ID,
+ enp->en_vport_id);
+ EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, VADAPTOR_SET_MAC_IN_MACADDR),
+ epp->ep_mac_addr);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_mac_addr_set(
+ __in efx_nic_t *enp)
+{
+ int rc;
+
+ if ((rc = efx_mcdi_vadapter_set_mac(enp)) != 0)
+ goto fail1;
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+__checkReturn int
+hunt_mac_reconfigure(
+ __in efx_nic_t *enp)
+{
+ efx_port_t *epp = &(enp->en_port);
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_SET_MAC_IN_LEN,
+ MC_CMD_SET_MAC_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_SET_MAC;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_SET_MAC_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_SET_MAC_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, SET_MAC_IN_MTU, epp->ep_mac_pdu);
+ MCDI_IN_SET_DWORD(req, SET_MAC_IN_DRAIN, epp->ep_mac_drain ? 1 : 0);
+ EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, SET_MAC_IN_ADDR),
+ epp->ep_mac_addr);
+
+ /*
+ * Note: The Huntington MAC does not support REJECT_BRDCST.
+ * The REJECT_UNCST flag will also prevent multicast traffic
+ * from reaching the filters. As Huntington filters drop any
+ * traffic that does not match a filter it is ok to leave the
+ * MAC running in promiscuous mode. See bug41141.
+ */
+ MCDI_IN_POPULATE_DWORD_2(req, SET_MAC_IN_REJECT,
+ SET_MAC_IN_REJECT_UNCST, 0,
+ SET_MAC_IN_REJECT_BRDCST, 0);
+
+ /*
+ * Flow control, whether it is auto-negotiated or not,
+ * is set via the PHY advertised capabilities. When set to
+ * automatic the MAC will use the PHY settings to determine
+ * the flow control settings.
+ */
+ MCDI_IN_SET_DWORD(req, SET_MAC_IN_FCNTL, MC_CMD_FCNTL_AUTO);
+
+ /* Do not include the Ethernet frame checksum in RX packets */
+ MCDI_IN_POPULATE_DWORD_1(req, SET_MAC_IN_FLAGS,
+ SET_MAC_IN_FLAG_INCLUDE_FCS, 0);
+
+ efx_mcdi_execute_quiet(enp, &req);
+
+ if (req.emr_rc != 0) {
+ /*
+ * Unprivileged functions cannot control link state,
+ * but still need to configure filters.
+ */
+ if (req.emr_rc != EACCES) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+ }
+
+ /*
+ * Apply the filters for the MAC configuration.
+ * If the NIC isn't ready to accept filters this may
+ * return success without setting anything.
+ */
+ rc = efx_filter_reconfigure(enp, epp->ep_mac_addr,
+ epp->ep_all_unicst, epp->ep_mulcst,
+ epp->ep_all_mulcst, epp->ep_brdcst,
+ epp->ep_mulcst_addr_list,
+ epp->ep_mulcst_addr_count);
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_mac_multicast_list_set(
+ __in efx_nic_t *enp)
+{
+ efx_port_t *epp = &(enp->en_port);
+ efx_mac_ops_t *emop = epp->ep_emop;
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ /* FIXME: Insert filters for multicast list */
+
+ if ((rc = emop->emo_reconfigure(enp)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_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);
+ efx_rxq_t *old_rxq;
+ boolean_t old_using_rss;
+ int rc;
+
+ hunt_filter_get_default_rxq(enp, &old_rxq, &old_using_rss);
+
+ hunt_filter_default_rxq_set(enp, erp, using_rss);
+
+ rc = efx_filter_reconfigure(enp, epp->ep_mac_addr,
+ epp->ep_all_unicst, epp->ep_mulcst,
+ epp->ep_all_mulcst, epp->ep_brdcst,
+ epp->ep_mulcst_addr_list,
+ epp->ep_mulcst_addr_count);
+
+ if (rc != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ hunt_filter_default_rxq_set(enp, old_rxq, old_using_rss);
+
+ return (rc);
+}
+
+ void
+hunt_mac_filter_default_rxq_clear(
+ __in efx_nic_t *enp)
+{
+ efx_port_t *epp = &(enp->en_port);
+
+ hunt_filter_default_rxq_clear(enp);
+
+ efx_filter_reconfigure(enp, epp->ep_mac_addr,
+ epp->ep_all_unicst, epp->ep_mulcst,
+ epp->ep_all_mulcst, epp->ep_brdcst,
+ epp->ep_mulcst_addr_list,
+ epp->ep_mulcst_addr_count);
+}
+
+
+#if EFSYS_OPT_LOOPBACK
+
+ __checkReturn int
+hunt_mac_loopback_set(
+ __in efx_nic_t *enp,
+ __in efx_link_mode_t link_mode,
+ __in efx_loopback_type_t loopback_type)
+{
+ /*
+ * TBD: Consider a common Siena/Huntington function. The code is
+ * essentially identical.
+ */
+
+ efx_port_t *epp = &(enp->en_port);
+ efx_phy_ops_t *epop = epp->ep_epop;
+ efx_loopback_type_t old_loopback_type;
+ efx_link_mode_t old_loopback_link_mode;
+ int rc;
+
+ /* The PHY object handles this on Huntington */
+ old_loopback_type = epp->ep_loopback_type;
+ old_loopback_link_mode = epp->ep_loopback_link_mode;
+ epp->ep_loopback_type = loopback_type;
+ epp->ep_loopback_link_mode = link_mode;
+
+ if ((rc = epop->epo_reconfigure(enp)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE(fail2);
+
+ epp->ep_loopback_type = old_loopback_type;
+ epp->ep_loopback_link_mode = old_loopback_link_mode;
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_LOOPBACK */
+
+#if EFSYS_OPT_MAC_STATS
+
+#define HUNT_MAC_STAT_READ(_esmp, _field, _eqp) \
+ EFSYS_MEM_READQ((_esmp), (_field) * sizeof (efx_qword_t), _eqp)
+
+
+ __checkReturn int
+hunt_mac_stats_update(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp,
+ __out_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat,
+ __out_opt uint32_t *generationp)
+{
+ efx_qword_t value;
+ efx_qword_t generation_start;
+ efx_qword_t generation_end;
+
+ _NOTE(ARGUNUSED(enp))
+
+ /* Read END first so we don't race with the MC */
+ EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFX_MAC_STATS_SIZE);
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_END,
+ &generation_end);
+ EFSYS_MEM_READ_BARRIER();
+
+ /* TX */
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_CONTROL_PKTS, &value);
+ EFSYS_STAT_SUBR_QWORD(&(stat[EFX_MAC_TX_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_PAUSE_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_PAUSE_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_UNICAST_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_UNICST_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTICAST_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULTICST_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BROADCAST_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_BRDCST_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BYTES, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_OCTETS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LT64_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_64_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_65_TO_127_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_65_TO_127_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_128_TO_255_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_128_TO_255_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_256_TO_511_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_256_TO_511_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_512_TO_1023_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_512_TO_1023_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_1024_TO_15XX_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_1024_TO_15XX_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value);
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_GTJUMBO_PKTS, &value);
+ EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_GE_15XX_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_BAD_FCS_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_ERRORS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_SGL_COL_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_MULT_COL_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_COL_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LATE_COLLISION_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LATE_COL_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_DEFERRED_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_DEF_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_DEF_PKTS]), &value);
+
+ /* RX */
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BYTES, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_OCTETS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNICAST_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_UNICST_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MULTICAST_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MULTICST_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BROADCAST_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_BRDCST_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PAUSE_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PAUSE_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_UNDERSIZE_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value);
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_64_PKTS, &value);
+ EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_LE_64_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_65_TO_127_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_65_TO_127_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_128_TO_255_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_128_TO_255_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_256_TO_511_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_256_TO_511_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_512_TO_1023_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_512_TO_1023_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_1024_TO_15XX_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_1024_TO_15XX_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value);
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_GTJUMBO_PKTS, &value);
+ EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_RX_GE_15XX_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BAD_FCS_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FCS_ERRORS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_OVERFLOW_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_DROP_EVENTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_FALSE_CARRIER_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_FALSE_CARRIER_ERRORS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_SYMBOL_ERRORS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_ALIGN_ERROR_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_ALIGN_ERRORS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_INTERNAL_ERRORS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_JABBER_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_JABBER_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_CHAR_ERR, &value);
+ EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_CHAR_ERR]),
+ &(value.eq_dword[0]));
+ EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_CHAR_ERR]),
+ &(value.eq_dword[1]));
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_CHAR_ERR, &value);
+ EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_CHAR_ERR]),
+ &(value.eq_dword[0]));
+ EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_CHAR_ERR]),
+ &(value.eq_dword[1]));
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES01_DISP_ERR, &value);
+ EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE0_DISP_ERR]),
+ &(value.eq_dword[0]));
+ EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE1_DISP_ERR]),
+ &(value.eq_dword[1]));
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_LANES23_DISP_ERR, &value);
+ EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE2_DISP_ERR]),
+ &(value.eq_dword[0]));
+ EFSYS_STAT_SET_DWORD(&(stat[EFX_MAC_RX_LANE3_DISP_ERR]),
+ &(value.eq_dword[1]));
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_MATCH_FAULT, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_MATCH_FAULT]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_NODESC_DROPS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_NODESC_DROP_CNT]), &value);
+
+ /* Packet memory (EF10 only) */
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_TRUNC_BB_OVERFLOW, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_TRUNC_BB_OVERFLOW]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_BB_OVERFLOW, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_BB_OVERFLOW]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_TRUNC_VFIFO_FULL, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_TRUNC_VFIFO_FULL]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_VFIFO_FULL, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_VFIFO_FULL]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_TRUNC_QBB, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_TRUNC_QBB]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_QBB, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_QBB]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_PM_DISCARD_MAPPING, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_PM_DISCARD_MAPPING]), &value);
+
+ /* RX datapath */
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_Q_DISABLED_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_Q_DISABLED_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_DI_DROPPED_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_DI_DROPPED_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_STREAMING_PKTS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_STREAMING_PKTS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_HLB_FETCH_CONDITIONS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_HLB_FETCH]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_RXDP_HLB_WAIT_CONDITIONS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RXDP_HLB_WAIT]), &value);
+
+
+ /* VADAPTER RX */
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_UNICAST_PACKETS,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_UNICAST_PACKETS]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_UNICAST_BYTES,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_UNICAST_BYTES]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_MULTICAST_PACKETS,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_MULTICAST_PACKETS]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_MULTICAST_BYTES,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_MULTICAST_BYTES]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BROADCAST_PACKETS,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BROADCAST_PACKETS]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BROADCAST_BYTES,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BROADCAST_BYTES]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BAD_PACKETS,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BAD_PACKETS]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_BAD_BYTES, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_BAD_BYTES]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_RX_OVERFLOW, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_RX_OVERFLOW]), &value);
+
+ /* VADAPTER TX */
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_UNICAST_PACKETS,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_UNICAST_PACKETS]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_UNICAST_BYTES,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_UNICAST_BYTES]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_MULTICAST_PACKETS,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_MULTICAST_PACKETS]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_MULTICAST_BYTES,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_MULTICAST_BYTES]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BROADCAST_PACKETS,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BROADCAST_PACKETS]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BROADCAST_BYTES,
+ &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BROADCAST_BYTES]),
+ &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BAD_PACKETS, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BAD_PACKETS]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_BAD_BYTES, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_BAD_BYTES]), &value);
+
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_VADAPTER_TX_OVERFLOW, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_VADAPTER_TX_OVERFLOW]), &value);
+
+
+ EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFX_MAC_STATS_SIZE);
+ EFSYS_MEM_READ_BARRIER();
+ HUNT_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_START,
+ &generation_start);
+
+ /* Check that we didn't read the stats in the middle of a DMA */
+ /* Not a good enough check ? */
+ if (memcmp(&generation_start, &generation_end,
+ sizeof (generation_start)))
+ return (EAGAIN);
+
+ if (generationp)
+ *generationp = EFX_QWORD_FIELD(generation_start, EFX_DWORD_0);
+
+ return (0);
+}
+
+#endif /* EFSYS_OPT_MAC_STATS */
+
+#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_mcdi.c b/sys/dev/sfxge/common/hunt_mcdi.c
new file mode 100644
index 0000000..8782bcc
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_mcdi.c
@@ -0,0 +1,465 @@
+/*-
+ * Copyright (c) 2012-2015 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_impl.h"
+
+
+#if EFSYS_OPT_HUNTINGTON
+
+#if EFSYS_OPT_MCDI
+
+#ifndef WITH_MCDI_V2
+#error "WITH_MCDI_V2 required for Huntington MCDIv2 commands."
+#endif
+
+typedef enum efx_mcdi_header_type_e {
+ EFX_MCDI_HEADER_TYPE_V1, /* MCDIv0 (BootROM), MCDIv1 commands */
+ EFX_MCDI_HEADER_TYPE_V2, /* MCDIv2 commands */
+} efx_mcdi_header_type_t;
+
+/*
+ * Return the header format to use for sending an MCDI request.
+ *
+ * An MCDIv1 (Siena compatible) command should use MCDIv2 encapsulation if the
+ * request input buffer or response output buffer are too large for the MCDIv1
+ * format. An MCDIv2 command must always be sent using MCDIv2 encapsulation.
+ */
+#define EFX_MCDI_HEADER_TYPE(_cmd, _length) \
+ ((((_cmd) & ~EFX_MASK32(MCDI_HEADER_CODE)) || \
+ ((_length) & ~EFX_MASK32(MCDI_HEADER_DATALEN))) ? \
+ EFX_MCDI_HEADER_TYPE_V2 : EFX_MCDI_HEADER_TYPE_V1)
+
+
+/*
+ * MCDI Header NOT_EPOCH flag
+ * ==========================
+ * A new epoch begins at initial startup or after an MC reboot, and defines when
+ * the MC should reject stale MCDI requests.
+ *
+ * The first MCDI request sent by the host should contain NOT_EPOCH=0, and all
+ * subsequent requests (until the next MC reboot) should contain NOT_EPOCH=1.
+ *
+ * After rebooting the MC will fail all requests with NOT_EPOCH=1 by writing a
+ * response with ERROR=1 and DATALEN=0 until a request is seen with NOT_EPOCH=0.
+ */
+
+
+ __checkReturn int
+hunt_mcdi_init(
+ __in efx_nic_t *enp,
+ __in const efx_mcdi_transport_t *emtp)
+{
+ efsys_mem_t *esmp = emtp->emt_dma_mem;
+ efx_dword_t dword;
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+ EFSYS_ASSERT(enp->en_features & EFX_FEATURE_MCDI_DMA);
+
+ /* A host DMA buffer is required for Huntington MCDI */
+ if (esmp == NULL) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ /*
+ * Ensure that the MC doorbell is in a known state before issuing MCDI
+ * commands. The recovery algorithm requires that the MC command buffer
+ * must be 256 byte aligned. See bug24769.
+ */
+ if ((EFSYS_MEM_ADDR(esmp) & 0xFF) != 0) {
+ rc = EINVAL;
+ goto fail2;
+ }
+ EFX_POPULATE_DWORD_1(dword, EFX_DWORD_0, 1);
+ EFX_BAR_WRITED(enp, ER_DZ_MC_DB_HWRD_REG, &dword, B_FALSE);
+
+ /* Save initial MC reboot status */
+ (void) hunt_mcdi_poll_reboot(enp);
+
+ /* Start a new epoch (allow fresh MCDI requests to succeed) */
+ efx_mcdi_new_epoch(enp);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_mcdi_fini(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+
+ emip->emi_new_epoch = B_FALSE;
+}
+
+ void
+hunt_mcdi_request_copyin(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp,
+ __in unsigned int seq,
+ __in boolean_t ev_cpl,
+ __in boolean_t new_epoch)
+{
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+ efsys_mem_t *esmp = emtp->emt_dma_mem;
+ efx_mcdi_header_type_t hdr_type;
+ efx_dword_t dword;
+ unsigned int xflags;
+ unsigned int pos;
+ size_t offset;
+
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
+
+ xflags = 0;
+ if (ev_cpl)
+ xflags |= MCDI_HEADER_XFLAGS_EVREQ;
+
+ offset = 0;
+
+ hdr_type = EFX_MCDI_HEADER_TYPE(emrp->emr_cmd,
+ MAX(emrp->emr_in_length, emrp->emr_out_length));
+
+ if (hdr_type == EFX_MCDI_HEADER_TYPE_V2) {
+ /* Construct MCDI v2 header */
+ EFX_POPULATE_DWORD_8(dword,
+ MCDI_HEADER_CODE, MC_CMD_V2_EXTN,
+ MCDI_HEADER_RESYNC, 1,
+ MCDI_HEADER_DATALEN, 0,
+ MCDI_HEADER_SEQ, seq,
+ MCDI_HEADER_NOT_EPOCH, new_epoch ? 0 : 1,
+ MCDI_HEADER_ERROR, 0,
+ MCDI_HEADER_RESPONSE, 0,
+ MCDI_HEADER_XFLAGS, xflags);
+ EFSYS_MEM_WRITED(esmp, offset, &dword);
+ offset += sizeof (dword);
+
+ EFX_POPULATE_DWORD_2(dword,
+ MC_CMD_V2_EXTN_IN_EXTENDED_CMD, emrp->emr_cmd,
+ MC_CMD_V2_EXTN_IN_ACTUAL_LEN, emrp->emr_in_length);
+ EFSYS_MEM_WRITED(esmp, offset, &dword);
+ offset += sizeof (dword);
+ } else {
+ /* Construct MCDI v1 header */
+ EFX_POPULATE_DWORD_8(dword,
+ MCDI_HEADER_CODE, emrp->emr_cmd,
+ MCDI_HEADER_RESYNC, 1,
+ MCDI_HEADER_DATALEN, emrp->emr_in_length,
+ MCDI_HEADER_SEQ, seq,
+ MCDI_HEADER_NOT_EPOCH, new_epoch ? 0 : 1,
+ MCDI_HEADER_ERROR, 0,
+ MCDI_HEADER_RESPONSE, 0,
+ MCDI_HEADER_XFLAGS, xflags);
+ EFSYS_MEM_WRITED(esmp, offset, &dword);
+ offset += sizeof (dword);
+ }
+
+ /* Construct the payload */
+ for (pos = 0; pos < emrp->emr_in_length; pos += sizeof (efx_dword_t)) {
+ memcpy(&dword, MCDI_IN(*emrp, efx_dword_t, pos),
+ MIN(sizeof (dword), emrp->emr_in_length - pos));
+ EFSYS_MEM_WRITED(esmp, offset + pos, &dword);
+ }
+
+ /* Ring the doorbell to post the command DMA address to the MC */
+ EFSYS_ASSERT((EFSYS_MEM_ADDR(esmp) & 0xFF) == 0);
+
+ /* Guarantee ordering of memory (MCDI request) and PIO (MC doorbell) */
+ EFSYS_DMA_SYNC_FOR_DEVICE(esmp, 0, offset + emrp->emr_in_length);
+ EFSYS_PIO_WRITE_BARRIER();
+
+ EFX_POPULATE_DWORD_1(dword,
+ EFX_DWORD_0, EFSYS_MEM_ADDR(esmp) >> 32);
+ EFX_BAR_WRITED(enp, ER_DZ_MC_DB_LWRD_REG, &dword, B_FALSE);
+
+ EFX_POPULATE_DWORD_1(dword,
+ EFX_DWORD_0, EFSYS_MEM_ADDR(esmp) & 0xffffffff);
+ EFX_BAR_WRITED(enp, ER_DZ_MC_DB_HWRD_REG, &dword, B_FALSE);
+}
+
+ void
+hunt_mcdi_request_copyout(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp)
+{
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+ efsys_mem_t *esmp = emtp->emt_dma_mem;
+ unsigned int pos;
+ unsigned int offset;
+ efx_dword_t hdr;
+ efx_dword_t hdr2;
+ efx_dword_t data;
+ size_t bytes;
+
+ if (emrp->emr_out_buf == NULL)
+ return;
+
+ /* Read the command header to detect MCDI response format */
+ EFSYS_MEM_READD(esmp, 0, &hdr);
+ if (EFX_DWORD_FIELD(hdr, MCDI_HEADER_CODE) == MC_CMD_V2_EXTN) {
+ offset = 2 * sizeof (efx_dword_t);
+
+ /*
+ * Read the actual payload length. The length given in the event
+ * is only correct for responses with the V1 format.
+ */
+ EFSYS_MEM_READD(esmp, sizeof (efx_dword_t), &hdr2);
+ emrp->emr_out_length_used = EFX_DWORD_FIELD(hdr2,
+ MC_CMD_V2_EXTN_IN_ACTUAL_LEN);
+ } else {
+ offset = sizeof (efx_dword_t);
+ }
+
+ /* Copy payload out into caller supplied buffer */
+ bytes = MIN(emrp->emr_out_length_used, emrp->emr_out_length);
+ for (pos = 0; pos < bytes; pos += sizeof (efx_dword_t)) {
+ EFSYS_MEM_READD(esmp, offset + pos, &data);
+ memcpy(MCDI_OUT(*emrp, efx_dword_t, pos), &data,
+ MIN(sizeof (data), bytes - pos));
+ }
+}
+
+ __checkReturn boolean_t
+hunt_mcdi_request_poll(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ const efx_mcdi_transport_t *emtp = enp->en_mcdi.em_emtp;
+ efsys_mem_t *esmp = emtp->emt_dma_mem;
+ efx_mcdi_req_t *emrp;
+ efx_dword_t dword;
+ unsigned int seq;
+ unsigned int cmd;
+ unsigned int length;
+ size_t offset;
+ int state;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
+
+ /* Serialise against post-watchdog efx_mcdi_ev* */
+ EFSYS_LOCK(enp->en_eslp, state);
+
+ EFSYS_ASSERT(emip->emi_pending_req != NULL);
+ EFSYS_ASSERT(!emip->emi_ev_cpl);
+ emrp = emip->emi_pending_req;
+
+ offset = 0;
+
+ /* Read the command header */
+ EFSYS_MEM_READD(esmp, offset, &dword);
+ offset += sizeof (efx_dword_t);
+ if (EFX_DWORD_FIELD(dword, MCDI_HEADER_RESPONSE) == 0) {
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ return (B_FALSE);
+ }
+ if (EFX_DWORD_FIELD(dword, MCDI_HEADER_CODE) == MC_CMD_V2_EXTN) {
+ efx_dword_t dword2;
+
+ EFSYS_MEM_READD(esmp, offset, &dword2);
+ offset += sizeof (efx_dword_t);
+
+ cmd = EFX_DWORD_FIELD(dword2, MC_CMD_V2_EXTN_IN_EXTENDED_CMD);
+ length = EFX_DWORD_FIELD(dword2, MC_CMD_V2_EXTN_IN_ACTUAL_LEN);
+ } else {
+ cmd = EFX_DWORD_FIELD(dword, MCDI_HEADER_CODE);
+ length = EFX_DWORD_FIELD(dword, MCDI_HEADER_DATALEN);
+ }
+
+ /* Request complete */
+ emip->emi_pending_req = NULL;
+ seq = (emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ);
+
+ /* Check for synchronous reboot */
+ if (EFX_DWORD_FIELD(dword, MCDI_HEADER_ERROR) != 0 && length == 0) {
+ /* The MC has rebooted since the request was sent. */
+ EFSYS_SPIN(EFX_MCDI_STATUS_SLEEP_US);
+ hunt_mcdi_poll_reboot(enp);
+
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ rc = EIO;
+ goto fail1;
+ }
+
+ /* Ensure stale MCDI requests fail after an MC reboot. */
+ emip->emi_new_epoch = B_FALSE;
+
+ EFSYS_UNLOCK(enp->en_eslp, state);
+
+ /* Check that the returned data is consistent */
+ if (cmd != emrp->emr_cmd ||
+ EFX_DWORD_FIELD(dword, MCDI_HEADER_SEQ) != seq) {
+ /* Response is for a different request */
+ rc = EIO;
+ goto fail2;
+ }
+ if (EFX_DWORD_FIELD(dword, MCDI_HEADER_ERROR)) {
+ efx_dword_t errdword;
+ int errcode;
+ int argnum;
+
+ /* Read error code (and arg num for MCDI v2 commands) */
+ EFSYS_MEM_READD(esmp, offset + MC_CMD_ERR_CODE_OFST, &errdword);
+ errcode = EFX_DWORD_FIELD(errdword, EFX_DWORD_0);
+
+ EFSYS_MEM_READD(esmp, offset + MC_CMD_ERR_ARG_OFST, &errdword);
+ argnum = EFX_DWORD_FIELD(errdword, EFX_DWORD_0);
+
+ rc = efx_mcdi_request_errcode(errcode);
+ if (!emrp->emr_quiet) {
+ EFSYS_PROBE3(mcdi_err_arg, int, emrp->emr_cmd,
+ int, errcode, int, argnum);
+ }
+ goto fail3;
+
+ } else {
+ emrp->emr_out_length_used = length;
+ emrp->emr_rc = 0;
+ hunt_mcdi_request_copyout(enp, emrp);
+ }
+
+ goto out;
+
+fail3:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE(fail3);
+fail2:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE(fail2);
+fail1:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE1(fail1, int, rc);
+
+ /* Fill out error state */
+ emrp->emr_rc = rc;
+ emrp->emr_out_length_used = 0;
+
+ /* Reboot/Assertion */
+ if (rc == EIO || rc == EINTR)
+ efx_mcdi_raise_exception(enp, emrp, rc);
+
+out:
+ return (B_TRUE);
+}
+
+ int
+hunt_mcdi_poll_reboot(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_dword_t dword;
+ uint32_t old_status;
+ uint32_t new_status;
+ int rc;
+
+ old_status = emip->emi_mc_reboot_status;
+
+ /* Update MC reboot status word */
+ EFX_BAR_TBL_READD(enp, ER_DZ_BIU_MC_SFT_STATUS_REG, 0, &dword, B_FALSE);
+ new_status = dword.ed_u32[0];
+
+ /* MC has rebooted if the value has changed */
+ if (new_status != old_status) {
+ emip->emi_mc_reboot_status = new_status;
+
+ /*
+ * FIXME: Ignore detected MC REBOOT for now.
+ *
+ * The Siena support for checking for MC reboot from status
+ * flags is broken - see comments in siena_mcdi_poll_reboot().
+ * As the generic MCDI code is shared the Huntington reboot
+ * detection suffers similar problems.
+ *
+ * Do not report an error when the boot status changes until
+ * this can be handled by common code drivers (and reworked to
+ * support Siena too).
+ */
+ if (B_FALSE) {
+ rc = EIO;
+ goto fail1;
+ }
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_mcdi_fw_update_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
+
+ /* use privilege mask state at MCDI attach */
+ *supportedp = (encp->enc_privilege_mask &
+ MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN)
+ == MC_CMD_PRIVILEGE_MASK_IN_GRP_ADMIN;
+
+ return (0);
+}
+
+ __checkReturn int
+hunt_mcdi_macaddr_change_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
+
+ /* use privilege mask state at MCDI attach */
+ *supportedp = (encp->enc_privilege_mask &
+ MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING)
+ == MC_CMD_PRIVILEGE_MASK_IN_GRP_MAC_SPOOFING;
+
+ return (0);
+}
+
+#endif /* EFSYS_OPT_MCDI */
+
+#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_nic.c b/sys/dev/sfxge/common/hunt_nic.c
new file mode 100644
index 0000000..a4babc3
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_nic.c
@@ -0,0 +1,1741 @@
+/*-
+ * Copyright (c) 2012-2015 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_impl.h"
+#include "mcdi_mon.h"
+
+#if EFSYS_OPT_HUNTINGTON
+
+#include "ef10_tlv_layout.h"
+
+static __checkReturn int
+efx_mcdi_get_port_assignment(
+ __in efx_nic_t *enp,
+ __out uint32_t *portp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN,
+ MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN)];
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_PORT_ASSIGNMENT;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_PORT_ASSIGNMENT_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_PORT_ASSIGNMENT_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ *portp = MCDI_OUT_DWORD(req, GET_PORT_ASSIGNMENT_OUT_PORT);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_get_port_modes(
+ __in efx_nic_t *enp,
+ __out uint32_t *modesp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_PORT_MODES_IN_LEN,
+ MC_CMD_GET_PORT_MODES_OUT_LEN)];
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_PORT_MODES;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_PORT_MODES_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_PORT_MODES_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ /* Accept pre-Medford size (8 bytes - no CurrentMode field) */
+ if (req.emr_out_length_used <
+ MC_CMD_GET_PORT_MODES_OUT_CURRENT_MODE_OFST) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ *modesp = MCDI_OUT_DWORD(req, GET_PORT_MODES_OUT_MODES);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+static __checkReturn int
+efx_mcdi_vadaptor_alloc(
+ __in efx_nic_t *enp,
+ __in uint32_t port_id)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_VADAPTOR_ALLOC_IN_LEN,
+ MC_CMD_VADAPTOR_ALLOC_OUT_LEN)];
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_vport_id, ==, EVB_PORT_ID_NULL);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_VADAPTOR_ALLOC;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_VADAPTOR_ALLOC_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_VADAPTOR_ALLOC_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, VADAPTOR_ALLOC_IN_UPSTREAM_PORT_ID, port_id);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_vadaptor_free(
+ __in efx_nic_t *enp,
+ __in uint32_t port_id)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_VADAPTOR_FREE_IN_LEN,
+ MC_CMD_VADAPTOR_FREE_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_VADAPTOR_FREE;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_VADAPTOR_FREE_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_VADAPTOR_FREE_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, VADAPTOR_FREE_IN_UPSTREAM_PORT_ID, port_id);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_get_mac_address_pf(
+ __in efx_nic_t *enp,
+ __out_ecount_opt(6) uint8_t mac_addrp[6])
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_MAC_ADDRESSES_IN_LEN,
+ MC_CMD_GET_MAC_ADDRESSES_OUT_LEN)];
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_MAC_ADDRESSES;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_MAC_ADDRESSES_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_MAC_ADDRESSES_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_MAC_ADDRESSES_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ if (MCDI_OUT_DWORD(req, GET_MAC_ADDRESSES_OUT_MAC_COUNT) < 1) {
+ rc = ENOENT;
+ goto fail3;
+ }
+
+ if (mac_addrp != NULL) {
+ uint8_t *addrp;
+
+ addrp = MCDI_OUT2(req, uint8_t,
+ GET_MAC_ADDRESSES_OUT_MAC_ADDR_BASE);
+
+ EFX_MAC_ADDR_COPY(mac_addrp, addrp);
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_get_mac_address_vf(
+ __in efx_nic_t *enp,
+ __out_ecount_opt(6) uint8_t mac_addrp[6])
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN,
+ MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX)];
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_VPORT_GET_MAC_ADDRESSES;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMAX;
+
+ MCDI_IN_SET_DWORD(req, VPORT_GET_MAC_ADDRESSES_IN_VPORT_ID,
+ EVB_PORT_ID_ASSIGNED);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used <
+ MC_CMD_VPORT_GET_MAC_ADDRESSES_OUT_LENMIN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ if (MCDI_OUT_DWORD(req,
+ VPORT_GET_MAC_ADDRESSES_OUT_MACADDR_COUNT) < 1) {
+ rc = ENOENT;
+ goto fail3;
+ }
+
+ if (mac_addrp != NULL) {
+ uint8_t *addrp;
+
+ addrp = MCDI_OUT2(req, uint8_t,
+ VPORT_GET_MAC_ADDRESSES_OUT_MACADDR);
+
+ EFX_MAC_ADDR_COPY(mac_addrp, addrp);
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_get_clock(
+ __in efx_nic_t *enp,
+ __out uint32_t *sys_freqp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_CLOCK_IN_LEN,
+ MC_CMD_GET_CLOCK_OUT_LEN)];
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_CLOCK;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_CLOCK_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_CLOCK_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_CLOCK_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ *sys_freqp = MCDI_OUT_DWORD(req, GET_CLOCK_OUT_SYS_FREQ);
+ if (*sys_freqp == 0) {
+ rc = EINVAL;
+ goto fail3;
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_get_vector_cfg(
+ __in efx_nic_t *enp,
+ __out_opt uint32_t *vec_basep,
+ __out_opt uint32_t *pf_nvecp,
+ __out_opt uint32_t *vf_nvecp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_VECTOR_CFG_IN_LEN,
+ MC_CMD_GET_VECTOR_CFG_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_VECTOR_CFG;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_VECTOR_CFG_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_VECTOR_CFG_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_VECTOR_CFG_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ if (vec_basep != NULL)
+ *vec_basep = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VEC_BASE);
+ if (pf_nvecp != NULL)
+ *pf_nvecp = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VECS_PER_PF);
+ if (vf_nvecp != NULL)
+ *vf_nvecp = MCDI_OUT_DWORD(req, GET_VECTOR_CFG_OUT_VECS_PER_VF);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_get_capabilities(
+ __in efx_nic_t *enp,
+ __out efx_dword_t *flagsp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_CAPABILITIES_IN_LEN,
+ MC_CMD_GET_CAPABILITIES_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_CAPABILITIES;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_CAPABILITIES_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_CAPABILITIES_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_CAPABILITIES_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ *flagsp = *MCDI_OUT2(req, efx_dword_t, GET_CAPABILITIES_OUT_FLAGS1);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+static __checkReturn int
+efx_mcdi_alloc_vis(
+ __in efx_nic_t *enp,
+ __in uint32_t min_vi_count,
+ __in uint32_t max_vi_count,
+ __out_opt uint32_t *vi_basep,
+ __out uint32_t *vi_countp)
+
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_ALLOC_VIS_IN_LEN,
+ MC_CMD_ALLOC_VIS_OUT_LEN)];
+ int rc;
+
+ if (vi_countp == NULL) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_ALLOC_VIS;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_ALLOC_VIS_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_ALLOC_VIS_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, ALLOC_VIS_IN_MIN_VI_COUNT, min_vi_count);
+ MCDI_IN_SET_DWORD(req, ALLOC_VIS_IN_MAX_VI_COUNT, max_vi_count);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_ALLOC_VIS_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail3;
+ }
+
+ if (vi_basep != NULL)
+ *vi_basep = MCDI_OUT_DWORD(req, ALLOC_VIS_OUT_VI_BASE);
+
+ if (vi_countp != NULL)
+ *vi_countp = MCDI_OUT_DWORD(req, ALLOC_VIS_OUT_VI_COUNT);
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+static __checkReturn int
+efx_mcdi_free_vis(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_req_t req;
+ int rc;
+
+ EFX_STATIC_ASSERT(MC_CMD_FREE_VIS_IN_LEN == 0);
+ EFX_STATIC_ASSERT(MC_CMD_FREE_VIS_OUT_LEN == 0);
+
+ req.emr_cmd = MC_CMD_FREE_VIS;
+ req.emr_in_buf = NULL;
+ req.emr_in_length = 0;
+ req.emr_out_buf = NULL;
+ req.emr_out_length = 0;
+
+ efx_mcdi_execute_quiet(enp, &req);
+
+ /* Ignore ELREADY (no allocated VIs, so nothing to free) */
+ if ((req.emr_rc != 0) && (req.emr_rc != EALREADY)) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+static __checkReturn int
+efx_mcdi_alloc_piobuf(
+ __in efx_nic_t *enp,
+ __out efx_piobuf_handle_t *handlep)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_ALLOC_PIOBUF_IN_LEN,
+ MC_CMD_ALLOC_PIOBUF_OUT_LEN)];
+ int rc;
+
+ if (handlep == NULL) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_ALLOC_PIOBUF;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_ALLOC_PIOBUF_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_ALLOC_PIOBUF_OUT_LEN;
+
+ efx_mcdi_execute_quiet(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_ALLOC_PIOBUF_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail3;
+ }
+
+ *handlep = MCDI_OUT_DWORD(req, ALLOC_PIOBUF_OUT_PIOBUF_HANDLE);
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_free_piobuf(
+ __in efx_nic_t *enp,
+ __out efx_piobuf_handle_t handle)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_FREE_PIOBUF_IN_LEN,
+ MC_CMD_FREE_PIOBUF_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_FREE_PIOBUF;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_FREE_PIOBUF_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_FREE_PIOBUF_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, FREE_PIOBUF_IN_PIOBUF_HANDLE, handle);
+
+ efx_mcdi_execute_quiet(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_link_piobuf(
+ __in efx_nic_t *enp,
+ __in uint32_t vi_index,
+ __in efx_piobuf_handle_t handle)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_LINK_PIOBUF_IN_LEN,
+ MC_CMD_LINK_PIOBUF_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_LINK_PIOBUF;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_LINK_PIOBUF_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_LINK_PIOBUF_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, LINK_PIOBUF_IN_PIOBUF_HANDLE, handle);
+ MCDI_IN_SET_DWORD(req, LINK_PIOBUF_IN_TXQ_INSTANCE, vi_index);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_unlink_piobuf(
+ __in efx_nic_t *enp,
+ __in uint32_t vi_index)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_UNLINK_PIOBUF_IN_LEN,
+ MC_CMD_UNLINK_PIOBUF_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_UNLINK_PIOBUF;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_UNLINK_PIOBUF_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_UNLINK_PIOBUF_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, UNLINK_PIOBUF_IN_TXQ_INSTANCE, vi_index);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static void
+hunt_nic_alloc_piobufs(
+ __in efx_nic_t *enp,
+ __in uint32_t max_piobuf_count)
+{
+ efx_piobuf_handle_t *handlep;
+ unsigned int i;
+ int rc;
+
+ EFSYS_ASSERT3U(max_piobuf_count, <=,
+ EFX_ARRAY_SIZE(enp->en_u.hunt.enu_piobuf_handle));
+
+ enp->en_u.hunt.enu_piobuf_count = 0;
+
+ for (i = 0; i < max_piobuf_count; i++) {
+ handlep = &enp->en_u.hunt.enu_piobuf_handle[i];
+
+ if ((rc = efx_mcdi_alloc_piobuf(enp, handlep)) != 0)
+ goto fail1;
+
+ enp->en_u.hunt.enu_pio_alloc_map[i] = 0;
+ enp->en_u.hunt.enu_piobuf_count++;
+ }
+
+ return;
+
+fail1:
+ for (i = 0; i < enp->en_u.hunt.enu_piobuf_count; i++) {
+ handlep = &enp->en_u.hunt.enu_piobuf_handle[i];
+
+ efx_mcdi_free_piobuf(enp, *handlep);
+ *handlep = EFX_PIOBUF_HANDLE_INVALID;
+ }
+ enp->en_u.hunt.enu_piobuf_count = 0;
+}
+
+
+static void
+hunt_nic_free_piobufs(
+ __in efx_nic_t *enp)
+{
+ efx_piobuf_handle_t *handlep;
+ unsigned int i;
+
+ for (i = 0; i < enp->en_u.hunt.enu_piobuf_count; i++) {
+ handlep = &enp->en_u.hunt.enu_piobuf_handle[i];
+
+ efx_mcdi_free_piobuf(enp, *handlep);
+ *handlep = EFX_PIOBUF_HANDLE_INVALID;
+ }
+ enp->en_u.hunt.enu_piobuf_count = 0;
+}
+
+/* Sub-allocate a block from a piobuf */
+ __checkReturn int
+hunt_nic_pio_alloc(
+ __inout efx_nic_t *enp,
+ __out uint32_t *bufnump,
+ __out efx_piobuf_handle_t *handlep,
+ __out uint32_t *blknump,
+ __out uint32_t *offsetp,
+ __out size_t *sizep)
+{
+ efx_drv_cfg_t *edcp = &enp->en_drv_cfg;
+ uint32_t blk_per_buf;
+ uint32_t buf, blk;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
+ EFSYS_ASSERT(bufnump);
+ EFSYS_ASSERT(handlep);
+ EFSYS_ASSERT(blknump);
+ EFSYS_ASSERT(offsetp);
+ EFSYS_ASSERT(sizep);
+
+ if ((edcp->edc_pio_alloc_size == 0) ||
+ (enp->en_u.hunt.enu_piobuf_count == 0)) {
+ rc = ENOMEM;
+ goto fail1;
+ }
+ blk_per_buf = HUNT_PIOBUF_SIZE / edcp->edc_pio_alloc_size;
+
+ for (buf = 0; buf < enp->en_u.hunt.enu_piobuf_count; buf++) {
+ uint32_t *map = &enp->en_u.hunt.enu_pio_alloc_map[buf];
+
+ if (~(*map) == 0)
+ continue;
+
+ EFSYS_ASSERT3U(blk_per_buf, <=, (8 * sizeof (*map)));
+ for (blk = 0; blk < blk_per_buf; blk++) {
+ if ((*map & (1u << blk)) == 0) {
+ *map |= (1u << blk);
+ goto done;
+ }
+ }
+ }
+ rc = ENOMEM;
+ goto fail2;
+
+done:
+ *handlep = enp->en_u.hunt.enu_piobuf_handle[buf];
+ *bufnump = buf;
+ *blknump = blk;
+ *sizep = edcp->edc_pio_alloc_size;
+ *offsetp = blk * (*sizep);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+/* Free a piobuf sub-allocated block */
+ __checkReturn int
+hunt_nic_pio_free(
+ __inout efx_nic_t *enp,
+ __in uint32_t bufnum,
+ __in uint32_t blknum)
+{
+ uint32_t *map;
+ int rc;
+
+ if ((bufnum >= enp->en_u.hunt.enu_piobuf_count) ||
+ (blknum >= (8 * sizeof (*map)))) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ map = &enp->en_u.hunt.enu_pio_alloc_map[bufnum];
+ if ((*map & (1u << blknum)) == 0) {
+ rc = ENOENT;
+ goto fail2;
+ }
+ *map &= ~(1u << blknum);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nic_pio_link(
+ __inout efx_nic_t *enp,
+ __in uint32_t vi_index,
+ __in efx_piobuf_handle_t handle)
+{
+ return (efx_mcdi_link_piobuf(enp, vi_index, handle));
+}
+
+ __checkReturn int
+hunt_nic_pio_unlink(
+ __inout efx_nic_t *enp,
+ __in uint32_t vi_index)
+{
+ return (efx_mcdi_unlink_piobuf(enp, vi_index));
+}
+
+static __checkReturn int
+hunt_get_datapath_caps(
+ __in efx_nic_t *enp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_dword_t datapath_capabilities;
+ int rc;
+
+ if ((rc = efx_mcdi_get_capabilities(enp, &datapath_capabilities)) != 0)
+ goto fail1;
+
+ /*
+ * Huntington RXDP firmware inserts a 0 or 14 byte prefix.
+ * We only support the 14 byte prefix here.
+ */
+ if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities,
+ GET_CAPABILITIES_OUT_RX_PREFIX_LEN_14) != 1) {
+ rc = ENOTSUP;
+ goto fail2;
+ }
+ encp->enc_rx_prefix_size = 14;
+
+ /* Check if the firmware supports TSO */
+ if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities,
+ GET_CAPABILITIES_OUT_TX_TSO) == 1)
+ encp->enc_fw_assisted_tso_enabled = B_TRUE;
+ else
+ encp->enc_fw_assisted_tso_enabled = B_FALSE;
+
+ /* Check if the firmware has vadapter/vport/vswitch support */
+ if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities,
+ GET_CAPABILITIES_OUT_EVB) == 1)
+ encp->enc_datapath_cap_evb = B_TRUE;
+ else
+ encp->enc_datapath_cap_evb = B_FALSE;
+
+ /* Check if the firmware supports VLAN insertion */
+ if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities,
+ GET_CAPABILITIES_OUT_TX_VLAN_INSERTION) == 1)
+ encp->enc_hw_tx_insert_vlan_enabled = B_TRUE;
+ else
+ encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
+
+ /* Check if the firmware supports RX event batching */
+ if (MCDI_CMD_DWORD_FIELD(&datapath_capabilities,
+ GET_CAPABILITIES_OUT_RX_BATCHING) == 1) {
+ encp->enc_rx_batching_enabled = B_TRUE;
+ encp->enc_rx_batch_max = 16;
+ } else {
+ encp->enc_rx_batching_enabled = B_FALSE;
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+/*
+ * The external port mapping is a one-based numbering of the external
+ * connectors on the board. It does not distinguish off-board separated
+ * outputs such as multi-headed cables.
+ * The number of ports that map to each external port connector
+ * on the board is determined by the chip family and the port modes to
+ * which the NIC can be configured. The mapping table lists modes with
+ * port numbering requirements in increasing order.
+ */
+static struct {
+ efx_family_t family;
+ uint32_t modes_mask;
+ uint32_t stride;
+} __hunt_external_port_mappings[] = {
+ /* Supported modes requiring 1 output per port */
+ {
+ EFX_FAMILY_HUNTINGTON,
+ (1 << TLV_PORT_MODE_10G) |
+ (1 << TLV_PORT_MODE_40G) |
+ (1 << TLV_PORT_MODE_10G_10G) |
+ (1 << TLV_PORT_MODE_40G_40G),
+ 1
+ },
+ /* Supported modes requiring 2 outputs per port */
+ {
+ EFX_FAMILY_HUNTINGTON,
+ (1 << TLV_PORT_MODE_10G_10G_10G_10G) |
+ (1 << TLV_PORT_MODE_40G_10G_10G) |
+ (1 << TLV_PORT_MODE_10G_10G_40G),
+ 2
+ }
+};
+
+static __checkReturn int
+hunt_external_port_mapping(
+ __in efx_nic_t *enp,
+ __in uint32_t port,
+ __out uint8_t *external_portp)
+{
+ int rc;
+ int i;
+ uint32_t port_modes;
+ uint32_t matches;
+ uint32_t stride = 1; /* default 1-1 mapping */
+
+ if ((rc = efx_mcdi_get_port_modes(enp, &port_modes)) != 0) {
+ /* No port mode information available - use default mapping */
+ goto out;
+ }
+
+ /*
+ * Infer the internal port -> external port mapping from
+ * the possible port modes for this NIC.
+ */
+ for (i = 0; i < EFX_ARRAY_SIZE(__hunt_external_port_mappings); ++i) {
+ if (__hunt_external_port_mappings[i].family !=
+ enp->en_family)
+ continue;
+ matches = (__hunt_external_port_mappings[i].modes_mask &
+ port_modes);
+ if (matches != 0) {
+ stride = __hunt_external_port_mappings[i].stride;
+ port_modes &= ~matches;
+ }
+ }
+
+ if (port_modes != 0) {
+ /* Some advertised modes are not supported */
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+out:
+ /*
+ * Scale as required by last matched mode and then convert to
+ * one-based numbering
+ */
+ *external_portp = (uint8_t)(port / stride) + 1;
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+hunt_board_cfg(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ uint8_t mac_addr[6];
+ uint32_t board_type = 0;
+ hunt_link_state_t hls;
+ efx_port_t *epp = &(enp->en_port);
+ uint32_t port;
+ uint32_t pf;
+ uint32_t vf;
+ uint32_t mask;
+ uint32_t flags;
+ uint32_t sysclk;
+ uint32_t base, nvec;
+ int rc;
+
+ if ((rc = efx_mcdi_get_port_assignment(enp, &port)) != 0)
+ goto fail1;
+
+ /*
+ * NOTE: The MCDI protocol numbers ports from zero.
+ * The common code MCDI interface numbers ports from one.
+ */
+ emip->emi_port = port + 1;
+
+ if ((rc = hunt_external_port_mapping(enp, port,
+ &encp->enc_external_port)) != 0)
+ goto fail2;
+
+ /*
+ * Get PCIe function number from firmware (used for
+ * per-function privilege and dynamic config info).
+ * - PCIe PF: pf = PF number, vf = 0xffff.
+ * - PCIe VF: pf = parent PF, vf = VF number.
+ */
+ if ((rc = efx_mcdi_get_function_info(enp, &pf, &vf)) != 0)
+ goto fail3;
+
+ encp->enc_pf = pf;
+ encp->enc_vf = vf;
+
+ /* MAC address for this function */
+ if (EFX_PCI_FUNCTION_IS_PF(encp)) {
+ rc = efx_mcdi_get_mac_address_pf(enp, mac_addr);
+ } else {
+ rc = efx_mcdi_get_mac_address_vf(enp, mac_addr);
+ }
+ if ((rc == 0) && (mac_addr[0] & 0x02)) {
+ /*
+ * If the static config does not include a global MAC address
+ * pool then the board may return a locally administered MAC
+ * address (this should only happen on incorrectly programmed
+ * boards).
+ */
+ rc = EINVAL;
+ }
+ if (rc != 0)
+ goto fail4;
+
+ EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
+
+ /* Board configuration */
+ rc = efx_mcdi_get_board_cfg(enp, &board_type, NULL, NULL);
+ if (rc != 0) {
+ /* Unprivileged functions may not be able to read board cfg */
+ if (rc == EACCES)
+ board_type = 0;
+ else
+ goto fail5;
+ }
+
+ encp->enc_board_type = board_type;
+ encp->enc_clk_mult = 1; /* not used for Huntington */
+
+ /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
+ if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
+ goto fail6;
+
+ /* Obtain the default PHY advertised capabilities */
+ if ((rc = hunt_phy_get_link(enp, &hls)) != 0)
+ goto fail7;
+ epp->ep_default_adv_cap_mask = hls.hls_adv_cap_mask;
+ epp->ep_adv_cap_mask = hls.hls_adv_cap_mask;
+
+ /*
+ * Enable firmware workarounds for hardware errata.
+ * Expected responses are:
+ * - 0 (zero):
+ * Success: workaround enabled or disabled as requested.
+ * - MC_CMD_ERR_ENOSYS (reported as ENOTSUP):
+ * Firmware does not support the MC_CMD_WORKAROUND request.
+ * (assume that the workaround is not supported).
+ * - MC_CMD_ERR_ENOENT (reported as ENOENT):
+ * Firmware does not support the requested workaround.
+ * - MC_CMD_ERR_EPERM (reported as EACCES):
+ * Unprivileged function cannot enable/disable workarounds.
+ *
+ * See efx_mcdi_request_errcode() for MCDI error translations.
+ */
+
+ /*
+ * If the bug35388 workaround is enabled, then use an indirect access
+ * method to avoid unsafe EVQ writes.
+ */
+ rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG35388, B_TRUE,
+ NULL);
+ if ((rc == 0) || (rc == EACCES))
+ encp->enc_bug35388_workaround = B_TRUE;
+ else if ((rc == ENOTSUP) || (rc == ENOENT))
+ encp->enc_bug35388_workaround = B_FALSE;
+ else
+ goto fail8;
+
+ /*
+ * If the bug41750 workaround is enabled, then do not test interrupts,
+ * as the test will fail (seen with Greenport controllers).
+ */
+ rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG41750, B_TRUE,
+ NULL);
+ if (rc == 0) {
+ encp->enc_bug41750_workaround = B_TRUE;
+ } else if (rc == EACCES) {
+ /* Assume a controller with 40G ports needs the workaround. */
+ if (epp->ep_default_adv_cap_mask & EFX_PHY_CAP_40000FDX)
+ encp->enc_bug41750_workaround = B_TRUE;
+ else
+ encp->enc_bug41750_workaround = B_FALSE;
+ } else if ((rc == ENOTSUP) || (rc == ENOENT)) {
+ encp->enc_bug41750_workaround = B_FALSE;
+ } else {
+ goto fail9;
+ }
+ if (EFX_PCI_FUNCTION_IS_VF(encp)) {
+ /* Interrupt testing does not work for VFs. See bug50084. */
+ encp->enc_bug41750_workaround = B_TRUE;
+ }
+
+ /*
+ * If the bug26807 workaround is enabled, then firmware has enabled
+ * support for chained multicast filters. Firmware will reset (FLR)
+ * functions which have filters in the hardware filter table when the
+ * workaround is enabled/disabled.
+ *
+ * We must recheck if the workaround is enabled after inserting the
+ * first hardware filter, in case it has been changed since this check.
+ */
+ rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG26807,
+ B_TRUE, &flags);
+ if (rc == 0) {
+ encp->enc_bug26807_workaround = B_TRUE;
+ if (flags & (1 << MC_CMD_WORKAROUND_EXT_OUT_FLR_DONE_LBN)) {
+ /*
+ * Other functions had installed filters before the
+ * workaround was enabled, and they have been reset
+ * by firmware.
+ */
+ EFSYS_PROBE(bug26807_workaround_flr_done);
+ /* FIXME: bump MC warm boot count ? */
+ }
+ } else if (rc == EACCES) {
+ /*
+ * Unprivileged functions cannot enable the workaround in older
+ * firmware.
+ */
+ encp->enc_bug26807_workaround = B_FALSE;
+ } else if ((rc == ENOTSUP) || (rc == ENOENT)) {
+ encp->enc_bug26807_workaround = B_FALSE;
+ } else {
+ goto fail10;
+ }
+
+ /* Get sysclk frequency (in MHz). */
+ if ((rc = efx_mcdi_get_clock(enp, &sysclk)) != 0)
+ goto fail11;
+
+ /*
+ * The timer quantum is 1536 sysclk cycles, documented for the
+ * EV_TMR_VAL field of EV_TIMER_TBL. Scale for MHz and ns units.
+ */
+ encp->enc_evq_timer_quantum_ns = 1536000UL / sysclk; /* 1536 cycles */
+ if (encp->enc_bug35388_workaround) {
+ encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
+ ERF_DD_EVQ_IND_TIMER_VAL_WIDTH) / 1000;
+ } else {
+ encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
+ FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
+ }
+
+ /* Check capabilities of running datapath firmware */
+ if ((rc = hunt_get_datapath_caps(enp)) != 0)
+ goto fail12;
+
+ /* Alignment for receive packet DMA buffers */
+ encp->enc_rx_buf_align_start = 1;
+ encp->enc_rx_buf_align_end = 64; /* RX DMA end padding */
+
+ /* Alignment for WPTR updates */
+ encp->enc_rx_push_align = HUNTINGTON_RX_WPTR_ALIGN;
+
+ /*
+ * Set resource limits for MC_CMD_ALLOC_VIS. Note that we cannot use
+ * MC_CMD_GET_RESOURCE_LIMITS here as that reports the available
+ * resources (allocated to this PCIe function), which is zero until
+ * after we have allocated VIs.
+ */
+ encp->enc_evq_limit = 1024;
+ encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET;
+ encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET;
+
+ encp->enc_buftbl_limit = 0xFFFFFFFF;
+
+ encp->enc_piobuf_limit = HUNT_PIOBUF_NBUFS;
+ encp->enc_piobuf_size = HUNT_PIOBUF_SIZE;
+
+ /*
+ * Get the current privilege mask. Note that this may be modified
+ * dynamically, so this value is informational only. DO NOT use
+ * the privilege mask to check for sufficient privileges, as that
+ * can result in time-of-check/time-of-use bugs.
+ */
+ if ((rc = efx_mcdi_privilege_mask(enp, pf, vf, &mask)) != 0)
+ goto fail13;
+
+ encp->enc_privilege_mask = mask;
+
+ /* Get interrupt vector limits */
+ if ((rc = efx_mcdi_get_vector_cfg(enp, &base, &nvec, NULL)) != 0) {
+ if (EFX_PCI_FUNCTION_IS_PF(encp))
+ goto fail14;
+
+ /* Ignore error (cannot query vector limits from a VF). */
+ base = 0;
+ nvec = 1024;
+ }
+ encp->enc_intr_vec_base = base;
+ encp->enc_intr_limit = nvec;
+
+ /*
+ * Maximum number of bytes into the frame the TCP header can start for
+ * firmware assisted TSO to work.
+ */
+ encp->enc_tx_tso_tcp_header_offset_limit = 208;
+
+ return (0);
+
+fail14:
+ EFSYS_PROBE(fail14);
+fail13:
+ EFSYS_PROBE(fail13);
+fail12:
+ EFSYS_PROBE(fail12);
+fail11:
+ EFSYS_PROBE(fail11);
+fail10:
+ EFSYS_PROBE(fail10);
+fail9:
+ EFSYS_PROBE(fail9);
+fail8:
+ EFSYS_PROBE(fail8);
+fail7:
+ EFSYS_PROBE(fail7);
+fail6:
+ EFSYS_PROBE(fail6);
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+ __checkReturn int
+hunt_nic_probe(
+ __in efx_nic_t *enp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
+
+ /* Read and clear any assertion state */
+ if ((rc = efx_mcdi_read_assertion(enp)) != 0)
+ goto fail1;
+
+ /* Exit the assertion handler */
+ if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
+ if (rc != EACCES)
+ goto fail2;
+
+ if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
+ goto fail3;
+
+ if ((rc = hunt_board_cfg(enp)) != 0)
+ if (rc != EACCES)
+ goto fail4;
+
+ /*
+ * Set default driver config limits (based on board config).
+ *
+ * FIXME: For now allocate a fixed number of VIs which is likely to be
+ * sufficient and small enough to allow multiple functions on the same
+ * port.
+ */
+ edcp->edc_min_vi_count = edcp->edc_max_vi_count =
+ MIN(128, MAX(encp->enc_rxq_limit, encp->enc_txq_limit));
+
+ /* The client driver must configure and enable PIO buffer support */
+ edcp->edc_max_piobuf_count = 0;
+ edcp->edc_pio_alloc_size = 0;
+
+#if EFSYS_OPT_MAC_STATS
+ /* Wipe the MAC statistics */
+ if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
+ goto fail5;
+#endif
+
+#if EFSYS_OPT_LOOPBACK
+ if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
+ goto fail6;
+#endif
+
+#if EFSYS_OPT_MON_STATS
+ if ((rc = mcdi_mon_cfg_build(enp)) != 0) {
+ /* Unprivileged functions do not have access to sensors */
+ if (rc != EACCES)
+ goto fail7;
+ }
+#endif
+
+ encp->enc_features = enp->en_features;
+
+ return (0);
+
+#if EFSYS_OPT_MON_STATS
+fail7:
+ EFSYS_PROBE(fail7);
+#endif
+#if EFSYS_OPT_LOOPBACK
+fail6:
+ EFSYS_PROBE(fail6);
+#endif
+#if EFSYS_OPT_MAC_STATS
+fail5:
+ EFSYS_PROBE(fail5);
+#endif
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nic_set_drv_limits(
+ __inout efx_nic_t *enp,
+ __in efx_drv_limits_t *edlp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
+ uint32_t min_evq_count, max_evq_count;
+ uint32_t min_rxq_count, max_rxq_count;
+ uint32_t min_txq_count, max_txq_count;
+ int rc;
+
+ if (edlp == NULL) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ /* Get minimum required and maximum usable VI limits */
+ min_evq_count = MIN(edlp->edl_min_evq_count, encp->enc_evq_limit);
+ min_rxq_count = MIN(edlp->edl_min_rxq_count, encp->enc_rxq_limit);
+ min_txq_count = MIN(edlp->edl_min_txq_count, encp->enc_txq_limit);
+
+ edcp->edc_min_vi_count =
+ MAX(min_evq_count, MAX(min_rxq_count, min_txq_count));
+
+ max_evq_count = MIN(edlp->edl_max_evq_count, encp->enc_evq_limit);
+ max_rxq_count = MIN(edlp->edl_max_rxq_count, encp->enc_rxq_limit);
+ max_txq_count = MIN(edlp->edl_max_txq_count, encp->enc_txq_limit);
+
+ edcp->edc_max_vi_count =
+ MAX(max_evq_count, MAX(max_rxq_count, max_txq_count));
+
+ /*
+ * Check limits for sub-allocated piobuf blocks.
+ * PIO is optional, so don't fail if the limits are incorrect.
+ */
+ if ((encp->enc_piobuf_size == 0) ||
+ (encp->enc_piobuf_limit == 0) ||
+ (edlp->edl_min_pio_alloc_size == 0) ||
+ (edlp->edl_min_pio_alloc_size > encp->enc_piobuf_size)) {
+ /* Disable PIO */
+ edcp->edc_max_piobuf_count = 0;
+ edcp->edc_pio_alloc_size = 0;
+ } else {
+ uint32_t blk_size, blk_count, blks_per_piobuf;
+
+ blk_size =
+ MAX(edlp->edl_min_pio_alloc_size, HUNT_MIN_PIO_ALLOC_SIZE);
+
+ blks_per_piobuf = encp->enc_piobuf_size / blk_size;
+ EFSYS_ASSERT3U(blks_per_piobuf, <=, 32);
+
+ blk_count = (encp->enc_piobuf_limit * blks_per_piobuf);
+
+ /* A zero max pio alloc count means unlimited */
+ if ((edlp->edl_max_pio_alloc_count > 0) &&
+ (edlp->edl_max_pio_alloc_count < blk_count)) {
+ blk_count = edlp->edl_max_pio_alloc_count;
+ }
+
+ edcp->edc_pio_alloc_size = blk_size;
+ edcp->edc_max_piobuf_count =
+ (blk_count + (blks_per_piobuf - 1)) / blks_per_piobuf;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+ __checkReturn int
+hunt_nic_reset(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_ENTITY_RESET_IN_LEN,
+ MC_CMD_ENTITY_RESET_OUT_LEN)];
+ int rc;
+
+ /* hunt_nic_reset() is called to recover from BADASSERT failures. */
+ if ((rc = efx_mcdi_read_assertion(enp)) != 0)
+ goto fail1;
+ if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
+ goto fail2;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_ENTITY_RESET;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_ENTITY_RESET_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_ENTITY_RESET_OUT_LEN;
+
+ MCDI_IN_POPULATE_DWORD_1(req, ENTITY_RESET_IN_FLAG,
+ ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET, 1);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail3;
+ }
+
+ /* Clear RX/TX DMA queue errors */
+ enp->en_reset_flags &= ~(EFX_RESET_RXQ_ERR | EFX_RESET_TXQ_ERR);
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nic_init(
+ __in efx_nic_t *enp)
+{
+ efx_drv_cfg_t *edcp = &(enp->en_drv_cfg);
+ uint32_t min_vi_count, max_vi_count;
+ uint32_t vi_count, vi_base;
+ uint32_t i;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
+
+ /* Enable reporting of some events (e.g. link change) */
+ if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
+ goto fail1;
+
+ /* Allocate (optional) on-chip PIO buffers */
+ hunt_nic_alloc_piobufs(enp, edcp->edc_max_piobuf_count);
+
+ /*
+ * For best performance, PIO writes should use a write-combined
+ * (WC) memory mapping. Using a separate WC mapping for the PIO
+ * aperture of each VI would be a burden to drivers (and not
+ * possible if the host page size is >4Kbyte).
+ *
+ * To avoid this we use a single uncached (UC) mapping for VI
+ * register access, and a single WC mapping for extra VIs used
+ * for PIO writes.
+ *
+ * Each piobuf must be linked to a VI in the WC mapping, and to
+ * each VI that is using a sub-allocated block from the piobuf.
+ */
+ min_vi_count = edcp->edc_min_vi_count;
+ max_vi_count = edcp->edc_max_vi_count + enp->en_u.hunt.enu_piobuf_count;
+
+ /* Ensure that the previously attached driver's VIs are freed */
+ if ((rc = efx_mcdi_free_vis(enp)) != 0)
+ goto fail2;
+
+ /*
+ * Reserve VI resources (EVQ+RXQ+TXQ) for this PCIe function. If this
+ * fails then retrying the request for fewer VI resources may succeed.
+ */
+ vi_count = 0;
+ if ((rc = efx_mcdi_alloc_vis(enp, min_vi_count, max_vi_count,
+ &vi_base, &vi_count)) != 0)
+ goto fail3;
+
+ EFSYS_PROBE2(vi_alloc, uint32_t, vi_base, uint32_t, vi_count);
+
+ if (vi_count < min_vi_count) {
+ rc = ENOMEM;
+ goto fail4;
+ }
+
+ enp->en_u.hunt.enu_vi_base = vi_base;
+ enp->en_u.hunt.enu_vi_count = vi_count;
+
+ if (vi_count < min_vi_count + enp->en_u.hunt.enu_piobuf_count) {
+ /* Not enough extra VIs to map piobufs */
+ hunt_nic_free_piobufs(enp);
+ }
+
+ enp->en_u.hunt.enu_pio_write_vi_base =
+ vi_count - enp->en_u.hunt.enu_piobuf_count;
+
+ /* Save UC memory mapping details */
+ enp->en_u.hunt.enu_uc_mem_map_offset = 0;
+ if (enp->en_u.hunt.enu_piobuf_count > 0) {
+ enp->en_u.hunt.enu_uc_mem_map_size =
+ (ER_DZ_TX_PIOBUF_STEP *
+ enp->en_u.hunt.enu_pio_write_vi_base);
+ } else {
+ enp->en_u.hunt.enu_uc_mem_map_size =
+ (ER_DZ_TX_PIOBUF_STEP *
+ enp->en_u.hunt.enu_vi_count);
+ }
+
+ /* Save WC memory mapping details */
+ enp->en_u.hunt.enu_wc_mem_map_offset =
+ enp->en_u.hunt.enu_uc_mem_map_offset +
+ enp->en_u.hunt.enu_uc_mem_map_size;
+
+ enp->en_u.hunt.enu_wc_mem_map_size =
+ (ER_DZ_TX_PIOBUF_STEP *
+ enp->en_u.hunt.enu_piobuf_count);
+
+ /* Link piobufs to extra VIs in WC mapping */
+ if (enp->en_u.hunt.enu_piobuf_count > 0) {
+ for (i = 0; i < enp->en_u.hunt.enu_piobuf_count; i++) {
+ rc = efx_mcdi_link_piobuf(enp,
+ enp->en_u.hunt.enu_pio_write_vi_base + i,
+ enp->en_u.hunt.enu_piobuf_handle[i]);
+ if (rc != 0)
+ break;
+ }
+ }
+
+ /* Allocate a vAdapter attached to our upstream vPort/pPort */
+ if ((rc = efx_mcdi_vadaptor_alloc(enp, EVB_PORT_ID_ASSIGNED)) != 0)
+ goto fail5;
+
+ enp->en_vport_id = EVB_PORT_ID_ASSIGNED;
+
+ return (0);
+
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+
+ hunt_nic_free_piobufs(enp);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nic_get_vi_pool(
+ __in efx_nic_t *enp,
+ __out uint32_t *vi_countp)
+{
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
+
+ /*
+ * Report VIs that the client driver can use.
+ * Do not include VIs used for PIO buffer writes.
+ */
+ *vi_countp = enp->en_u.hunt.enu_pio_write_vi_base;
+
+ return (0);
+}
+
+ __checkReturn int
+hunt_nic_get_bar_region(
+ __in efx_nic_t *enp,
+ __in efx_nic_region_t region,
+ __out uint32_t *offsetp,
+ __out size_t *sizep)
+{
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_HUNTINGTON);
+
+ /*
+ * TODO: Specify host memory mapping alignment and granularity
+ * in efx_drv_limits_t so that they can be taken into account
+ * when allocating extra VIs for PIO writes.
+ */
+ switch (region) {
+ case EFX_REGION_VI:
+ /* UC mapped memory BAR region for VI registers */
+ *offsetp = enp->en_u.hunt.enu_uc_mem_map_offset;
+ *sizep = enp->en_u.hunt.enu_uc_mem_map_size;
+ break;
+
+ case EFX_REGION_PIO_WRITE_VI:
+ /* WC mapped memory BAR region for piobuf writes */
+ *offsetp = enp->en_u.hunt.enu_wc_mem_map_offset;
+ *sizep = enp->en_u.hunt.enu_wc_mem_map_size;
+ break;
+
+ default:
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_nic_fini(
+ __in efx_nic_t *enp)
+{
+ (void) efx_mcdi_vadaptor_free(enp, enp->en_vport_id);
+ enp->en_vport_id = 0;
+
+ /* FIXME: do we need to unlink piobufs ? */
+ hunt_nic_free_piobufs(enp);
+
+ (void) efx_mcdi_free_vis(enp);
+ enp->en_u.hunt.enu_vi_count = 0;
+}
+
+ void
+hunt_nic_unprobe(
+ __in efx_nic_t *enp)
+{
+#if EFSYS_OPT_MON_STATS
+ mcdi_mon_cfg_free(enp);
+#endif /* EFSYS_OPT_MON_STATS */
+ (void) efx_mcdi_drv_attach(enp, B_FALSE);
+}
+
+#if EFSYS_OPT_DIAG
+
+ __checkReturn int
+hunt_nic_register_test(
+ __in efx_nic_t *enp)
+{
+ int rc;
+
+ /* FIXME */
+ _NOTE(ARGUNUSED(enp))
+ if (B_FALSE) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ /* FIXME */
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_DIAG */
+
+
+
+#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_nvram.c b/sys/dev/sfxge/common/hunt_nvram.c
new file mode 100644
index 0000000..3e130f4
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_nvram.c
@@ -0,0 +1,1538 @@
+/*-
+ * Copyright (c) 2012-2015 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_types.h"
+#include "efx_regs.h"
+#include "efx_impl.h"
+
+#if EFSYS_OPT_HUNTINGTON
+
+#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
+
+#include "ef10_tlv_layout.h"
+
+/* Cursor for TLV partition format */
+typedef struct tlv_cursor_s {
+ uint32_t *block; /* Base of data block */
+ uint32_t *current; /* Cursor position */
+ uint32_t *end; /* End tag position */
+ uint32_t *limit; /* Last dword of data block */
+} tlv_cursor_t;
+
+static __checkReturn int
+tlv_validate_state(
+ __in tlv_cursor_t *cursor);
+
+
+/*
+ * Operations on TLV formatted partition data.
+ */
+static uint32_t
+tlv_tag(
+ __in tlv_cursor_t *cursor)
+{
+ uint32_t dword, tag;
+
+ dword = cursor->current[0];
+ tag = __LE_TO_CPU_32(dword);
+
+ return (tag);
+}
+
+static size_t
+tlv_length(
+ __in tlv_cursor_t *cursor)
+{
+ uint32_t dword, length;
+
+ if (tlv_tag(cursor) == TLV_TAG_END)
+ return (0);
+
+ dword = cursor->current[1];
+ length = __LE_TO_CPU_32(dword);
+
+ return ((size_t)length);
+}
+
+static uint8_t *
+tlv_value(
+ __in tlv_cursor_t *cursor)
+{
+ if (tlv_tag(cursor) == TLV_TAG_END)
+ return (NULL);
+
+ return ((uint8_t *)(&cursor->current[2]));
+}
+
+static uint8_t *
+tlv_item(
+ __in tlv_cursor_t *cursor)
+{
+ if (tlv_tag(cursor) == TLV_TAG_END)
+ return (NULL);
+
+ return ((uint8_t *)cursor->current);
+}
+
+/*
+ * TLV item DWORD length is tag + length + value (rounded up to DWORD)
+ * equivalent to tlv_n_words_for_len in mc-comms tlv.c
+ */
+#define TLV_DWORD_COUNT(length) \
+ (1 + 1 + (((length) + sizeof (uint32_t) - 1) / sizeof (uint32_t)))
+
+
+static uint32_t *
+tlv_next_item_ptr(
+ __in tlv_cursor_t *cursor)
+{
+ uint32_t length;
+
+ length = tlv_length(cursor);
+
+ return (cursor->current + TLV_DWORD_COUNT(length));
+}
+
+static int
+tlv_advance(
+ __in tlv_cursor_t *cursor)
+{
+ int rc;
+
+ if ((rc = tlv_validate_state(cursor)) != 0)
+ goto fail1;
+
+ if (cursor->current == cursor->end) {
+ /* No more tags after END tag */
+ cursor->current = NULL;
+ rc = ENOENT;
+ goto fail2;
+ }
+
+ /* Advance to next item and validate */
+ cursor->current = tlv_next_item_ptr(cursor);
+
+ if ((rc = tlv_validate_state(cursor)) != 0)
+ goto fail3;
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static int
+tlv_rewind(
+ __in tlv_cursor_t *cursor)
+{
+ int rc;
+
+ cursor->current = cursor->block;
+
+ if ((rc = tlv_validate_state(cursor)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static int
+tlv_find(
+ __in tlv_cursor_t *cursor,
+ __in uint32_t tag)
+{
+ int rc;
+
+ rc = tlv_rewind(cursor);
+ while (rc == 0) {
+ if (tlv_tag(cursor) == tag)
+ break;
+
+ rc = tlv_advance(cursor);
+ }
+ return (rc);
+}
+
+static __checkReturn int
+tlv_validate_state(
+ __in tlv_cursor_t *cursor)
+{
+ int rc;
+
+ /* Check cursor position */
+ if (cursor->current < cursor->block) {
+ rc = EINVAL;
+ goto fail1;
+ }
+ if (cursor->current > cursor->limit) {
+ rc = EINVAL;
+ goto fail2;
+ }
+
+ if (tlv_tag(cursor) != TLV_TAG_END) {
+ /* Check current item has space for tag and length */
+ if (cursor->current > (cursor->limit - 2)) {
+ cursor->current = NULL;
+ rc = EFAULT;
+ goto fail3;
+ }
+
+ /* Check we have value data for current item and another tag */
+ if (tlv_next_item_ptr(cursor) > (cursor->limit - 1)) {
+ cursor->current = NULL;
+ rc = EFAULT;
+ goto fail4;
+ }
+ }
+
+ return (0);
+
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static int
+tlv_init_cursor(
+ __in tlv_cursor_t *cursor,
+ __in uint32_t *block,
+ __in uint32_t *limit)
+{
+ cursor->block = block;
+ cursor->limit = limit;
+
+ cursor->current = cursor->block;
+ cursor->end = NULL;
+
+ return (tlv_validate_state(cursor));
+}
+
+static int
+tlv_init_cursor_from_size(
+ __in tlv_cursor_t *cursor,
+ __in uint8_t *block,
+ __in size_t size)
+{
+ uint32_t *limit;
+ limit = (uint32_t *)(block + size - sizeof (uint32_t));
+ return (tlv_init_cursor(cursor, (uint32_t *)block, limit));
+}
+
+static int
+tlv_require_end(
+ __in tlv_cursor_t *cursor)
+{
+ uint32_t *pos;
+ int rc;
+
+ if (cursor->end == NULL) {
+ pos = cursor->current;
+ if ((rc = tlv_find(cursor, TLV_TAG_END)) != 0)
+ goto fail1;
+
+ cursor->end = cursor->current;
+ cursor->current = pos;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static size_t
+tlv_block_length_used(
+ __in tlv_cursor_t *cursor)
+{
+ int rc;
+
+ if ((rc = tlv_validate_state(cursor)) != 0)
+ goto fail1;
+
+ if ((rc = tlv_require_end(cursor)) != 0)
+ goto fail2;
+
+ /* Return space used (including the END tag) */
+ return (cursor->end + 1 - cursor->block) * sizeof (uint32_t);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (0);
+}
+
+
+static __checkReturn uint32_t *
+tlv_write(
+ __in tlv_cursor_t *cursor,
+ __in uint32_t tag,
+ __in_bcount(size) uint8_t *data,
+ __in size_t size)
+{
+ uint32_t len = size;
+ uint32_t *ptr;
+
+ ptr = cursor->current;
+
+ *ptr++ = __CPU_TO_LE_32(tag);
+ *ptr++ = __CPU_TO_LE_32(len);
+
+ if (len > 0) {
+ ptr[(len - 1) / sizeof (uint32_t)] = 0;
+ memcpy(ptr, data, len);
+ ptr += P2ROUNDUP(len, sizeof (uint32_t)) / sizeof (*ptr);
+ }
+
+ return (ptr);
+}
+
+static __checkReturn int
+tlv_insert(
+ __in tlv_cursor_t *cursor,
+ __in uint32_t tag,
+ __in uint8_t *data,
+ __in size_t size)
+{
+ unsigned int delta;
+ int rc;
+
+ if ((rc = tlv_validate_state(cursor)) != 0)
+ goto fail1;
+
+ if ((rc = tlv_require_end(cursor)) != 0)
+ goto fail2;
+
+ if (tag == TLV_TAG_END) {
+ rc = EINVAL;
+ goto fail3;
+ }
+
+ delta = TLV_DWORD_COUNT(size);
+ if (cursor->end + 1 + delta > cursor->limit) {
+ rc = ENOSPC;
+ goto fail4;
+ }
+
+ /* Move data up: new space at cursor->current */
+ memmove(cursor->current + delta, cursor->current,
+ (cursor->end + 1 - cursor->current) * sizeof (uint32_t));
+
+ /* Adjust the end pointer */
+ cursor->end += delta;
+
+ /* Write new TLV item */
+ tlv_write(cursor, tag, data, size);
+
+ return (0);
+
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+tlv_modify(
+ __in tlv_cursor_t *cursor,
+ __in uint32_t tag,
+ __in uint8_t *data,
+ __in size_t size)
+{
+ uint32_t *pos;
+ unsigned int old_ndwords;
+ unsigned int new_ndwords;
+ unsigned int delta;
+ int rc;
+
+ if ((rc = tlv_validate_state(cursor)) != 0)
+ goto fail1;
+
+ if (tlv_tag(cursor) == TLV_TAG_END) {
+ rc = EINVAL;
+ goto fail2;
+ }
+ if (tlv_tag(cursor) != tag) {
+ rc = EINVAL;
+ goto fail3;
+ }
+
+ old_ndwords = TLV_DWORD_COUNT(tlv_length(cursor));
+ new_ndwords = TLV_DWORD_COUNT(size);
+
+ if ((rc = tlv_require_end(cursor)) != 0)
+ goto fail4;
+
+ if (new_ndwords > old_ndwords) {
+ /* Expand space used for TLV item */
+ delta = new_ndwords - old_ndwords;
+ pos = cursor->current + old_ndwords;
+
+ if (cursor->end + 1 + delta > cursor->limit) {
+ rc = ENOSPC;
+ goto fail5;
+ }
+
+ /* Move up: new space at (cursor->current + old_ndwords) */
+ memmove(pos + delta, pos,
+ (cursor->end + 1 - pos) * sizeof (uint32_t));
+
+ /* Adjust the end pointer */
+ cursor->end += delta;
+
+ } else if (new_ndwords < old_ndwords) {
+ /* Shrink space used for TLV item */
+ delta = old_ndwords - new_ndwords;
+ pos = cursor->current + new_ndwords;
+
+ /* Move down: remove words at (cursor->current + new_ndwords) */
+ memmove(pos, pos + delta,
+ (cursor->end + 1 - pos) * sizeof (uint32_t));
+
+ /* Zero the new space at the end of the TLV chain */
+ memset(cursor->end + 1 - delta, 0, delta * sizeof (uint32_t));
+
+ /* Adjust the end pointer */
+ cursor->end -= delta;
+ }
+
+ /* Write new data */
+ tlv_write(cursor, tag, data, size);
+
+ return (0);
+
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+/* Validate TLV formatted partition contents (before writing to flash) */
+ __checkReturn int
+efx_nvram_tlv_validate(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in_bcount(partn_size) caddr_t partn_data,
+ __in size_t partn_size)
+{
+ tlv_cursor_t cursor;
+ struct tlv_partition_header *header;
+ struct tlv_partition_trailer *trailer;
+ size_t total_length;
+ uint32_t cksum;
+ int pos;
+ int rc;
+
+ EFX_STATIC_ASSERT(sizeof (*header) <= HUNTINGTON_NVRAM_CHUNK);
+
+ if ((partn_data == NULL) || (partn_size == 0)) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ /* The partition header must be the first item (at offset zero) */
+ if ((rc = tlv_init_cursor_from_size(&cursor, partn_data,
+ partn_size)) != 0) {
+ rc = EFAULT;
+ goto fail2;
+ }
+ if (tlv_tag(&cursor) != TLV_TAG_PARTITION_HEADER) {
+ rc = EINVAL;
+ goto fail3;
+ }
+ header = (struct tlv_partition_header *)tlv_item(&cursor);
+
+ /* Check TLV partition length (includes the END tag) */
+ total_length = __LE_TO_CPU_32(header->total_length);
+ if (total_length > partn_size) {
+ rc = EFBIG;
+ goto fail4;
+ }
+
+ /* Check partition ends with PARTITION_TRAILER and END tags */
+ if ((rc = tlv_find(&cursor, TLV_TAG_PARTITION_TRAILER)) != 0) {
+ rc = EINVAL;
+ goto fail5;
+ }
+ trailer = (struct tlv_partition_trailer *)tlv_item(&cursor);
+
+ if ((rc = tlv_advance(&cursor)) != 0) {
+ rc = EINVAL;
+ goto fail6;
+ }
+ if (tlv_tag(&cursor) != TLV_TAG_END) {
+ rc = EINVAL;
+ goto fail7;
+ }
+
+ /* Check generation counts are consistent */
+ if (trailer->generation != header->generation) {
+ rc = EINVAL;
+ goto fail8;
+ }
+
+ /* Verify partition checksum */
+ cksum = 0;
+ for (pos = 0; (size_t)pos < total_length; pos += sizeof (uint32_t)) {
+ cksum += *((uint32_t *)(partn_data + pos));
+ }
+ if (cksum != 0) {
+ rc = EINVAL;
+ goto fail9;
+ }
+
+ return (0);
+
+fail9:
+ EFSYS_PROBE(fail9);
+fail8:
+ EFSYS_PROBE(fail8);
+fail7:
+ EFSYS_PROBE(fail7);
+fail6:
+ EFSYS_PROBE(fail6);
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+/* Read and validate an entire TLV formatted partition */
+static __checkReturn int
+hunt_nvram_read_tlv_partition(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in_bcount(partn_size) caddr_t partn_data,
+ __in size_t partn_size)
+{
+ tlv_cursor_t cursor;
+ struct tlv_partition_header *header;
+ struct tlv_partition_trailer *trailer;
+ size_t total_length;
+ uint32_t cksum;
+ int pos;
+ int rc;
+
+ EFX_STATIC_ASSERT(sizeof (*header) <= HUNTINGTON_NVRAM_CHUNK);
+
+ if ((partn_data == NULL) || (partn_size == 0)) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ /* Read initial chunk of partition */
+ if ((rc = hunt_nvram_partn_read(enp, partn, 0, partn_data,
+ HUNTINGTON_NVRAM_CHUNK)) != 0) {
+ goto fail2;
+ }
+
+ /* The partition header must be the first item (at offset zero) */
+ if ((rc = tlv_init_cursor_from_size(&cursor, partn_data,
+ partn_size)) != 0) {
+ rc = EFAULT;
+ goto fail3;
+ }
+ if (tlv_tag(&cursor) != TLV_TAG_PARTITION_HEADER) {
+ rc = EINVAL;
+ goto fail4;
+ }
+ header = (struct tlv_partition_header *)tlv_item(&cursor);
+
+ /* Check TLV partition length (includes the END tag) */
+ total_length = __LE_TO_CPU_32(header->total_length);
+ if (total_length > partn_size) {
+ rc = EFBIG;
+ goto fail5;
+ }
+
+ /* Read the remaining partition content */
+ if (total_length > HUNTINGTON_NVRAM_CHUNK) {
+ if ((rc = hunt_nvram_partn_read(enp, partn,
+ HUNTINGTON_NVRAM_CHUNK,
+ partn_data + HUNTINGTON_NVRAM_CHUNK,
+ total_length - HUNTINGTON_NVRAM_CHUNK)) != 0)
+ goto fail6;
+ }
+
+ /* Check partition ends with PARTITION_TRAILER and END tags */
+ if ((rc = tlv_find(&cursor, TLV_TAG_PARTITION_TRAILER)) != 0) {
+ rc = EINVAL;
+ goto fail7;
+ }
+ trailer = (struct tlv_partition_trailer *)tlv_item(&cursor);
+
+ if ((rc = tlv_advance(&cursor)) != 0) {
+ rc = EINVAL;
+ goto fail8;
+ }
+ if (tlv_tag(&cursor) != TLV_TAG_END) {
+ rc = EINVAL;
+ goto fail9;
+ }
+
+ /* Check data read from partition is consistent */
+ if (trailer->generation != header->generation) {
+ /*
+ * The partition data may have been modified between successive
+ * MCDI NVRAM_READ requests by the MC or another PCI function.
+ *
+ * The caller must retry to obtain consistent partition data.
+ */
+ rc = EAGAIN;
+ goto fail10;
+ }
+
+ /* Verify partition checksum */
+ cksum = 0;
+ for (pos = 0; (size_t)pos < total_length; pos += sizeof (uint32_t)) {
+ cksum += *((uint32_t *)(partn_data + pos));
+ }
+ if (cksum != 0) {
+ rc = EINVAL;
+ goto fail11;
+ }
+
+ return (0);
+
+fail11:
+ EFSYS_PROBE(fail11);
+fail10:
+ EFSYS_PROBE(fail10);
+fail9:
+ EFSYS_PROBE(fail9);
+fail8:
+ EFSYS_PROBE(fail8);
+fail7:
+ EFSYS_PROBE(fail7);
+fail6:
+ EFSYS_PROBE(fail6);
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+/*
+ * Read a single TLV item from a host memory
+ * buffer containing a TLV formatted partition.
+ */
+ __checkReturn int
+hunt_nvram_buf_read_tlv(
+ __in efx_nic_t *enp,
+ __in_bcount(partn_size) caddr_t partn_data,
+ __in size_t partn_size,
+ __in uint32_t tag,
+ __deref_out_bcount_opt(*sizep) caddr_t *datap,
+ __out size_t *sizep)
+{
+ tlv_cursor_t cursor;
+ caddr_t data;
+ size_t length;
+ caddr_t value;
+ int rc;
+
+ if ((partn_data == NULL) || (partn_size == 0)) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ /* Find requested TLV tag in partition data */
+ if ((rc = tlv_init_cursor_from_size(&cursor, partn_data,
+ partn_size)) != 0) {
+ rc = EFAULT;
+ goto fail2;
+ }
+ if ((rc = tlv_find(&cursor, tag)) != 0) {
+ rc = ENOENT;
+ goto fail3;
+ }
+ value = tlv_value(&cursor);
+ length = tlv_length(&cursor);
+
+ if (length == 0)
+ data = NULL;
+ else {
+ /* Copy out data from TLV item */
+ EFSYS_KMEM_ALLOC(enp->en_esip, length, data);
+ if (data == NULL) {
+ rc = ENOMEM;
+ goto fail4;
+ }
+ memcpy(data, value, length);
+ }
+
+ *datap = data;
+ *sizep = length;
+
+ return (0);
+
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+
+/* Read a single TLV item from a TLV formatted partition */
+ __checkReturn int
+hunt_nvram_partn_read_tlv(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in uint32_t tag,
+ __deref_out_bcount_opt(*sizep) caddr_t *datap,
+ __out size_t *sizep)
+{
+ caddr_t partn_data = NULL;
+ size_t partn_size = 0;
+ size_t length;
+ caddr_t data;
+ int retry;
+ int rc;
+
+ /* Allocate sufficient memory for the entire partition */
+ if ((rc = hunt_nvram_partn_size(enp, partn, &partn_size)) != 0)
+ goto fail1;
+
+ if (partn_size == 0) {
+ rc = ENOENT;
+ goto fail2;
+ }
+
+ EFSYS_KMEM_ALLOC(enp->en_esip, partn_size, partn_data);
+ if (partn_data == NULL) {
+ rc = ENOMEM;
+ goto fail3;
+ }
+
+ /*
+ * Read the entire TLV partition. Retry until consistent partition
+ * contents are returned. Inconsistent data may be read if:
+ * a) the partition contents are invalid
+ * b) the MC has rebooted while we were reading the partition
+ * c) the partition has been modified while we were reading it
+ * Limit retry attempts to ensure forward progress.
+ */
+ retry = 10;
+ do {
+ rc = hunt_nvram_read_tlv_partition(enp, partn,
+ partn_data, partn_size);
+ } while ((rc == EAGAIN) && (--retry > 0));
+
+ if (rc != 0) {
+ /* Failed to obtain consistent partition data */
+ goto fail4;
+ }
+
+ if ((rc = hunt_nvram_buf_read_tlv(enp, partn_data, partn_size,
+ tag, &data, &length)) != 0)
+ goto fail5;
+
+ EFSYS_KMEM_FREE(enp->en_esip, partn_size, partn_data);
+
+ *datap = data;
+ *sizep = length;
+
+ return (0);
+
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
+
+ EFSYS_KMEM_FREE(enp->en_esip, partn_size, partn_data);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+/*
+ * Add or update a single TLV item in a host memory buffer containing a TLV
+ * formatted partition.
+ */
+ __checkReturn int
+hunt_nvram_buf_write_tlv(
+ __inout_bcount(partn_size) caddr_t partn_data,
+ __in size_t partn_size,
+ __in uint32_t tag,
+ __in_bcount(tag_size) caddr_t tag_data,
+ __in size_t tag_size,
+ __out size_t *total_lengthp)
+{
+ tlv_cursor_t cursor;
+ struct tlv_partition_header *header;
+ struct tlv_partition_trailer *trailer;
+ uint32_t generation;
+ uint32_t cksum;
+ int pos;
+ int rc;
+
+ /* The partition header must be the first item (at offset zero) */
+ if ((rc = tlv_init_cursor_from_size(&cursor, partn_data,
+ partn_size)) != 0) {
+ rc = EFAULT;
+ goto fail1;
+ }
+ if (tlv_tag(&cursor) != TLV_TAG_PARTITION_HEADER) {
+ rc = EINVAL;
+ goto fail2;
+ }
+ header = (struct tlv_partition_header *)tlv_item(&cursor);
+
+ /* Update the TLV chain to contain the new data */
+ if ((rc = tlv_find(&cursor, tag)) == 0) {
+ /* Modify existing TLV item */
+ if ((rc = tlv_modify(&cursor, tag,
+ tag_data, tag_size)) != 0)
+ goto fail3;
+ } else {
+ /* Insert a new TLV item before the PARTITION_TRAILER */
+ rc = tlv_find(&cursor, TLV_TAG_PARTITION_TRAILER);
+ if (rc != 0) {
+ rc = EINVAL;
+ goto fail4;
+ }
+ if ((rc = tlv_insert(&cursor, tag,
+ tag_data, tag_size)) != 0) {
+ rc = EINVAL;
+ goto fail5;
+ }
+ }
+
+ /* Find the trailer tag */
+ if ((rc = tlv_find(&cursor, TLV_TAG_PARTITION_TRAILER)) != 0) {
+ rc = EINVAL;
+ goto fail6;
+ }
+ trailer = (struct tlv_partition_trailer *)tlv_item(&cursor);
+
+ /* Update PARTITION_HEADER and PARTITION_TRAILER fields */
+ *total_lengthp = tlv_block_length_used(&cursor);
+ EFSYS_ASSERT3U(*total_lengthp, <=, partn_size);
+ generation = __LE_TO_CPU_32(header->generation) + 1;
+
+ header->total_length = __CPU_TO_LE_32(*total_lengthp);
+ header->generation = __CPU_TO_LE_32(generation);
+ trailer->generation = __CPU_TO_LE_32(generation);
+
+ /* Recompute PARTITION_TRAILER checksum */
+ trailer->checksum = 0;
+ cksum = 0;
+ for (pos = 0; (size_t)pos < *total_lengthp; pos += sizeof (uint32_t)) {
+ cksum += *((uint32_t *)(partn_data + pos));
+ }
+ trailer->checksum = ~cksum + 1;
+
+ return (0);
+
+fail6:
+ EFSYS_PROBE(fail6);
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+/* Add or update a single TLV item in a TLV formatted partition */
+ __checkReturn int
+hunt_nvram_partn_write_tlv(
+ __in efx_nic_t *enp,
+ __in uint32_t partn,
+ __in uint32_t tag,
+ __in_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ size_t partn_size;
+ caddr_t partn_data;
+ size_t total_length;
+ int rc;
+
+ EFSYS_ASSERT3U(partn, ==, NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG);
+
+ /* Allocate sufficient memory for the entire partition */
+ if ((rc = hunt_nvram_partn_size(enp, partn, &partn_size)) != 0)
+ goto fail1;
+
+ EFSYS_KMEM_ALLOC(enp->en_esip, partn_size, partn_data);
+ if (partn_data == NULL) {
+ rc = ENOMEM;
+ goto fail2;
+ }
+
+ /* Lock the partition */
+ if ((rc = hunt_nvram_partn_lock(enp, partn)) != 0)
+ goto fail3;
+
+ /* Read the partition contents (no need to retry when locked). */
+ if ((rc = hunt_nvram_read_tlv_partition(enp, partn,
+ partn_data, partn_size)) != 0) {
+ /* Failed to obtain consistent partition data */
+ goto fail4;
+ }
+
+ /* Update the contents in memory */
+ if ((rc = hunt_nvram_buf_write_tlv(partn_data, partn_size,
+ tag, data, size, &total_length)) != 0)
+ goto fail5;
+
+ /* Erase the whole partition */
+ if ((rc = hunt_nvram_partn_erase(enp, partn, 0, partn_size)) != 0)
+ goto fail6;
+
+ /* Write new partition contents to NVRAM */
+ if ((rc = hunt_nvram_partn_write(enp, partn, 0, partn_data,
+ total_length)) != 0)
+ goto fail7;
+
+ /* Unlock the partition */
+ hunt_nvram_partn_unlock(enp, partn);
+
+ EFSYS_KMEM_FREE(enp->en_esip, partn_size, partn_data);
+
+ return (0);
+
+fail7:
+ EFSYS_PROBE(fail7);
+fail6:
+ EFSYS_PROBE(fail6);
+fail5:
+ EFSYS_PROBE(fail5);
+fail4:
+ EFSYS_PROBE(fail4);
+
+ hunt_nvram_partn_unlock(enp, partn);
+fail3:
+ EFSYS_PROBE(fail3);
+
+ EFSYS_KMEM_FREE(enp->en_esip, partn_size, partn_data);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nvram_partn_size(
+ __in efx_nic_t *enp,
+ __in unsigned int partn,
+ __out size_t *sizep)
+{
+ int rc;
+
+ if ((rc = efx_mcdi_nvram_info(enp, partn, sizep, NULL, NULL)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nvram_partn_lock(
+ __in efx_nic_t *enp,
+ __in unsigned int partn)
+{
+ int rc;
+
+ if ((rc = efx_mcdi_nvram_update_start(enp, partn)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nvram_partn_read(
+ __in efx_nic_t *enp,
+ __in unsigned int partn,
+ __in unsigned int offset,
+ __out_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ size_t chunk;
+ int rc;
+
+ while (size > 0) {
+ chunk = MIN(size, HUNTINGTON_NVRAM_CHUNK);
+
+ if ((rc = efx_mcdi_nvram_read(enp, partn, offset,
+ data, chunk)) != 0) {
+ goto fail1;
+ }
+
+ size -= chunk;
+ data += chunk;
+ offset += chunk;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nvram_partn_erase(
+ __in efx_nic_t *enp,
+ __in unsigned int partn,
+ __in unsigned int offset,
+ __in size_t size)
+{
+ int rc;
+
+ if ((rc = efx_mcdi_nvram_erase(enp, partn, offset, size)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nvram_partn_write(
+ __in efx_nic_t *enp,
+ __in unsigned int partn,
+ __in unsigned int offset,
+ __out_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ size_t chunk;
+ int rc;
+
+ while (size > 0) {
+ chunk = MIN(size, HUNTINGTON_NVRAM_CHUNK);
+
+ if ((rc = efx_mcdi_nvram_write(enp, partn, offset,
+ data, chunk)) != 0) {
+ goto fail1;
+ }
+
+ size -= chunk;
+ data += chunk;
+ offset += chunk;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_nvram_partn_unlock(
+ __in efx_nic_t *enp,
+ __in unsigned int partn)
+{
+ boolean_t reboot;
+ int rc;
+
+ reboot = B_FALSE;
+ if ((rc = efx_mcdi_nvram_update_finish(enp, partn, reboot)) != 0)
+ goto fail1;
+
+ return;
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+}
+
+ __checkReturn int
+hunt_nvram_partn_set_version(
+ __in efx_nic_t *enp,
+ __in unsigned int partn,
+ __in_ecount(4) uint16_t version[4])
+{
+ struct tlv_partition_version partn_version;
+ size_t size;
+ int rc;
+
+ /* Add or modify partition version TLV item */
+ partn_version.version_w = __CPU_TO_LE_16(version[0]);
+ partn_version.version_x = __CPU_TO_LE_16(version[1]);
+ partn_version.version_y = __CPU_TO_LE_16(version[2]);
+ partn_version.version_z = __CPU_TO_LE_16(version[3]);
+
+ size = sizeof (partn_version) - (2 * sizeof (uint32_t));
+
+ if ((rc = hunt_nvram_partn_write_tlv(enp,
+ NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG,
+ TLV_TAG_PARTITION_VERSION(partn),
+ (caddr_t)&partn_version.version_w, size)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_VPD || EFSYS_OPT_NVRAM */
+
+#if EFSYS_OPT_NVRAM
+
+typedef struct hunt_parttbl_entry_s {
+ unsigned int partn;
+ unsigned int port;
+ efx_nvram_type_t nvtype;
+} hunt_parttbl_entry_t;
+
+/* Translate EFX NVRAM types to firmware partition types */
+static hunt_parttbl_entry_t hunt_parttbl[] = {
+ {NVRAM_PARTITION_TYPE_MC_FIRMWARE, 1, EFX_NVRAM_MC_FIRMWARE},
+ {NVRAM_PARTITION_TYPE_MC_FIRMWARE, 2, EFX_NVRAM_MC_FIRMWARE},
+ {NVRAM_PARTITION_TYPE_MC_FIRMWARE, 3, EFX_NVRAM_MC_FIRMWARE},
+ {NVRAM_PARTITION_TYPE_MC_FIRMWARE, 4, EFX_NVRAM_MC_FIRMWARE},
+ {NVRAM_PARTITION_TYPE_MC_FIRMWARE_BACKUP, 1, EFX_NVRAM_MC_GOLDEN},
+ {NVRAM_PARTITION_TYPE_MC_FIRMWARE_BACKUP, 2, EFX_NVRAM_MC_GOLDEN},
+ {NVRAM_PARTITION_TYPE_MC_FIRMWARE_BACKUP, 3, EFX_NVRAM_MC_GOLDEN},
+ {NVRAM_PARTITION_TYPE_MC_FIRMWARE_BACKUP, 4, EFX_NVRAM_MC_GOLDEN},
+ {NVRAM_PARTITION_TYPE_EXPANSION_ROM, 1, EFX_NVRAM_BOOTROM},
+ {NVRAM_PARTITION_TYPE_EXPANSION_ROM, 2, EFX_NVRAM_BOOTROM},
+ {NVRAM_PARTITION_TYPE_EXPANSION_ROM, 3, EFX_NVRAM_BOOTROM},
+ {NVRAM_PARTITION_TYPE_EXPANSION_ROM, 4, EFX_NVRAM_BOOTROM},
+ {NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT0, 1, EFX_NVRAM_BOOTROM_CFG},
+ {NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT1, 2, EFX_NVRAM_BOOTROM_CFG},
+ {NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT2, 3, EFX_NVRAM_BOOTROM_CFG},
+ {NVRAM_PARTITION_TYPE_EXPROM_CONFIG_PORT3, 4, EFX_NVRAM_BOOTROM_CFG},
+ {NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG, 1, EFX_NVRAM_DYNAMIC_CFG},
+ {NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG, 2, EFX_NVRAM_DYNAMIC_CFG},
+ {NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG, 3, EFX_NVRAM_DYNAMIC_CFG},
+ {NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG, 4, EFX_NVRAM_DYNAMIC_CFG}
+};
+
+static __checkReturn hunt_parttbl_entry_t *
+hunt_parttbl_entry(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ hunt_parttbl_entry_t *entry;
+ int i;
+
+ EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
+
+ for (i = 0; i < EFX_ARRAY_SIZE(hunt_parttbl); i++) {
+ entry = &hunt_parttbl[i];
+
+ if (entry->port == emip->emi_port && entry->nvtype == type)
+ return (entry);
+ }
+
+ return (NULL);
+}
+
+
+#if EFSYS_OPT_DIAG
+
+ __checkReturn int
+hunt_nvram_test(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ hunt_parttbl_entry_t *entry;
+ unsigned int npartns = 0;
+ uint32_t *partns = NULL;
+ size_t size;
+ int i;
+ unsigned int j;
+ int rc;
+
+ /* Find supported partitions */
+ size = MC_CMD_NVRAM_PARTITIONS_OUT_TYPE_ID_MAXNUM * sizeof (uint32_t);
+ EFSYS_KMEM_ALLOC(enp->en_esip, size, partns);
+ if (partns == NULL) {
+ rc = ENOMEM;
+ goto fail1;
+ }
+
+ if ((rc = efx_mcdi_nvram_partitions(enp, (caddr_t)partns, size,
+ &npartns)) != 0) {
+ goto fail2;
+ }
+
+ /*
+ * Iterate over the list of supported partition types
+ * applicable to *this* port
+ */
+ for (i = 0; i < EFX_ARRAY_SIZE(hunt_parttbl); i++) {
+ entry = &hunt_parttbl[i];
+
+ if (entry->port != emip->emi_port)
+ continue;
+
+ for (j = 0; j < npartns; j++) {
+ if (entry->partn == partns[j]) {
+ rc = efx_mcdi_nvram_test(enp, entry->partn);
+ if (rc != 0)
+ goto fail3;
+ }
+ }
+ }
+
+ EFSYS_KMEM_FREE(enp->en_esip, size, partns);
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+ EFSYS_KMEM_FREE(enp->en_esip, size, partns);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_DIAG */
+
+ __checkReturn int
+hunt_nvram_size(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __out size_t *sizep)
+{
+ hunt_parttbl_entry_t *entry;
+ uint32_t partn;
+ int rc;
+
+ if ((entry = hunt_parttbl_entry(enp, type)) == NULL) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ partn = entry->partn;
+
+ if ((rc = hunt_nvram_partn_size(enp, partn, sizep)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ *sizep = 0;
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nvram_get_version(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __out uint32_t *subtypep,
+ __out_ecount(4) uint16_t version[4])
+{
+ hunt_parttbl_entry_t *entry;
+ uint32_t partn;
+ int rc;
+
+ if ((entry = hunt_parttbl_entry(enp, type)) == NULL) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ partn = entry->partn;
+
+ /* FIXME: get highest partn version from all ports */
+ /* FIXME: return partn description if available */
+
+ if ((rc = efx_mcdi_nvram_metadata(enp, partn, subtypep,
+ version, NULL, 0)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nvram_rw_start(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __out size_t *chunk_sizep)
+{
+ hunt_parttbl_entry_t *entry;
+ uint32_t partn;
+ int rc;
+
+ if ((entry = hunt_parttbl_entry(enp, type)) == NULL) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ partn = entry->partn;
+
+ if ((rc = hunt_nvram_partn_lock(enp, partn)) != 0)
+ goto fail2;
+
+ if (chunk_sizep != NULL)
+ *chunk_sizep = HUNTINGTON_NVRAM_CHUNK;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nvram_read_chunk(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __in unsigned int offset,
+ __out_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ hunt_parttbl_entry_t *entry;
+ int rc;
+
+ if ((entry = hunt_parttbl_entry(enp, type)) == NULL) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+ if ((rc = hunt_nvram_partn_read(enp, entry->partn,
+ offset, data, size)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nvram_erase(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type)
+{
+ hunt_parttbl_entry_t *entry;
+ size_t size;
+ int rc;
+
+ if ((entry = hunt_parttbl_entry(enp, type)) == NULL) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+ if ((rc = hunt_nvram_partn_size(enp, entry->partn, &size)) != 0)
+ goto fail2;
+
+ if ((rc = hunt_nvram_partn_erase(enp, entry->partn, 0, size)) != 0)
+ goto fail3;
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_nvram_write_chunk(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __in unsigned int offset,
+ __in_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ hunt_parttbl_entry_t *entry;
+ int rc;
+
+ if ((entry = hunt_parttbl_entry(enp, type)) == NULL) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+ if ((rc = hunt_nvram_partn_write(enp, entry->partn,
+ offset, data, size)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_nvram_rw_finish(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type)
+{
+ hunt_parttbl_entry_t *entry;
+
+ if ((entry = hunt_parttbl_entry(enp, type)) != NULL)
+ hunt_nvram_partn_unlock(enp, entry->partn);
+}
+
+ __checkReturn int
+hunt_nvram_set_version(
+ __in efx_nic_t *enp,
+ __in efx_nvram_type_t type,
+ __in_ecount(4) uint16_t version[4])
+{
+ hunt_parttbl_entry_t *entry;
+ unsigned int partn;
+ int rc;
+
+ if ((entry = hunt_parttbl_entry(enp, type)) == NULL) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ partn = entry->partn;
+
+ if ((rc = hunt_nvram_partn_set_version(enp, partn, version)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_NVRAM */
+
+#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_phy.c b/sys/dev/sfxge/common/hunt_phy.c
new file mode 100644
index 0000000..1cffea2
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_phy.c
@@ -0,0 +1,701 @@
+/*-
+ * Copyright (c) 2012-2015 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_impl.h"
+
+#if EFSYS_OPT_HUNTINGTON
+
+static void
+hunt_phy_decode_cap(
+ __in uint32_t mcdi_cap,
+ __out uint32_t *maskp)
+{
+ /*
+ * TBD: consider common Siena/Hunt function: Hunt is a superset of
+ * Siena here (adds 40G)
+ */
+
+ uint32_t mask;
+
+ mask = 0;
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_10HDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_10HDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_10FDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_10FDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_100HDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_100HDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_100FDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_100FDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_1000HDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_1000HDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_1000FDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_1000FDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_10000FDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_10000FDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_40000FDX_LBN))
+ mask |= (1 << EFX_PHY_CAP_40000FDX);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_PAUSE_LBN))
+ mask |= (1 << EFX_PHY_CAP_PAUSE);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_ASYM_LBN))
+ mask |= (1 << EFX_PHY_CAP_ASYM);
+ if (mcdi_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
+ mask |= (1 << EFX_PHY_CAP_AN);
+
+ *maskp = mask;
+}
+
+static void
+hunt_phy_decode_link_mode(
+ __in efx_nic_t *enp,
+ __in uint32_t link_flags,
+ __in unsigned int speed,
+ __in unsigned int fcntl,
+ __out efx_link_mode_t *link_modep,
+ __out unsigned int *fcntlp)
+{
+ /*
+ * TBD: consider common Siena/Hunt function: Hunt is a superset of
+ * Siena here (adds 40G and generate-only flow control)
+ */
+
+ boolean_t fd = !!(link_flags &
+ (1 << MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN));
+ boolean_t up = !!(link_flags &
+ (1 << MC_CMD_GET_LINK_OUT_LINK_UP_LBN));
+
+ _NOTE(ARGUNUSED(enp))
+
+ if (!up)
+ *link_modep = EFX_LINK_DOWN;
+ else if (speed == 40000 && fd)
+ *link_modep = EFX_LINK_40000FDX;
+ else if (speed == 10000 && fd)
+ *link_modep = EFX_LINK_10000FDX;
+ else if (speed == 1000)
+ *link_modep = fd ? EFX_LINK_1000FDX : EFX_LINK_1000HDX;
+ else if (speed == 100)
+ *link_modep = fd ? EFX_LINK_100FDX : EFX_LINK_100HDX;
+ else if (speed == 10)
+ *link_modep = fd ? EFX_LINK_10FDX : EFX_LINK_10HDX;
+ else
+ *link_modep = EFX_LINK_UNKNOWN;
+
+ if (fcntl == MC_CMD_FCNTL_OFF)
+ *fcntlp = 0;
+ else if (fcntl == MC_CMD_FCNTL_RESPOND)
+ *fcntlp = EFX_FCNTL_RESPOND;
+ else if (fcntl == MC_CMD_FCNTL_GENERATE)
+ *fcntlp = EFX_FCNTL_GENERATE;
+ else if (fcntl == MC_CMD_FCNTL_BIDIR)
+ *fcntlp = EFX_FCNTL_RESPOND | EFX_FCNTL_GENERATE;
+ else {
+ EFSYS_PROBE1(mc_pcol_error, int, fcntl);
+ *fcntlp = 0;
+ }
+}
+
+
+ void
+hunt_phy_link_ev(
+ __in efx_nic_t *enp,
+ __in efx_qword_t *eqp,
+ __out efx_link_mode_t *link_modep)
+{
+ /*
+ * TBD: consider common Siena/Hunt function: Hunt is a superset of
+ * Siena here (adds 40G)
+ */
+
+ efx_port_t *epp = &(enp->en_port);
+ unsigned int link_flags;
+ unsigned int speed;
+ unsigned int fcntl;
+ efx_link_mode_t link_mode;
+ uint32_t lp_cap_mask;
+
+ /*
+ * Convert the LINKCHANGE speed enumeration into mbit/s, in the
+ * same way as GET_LINK encodes the speed
+ */
+ switch (MCDI_EV_FIELD(eqp, LINKCHANGE_SPEED)) {
+ case MCDI_EVENT_LINKCHANGE_SPEED_100M:
+ speed = 100;
+ break;
+ case MCDI_EVENT_LINKCHANGE_SPEED_1G:
+ speed = 1000;
+ break;
+ case MCDI_EVENT_LINKCHANGE_SPEED_10G:
+ speed = 10000;
+ break;
+ case MCDI_EVENT_LINKCHANGE_SPEED_40G:
+ speed = 40000;
+ break;
+ default:
+ speed = 0;
+ break;
+ }
+
+ link_flags = MCDI_EV_FIELD(eqp, LINKCHANGE_LINK_FLAGS);
+ hunt_phy_decode_link_mode(enp, link_flags, speed,
+ MCDI_EV_FIELD(eqp, LINKCHANGE_FCNTL),
+ &link_mode, &fcntl);
+ hunt_phy_decode_cap(MCDI_EV_FIELD(eqp, LINKCHANGE_LP_CAP),
+ &lp_cap_mask);
+
+ /*
+ * It's safe to update ep_lp_cap_mask without the driver's port lock
+ * because presumably any concurrently running efx_port_poll() is
+ * only going to arrive at the same value.
+ *
+ * ep_fcntl has two meanings. It's either the link common fcntl
+ * (if the PHY supports AN), or it's the forced link state. If
+ * the former, it's safe to update the value for the same reason as
+ * for ep_lp_cap_mask. If the latter, then just ignore the value,
+ * because we can race with efx_mac_fcntl_set().
+ */
+ epp->ep_lp_cap_mask = lp_cap_mask;
+ epp->ep_fcntl = fcntl;
+
+ *link_modep = link_mode;
+}
+
+ __checkReturn int
+hunt_phy_power(
+ __in efx_nic_t *enp,
+ __in boolean_t power)
+{
+ /* TBD: consider common Siena/Hunt function: essentially identical */
+
+ int rc;
+
+ if (!power)
+ return (0);
+
+ /* Check if the PHY is a zombie */
+ if ((rc = hunt_phy_verify(enp)) != 0)
+ goto fail1;
+
+ enp->en_reset_flags |= EFX_RESET_PHY;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_phy_get_link(
+ __in efx_nic_t *enp,
+ __out hunt_link_state_t *hlsp)
+{
+ /*
+ * TBD: consider common Siena/Hunt function: Hunt is very similar
+ * (at least for now; not clear that the loopbacks should necessarily
+ * be quite the same...)
+ */
+
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_LINK_IN_LEN,
+ MC_CMD_GET_LINK_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_LINK;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_LINK_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_LINK_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_LINK_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ hunt_phy_decode_cap(MCDI_OUT_DWORD(req, GET_LINK_OUT_CAP),
+ &hlsp->hls_adv_cap_mask);
+ hunt_phy_decode_cap(MCDI_OUT_DWORD(req, GET_LINK_OUT_LP_CAP),
+ &hlsp->hls_lp_cap_mask);
+
+ hunt_phy_decode_link_mode(enp, MCDI_OUT_DWORD(req, GET_LINK_OUT_FLAGS),
+ MCDI_OUT_DWORD(req, GET_LINK_OUT_LINK_SPEED),
+ MCDI_OUT_DWORD(req, GET_LINK_OUT_FCNTL),
+ &hlsp->hls_link_mode, &hlsp->hls_fcntl);
+
+#if EFSYS_OPT_LOOPBACK
+ /* Assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespace agree */
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_NONE == EFX_LOOPBACK_OFF);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_DATA == EFX_LOOPBACK_DATA);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMAC == EFX_LOOPBACK_GMAC);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGMII == EFX_LOOPBACK_XGMII);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGXS == EFX_LOOPBACK_XGXS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI == EFX_LOOPBACK_XAUI);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII == EFX_LOOPBACK_GMII);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII == EFX_LOOPBACK_SGMII);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XGBR == EFX_LOOPBACK_XGBR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI == EFX_LOOPBACK_XFI);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XAUI_FAR == EFX_LOOPBACK_XAUI_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GMII_FAR == EFX_LOOPBACK_GMII_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_SGMII_FAR == EFX_LOOPBACK_SGMII_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_XFI_FAR == EFX_LOOPBACK_XFI_FAR);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_GPHY == EFX_LOOPBACK_GPHY);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PHYXS == EFX_LOOPBACK_PHY_XS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PCS == EFX_LOOPBACK_PCS);
+ EFX_STATIC_ASSERT(MC_CMD_LOOPBACK_PMAPMD == EFX_LOOPBACK_PMA_PMD);
+
+ hlsp->hls_loopback = MCDI_OUT_DWORD(req, GET_LINK_OUT_LOOPBACK_MODE);
+#endif /* EFSYS_OPT_LOOPBACK */
+
+ hlsp->hls_mac_up = MCDI_OUT_DWORD(req, GET_LINK_OUT_MAC_FAULT) == 0;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_phy_reconfigure(
+ __in efx_nic_t *enp)
+{
+ /*
+ * TBD: this is a little different for now (no LED support for Hunt
+ * yet), but ultimately should consider common Siena/Hunt function:
+ * Hunt should be a superset of Siena here (adds 40G)
+ */
+
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_port_t *epp = &(enp->en_port);
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_SET_LINK_IN_LEN,
+ MC_CMD_SET_LINK_OUT_LEN)];
+ uint32_t cap_mask;
+ unsigned int led_mode;
+ unsigned int speed;
+ int rc;
+
+ if (~encp->enc_func_flags & EFX_NIC_FUNC_LINKCTRL)
+ goto out;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_SET_LINK;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_SET_LINK_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_SET_LINK_OUT_LEN;
+
+ cap_mask = epp->ep_adv_cap_mask;
+ MCDI_IN_POPULATE_DWORD_10(req, SET_LINK_IN_CAP,
+ PHY_CAP_10HDX, (cap_mask >> EFX_PHY_CAP_10HDX) & 0x1,
+ PHY_CAP_10FDX, (cap_mask >> EFX_PHY_CAP_10FDX) & 0x1,
+ PHY_CAP_100HDX, (cap_mask >> EFX_PHY_CAP_100HDX) & 0x1,
+ PHY_CAP_100FDX, (cap_mask >> EFX_PHY_CAP_100FDX) & 0x1,
+ PHY_CAP_1000HDX, (cap_mask >> EFX_PHY_CAP_1000HDX) & 0x1,
+ PHY_CAP_1000FDX, (cap_mask >> EFX_PHY_CAP_1000FDX) & 0x1,
+ PHY_CAP_10000FDX, (cap_mask >> EFX_PHY_CAP_10000FDX) & 0x1,
+ PHY_CAP_PAUSE, (cap_mask >> EFX_PHY_CAP_PAUSE) & 0x1,
+ PHY_CAP_ASYM, (cap_mask >> EFX_PHY_CAP_ASYM) & 0x1,
+ PHY_CAP_AN, (cap_mask >> EFX_PHY_CAP_AN) & 0x1);
+ /* Too many fields for for POPULATE macros, so insert this afterwards */
+ MCDI_IN_SET_DWORD_FIELD(req, SET_LINK_IN_CAP,
+ PHY_CAP_40000FDX, (cap_mask >> EFX_PHY_CAP_40000FDX) & 0x1);
+
+#if EFSYS_OPT_LOOPBACK
+ MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_MODE,
+ epp->ep_loopback_type);
+ switch (epp->ep_loopback_link_mode) {
+ case EFX_LINK_100FDX:
+ speed = 100;
+ break;
+ case EFX_LINK_1000FDX:
+ speed = 1000;
+ break;
+ case EFX_LINK_10000FDX:
+ speed = 10000;
+ break;
+ case EFX_LINK_40000FDX:
+ speed = 40000;
+ break;
+ default:
+ speed = 0;
+ }
+#else
+ MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_MODE, MC_CMD_LOOPBACK_NONE);
+ speed = 0;
+#endif /* EFSYS_OPT_LOOPBACK */
+ MCDI_IN_SET_DWORD(req, SET_LINK_IN_LOOPBACK_SPEED, speed);
+
+#if EFSYS_OPT_PHY_FLAGS
+ MCDI_IN_SET_DWORD(req, SET_LINK_IN_FLAGS, epp->ep_phy_flags);
+#else
+ MCDI_IN_SET_DWORD(req, SET_LINK_IN_FLAGS, 0);
+#endif /* EFSYS_OPT_PHY_FLAGS */
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ /* And set the blink mode */
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_SET_ID_LED;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_SET_ID_LED_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_SET_ID_LED_OUT_LEN;
+
+#if EFSYS_OPT_PHY_LED_CONTROL
+ switch (epp->ep_phy_led_mode) {
+ case EFX_PHY_LED_DEFAULT:
+ led_mode = MC_CMD_LED_DEFAULT;
+ break;
+ case EFX_PHY_LED_OFF:
+ led_mode = MC_CMD_LED_OFF;
+ break;
+ case EFX_PHY_LED_ON:
+ led_mode = MC_CMD_LED_ON;
+ break;
+ default:
+ EFSYS_ASSERT(0);
+ led_mode = MC_CMD_LED_DEFAULT;
+ }
+
+ MCDI_IN_SET_DWORD(req, SET_ID_LED_IN_STATE, led_mode);
+#else
+ MCDI_IN_SET_DWORD(req, SET_ID_LED_IN_STATE, MC_CMD_LED_DEFAULT);
+#endif /* EFSYS_OPT_PHY_LED_CONTROL */
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+out:
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_phy_verify(
+ __in efx_nic_t *enp)
+{
+ /* TBD: consider common Siena/Hunt function: essentially identical */
+
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_GET_PHY_STATE_IN_LEN,
+ MC_CMD_GET_PHY_STATE_OUT_LEN)];
+ uint32_t state;
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_GET_PHY_STATE;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_PHY_STATE_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_PHY_STATE_OUT_LEN;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_GET_PHY_STATE_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ state = MCDI_OUT_DWORD(req, GET_PHY_STATE_OUT_STATE);
+ if (state != MC_CMD_PHY_STATE_OK) {
+ if (state != MC_CMD_PHY_STATE_ZOMBIE)
+ EFSYS_PROBE1(mc_pcol_error, int, state);
+ rc = ENOTACTIVE;
+ goto fail3;
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_phy_oui_get(
+ __in efx_nic_t *enp,
+ __out uint32_t *ouip)
+{
+ _NOTE(ARGUNUSED(enp, ouip))
+
+ return (ENOTSUP);
+}
+
+#if EFSYS_OPT_PHY_STATS
+
+ __checkReturn int
+hunt_phy_stats_update(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp,
+ __out_ecount(EFX_PHY_NSTATS) uint32_t *stat)
+{
+ /* TBD: no stats support in firmware yet */
+ _NOTE(ARGUNUSED(enp, esmp))
+ memset(stat, 0, EFX_PHY_NSTATS * sizeof (*stat));
+
+ return (0);
+}
+
+#endif /* EFSYS_OPT_PHY_STATS */
+
+#if EFSYS_OPT_PHY_PROPS
+
+#if EFSYS_OPT_NAMES
+
+extern const char *
+hunt_phy_prop_name(
+ __in efx_nic_t *enp,
+ __in unsigned int id)
+{
+ _NOTE(ARGUNUSED(enp, id))
+
+ return (NULL);
+}
+
+#endif /* EFSYS_OPT_NAMES */
+
+extern __checkReturn int
+hunt_phy_prop_get(
+ __in efx_nic_t *enp,
+ __in unsigned int id,
+ __in uint32_t flags,
+ __out uint32_t *valp)
+{
+ _NOTE(ARGUNUSED(enp, id, flags, valp))
+
+ return (ENOTSUP);
+}
+
+extern __checkReturn int
+hunt_phy_prop_set(
+ __in efx_nic_t *enp,
+ __in unsigned int id,
+ __in uint32_t val)
+{
+ _NOTE(ARGUNUSED(enp, id, val))
+
+ return (ENOTSUP);
+}
+
+#endif /* EFSYS_OPT_PHY_PROPS */
+
+#if EFSYS_OPT_BIST
+
+ __checkReturn int
+hunt_bist_enable_offline(
+ __in efx_nic_t *enp)
+{
+ int rc;
+
+ if ((rc = efx_mcdi_bist_enable_offline(enp)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_bist_start(
+ __in efx_nic_t *enp,
+ __in efx_bist_type_t type)
+{
+ int rc;
+
+ if ((rc = efx_mcdi_bist_start(enp, type)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_bist_poll(
+ __in efx_nic_t *enp,
+ __in efx_bist_type_t type,
+ __out efx_bist_result_t *resultp,
+ __out_opt __drv_when(count > 0, __notnull)
+ uint32_t *value_maskp,
+ __out_ecount_opt(count) __drv_when(count > 0, __notnull)
+ unsigned long *valuesp,
+ __in size_t count)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_POLL_BIST_IN_LEN,
+ MCDI_CTL_SDU_LEN_MAX)];
+ uint32_t value_mask = 0;
+ uint32_t result;
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_POLL_BIST;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_POLL_BIST_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MCDI_CTL_SDU_LEN_MAX;
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_POLL_BIST_OUT_RESULT_OFST + 4) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ if (count > 0)
+ (void) memset(valuesp, '\0', count * sizeof (unsigned long));
+
+ result = MCDI_OUT_DWORD(req, POLL_BIST_OUT_RESULT);
+
+ if (result == MC_CMD_POLL_BIST_FAILED &&
+ req.emr_out_length >= MC_CMD_POLL_BIST_OUT_MEM_LEN &&
+ count > EFX_BIST_MEM_ECC_FATAL) {
+ if (valuesp != NULL) {
+ valuesp[EFX_BIST_MEM_TEST] =
+ MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_TEST);
+ valuesp[EFX_BIST_MEM_ADDR] =
+ MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_ADDR);
+ valuesp[EFX_BIST_MEM_BUS] =
+ MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_BUS);
+ valuesp[EFX_BIST_MEM_EXPECT] =
+ MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_EXPECT);
+ valuesp[EFX_BIST_MEM_ACTUAL] =
+ MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_ACTUAL);
+ valuesp[EFX_BIST_MEM_ECC] =
+ MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_ECC);
+ valuesp[EFX_BIST_MEM_ECC_PARITY] =
+ MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_ECC_PARITY);
+ valuesp[EFX_BIST_MEM_ECC_FATAL] =
+ MCDI_OUT_DWORD(req, POLL_BIST_OUT_MEM_ECC_FATAL);
+ }
+ value_mask |= (1 << EFX_BIST_MEM_TEST) |
+ (1 << EFX_BIST_MEM_ADDR) |
+ (1 << EFX_BIST_MEM_BUS) |
+ (1 << EFX_BIST_MEM_EXPECT) |
+ (1 << EFX_BIST_MEM_ACTUAL) |
+ (1 << EFX_BIST_MEM_ECC) |
+ (1 << EFX_BIST_MEM_ECC_PARITY) |
+ (1 << EFX_BIST_MEM_ECC_FATAL);
+ } else if (result == MC_CMD_POLL_BIST_FAILED &&
+ encp->enc_phy_type == EFX_PHY_XFI_FARMI &&
+ req.emr_out_length >= MC_CMD_POLL_BIST_OUT_MRSFP_LEN &&
+ count > EFX_BIST_FAULT_CODE) {
+ if (valuesp != NULL)
+ valuesp[EFX_BIST_FAULT_CODE] =
+ MCDI_OUT_DWORD(req, POLL_BIST_OUT_MRSFP_TEST);
+ value_mask |= 1 << EFX_BIST_FAULT_CODE;
+ }
+
+ if (value_maskp != NULL)
+ *value_maskp = value_mask;
+
+ EFSYS_ASSERT(resultp != NULL);
+ if (result == MC_CMD_POLL_BIST_RUNNING)
+ *resultp = EFX_BIST_RESULT_RUNNING;
+ else if (result == MC_CMD_POLL_BIST_PASSED)
+ *resultp = EFX_BIST_RESULT_PASSED;
+ else
+ *resultp = EFX_BIST_RESULT_FAILED;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_bist_stop(
+ __in efx_nic_t *enp,
+ __in efx_bist_type_t type)
+{
+ /* There is no way to stop BIST on Huntinton. */
+ _NOTE(ARGUNUSED(enp, type))
+}
+
+#endif /* EFSYS_OPT_BIST */
+
+#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_rx.c b/sys/dev/sfxge/common/hunt_rx.c
new file mode 100644
index 0000000..991f293
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_rx.c
@@ -0,0 +1,765 @@
+/*-
+ * Copyright (c) 2012-2015 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_impl.h"
+
+
+#if EFSYS_OPT_HUNTINGTON
+
+
+static __checkReturn int
+efx_mcdi_init_rxq(
+ __in efx_nic_t *enp,
+ __in uint32_t size,
+ __in uint32_t target_evq,
+ __in uint32_t label,
+ __in uint32_t instance,
+ __in efsys_mem_t *esmp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[
+ MAX(MC_CMD_INIT_RXQ_IN_LEN(EFX_RXQ_NBUFS(EFX_RXQ_MAXNDESCS)),
+ MC_CMD_INIT_RXQ_OUT_LEN)];
+ int npages = EFX_RXQ_NBUFS(size);
+ int i;
+ efx_qword_t *dma_addr;
+ uint64_t addr;
+ int rc;
+
+ EFSYS_ASSERT3U(size, <=, EFX_RXQ_MAXNDESCS);
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_INIT_RXQ;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_INIT_RXQ_IN_LEN(npages);
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_INIT_RXQ_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_SIZE, size);
+ MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_TARGET_EVQ, target_evq);
+ MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_LABEL, label);
+ MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_INSTANCE, instance);
+ MCDI_IN_POPULATE_DWORD_5(req, INIT_RXQ_IN_FLAGS,
+ INIT_RXQ_IN_FLAG_BUFF_MODE, 0,
+ INIT_RXQ_IN_FLAG_HDR_SPLIT, 0,
+ INIT_RXQ_IN_FLAG_TIMESTAMP, 0,
+ INIT_RXQ_IN_CRC_MODE, 0,
+ INIT_RXQ_IN_FLAG_PREFIX, 1);
+ MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_OWNER_ID, 0);
+ MCDI_IN_SET_DWORD(req, INIT_RXQ_IN_PORT_ID, EVB_PORT_ID_ASSIGNED);
+
+ dma_addr = MCDI_IN2(req, efx_qword_t, INIT_RXQ_IN_DMA_ADDR);
+ addr = EFSYS_MEM_ADDR(esmp);
+
+ for (i = 0; i < npages; i++) {
+ EFX_POPULATE_QWORD_2(*dma_addr,
+ EFX_DWORD_1, (uint32_t)(addr >> 32),
+ EFX_DWORD_0, (uint32_t)(addr & 0xffffffff));
+
+ dma_addr++;
+ addr += EFX_BUF_SIZE;
+ }
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_fini_rxq(
+ __in efx_nic_t *enp,
+ __in uint32_t instance)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_FINI_RXQ_IN_LEN,
+ MC_CMD_FINI_RXQ_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_FINI_RXQ;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_FINI_RXQ_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_FINI_RXQ_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, FINI_RXQ_IN_INSTANCE, instance);
+
+ efx_mcdi_execute(enp, &req);
+
+ if ((req.emr_rc != 0) && (req.emr_rc != MC_CMD_ERR_EALREADY)) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+#if EFSYS_OPT_RX_SCALE
+static __checkReturn int
+efx_mcdi_rss_context_alloc(
+ __in efx_nic_t *enp,
+ __out uint32_t *rss_contextp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN,
+ MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN)];
+ uint32_t rss_context;
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_RSS_CONTEXT_ALLOC;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_RSS_CONTEXT_ALLOC_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, RSS_CONTEXT_ALLOC_IN_UPSTREAM_PORT_ID,
+ EVB_PORT_ID_ASSIGNED);
+ MCDI_IN_SET_DWORD(req, RSS_CONTEXT_ALLOC_IN_TYPE,
+ MC_CMD_RSS_CONTEXT_ALLOC_IN_TYPE_EXCLUSIVE);
+ /* NUM_QUEUES is only used to validate indirection table offsets */
+ MCDI_IN_SET_DWORD(req, RSS_CONTEXT_ALLOC_IN_NUM_QUEUES, 64);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ if (req.emr_out_length_used < MC_CMD_RSS_CONTEXT_ALLOC_OUT_LEN) {
+ rc = EMSGSIZE;
+ goto fail2;
+ }
+
+ rss_context = MCDI_OUT_DWORD(req, RSS_CONTEXT_ALLOC_OUT_RSS_CONTEXT_ID);
+ if (rss_context == HUNTINGTON_RSS_CONTEXT_INVALID) {
+ rc = ENOENT;
+ goto fail3;
+ }
+
+ *rss_contextp = rss_context;
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+#if EFSYS_OPT_RX_SCALE
+static int
+efx_mcdi_rss_context_free(
+ __in efx_nic_t *enp,
+ __in uint32_t rss_context)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_FREE_IN_LEN,
+ MC_CMD_RSS_CONTEXT_FREE_OUT_LEN)];
+ int rc;
+
+ if (rss_context == HUNTINGTON_RSS_CONTEXT_INVALID) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_RSS_CONTEXT_FREE;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_RSS_CONTEXT_FREE_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_RSS_CONTEXT_FREE_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, RSS_CONTEXT_FREE_IN_RSS_CONTEXT_ID, rss_context);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+#if EFSYS_OPT_RX_SCALE
+static int
+efx_mcdi_rss_context_set_flags(
+ __in efx_nic_t *enp,
+ __in uint32_t rss_context,
+ __in efx_rx_hash_type_t type)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN,
+ MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN)];
+ int rc;
+
+ if (rss_context == HUNTINGTON_RSS_CONTEXT_INVALID) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_RSS_CONTEXT_SET_FLAGS;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_RSS_CONTEXT_SET_FLAGS_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_RSS_CONTEXT_SET_FLAGS_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, RSS_CONTEXT_SET_FLAGS_IN_RSS_CONTEXT_ID,
+ rss_context);
+
+ MCDI_IN_POPULATE_DWORD_4(req, RSS_CONTEXT_SET_FLAGS_IN_FLAGS,
+ RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV4_EN,
+ (type & (1U << EFX_RX_HASH_IPV4)) ? 1 : 0,
+ RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV4_EN,
+ (type & (1U << EFX_RX_HASH_TCPIPV4)) ? 1 : 0,
+ RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_IPV6_EN,
+ (type & (1U << EFX_RX_HASH_IPV6)) ? 1 : 0,
+ RSS_CONTEXT_SET_FLAGS_IN_TOEPLITZ_TCPV6_EN,
+ (type & (1U << EFX_RX_HASH_TCPIPV6)) ? 1 : 0);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+#if EFSYS_OPT_RX_SCALE
+static int
+efx_mcdi_rss_context_set_key(
+ __in efx_nic_t *enp,
+ __in uint32_t rss_context,
+ __in_ecount(n) uint8_t *key,
+ __in size_t n)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_KEY_IN_LEN,
+ MC_CMD_RSS_CONTEXT_SET_KEY_OUT_LEN)];
+ int rc;
+
+ if (rss_context == HUNTINGTON_RSS_CONTEXT_INVALID) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_RSS_CONTEXT_SET_KEY;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_RSS_CONTEXT_SET_KEY_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_RSS_CONTEXT_SET_KEY_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, RSS_CONTEXT_SET_KEY_IN_RSS_CONTEXT_ID,
+ rss_context);
+
+ EFSYS_ASSERT3U(n, ==, MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_LEN);
+ if (n != MC_CMD_RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY_LEN) {
+ rc = EINVAL;
+ goto fail2;
+ }
+
+ memcpy(MCDI_IN2(req, uint8_t, RSS_CONTEXT_SET_KEY_IN_TOEPLITZ_KEY),
+ key, n);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail3;
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+#if EFSYS_OPT_RX_SCALE
+static int
+efx_mcdi_rss_context_set_table(
+ __in efx_nic_t *enp,
+ __in uint32_t rss_context,
+ __in_ecount(n) unsigned int *table,
+ __in size_t n)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN,
+ MC_CMD_RSS_CONTEXT_SET_TABLE_OUT_LEN)];
+ uint8_t *req_table;
+ int i, rc;
+
+ if (rss_context == HUNTINGTON_RSS_CONTEXT_INVALID) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_RSS_CONTEXT_SET_TABLE;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_RSS_CONTEXT_SET_TABLE_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_RSS_CONTEXT_SET_TABLE_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, RSS_CONTEXT_SET_TABLE_IN_RSS_CONTEXT_ID,
+ rss_context);
+
+ req_table =
+ MCDI_IN2(req, uint8_t, RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE);
+
+ for (i = 0;
+ i < MC_CMD_RSS_CONTEXT_SET_TABLE_IN_INDIRECTION_TABLE_LEN;
+ i++) {
+ req_table[i] = (n > 0) ? (uint8_t)table[i % n] : 0;
+ }
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+
+ __checkReturn int
+hunt_rx_init(
+ __in efx_nic_t *enp)
+{
+#if EFSYS_OPT_RX_SCALE
+
+ if (efx_mcdi_rss_context_alloc(enp, &enp->en_rss_context) == 0) {
+ /*
+ * Allocated an exclusive RSS context, which allows both the
+ * indirection table and key to be modified.
+ */
+ enp->en_rss_support = EFX_RX_SCALE_EXCLUSIVE;
+ enp->en_hash_support = EFX_RX_HASH_AVAILABLE;
+ } else {
+ /*
+ * Failed to allocate an exclusive RSS context. Continue
+ * operation without support for RSS. The pseudo-header in
+ * received packets will not contain a Toeplitz hash value.
+ */
+ enp->en_rss_support = EFX_RX_SCALE_UNAVAILABLE;
+ enp->en_hash_support = EFX_RX_HASH_UNAVAILABLE;
+ }
+
+#endif /* EFSYS_OPT_RX_SCALE */
+
+ return (0);
+}
+
+#if EFSYS_OPT_RX_HDR_SPLIT
+ __checkReturn int
+hunt_rx_hdr_split_enable(
+ __in efx_nic_t *enp,
+ __in unsigned int hdr_buf_size,
+ __in unsigned int pld_buf_size)
+{
+ int rc;
+
+ /* FIXME */
+ _NOTE(ARGUNUSED(enp, hdr_buf_size, pld_buf_size))
+ if (B_FALSE) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ /* FIXME */
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_HDR_SPLIT */
+
+#if EFSYS_OPT_RX_SCATTER
+ __checkReturn int
+hunt_rx_scatter_enable(
+ __in efx_nic_t *enp,
+ __in unsigned int buf_size)
+{
+ _NOTE(ARGUNUSED(enp, buf_size))
+ return (0);
+}
+#endif /* EFSYS_OPT_RX_SCATTER */
+
+#if EFSYS_OPT_RX_SCALE
+ __checkReturn int
+hunt_rx_scale_mode_set(
+ __in efx_nic_t *enp,
+ __in efx_rx_hash_alg_t alg,
+ __in efx_rx_hash_type_t type,
+ __in boolean_t insert)
+{
+ int rc;
+
+ EFSYS_ASSERT3U(alg, ==, EFX_RX_HASHALG_TOEPLITZ);
+ EFSYS_ASSERT3U(insert, ==, B_TRUE);
+
+ if ((alg != EFX_RX_HASHALG_TOEPLITZ) || (insert == B_FALSE)) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ if (enp->en_rss_support == EFX_RX_SCALE_UNAVAILABLE) {
+ rc = ENOTSUP;
+ goto fail2;
+ }
+
+ if ((rc = efx_mcdi_rss_context_set_flags(enp,
+ enp->en_rss_context, type)) != 0)
+ goto fail3;
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+#if EFSYS_OPT_RX_SCALE
+ __checkReturn int
+hunt_rx_scale_key_set(
+ __in efx_nic_t *enp,
+ __in_ecount(n) uint8_t *key,
+ __in size_t n)
+{
+ int rc;
+
+ if (enp->en_rss_support == EFX_RX_SCALE_UNAVAILABLE) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+ if ((rc = efx_mcdi_rss_context_set_key(enp,
+ enp->en_rss_context, key, n)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+#if EFSYS_OPT_RX_SCALE
+ __checkReturn int
+hunt_rx_scale_tbl_set(
+ __in efx_nic_t *enp,
+ __in_ecount(n) unsigned int *table,
+ __in size_t n)
+{
+ int rc;
+
+ if (enp->en_rss_support == EFX_RX_SCALE_UNAVAILABLE) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+
+ if ((rc = efx_mcdi_rss_context_set_table(enp,
+ enp->en_rss_context, table, n)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+#endif /* EFSYS_OPT_RX_SCALE */
+
+ void
+hunt_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_qword_t qword;
+ unsigned int i;
+ unsigned int offset;
+ unsigned int id;
+
+ /* The client driver must not overfill the queue */
+ EFSYS_ASSERT3U(added - completed + n, <=,
+ EFX_RXQ_LIMIT(erp->er_mask + 1));
+
+ id = added & (erp->er_mask);
+ for (i = 0; i < n; i++) {
+ EFSYS_PROBE4(rx_post, unsigned int, erp->er_index,
+ unsigned int, id, efsys_dma_addr_t, addrp[i],
+ size_t, size);
+
+ EFX_POPULATE_QWORD_3(qword,
+ ESF_DZ_RX_KER_BYTE_CNT, (uint32_t)(size),
+ ESF_DZ_RX_KER_BUF_ADDR_DW0,
+ (uint32_t)(addrp[i] & 0xffffffff),
+ ESF_DZ_RX_KER_BUF_ADDR_DW1,
+ (uint32_t)(addrp[i] >> 32));
+
+ offset = id * sizeof (efx_qword_t);
+ EFSYS_MEM_WRITEQ(erp->er_esmp, offset, &qword);
+
+ id = (id + 1) & (erp->er_mask);
+ }
+}
+
+ void
+hunt_rx_qpush(
+ __in efx_rxq_t *erp,
+ __in unsigned int added,
+ __inout unsigned int *pushedp)
+{
+ efx_nic_t *enp = erp->er_enp;
+ unsigned int pushed = *pushedp;
+ uint32_t wptr;
+ efx_dword_t dword;
+
+ /* Hardware has alignment restriction for WPTR */
+ wptr = P2ALIGN(added, HUNTINGTON_RX_WPTR_ALIGN);
+ if (pushed == wptr)
+ return;
+
+ *pushedp = wptr;
+
+ /* Push the populated descriptors out */
+ wptr &= erp->er_mask;
+
+ EFX_POPULATE_DWORD_1(dword, ERF_DZ_RX_DESC_WPTR, wptr);
+
+ /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
+ EFX_DMA_SYNC_QUEUE_FOR_DEVICE(erp->er_esmp, erp->er_mask + 1,
+ wptr, pushed & erp->er_mask);
+ EFSYS_PIO_WRITE_BARRIER();
+ EFX_BAR_TBL_WRITED(enp, ER_DZ_RX_DESC_UPD_REG,
+ erp->er_index, &dword, B_FALSE);
+}
+
+ __checkReturn int
+hunt_rx_qflush(
+ __in efx_rxq_t *erp)
+{
+ efx_nic_t *enp = erp->er_enp;
+ int rc;
+
+ if ((rc = efx_mcdi_fini_rxq(enp, erp->er_index)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_rx_qenable(
+ __in efx_rxq_t *erp)
+{
+ /* FIXME */
+ _NOTE(ARGUNUSED(erp))
+ /* FIXME */
+}
+
+ __checkReturn int
+hunt_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,
+ __in efx_rxq_t *erp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ int rc;
+
+ _NOTE(ARGUNUSED(erp))
+
+ EFX_STATIC_ASSERT(EFX_EV_RX_NLABELS == (1 << ESF_DZ_RX_QLABEL_WIDTH));
+ EFSYS_ASSERT3U(label, <, EFX_EV_RX_NLABELS);
+ EFSYS_ASSERT3U(enp->en_rx_qcount + 1, <, encp->enc_rxq_limit);
+
+ EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MAXNDESCS));
+ EFX_STATIC_ASSERT(ISP2(EFX_RXQ_MINNDESCS));
+
+ if (!ISP2(n) || (n < EFX_RXQ_MINNDESCS) || (n > EFX_RXQ_MAXNDESCS)) {
+ rc = EINVAL;
+ goto fail1;
+ }
+ if (index >= encp->enc_rxq_limit) {
+ rc = EINVAL;
+ goto fail2;
+ }
+
+ /*
+ * FIXME: Siena code handles different queue types (default, header
+ * split, scatter); we'll need to do something more here later, but
+ * all that stuff is TBD for now.
+ */
+
+ if ((rc = efx_mcdi_init_rxq(enp, n, eep->ee_index, label, index,
+ esmp)) != 0)
+ goto fail3;
+
+ erp->er_eep = eep;
+ erp->er_label = label;
+
+ hunt_ev_rxlabel_init(eep, erp, label);
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_rx_qdestroy(
+ __in efx_rxq_t *erp)
+{
+ efx_nic_t *enp = erp->er_enp;
+ efx_evq_t *eep = erp->er_eep;
+ unsigned int label = erp->er_label;
+
+ hunt_ev_rxlabel_fini(eep, label);
+
+ EFSYS_ASSERT(enp->en_rx_qcount != 0);
+ --enp->en_rx_qcount;
+
+ EFSYS_KMEM_FREE(enp->en_esip, sizeof (efx_rxq_t), erp);
+}
+
+ void
+hunt_rx_fini(
+ __in efx_nic_t *enp)
+{
+#if EFSYS_OPT_RX_SCALE
+ if (enp->en_rss_support != EFX_RX_SCALE_UNAVAILABLE) {
+ (void) efx_mcdi_rss_context_free(enp, enp->en_rss_context);
+ }
+ enp->en_rss_context = 0;
+ enp->en_rss_support = EFX_RX_SCALE_UNAVAILABLE;
+#else
+ _NOTE(ARGUNUSED(enp))
+#endif /* EFSYS_OPT_RX_SCALE */
+}
+
+#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_sram.c b/sys/dev/sfxge/common/hunt_sram.c
new file mode 100644
index 0000000..947e033
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_sram.c
@@ -0,0 +1,69 @@
+/*-
+ * Copyright (c) 2012-2015 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_impl.h"
+
+#if EFSYS_OPT_HUNTINGTON
+
+
+#if EFSYS_OPT_DIAG
+
+ __checkReturn int
+hunt_sram_test(
+ __in efx_nic_t *enp,
+ __in efx_sram_pattern_fn_t func)
+{
+ int rc;
+
+ /* FIXME */
+ _NOTE(ARGUNUSED(enp))
+ _NOTE(ARGUNUSED(func))
+ if (B_FALSE) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ /* FIXME */
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+#endif /* EFSYS_OPT_DIAG */
+
+#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_tx.c b/sys/dev/sfxge/common/hunt_tx.c
new file mode 100755
index 0000000..ee5691a
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_tx.c
@@ -0,0 +1,679 @@
+/*-
+ * Copyright (c) 2012-2015 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_impl.h"
+
+
+#if EFSYS_OPT_HUNTINGTON
+
+#if EFSYS_OPT_QSTATS
+#define EFX_TX_QSTAT_INCR(_etp, _stat) \
+ do { \
+ (_etp)->et_stat[_stat]++; \
+ _NOTE(CONSTANTCONDITION) \
+ } while (B_FALSE)
+#else
+#define EFX_TX_QSTAT_INCR(_etp, _stat)
+#endif
+
+static __checkReturn int
+efx_mcdi_init_txq(
+ __in efx_nic_t *enp,
+ __in uint32_t size,
+ __in uint32_t target_evq,
+ __in uint32_t label,
+ __in uint32_t instance,
+ __in uint16_t flags,
+ __in efsys_mem_t *esmp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_INIT_TXQ_IN_LEN(EFX_TXQ_MAX_BUFS),
+ MC_CMD_INIT_TXQ_OUT_LEN)];
+ efx_qword_t *dma_addr;
+ uint64_t addr;
+ int npages;
+ int i;
+ int rc;
+
+ EFSYS_ASSERT(EFX_TXQ_MAX_BUFS >=
+ EFX_TXQ_NBUFS(EFX_TXQ_MAXNDESCS(&enp->en_nic_cfg)));
+
+ npages = EFX_TXQ_NBUFS(size);
+ if (npages > MC_CMD_INIT_TXQ_IN_DMA_ADDR_MAXNUM) {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_INIT_TXQ;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_INIT_TXQ_IN_LEN(npages);
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_INIT_TXQ_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, INIT_TXQ_IN_SIZE, size);
+ MCDI_IN_SET_DWORD(req, INIT_TXQ_IN_TARGET_EVQ, target_evq);
+ MCDI_IN_SET_DWORD(req, INIT_TXQ_IN_LABEL, label);
+ MCDI_IN_SET_DWORD(req, INIT_TXQ_IN_INSTANCE, instance);
+
+ MCDI_IN_POPULATE_DWORD_6(req, INIT_TXQ_IN_FLAGS,
+ INIT_TXQ_IN_FLAG_BUFF_MODE, 0,
+ INIT_TXQ_IN_FLAG_IP_CSUM_DIS, (flags & EFX_CKSUM_IPV4) ? 0 : 1,
+ INIT_TXQ_IN_FLAG_TCP_CSUM_DIS, (flags & EFX_CKSUM_TCPUDP) ? 0 : 1,
+ INIT_TXQ_IN_FLAG_TCP_UDP_ONLY, 0,
+ INIT_TXQ_IN_CRC_MODE, 0,
+ INIT_TXQ_IN_FLAG_TIMESTAMP, 0);
+
+ MCDI_IN_SET_DWORD(req, INIT_TXQ_IN_OWNER_ID, 0);
+ MCDI_IN_SET_DWORD(req, INIT_TXQ_IN_PORT_ID, EVB_PORT_ID_ASSIGNED);
+
+ dma_addr = MCDI_IN2(req, efx_qword_t, INIT_TXQ_IN_DMA_ADDR);
+ addr = EFSYS_MEM_ADDR(esmp);
+
+ for (i = 0; i < npages; i++) {
+ EFX_POPULATE_QWORD_2(*dma_addr,
+ EFX_DWORD_1, (uint32_t)(addr >> 32),
+ EFX_DWORD_0, (uint32_t)(addr & 0xffffffff));
+
+ dma_addr++;
+ addr += EFX_BUF_SIZE;
+ }
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail2;
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_fini_txq(
+ __in efx_nic_t *enp,
+ __in uint32_t instance)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_FINI_TXQ_IN_LEN,
+ MC_CMD_FINI_TXQ_OUT_LEN)];
+ int rc;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_FINI_TXQ;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_FINI_TXQ_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_FINI_TXQ_OUT_LEN;
+
+ MCDI_IN_SET_DWORD(req, FINI_TXQ_IN_INSTANCE, instance);
+
+ efx_mcdi_execute(enp, &req);
+
+ if ((req.emr_rc != 0) && (req.emr_rc != MC_CMD_ERR_EALREADY)) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_tx_init(
+ __in efx_nic_t *enp)
+{
+ _NOTE(ARGUNUSED(enp))
+ return (0);
+}
+
+ void
+hunt_tx_fini(
+ __in efx_nic_t *enp)
+{
+ _NOTE(ARGUNUSED(enp))
+}
+
+ __checkReturn int
+hunt_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,
+ __in efx_txq_t *etp,
+ __out unsigned int *addedp)
+{
+ efx_qword_t desc;
+ int rc;
+
+
+ if ((rc = efx_mcdi_init_txq(enp, n, eep->ee_index, label, index, flags,
+ esmp)) != 0)
+ goto fail1;
+
+ /*
+ * A previous user of this TX queue may have written a descriptor to the
+ * TX push collector, but not pushed the doorbell (e.g. after a crash).
+ * The next doorbell write would then push the stale descriptor.
+ *
+ * Ensure the (per network port) TX push collector is cleared by writing
+ * a no-op TX option descriptor. See bug29981 for details.
+ */
+ *addedp = 1;
+ EFX_POPULATE_QWORD_4(desc,
+ ESF_DZ_TX_DESC_IS_OPT, 1,
+ ESF_DZ_TX_OPTION_TYPE, ESE_DZ_TX_OPTION_DESC_CRC_CSUM,
+ ESF_DZ_TX_OPTION_UDP_TCP_CSUM, (flags & EFX_CKSUM_TCPUDP) ? 1 : 0,
+ ESF_DZ_TX_OPTION_IP_CSUM, (flags & EFX_CKSUM_IPV4) ? 1 : 0);
+
+ EFSYS_MEM_WRITEQ(etp->et_esmp, 0, &desc);
+ hunt_tx_qpush(etp, *addedp, 0);
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_tx_qdestroy(
+ __in efx_txq_t *etp)
+{
+ /* FIXME */
+ _NOTE(ARGUNUSED(etp))
+ /* FIXME */
+}
+
+ __checkReturn int
+hunt_tx_qpio_enable(
+ __in efx_txq_t *etp)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efx_piobuf_handle_t handle;
+ int rc;
+
+ if (etp->et_pio_size != 0) {
+ rc = EALREADY;
+ goto fail1;
+ }
+
+ /* Sub-allocate a PIO block from a piobuf */
+ if ((rc = hunt_nic_pio_alloc(enp,
+ &etp->et_pio_bufnum,
+ &handle,
+ &etp->et_pio_blknum,
+ &etp->et_pio_offset,
+ &etp->et_pio_size)) != 0) {
+ goto fail2;
+ }
+ EFSYS_ASSERT3U(etp->et_pio_size, !=, 0);
+
+ /* Link the piobuf to this TXQ */
+ if ((rc = hunt_nic_pio_link(enp, etp->et_index, handle)) != 0) {
+ goto fail3;
+ }
+
+ /*
+ * et_pio_offset is the offset of the sub-allocated block within the
+ * hardware PIO buffer. It is used as the buffer address in the PIO
+ * option descriptor.
+ *
+ * et_pio_write_offset is the offset of the sub-allocated block from the
+ * start of the write-combined memory mapping, and is used for writing
+ * data into the PIO buffer.
+ */
+ etp->et_pio_write_offset =
+ (etp->et_pio_bufnum * ER_DZ_TX_PIOBUF_STEP) +
+ ER_DZ_TX_PIOBUF_OFST + etp->et_pio_offset;
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+ hunt_nic_pio_free(enp, etp->et_pio_bufnum, etp->et_pio_blknum);
+ etp->et_pio_size = 0;
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_tx_qpio_disable(
+ __in efx_txq_t *etp)
+{
+ efx_nic_t *enp = etp->et_enp;
+
+ if (etp->et_pio_size != 0) {
+ /* Unlink the piobuf from this TXQ */
+ hunt_nic_pio_unlink(enp, etp->et_index);
+
+ /* Free the sub-allocated PIO block */
+ hunt_nic_pio_free(enp, etp->et_pio_bufnum, etp->et_pio_blknum);
+ etp->et_pio_size = 0;
+ etp->et_pio_write_offset = 0;
+ }
+}
+
+ __checkReturn int
+hunt_tx_qpio_write(
+ __in efx_txq_t *etp,
+ __in_ecount(length) uint8_t *buffer,
+ __in size_t length,
+ __in size_t offset)
+{
+ efx_nic_t *enp = etp->et_enp;
+ efsys_bar_t *esbp = enp->en_esbp;
+ uint32_t write_offset;
+ uint32_t write_offset_limit;
+ efx_qword_t *eqp;
+ int rc;
+
+ EFSYS_ASSERT(length % sizeof (efx_qword_t) == 0);
+
+ if (etp->et_pio_size == 0) {
+ rc = ENOENT;
+ goto fail1;
+ }
+ if (offset + length > etp->et_pio_size) {
+ rc = ENOSPC;
+ goto fail2;
+ }
+
+ /*
+ * Writes to PIO buffers must be 64 bit aligned, and multiples of
+ * 64 bits.
+ */
+ write_offset = etp->et_pio_write_offset + offset;
+ write_offset_limit = write_offset + length;
+ eqp = (efx_qword_t *)buffer;
+ while (write_offset < write_offset_limit) {
+ EFSYS_BAR_WC_WRITEQ(esbp, write_offset, eqp);
+ eqp++;
+ write_offset += sizeof (efx_qword_t);
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_tx_qpio_post(
+ __in efx_txq_t *etp,
+ __in size_t pkt_length,
+ __in unsigned int completed,
+ __inout unsigned int *addedp)
+{
+ efx_qword_t pio_desc;
+ unsigned int id;
+ size_t offset;
+ unsigned int added = *addedp;
+ int rc;
+
+
+ if (added - completed + 1 > EFX_TXQ_LIMIT(etp->et_mask + 1)) {
+ rc = ENOSPC;
+ goto fail1;
+ }
+
+ if (etp->et_pio_size == 0) {
+ rc = ENOENT;
+ goto fail2;
+ }
+
+ id = added++ & etp->et_mask;
+ offset = id * sizeof (efx_qword_t);
+
+ EFSYS_PROBE4(tx_pio_post, unsigned int, etp->et_index,
+ unsigned int, id, uint32_t, etp->et_pio_offset,
+ size_t, pkt_length);
+
+ EFX_POPULATE_QWORD_5(pio_desc,
+ ESF_DZ_TX_DESC_IS_OPT, 1,
+ ESF_DZ_TX_OPTION_TYPE, 1,
+ ESF_DZ_TX_PIO_CONT, 0,
+ ESF_DZ_TX_PIO_BYTE_CNT, pkt_length,
+ ESF_DZ_TX_PIO_BUF_ADDR, etp->et_pio_offset);
+
+ EFSYS_MEM_WRITEQ(etp->et_esmp, offset, &pio_desc);
+
+ EFX_TX_QSTAT_INCR(etp, TX_POST_PIO);
+
+ *addedp = added;
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_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)
+{
+ unsigned int added = *addedp;
+ unsigned int i;
+ int rc;
+
+ if (added - completed + n > EFX_TXQ_LIMIT(etp->et_mask + 1)) {
+ rc = ENOSPC;
+ goto fail1;
+ }
+
+ for (i = 0; i < n; i++) {
+ efx_buffer_t *ebp = &eb[i];
+ efsys_dma_addr_t addr = ebp->eb_addr;
+ size_t size = ebp->eb_size;
+ boolean_t eop = ebp->eb_eop;
+ unsigned int id;
+ size_t offset;
+ efx_qword_t qword;
+
+ /* Fragments must not span 4k boundaries. */
+ EFSYS_ASSERT(P2ROUNDUP(addr + 1, 4096) >= (addr + size));
+
+ id = added++ & etp->et_mask;
+ offset = id * sizeof (efx_qword_t);
+
+ EFSYS_PROBE5(tx_post, unsigned int, etp->et_index,
+ unsigned int, id, efsys_dma_addr_t, addr,
+ size_t, size, boolean_t, eop);
+
+ EFX_POPULATE_QWORD_5(qword,
+ ESF_DZ_TX_KER_TYPE, 0,
+ ESF_DZ_TX_KER_CONT, (eop) ? 0 : 1,
+ ESF_DZ_TX_KER_BYTE_CNT, (uint32_t)(size),
+ ESF_DZ_TX_KER_BUF_ADDR_DW0, (uint32_t)(addr & 0xffffffff),
+ ESF_DZ_TX_KER_BUF_ADDR_DW1, (uint32_t)(addr >> 32));
+
+ EFSYS_MEM_WRITEQ(etp->et_esmp, offset, &qword);
+ }
+
+ EFX_TX_QSTAT_INCR(etp, TX_POST);
+
+ *addedp = added;
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+/*
+ * This improves performance by pushing a TX descriptor at the same time as the
+ * doorbell. The descriptor must be added to the TXQ, so that can be used if the
+ * hardware decides not to use the pushed descriptor.
+ */
+ void
+hunt_tx_qpush(
+ __in efx_txq_t *etp,
+ __in unsigned int added,
+ __in unsigned int pushed)
+{
+ efx_nic_t *enp = etp->et_enp;
+ unsigned int wptr;
+ unsigned int id;
+ size_t offset;
+ efx_qword_t desc;
+ efx_oword_t oword;
+
+ wptr = added & etp->et_mask;
+ id = pushed & etp->et_mask;
+ offset = id * sizeof (efx_qword_t);
+
+ EFSYS_MEM_READQ(etp->et_esmp, offset, &desc);
+ EFX_POPULATE_OWORD_3(oword,
+ ERF_DZ_TX_DESC_WPTR, wptr,
+ ERF_DZ_TX_DESC_HWORD, EFX_QWORD_FIELD(desc, EFX_DWORD_1),
+ ERF_DZ_TX_DESC_LWORD, EFX_QWORD_FIELD(desc, EFX_DWORD_0));
+
+ /* Guarantee ordering of memory (descriptors) and PIO (doorbell) */
+ EFX_DMA_SYNC_QUEUE_FOR_DEVICE(etp->et_esmp, etp->et_mask + 1, wptr, id);
+ EFSYS_PIO_WRITE_BARRIER();
+ EFX_BAR_TBL_DOORBELL_WRITEO(enp, ER_DZ_TX_DESC_UPD_REG, etp->et_index,
+ &oword);
+}
+
+ __checkReturn int
+hunt_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)
+{
+ unsigned int added = *addedp;
+ unsigned int i;
+ int rc;
+
+ if (added - completed + n > EFX_TXQ_LIMIT(etp->et_mask + 1)) {
+ rc = ENOSPC;
+ goto fail1;
+ }
+
+ for (i = 0; i < n; i++) {
+ efx_desc_t *edp = &ed[i];
+ unsigned int id;
+ size_t offset;
+
+ id = added++ & etp->et_mask;
+ offset = id * sizeof (efx_desc_t);
+
+ EFSYS_MEM_WRITEQ(etp->et_esmp, offset, &edp->ed_eq);
+ }
+
+ EFSYS_PROBE3(tx_desc_post, unsigned int, etp->et_index,
+ unsigned int, added, unsigned int, n);
+
+ EFX_TX_QSTAT_INCR(etp, TX_POST);
+
+ *addedp = added;
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_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)
+{
+ /* Fragments must not span 4k boundaries. */
+ EFSYS_ASSERT(P2ROUNDUP(addr + 1, 4096) >= addr + size);
+
+ EFSYS_PROBE4(tx_desc_dma_create, unsigned int, etp->et_index,
+ efsys_dma_addr_t, addr,
+ size_t, size, boolean_t, eop);
+
+ EFX_POPULATE_QWORD_5(edp->ed_eq,
+ ESF_DZ_TX_KER_TYPE, 0,
+ ESF_DZ_TX_KER_CONT, (eop) ? 0 : 1,
+ ESF_DZ_TX_KER_BYTE_CNT, (uint32_t)(size),
+ ESF_DZ_TX_KER_BUF_ADDR_DW0, (uint32_t)(addr & 0xffffffff),
+ ESF_DZ_TX_KER_BUF_ADDR_DW1, (uint32_t)(addr >> 32));
+}
+
+ void
+hunt_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)
+{
+ EFSYS_PROBE4(tx_desc_tso_create, unsigned int, etp->et_index,
+ uint16_t, ipv4_id, uint32_t, tcp_seq,
+ uint8_t, tcp_flags);
+
+ EFX_POPULATE_QWORD_5(edp->ed_eq,
+ ESF_DZ_TX_DESC_IS_OPT, 1,
+ ESF_DZ_TX_OPTION_TYPE,
+ ESE_DZ_TX_OPTION_DESC_TSO,
+ ESF_DZ_TX_TSO_TCP_FLAGS, tcp_flags,
+ ESF_DZ_TX_TSO_IP_ID, ipv4_id,
+ ESF_DZ_TX_TSO_TCP_SEQNO, tcp_seq);
+}
+
+ void
+hunt_tx_qdesc_vlantci_create(
+ __in efx_txq_t *etp,
+ __in uint16_t tci,
+ __out efx_desc_t *edp)
+{
+ EFSYS_PROBE2(tx_desc_vlantci_create, unsigned int, etp->et_index,
+ uint16_t, tci);
+
+ EFX_POPULATE_QWORD_4(edp->ed_eq,
+ ESF_DZ_TX_DESC_IS_OPT, 1,
+ ESF_DZ_TX_OPTION_TYPE,
+ ESE_DZ_TX_OPTION_DESC_VLAN,
+ ESF_DZ_TX_VLAN_OP, tci ? 1 : 0,
+ ESF_DZ_TX_VLAN_TAG1, tci);
+}
+
+
+ __checkReturn int
+hunt_tx_qpace(
+ __in efx_txq_t *etp,
+ __in unsigned int ns)
+{
+ int rc;
+
+ /* FIXME */
+ _NOTE(ARGUNUSED(etp, ns))
+ if (B_FALSE) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ /* FIXME */
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_tx_qflush(
+ __in efx_txq_t *etp)
+{
+ efx_nic_t *enp = etp->et_enp;
+ int rc;
+
+ if ((rc = efx_mcdi_fini_txq(enp, etp->et_index)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_tx_qenable(
+ __in efx_txq_t *etp)
+{
+ /* FIXME */
+ _NOTE(ARGUNUSED(etp))
+ /* FIXME */
+}
+
+#if EFSYS_OPT_QSTATS
+ void
+hunt_tx_qstats_update(
+ __in efx_txq_t *etp,
+ __inout_ecount(TX_NQSTATS) efsys_stat_t *stat)
+{
+ /*
+ * TBD: Consider a common Siena/Huntington function. The code is
+ * essentially identical.
+ */
+
+ unsigned int id;
+
+ for (id = 0; id < TX_NQSTATS; id++) {
+ efsys_stat_t *essp = &stat[id];
+
+ EFSYS_STAT_INCR(essp, etp->et_stat[id]);
+ etp->et_stat[id] = 0;
+ }
+}
+
+#endif /* EFSYS_OPT_QSTATS */
+
+#endif /* EFSYS_OPT_HUNTINGTON */
diff --git a/sys/dev/sfxge/common/hunt_vpd.c b/sys/dev/sfxge/common/hunt_vpd.c
new file mode 100644
index 0000000..536ebbc
--- /dev/null
+++ b/sys/dev/sfxge/common/hunt_vpd.c
@@ -0,0 +1,435 @@
+/*-
+ * Copyright (c) 2009-2015 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_types.h"
+#include "efx_regs.h"
+#include "efx_impl.h"
+
+
+#if EFSYS_OPT_VPD
+
+#if EFSYS_OPT_HUNTINGTON
+
+#include "ef10_tlv_layout.h"
+
+ __checkReturn int
+hunt_vpd_init(
+ __in efx_nic_t *enp)
+{
+ caddr_t svpd;
+ size_t svpd_size;
+ uint32_t pci_pf;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE);
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ pci_pf = enp->en_nic_cfg.enc_pf;
+ /*
+ * The VPD interface exposes VPD resources from the combined static and
+ * dynamic VPD storage. As the static VPD configuration should *never*
+ * change, we can cache it.
+ */
+ svpd = NULL;
+ svpd_size = 0;
+ rc = hunt_nvram_partn_read_tlv(enp,
+ NVRAM_PARTITION_TYPE_STATIC_CONFIG,
+ TLV_TAG_PF_STATIC_VPD(pci_pf),
+ &svpd, &svpd_size);
+ if (rc != 0) {
+ if (rc == EACCES) {
+ /* Unpriviledged functions cannot access VPD */
+ goto out;
+ }
+ goto fail1;
+ }
+
+ if (svpd != NULL && svpd_size > 0) {
+ if ((rc = efx_vpd_hunk_verify(svpd, svpd_size, NULL)) != 0)
+ goto fail2;
+ }
+
+ enp->en_u.hunt.enu_svpd = svpd;
+ enp->en_u.hunt.enu_svpd_length = svpd_size;
+
+out:
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+ EFSYS_KMEM_FREE(enp->en_esip, svpd_size, svpd);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_vpd_size(
+ __in efx_nic_t *enp,
+ __out size_t *sizep)
+{
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ /*
+ * This function returns the total size the user should allocate
+ * for all VPD operations. We've already cached the static vpd,
+ * so we just need to return an upper bound on the dynamic vpd,
+ * which is the size of the DYNAMIC_CONFIG partition.
+ */
+ if ((rc = efx_mcdi_nvram_info(enp, NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG,
+ sizep, NULL, NULL)) != 0)
+ goto fail1;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_vpd_read(
+ __in efx_nic_t *enp,
+ __out_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ caddr_t dvpd;
+ size_t dvpd_size;
+ uint32_t pci_pf;
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ pci_pf = enp->en_nic_cfg.enc_pf;
+
+ if ((rc = hunt_nvram_partn_read_tlv(enp,
+ NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG,
+ TLV_TAG_PF_DYNAMIC_VPD(pci_pf),
+ &dvpd, &dvpd_size)) != 0)
+ goto fail1;
+
+ if (dvpd_size > size) {
+ rc = ENOSPC;
+ goto fail2;
+ }
+ memcpy(data, dvpd, dvpd_size);
+
+ /* Pad data with all-1s, consistent with update operations */
+ memset(data + dvpd_size, 0xff, size - dvpd_size);
+
+ EFSYS_KMEM_FREE(enp->en_esip, dvpd_size, dvpd);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+ EFSYS_KMEM_FREE(enp->en_esip, dvpd_size, dvpd);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_vpd_verify(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ efx_vpd_tag_t stag;
+ efx_vpd_tag_t dtag;
+ efx_vpd_keyword_t skey;
+ efx_vpd_keyword_t dkey;
+ unsigned int scont;
+ unsigned int dcont;
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ /*
+ * Strictly you could take the view that dynamic vpd is optional.
+ * Instead, to conform more closely to the read/verify/reinit()
+ * paradigm, we require dynamic vpd. hunt_vpd_reinit() will
+ * reinitialize it as required.
+ */
+ if ((rc = efx_vpd_hunk_verify(data, size, NULL)) != 0)
+ goto fail1;
+
+ /*
+ * Verify that there is no duplication between the static and
+ * dynamic cfg sectors.
+ */
+ if (enp->en_u.hunt.enu_svpd_length == 0)
+ goto done;
+
+ dcont = 0;
+ _NOTE(CONSTANTCONDITION)
+ while (1) {
+ if ((rc = efx_vpd_hunk_next(data, size, &dtag,
+ &dkey, NULL, NULL, &dcont)) != 0)
+ goto fail2;
+ if (dcont == 0)
+ break;
+
+ scont = 0;
+ _NOTE(CONSTANTCONDITION)
+ while (1) {
+ if ((rc = efx_vpd_hunk_next(
+ enp->en_u.hunt.enu_svpd,
+ enp->en_u.hunt.enu_svpd_length, &stag, &skey,
+ NULL, NULL, &scont)) != 0)
+ goto fail3;
+ if (scont == 0)
+ break;
+
+ if (stag == dtag && skey == dkey) {
+ rc = EEXIST;
+ goto fail4;
+ }
+ }
+ }
+
+done:
+ return (0);
+
+fail4:
+ EFSYS_PROBE(fail4);
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_vpd_reinit(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ boolean_t wantpid;
+ int rc;
+
+ /*
+ * Only create an ID string if the dynamic cfg doesn't have one
+ */
+ if (enp->en_u.hunt.enu_svpd_length == 0)
+ wantpid = B_TRUE;
+ else {
+ unsigned int offset;
+ uint8_t length;
+
+ rc = efx_vpd_hunk_get(enp->en_u.hunt.enu_svpd,
+ enp->en_u.hunt.enu_svpd_length,
+ EFX_VPD_ID, 0, &offset, &length);
+ if (rc == 0)
+ wantpid = B_FALSE;
+ else if (rc == ENOENT)
+ wantpid = B_TRUE;
+ else
+ goto fail1;
+ }
+
+ if ((rc = efx_vpd_hunk_reinit(data, size, wantpid)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_vpd_get(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size,
+ __inout efx_vpd_value_t *evvp)
+{
+ unsigned int offset;
+ uint8_t length;
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ /* Attempt to satisfy the request from svpd first */
+ if (enp->en_u.hunt.enu_svpd_length > 0) {
+ if ((rc = efx_vpd_hunk_get(enp->en_u.hunt.enu_svpd,
+ enp->en_u.hunt.enu_svpd_length, evvp->evv_tag,
+ evvp->evv_keyword, &offset, &length)) == 0) {
+ evvp->evv_length = length;
+ memcpy(evvp->evv_value,
+ enp->en_u.hunt.enu_svpd + offset, length);
+ return (0);
+ } else if (rc != ENOENT)
+ goto fail1;
+ }
+
+ /* And then from the provided data buffer */
+ if ((rc = efx_vpd_hunk_get(data, size, evvp->evv_tag,
+ evvp->evv_keyword, &offset, &length)) != 0)
+ goto fail2;
+
+ evvp->evv_length = length;
+ memcpy(evvp->evv_value, data + offset, length);
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_vpd_set(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size,
+ __in efx_vpd_value_t *evvp)
+{
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ /* If the provided (tag,keyword) exists in svpd, then it is readonly */
+ if (enp->en_u.hunt.enu_svpd_length > 0) {
+ unsigned int offset;
+ uint8_t length;
+
+ if ((rc = efx_vpd_hunk_get(enp->en_u.hunt.enu_svpd,
+ enp->en_u.hunt.enu_svpd_length, evvp->evv_tag,
+ evvp->evv_keyword, &offset, &length)) == 0) {
+ rc = EACCES;
+ goto fail1;
+ }
+ }
+
+ if ((rc = efx_vpd_hunk_set(data, size, evvp)) != 0)
+ goto fail2;
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+hunt_vpd_next(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size,
+ __out efx_vpd_value_t *evvp,
+ __inout unsigned int *contp)
+{
+ _NOTE(ARGUNUSED(enp, data, size, evvp, contp))
+
+ return (ENOTSUP);
+}
+
+ __checkReturn int
+hunt_vpd_write(
+ __in efx_nic_t *enp,
+ __in_bcount(size) caddr_t data,
+ __in size_t size)
+{
+ size_t vpd_length;
+ uint32_t pci_pf;
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ pci_pf = enp->en_nic_cfg.enc_pf;
+
+ /* Determine total length of new dynamic VPD */
+ if ((rc = efx_vpd_hunk_length(data, size, &vpd_length)) != 0)
+ goto fail1;
+
+ /* Store new dynamic VPD in DYNAMIC_CONFIG partition */
+ if ((rc = hunt_nvram_partn_write_tlv(enp,
+ NVRAM_PARTITION_TYPE_DYNAMIC_CONFIG,
+ TLV_TAG_PF_DYNAMIC_VPD(pci_pf),
+ data, vpd_length)) != 0) {
+ goto fail2;
+ }
+
+ return (0);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+hunt_vpd_fini(
+ __in efx_nic_t *enp)
+{
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_HUNTINGTON);
+
+ if (enp->en_u.hunt.enu_svpd_length > 0) {
+ EFSYS_KMEM_FREE(enp->en_esip, enp->en_u.hunt.enu_svpd_length,
+ enp->en_u.hunt.enu_svpd);
+
+ enp->en_u.hunt.enu_svpd = NULL;
+ enp->en_u.hunt.enu_svpd_length = 0;
+ }
+}
+
+#endif /* EFSYS_OPT_HUNTINGTON */
+
+#endif /* EFSYS_OPT_VPD */
diff --git a/sys/dev/sfxge/common/mcdi_mon.c b/sys/dev/sfxge/common/mcdi_mon.c
new file mode 100644
index 0000000..ec692be
--- /dev/null
+++ b/sys/dev/sfxge/common/mcdi_mon.c
@@ -0,0 +1,552 @@
+/*-
+ * Copyright (c) 2009-2015 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_impl.h"
+
+#if EFSYS_OPT_MON_MCDI
+
+#if EFSYS_OPT_MON_STATS
+
+#define MCDI_MON_NEXT_PAGE (uint16_t)0xfffe
+#define MCDI_MON_INVALID_SENSOR (uint16_t)0xfffd
+#define MCDI_MON_PAGE_SIZE 0x20
+
+/* Bitmasks of valid port(s) for each sensor */
+#define MCDI_MON_PORT_NONE (0x00)
+#define MCDI_MON_PORT_P1 (0x01)
+#define MCDI_MON_PORT_P2 (0x02)
+#define MCDI_MON_PORT_P3 (0x04)
+#define MCDI_MON_PORT_P4 (0x08)
+#define MCDI_MON_PORT_Px (0xFFFF)
+
+/* Entry for MCDI sensor in sensor map */
+#define STAT(portmask, stat) \
+ { (MCDI_MON_PORT_##portmask), (EFX_MON_STAT_##stat) }
+
+/* Entry for sensor next page flag in sensor map */
+#define STAT_NEXT_PAGE() \
+ { MCDI_MON_PORT_NONE, MCDI_MON_NEXT_PAGE }
+
+/* Placeholder for gaps in the array */
+#define STAT_NO_SENSOR() \
+ { MCDI_MON_PORT_NONE, MCDI_MON_INVALID_SENSOR }
+
+/* Map from MC sensors to monitor statistics */
+static const struct mcdi_sensor_map_s {
+ uint16_t msm_port_mask;
+ uint16_t msm_stat;
+} mcdi_sensor_map[] = {
+ /* Sensor page 0 MC_CMD_SENSOR_xxx */
+ STAT(Px, INT_TEMP), /* 0x00 CONTROLLER_TEMP */
+ STAT(Px, EXT_TEMP), /* 0x01 PHY_COMMON_TEMP */
+ STAT(Px, INT_COOLING), /* 0x02 CONTROLLER_COOLING */
+ STAT(P1, EXT_TEMP), /* 0x03 PHY0_TEMP */
+ STAT(P1, EXT_COOLING), /* 0x04 PHY0_COOLING */
+ STAT(P2, EXT_TEMP), /* 0x05 PHY1_TEMP */
+ STAT(P2, EXT_COOLING), /* 0x06 PHY1_COOLING */
+ STAT(Px, 1V), /* 0x07 IN_1V0 */
+ STAT(Px, 1_2V), /* 0x08 IN_1V2 */
+ STAT(Px, 1_8V), /* 0x09 IN_1V8 */
+ STAT(Px, 2_5V), /* 0x0a IN_2V5 */
+ STAT(Px, 3_3V), /* 0x0b IN_3V3 */
+ STAT(Px, 12V), /* 0x0c IN_12V0 */
+ STAT(Px, 1_2VA), /* 0x0d IN_1V2A */
+ STAT(Px, VREF), /* 0x0e IN_VREF */
+ STAT(Px, VAOE), /* 0x0f OUT_VAOE */
+ STAT(Px, AOE_TEMP), /* 0x10 AOE_TEMP */
+ STAT(Px, PSU_AOE_TEMP), /* 0x11 PSU_AOE_TEMP */
+ STAT(Px, PSU_TEMP), /* 0x12 PSU_TEMP */
+ STAT(Px, FAN0), /* 0x13 FAN_0 */
+ STAT(Px, FAN1), /* 0x14 FAN_1 */
+ STAT(Px, FAN2), /* 0x15 FAN_2 */
+ STAT(Px, FAN3), /* 0x16 FAN_3 */
+ STAT(Px, FAN4), /* 0x17 FAN_4 */
+ STAT(Px, VAOE_IN), /* 0x18 IN_VAOE */
+ STAT(Px, IAOE), /* 0x19 OUT_IAOE */
+ STAT(Px, IAOE_IN), /* 0x1a IN_IAOE */
+ STAT(Px, NIC_POWER), /* 0x1b NIC_POWER */
+ STAT(Px, 0_9V), /* 0x1c IN_0V9 */
+ STAT(Px, I0_9V), /* 0x1d IN_I0V9 */
+ STAT(Px, I1_2V), /* 0x1e IN_I1V2 */
+ STAT_NEXT_PAGE(), /* 0x1f Next page flag (not a sensor) */
+
+ /* Sensor page 1 MC_CMD_SENSOR_xxx */
+ STAT(Px, 0_9V_ADC), /* 0x20 IN_0V9_ADC */
+ STAT(Px, INT_TEMP2), /* 0x21 CONTROLLER_2_TEMP */
+ STAT(Px, VREG_TEMP), /* 0x22 VREG_INTERNAL_TEMP */
+ STAT(Px, VREG_0_9V_TEMP), /* 0x23 VREG_0V9_TEMP */
+ STAT(Px, VREG_1_2V_TEMP), /* 0x24 VREG_1V2_TEMP */
+ STAT(Px, INT_VPTAT), /* 0x25 CTRLR. VPTAT */
+ STAT(Px, INT_ADC_TEMP), /* 0x26 CTRLR. INTERNAL_TEMP */
+ STAT(Px, EXT_VPTAT), /* 0x27 CTRLR. VPTAT_EXTADC */
+ STAT(Px, EXT_ADC_TEMP), /* 0x28 CTRLR. INTERNAL_TEMP_EXTADC */
+ STAT(Px, AMBIENT_TEMP), /* 0x29 AMBIENT_TEMP */
+ STAT(Px, AIRFLOW), /* 0x2a AIRFLOW */
+ STAT(Px, VDD08D_VSS08D_CSR), /* 0x2b VDD08D_VSS08D_CSR */
+ STAT(Px, VDD08D_VSS08D_CSR_EXTADC), /* 0x2c VDD08D_VSS08D_CSR_EXTADC */
+ STAT(Px, HOTPOINT_TEMP), /* 0x2d HOTPOINT_TEMP */
+ STAT(P1, PHY_POWER_SWITCH_PORT0), /* 0x2e PHY_POWER_SWITCH_PORT0 */
+ STAT(P2, PHY_POWER_SWITCH_PORT1), /* 0x2f PHY_POWER_SWITCH_PORT1 */
+ STAT(Px, MUM_VCC), /* 0x30 MUM_VCC */
+ STAT(Px, 0V9_A), /* 0x31 0V9_A */
+ STAT(Px, I0V9_A), /* 0x32 I0V9_A */
+ STAT(Px, 0V9_A_TEMP), /* 0x33 0V9_A_TEMP */
+ STAT(Px, 0V9_B), /* 0x34 0V9_B */
+ STAT(Px, I0V9_B), /* 0x35 I0V9_B */
+ STAT(Px, 0V9_B_TEMP), /* 0x36 0V9_B_TEMP */
+ STAT(Px, CCOM_AVREG_1V2_SUPPLY), /* 0x37 CCOM_AVREG_1V2_SUPPLY */
+ STAT(Px, CCOM_AVREG_1V2_SUPPLY_EXT_ADC),
+ /* 0x38 CCOM_AVREG_1V2_SUPPLY_EXT_ADC */
+ STAT(Px, CCOM_AVREG_1V8_SUPPLY), /* 0x39 CCOM_AVREG_1V8_SUPPLY */
+ STAT(Px, CCOM_AVREG_1V8_SUPPLY_EXT_ADC),
+ /* 0x3a CCOM_AVREG_1V8_SUPPLY_EXT_ADC */
+ STAT_NO_SENSOR(), /* 0x3b (no sensor) */
+ STAT_NO_SENSOR(), /* 0x3c (no sensor) */
+ STAT_NO_SENSOR(), /* 0x3d (no sensor) */
+ STAT_NO_SENSOR(), /* 0x3e (no sensor) */
+ STAT_NEXT_PAGE(), /* 0x3f Next page flag (not a sensor) */
+
+ /* Sensor page 2 MC_CMD_SENSOR_xxx */
+ STAT(Px, CONTROLLER_MASTER_VPTAT), /* 0x40 MASTER_VPTAT */
+ STAT(Px, CONTROLLER_MASTER_INTERNAL_TEMP), /* 0x41 MASTER_INT_TEMP */
+ STAT(Px, CONTROLLER_MASTER_VPTAT_EXT_ADC), /* 0x42 MAST_VPTAT_EXT_ADC */
+ STAT(Px, CONTROLLER_MASTER_INTERNAL_TEMP_EXT_ADC),
+ /* 0x43 MASTER_INTERNAL_TEMP_EXT_ADC */
+ STAT(Px, CONTROLLER_SLAVE_VPTAT), /* 0x44 SLAVE_VPTAT */
+ STAT(Px, CONTROLLER_SLAVE_INTERNAL_TEMP), /* 0x45 SLAVE_INTERNAL_TEMP */
+ STAT(Px, CONTROLLER_SLAVE_VPTAT_EXT_ADC), /* 0x46 SLAVE_VPTAT_EXT_ADC */
+ STAT(Px, CONTROLLER_SLAVE_INTERNAL_TEMP_EXT_ADC),
+ /* 0x47 SLAVE_INTERNAL_TEMP_EXT_ADC */
+};
+
+#define MCDI_STATIC_SENSOR_ASSERT(_field) \
+ EFX_STATIC_ASSERT(MC_CMD_SENSOR_STATE_ ## _field \
+ == EFX_MON_STAT_STATE_ ## _field)
+
+static void
+mcdi_mon_decode_stats(
+ __in efx_nic_t *enp,
+ __in_ecount(sensor_mask_size) uint32_t *sensor_mask,
+ __in size_t sensor_mask_size,
+ __in_opt efsys_mem_t *esmp,
+ __out_ecount_opt(sensor_mask_size) uint32_t *stat_maskp,
+ __out_ecount_opt(EFX_MON_NSTATS) efx_mon_stat_value_t *stat)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ uint16_t port_mask;
+ uint16_t sensor;
+ size_t sensor_max;
+ uint32_t stat_mask[(EFX_ARRAY_SIZE(mcdi_sensor_map) + 31) / 32];
+ uint32_t idx = 0;
+ uint32_t page = 0;
+
+ /* Assert the MC_CMD_SENSOR and EFX_MON_STATE namespaces agree */
+ MCDI_STATIC_SENSOR_ASSERT(OK);
+ MCDI_STATIC_SENSOR_ASSERT(WARNING);
+ MCDI_STATIC_SENSOR_ASSERT(FATAL);
+ MCDI_STATIC_SENSOR_ASSERT(BROKEN);
+ MCDI_STATIC_SENSOR_ASSERT(NO_READING);
+
+ EFX_STATIC_ASSERT(sizeof (stat_mask[0]) * 8 ==
+ EFX_MON_MASK_ELEMENT_SIZE);
+ sensor_max =
+ MIN((8 * sensor_mask_size), EFX_ARRAY_SIZE(mcdi_sensor_map));
+
+ port_mask = 1U << emip->emi_port;
+
+ memset(stat_mask, 0, sizeof (stat_mask));
+
+ /*
+ * The MCDI sensor readings in the DMA buffer are a packed array of
+ * MC_CMD_SENSOR_VALUE_ENTRY structures, which only includes entries for
+ * supported sensors (bit set in sensor_mask). The sensor_mask and
+ * sensor readings do not include entries for the per-page NEXT_PAGE
+ * flag.
+ *
+ * sensor_mask may legitimately contain MCDI sensors that the driver
+ * does not understand.
+ */
+ for (sensor = 0; sensor < sensor_max; ++sensor) {
+ efx_mon_stat_t id = mcdi_sensor_map[sensor].msm_stat;
+
+ if ((sensor % MCDI_MON_PAGE_SIZE) == MC_CMD_SENSOR_PAGE0_NEXT) {
+ EFSYS_ASSERT3U(id, ==, MCDI_MON_NEXT_PAGE);
+ page++;
+ continue;
+ }
+ if (~(sensor_mask[page]) & (1U << sensor))
+ continue;
+ idx++;
+
+ if ((port_mask & mcdi_sensor_map[sensor].msm_port_mask) == 0)
+ continue;
+ EFSYS_ASSERT(id < EFX_MON_NSTATS);
+
+ /*
+ * stat_mask is a bitmask indexed by EFX_MON_* monitor statistic
+ * identifiers from efx_mon_stat_t (without NEXT_PAGE bits).
+ *
+ * If there is an entry in the MCDI sensor to monitor statistic
+ * map then the sensor reading is used for the value of the
+ * monitor statistic.
+ */
+ stat_mask[id / EFX_MON_MASK_ELEMENT_SIZE] |=
+ (1U << (id % EFX_MON_MASK_ELEMENT_SIZE));
+
+ if (stat != NULL && esmp != NULL && !EFSYS_MEM_IS_NULL(esmp)) {
+ efx_dword_t dword;
+
+ /* Get MCDI sensor reading from DMA buffer */
+ EFSYS_MEM_READD(esmp, 4 * (idx - 1), &dword);
+
+ /* Update EFX monitor stat from MCDI sensor reading */
+ stat[id].emsv_value = (uint16_t)EFX_DWORD_FIELD(dword,
+ MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE);
+
+ stat[id].emsv_state = (uint16_t)EFX_DWORD_FIELD(dword,
+ MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE);
+ }
+ }
+
+ if (stat_maskp != NULL) {
+ memcpy(stat_maskp, stat_mask, sizeof (stat_mask));
+ }
+}
+
+ __checkReturn int
+mcdi_mon_ev(
+ __in efx_nic_t *enp,
+ __in efx_qword_t *eqp,
+ __out efx_mon_stat_t *idp,
+ __out efx_mon_stat_value_t *valuep)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ uint16_t port_mask;
+ uint16_t sensor;
+ uint16_t state;
+ uint16_t value;
+ efx_mon_stat_t id;
+ int rc;
+
+ port_mask = (emip->emi_port == 1)
+ ? MCDI_MON_PORT_P1
+ : MCDI_MON_PORT_P2;
+
+ sensor = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_MONITOR);
+ state = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_STATE);
+ value = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_VALUE);
+
+ /* Hardware must support this MCDI sensor */
+ EFSYS_ASSERT3U(sensor, <, (8 * encp->enc_mcdi_sensor_mask_size));
+ EFSYS_ASSERT((sensor % MCDI_MON_PAGE_SIZE) != MC_CMD_SENSOR_PAGE0_NEXT);
+ EFSYS_ASSERT(encp->enc_mcdi_sensor_maskp != NULL);
+ EFSYS_ASSERT((encp->enc_mcdi_sensor_maskp[sensor / MCDI_MON_PAGE_SIZE] &
+ (1U << (sensor % MCDI_MON_PAGE_SIZE))) != 0);
+
+ /* But we don't have to understand it */
+ if (sensor >= EFX_ARRAY_SIZE(mcdi_sensor_map)) {
+ rc = ENOTSUP;
+ goto fail1;
+ }
+ id = mcdi_sensor_map[sensor].msm_stat;
+ if ((port_mask & mcdi_sensor_map[sensor].msm_port_mask) == 0)
+ return (ENODEV);
+ EFSYS_ASSERT(id < EFX_MON_NSTATS);
+
+ *idp = id;
+ valuep->emsv_value = value;
+ valuep->emsv_state = state;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+
+static __checkReturn int
+efx_mcdi_read_sensors(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp,
+ __in uint32_t size)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_READ_SENSORS_EXT_IN_LEN,
+ MC_CMD_READ_SENSORS_EXT_OUT_LEN)];
+ uint32_t addr_lo, addr_hi;
+
+ req.emr_cmd = MC_CMD_READ_SENSORS;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_READ_SENSORS_EXT_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_READ_SENSORS_EXT_OUT_LEN;
+
+ addr_lo = (uint32_t)(EFSYS_MEM_ADDR(esmp) & 0xffffffff);
+ addr_hi = (uint32_t)(EFSYS_MEM_ADDR(esmp) >> 32);
+
+ MCDI_IN_SET_DWORD(req, READ_SENSORS_EXT_IN_DMA_ADDR_LO, addr_lo);
+ MCDI_IN_SET_DWORD(req, READ_SENSORS_EXT_IN_DMA_ADDR_HI, addr_hi);
+ MCDI_IN_SET_DWORD(req, READ_SENSORS_EXT_IN_LENGTH, size);
+
+ efx_mcdi_execute(enp, &req);
+
+ return (req.emr_rc);
+}
+
+static __checkReturn int
+efx_mcdi_sensor_info_npages(
+ __in efx_nic_t *enp,
+ __out uint32_t *npagesp)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_SENSOR_INFO_EXT_IN_LEN,
+ MC_CMD_SENSOR_INFO_OUT_LENMAX)];
+ int page;
+ int rc;
+
+ EFSYS_ASSERT(npagesp != NULL);
+
+ page = 0;
+ do {
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_SENSOR_INFO;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_SENSOR_INFO_EXT_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_SENSOR_INFO_OUT_LENMAX;
+
+ MCDI_IN_SET_DWORD(req, SENSOR_INFO_EXT_IN_PAGE, page++);
+
+ efx_mcdi_execute_quiet(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+ } while (MCDI_OUT_DWORD(req, SENSOR_INFO_OUT_MASK) &
+ (1 << MC_CMD_SENSOR_PAGE0_NEXT));
+
+ *npagesp = page;
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+static __checkReturn int
+efx_mcdi_sensor_info(
+ __in efx_nic_t *enp,
+ __out_ecount(npages) uint32_t *sensor_maskp,
+ __in size_t npages)
+{
+ efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_SENSOR_INFO_EXT_IN_LEN,
+ MC_CMD_SENSOR_INFO_OUT_LENMAX)];
+ uint32_t page;
+ int rc;
+
+ EFSYS_ASSERT(sensor_maskp != NULL);
+
+ for (page = 0; page < npages; page++) {
+ uint32_t mask;
+
+ (void) memset(payload, 0, sizeof (payload));
+ req.emr_cmd = MC_CMD_SENSOR_INFO;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_SENSOR_INFO_EXT_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_SENSOR_INFO_OUT_LENMAX;
+
+ MCDI_IN_SET_DWORD(req, SENSOR_INFO_EXT_IN_PAGE, page);
+
+ efx_mcdi_execute(enp, &req);
+
+ if (req.emr_rc != 0) {
+ rc = req.emr_rc;
+ goto fail1;
+ }
+
+ mask = MCDI_OUT_DWORD(req, SENSOR_INFO_OUT_MASK);
+
+ if ((page != (npages - 1)) &&
+ ((mask & (1U << MC_CMD_SENSOR_PAGE0_NEXT)) == 0)) {
+ rc = EINVAL;
+ goto fail2;
+ }
+ sensor_maskp[page] = mask;
+ }
+
+ if (sensor_maskp[npages - 1] & (1U << MC_CMD_SENSOR_PAGE0_NEXT)) {
+ rc = EINVAL;
+ goto fail3;
+ }
+
+ return (0);
+
+fail3:
+ EFSYS_PROBE(fail3);
+fail2:
+ EFSYS_PROBE(fail2);
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+mcdi_mon_stats_update(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp,
+ __out_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ uint32_t size = encp->enc_mon_stat_dma_buf_size;
+ int rc;
+
+ if ((rc = efx_mcdi_read_sensors(enp, esmp, size)) != 0)
+ goto fail1;
+
+ EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, size);
+
+ mcdi_mon_decode_stats(enp,
+ encp->enc_mcdi_sensor_maskp,
+ encp->enc_mcdi_sensor_mask_size,
+ esmp, NULL, values);
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ __checkReturn int
+mcdi_mon_cfg_build(
+ __in efx_nic_t *enp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+ uint32_t npages;
+ int rc;
+
+ switch (enp->en_family) {
+#if EFSYS_OPT_SIENA
+ case EFX_FAMILY_SIENA:
+ encp->enc_mon_type = EFX_MON_SFC90X0;
+ break;
+#endif
+#if EFSYS_OPT_HUNTINGTON
+ case EFX_FAMILY_HUNTINGTON:
+ encp->enc_mon_type = EFX_MON_SFC91X0;
+ break;
+#endif
+ default:
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ /* Get mc sensor mask size */
+ npages = 0;
+ if ((rc = efx_mcdi_sensor_info_npages(enp, &npages)) != 0)
+ goto fail2;
+
+ encp->enc_mon_stat_dma_buf_size = npages * EFX_MON_STATS_PAGE_SIZE;
+ encp->enc_mcdi_sensor_mask_size = npages * sizeof (uint32_t);
+
+ /* Allocate mc sensor mask */
+ EFSYS_KMEM_ALLOC(enp->en_esip,
+ encp->enc_mcdi_sensor_mask_size,
+ encp->enc_mcdi_sensor_maskp);
+
+ if (encp->enc_mcdi_sensor_maskp == NULL) {
+ rc = ENOMEM;
+ goto fail3;
+ }
+
+ /* Read mc sensor mask */
+ if ((rc = efx_mcdi_sensor_info(enp,
+ encp->enc_mcdi_sensor_maskp,
+ npages)) != 0)
+ goto fail4;
+
+ /* Build monitor statistics mask */
+ mcdi_mon_decode_stats(enp,
+ encp->enc_mcdi_sensor_maskp,
+ encp->enc_mcdi_sensor_mask_size,
+ NULL, encp->enc_mon_stat_mask, NULL);
+
+ return (0);
+
+fail4:
+ EFSYS_PROBE(fail4);
+ EFSYS_KMEM_FREE(enp->en_esip,
+ encp->enc_mcdi_sensor_mask_size,
+ encp->enc_mcdi_sensor_maskp);
+
+fail3:
+ EFSYS_PROBE(fail3);
+
+fail2:
+ EFSYS_PROBE(fail2);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+mcdi_mon_cfg_free(
+ __in efx_nic_t *enp)
+{
+ efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
+
+ if (encp->enc_mcdi_sensor_maskp != NULL) {
+ EFSYS_KMEM_FREE(enp->en_esip,
+ encp->enc_mcdi_sensor_mask_size,
+ encp->enc_mcdi_sensor_maskp);
+ }
+}
+
+
+#endif /* EFSYS_OPT_MON_STATS */
+
+#endif /* EFSYS_OPT_MON_MCDI */
diff --git a/sys/dev/sfxge/common/mcdi_mon.h b/sys/dev/sfxge/common/mcdi_mon.h
new file mode 100644
index 0000000..30bb150
--- /dev/null
+++ b/sys/dev/sfxge/common/mcdi_mon.h
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (c) 2009-2015 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_MCDI_MON_H
+#define _SYS_MCDI_MON_H
+
+#include "efx.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if EFSYS_OPT_MON_MCDI
+
+#if EFSYS_OPT_MON_STATS
+
+ __checkReturn int
+mcdi_mon_cfg_build(
+ __in efx_nic_t *enp);
+
+ void
+mcdi_mon_cfg_free(
+ __in efx_nic_t *enp);
+
+
+extern __checkReturn int
+mcdi_mon_ev(
+ __in efx_nic_t *enp,
+ __in efx_qword_t *eqp,
+ __out efx_mon_stat_t *idp,
+ __out efx_mon_stat_value_t *valuep);
+
+extern __checkReturn int
+mcdi_mon_stats_update(
+ __in efx_nic_t *enp,
+ __in efsys_mem_t *esmp,
+ __out_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values);
+
+#endif /* EFSYS_OPT_MON_STATS */
+
+#endif /* EFSYS_OPT_MON_MCDI */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_MCDI_MON_H */
diff --git a/sys/dev/sfxge/common/siena_flash.h b/sys/dev/sfxge/common/siena_flash.h
index aed688b..c1ee1c5 100644
--- a/sys/dev/sfxge/common/siena_flash.h
+++ b/sys/dev/sfxge/common/siena_flash.h
@@ -1,26 +1,31 @@
/*-
- * Copyright 2007-2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2007-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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.
*
* $FreeBSD$
*/
@@ -48,6 +53,45 @@
#define SIENA_MC_BOOT_MAGIC (0x51E4A001)
#define SIENA_MC_BOOT_VERSION (1)
+
+/*Structures supporting an arbitrary number of binary blobs in the flash image
+ intended to house code and tables for the satellite cpus*/
+/*thanks to random.org for:*/
+#define BLOBS_HEADER_MAGIC (0xBDA3BBD4)
+#define BLOB_HEADER_MAGIC (0xA1478A91)
+
+typedef struct blobs_hdr_s { /* GENERATED BY scripts/genfwdef */
+ efx_dword_t magic;
+ efx_dword_t no_of_blobs;
+} blobs_hdr_t;
+
+typedef struct blob_hdr_s { /* GENERATED BY scripts/genfwdef */
+ efx_dword_t magic;
+ efx_dword_t cpu_type;
+ efx_dword_t build_variant;
+ efx_dword_t offset;
+ efx_dword_t length;
+ efx_dword_t checksum;
+} blob_hdr_t;
+
+#define BLOB_CPU_TYPE_TXDI_TEXT (0)
+#define BLOB_CPU_TYPE_RXDI_TEXT (1)
+#define BLOB_CPU_TYPE_TXDP_TEXT (2)
+#define BLOB_CPU_TYPE_RXDP_TEXT (3)
+#define BLOB_CPU_TYPE_RXHRSL_HR_LUT (4)
+#define BLOB_CPU_TYPE_RXHRSL_HR_LUT_CFG (5)
+#define BLOB_CPU_TYPE_TXHRSL_HR_LUT (6)
+#define BLOB_CPU_TYPE_TXHRSL_HR_LUT_CFG (7)
+#define BLOB_CPU_TYPE_RXHRSL_HR_PGM (8)
+#define BLOB_CPU_TYPE_RXHRSL_SL_PGM (9)
+#define BLOB_CPU_TYPE_TXHRSL_HR_PGM (10)
+#define BLOB_CPU_TYPE_TXHRSL_SL_PGM (11)
+#define BLOB_CPU_TYPE_RXDI_VTBL0 (12)
+#define BLOB_CPU_TYPE_TXDI_VTBL0 (13)
+#define BLOB_CPU_TYPE_RXDI_VTBL1 (14)
+#define BLOB_CPU_TYPE_TXDI_VTBL1 (15)
+#define BLOB_CPU_TYPE_DUMPSPEC (32)
+
typedef struct siena_mc_boot_hdr_s { /* GENERATED BY scripts/genfwdef */
efx_dword_t magic; /* = SIENA_MC_BOOT_MAGIC */
efx_word_t hdr_version; /* this structure definition is version 1 */
@@ -57,14 +101,21 @@ typedef struct siena_mc_boot_hdr_s { /* GENERATED BY scripts/genfwdef */
efx_byte_t firmware_version_c;
efx_word_t checksum; /* of whole header area + firmware image */
efx_word_t firmware_version_d;
- efx_word_t reserved_a[1]; /* (set to 0) */
+ efx_byte_t mcfw_subtype;
+ efx_byte_t reserved_a[1]; /* (set to 0) */
efx_dword_t firmware_text_offset; /* offset to firmware .text */
efx_dword_t firmware_text_size; /* length of firmware .text, in bytes */
efx_dword_t firmware_data_offset; /* offset to firmware .data */
efx_dword_t firmware_data_size; /* length of firmware .data, in bytes */
- efx_dword_t reserved_b[8]; /* (set to 0) */
+ efx_byte_t spi_rate; /* SPI rate for reading image, 0 is BootROM default */
+ efx_byte_t spi_phase_adj; /* SPI SDO/SCL phase adjustment, 0 is default (no adj) */
+ efx_word_t reserved_b[1]; /* (set to 0) */
+ efx_dword_t reserved_c[7]; /* (set to 0) */
} siena_mc_boot_hdr_t;
+#define SIENA_MC_BOOT_HDR_PADDING \
+ (SIENA_MC_BOOT_HDR_LEN - sizeof(siena_mc_boot_hdr_t))
+
#define SIENA_MC_STATIC_CONFIG_MAGIC (0xBDCF5555)
#define SIENA_MC_STATIC_CONFIG_VERSION (0)
@@ -81,8 +132,8 @@ typedef struct siena_mc_static_config_hdr_s { /* GENERATED BY scripts/genfwdef *
efx_byte_t green_mode_valid; /* Whether cal holds a valid value */
efx_word_t mac_addr_count;
efx_word_t mac_addr_stride;
- efx_word_t calibrated_vref;
- efx_word_t adc_vref;
+ efx_word_t calibrated_vref; /* Vref as measured during production */
+ efx_word_t adc_vref; /* Vref as read by ADC */
efx_dword_t reserved2[1]; /* (write as zero) */
efx_dword_t num_dbi_items;
struct {
@@ -117,17 +168,32 @@ typedef struct siena_mc_dynamic_config_hdr_s { /* GENERATED BY scripts/genfwdef
#define SIENA_MC_EXPROM_SINGLE_MAGIC (0xAA55) /* little-endian uint16_t */
#define SIENA_MC_EXPROM_COMBO_MAGIC (0xB0070102) /* little-endian uint32_t */
+#define SIENA_MC_EXPROM_COMBO_V2_MAGIC (0xB0070103) /* little-endian uint32_t */
typedef struct siena_mc_combo_rom_hdr_s { /* GENERATED BY scripts/genfwdef */
- efx_dword_t magic; /* = SIENA_MC_EXPROM_COMBO_MAGIC */
- efx_dword_t len1; /* length of first image */
- efx_dword_t len2; /* length of second image */
- efx_dword_t off1; /* offset of first byte to edit to combine images */
- efx_dword_t off2; /* offset of second byte to edit to combine images */
- efx_word_t infoblk0_off; /* infoblk offset */
- efx_word_t infoblk1_off; /* infoblk offset */
- efx_byte_t infoblk_len; /* length of space reserved for infoblk structures */
- efx_byte_t reserved[7]; /* (set to 0) */
+ efx_dword_t magic; /* = SIENA_MC_EXPROM_COMBO_MAGIC or SIENA_MC_EXPROM_COMBO_V2_MAGIC */
+ union {
+ struct {
+ efx_dword_t len1; /* length of first image */
+ efx_dword_t len2; /* length of second image */
+ efx_dword_t off1; /* offset of first byte to edit to combine images */
+ efx_dword_t off2; /* offset of second byte to edit to combine images */
+ efx_word_t infoblk0_off;/* infoblk offset */
+ efx_word_t infoblk1_off;/* infoblk offset */
+ efx_byte_t infoblk_len;/* length of space reserved for one infoblk structure */
+ efx_byte_t reserved[7];/* (set to 0) */
+ } v1;
+ struct {
+ efx_dword_t len1; /* length of first image */
+ efx_dword_t len2; /* length of second image */
+ efx_dword_t off1; /* offset of first byte to edit to combine images */
+ efx_dword_t off2; /* offset of second byte to edit to combine images */
+ efx_word_t infoblk_off;/* infoblk start offset */
+ efx_word_t infoblk_count;/* infoblk count */
+ efx_byte_t infoblk_len;/* length of space reserved for one infoblk structure */
+ efx_byte_t reserved[7];/* (set to 0) */
+ } v2;
+ };
} siena_mc_combo_rom_hdr_t;
#pragma pack()
diff --git a/sys/dev/sfxge/common/siena_impl.h b/sys/dev/sfxge/common/siena_impl.h
index 9d02808..b65e399 100644
--- a/sys/dev/sfxge/common/siena_impl.h
+++ b/sys/dev/sfxge/common/siena_impl.h
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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.
*
* $FreeBSD$
*/
@@ -101,6 +106,49 @@ siena_sram_test(
#endif /* EFSYS_OPT_DIAG */
+#if EFSYS_OPT_MCDI
+
+extern __checkReturn int
+siena_mcdi_init(
+ __in efx_nic_t *enp,
+ __in const efx_mcdi_transport_t *mtp);
+
+extern void
+siena_mcdi_request_copyin(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp,
+ __in unsigned int seq,
+ __in boolean_t ev_cpl,
+ __in boolean_t new_epoch);
+
+extern __checkReturn boolean_t
+siena_mcdi_request_poll(
+ __in efx_nic_t *enp);
+
+extern void
+siena_mcdi_request_copyout(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp);
+
+extern int
+siena_mcdi_poll_reboot(
+ __in efx_nic_t *enp);
+
+extern void
+siena_mcdi_fini(
+ __in efx_nic_t *enp);
+
+extern __checkReturn int
+siena_mcdi_fw_update_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp);
+
+extern __checkReturn int
+siena_mcdi_macaddr_change_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp);
+
+#endif /* EFSYS_OPT_MCDI */
#if EFSYS_OPT_NVRAM || EFSYS_OPT_VPD
@@ -170,6 +218,12 @@ siena_nvram_size(
__out size_t *sizep);
extern __checkReturn int
+siena_nvram_get_subtype(
+ __in efx_nic_t *enp,
+ __in unsigned int partn,
+ __out uint32_t *subtypep);
+
+extern __checkReturn int
siena_nvram_get_version(
__in efx_nic_t *enp,
__in efx_nvram_type_t type,
@@ -212,7 +266,7 @@ extern __checkReturn int
siena_nvram_set_version(
__in efx_nic_t *enp,
__in efx_nvram_type_t type,
- __out uint16_t version[4]);
+ __in_ecount(4) uint16_t version[4]);
#endif /* EFSYS_OPT_NVRAM */
@@ -341,7 +395,7 @@ siena_phy_stats_update(
#if EFSYS_OPT_NAMES
-extern const char __cs *
+extern const char *
siena_phy_prop_name(
__in efx_nic_t *enp,
__in unsigned int id);
@@ -363,18 +417,18 @@ siena_phy_prop_set(
#endif /* EFSYS_OPT_PHY_PROPS */
-#if EFSYS_OPT_PHY_BIST
+#if EFSYS_OPT_BIST
extern __checkReturn int
siena_phy_bist_start(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type);
+ __in efx_bist_type_t type);
extern __checkReturn int
siena_phy_bist_poll(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type,
- __out efx_phy_bist_result_t *resultp,
+ __in efx_bist_type_t type,
+ __out efx_bist_result_t *resultp,
__out_opt __drv_when(count > 0, __notnull)
uint32_t *value_maskp,
__out_ecount_opt(count) __drv_when(count > 0, __notnull)
@@ -384,9 +438,9 @@ siena_phy_bist_poll(
extern void
siena_phy_bist_stop(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type);
+ __in efx_bist_type_t type);
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
extern __checkReturn int
siena_mac_poll(
@@ -415,22 +469,6 @@ siena_mac_loopback_set(
#if EFSYS_OPT_MAC_STATS
extern __checkReturn int
-siena_mac_stats_clear(
- __in efx_nic_t *enp);
-
-extern __checkReturn int
-siena_mac_stats_upload(
- __in efx_nic_t *enp,
- __in efsys_mem_t *esmp);
-
-extern __checkReturn int
-siena_mac_stats_periodic(
- __in efx_nic_t *enp,
- __in efsys_mem_t *esmp,
- __in uint16_t period_ms,
- __in boolean_t events);
-
-extern __checkReturn int
siena_mac_stats_update(
__in efx_nic_t *enp,
__in efsys_mem_t *esmp,
@@ -439,39 +477,6 @@ siena_mac_stats_update(
#endif /* EFSYS_OPT_MAC_STATS */
-extern __checkReturn int
-siena_mon_reset(
- __in efx_nic_t *enp);
-
-extern __checkReturn int
-siena_mon_reconfigure(
- __in efx_nic_t *enp);
-
-#if EFSYS_OPT_MON_STATS
-
-extern void
-siena_mon_decode_stats(
- __in efx_nic_t *enp,
- __in uint32_t dmask,
- __in_opt efsys_mem_t *esmp,
- __out_opt uint32_t *vmaskp,
- __out_ecount_opt(EFX_MON_NSTATS) efx_mon_stat_value_t *value);
-
-extern __checkReturn int
-siena_mon_ev(
- __in efx_nic_t *enp,
- __in efx_qword_t *eqp,
- __out efx_mon_stat_t *idp,
- __out efx_mon_stat_value_t *valuep);
-
-extern __checkReturn int
-siena_mon_stats_update(
- __in efx_nic_t *enp,
- __in efsys_mem_t *esmp,
- __out_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values);
-
-#endif /* EFSYS_OPT_MON_STATS */
-
#ifdef __cplusplus
}
#endif
diff --git a/sys/dev/sfxge/common/siena_mac.c b/sys/dev/sfxge/common/siena_mac.c
index 38f5bc5..beeaea1 100644
--- a/sys/dev/sfxge/common/siena_mac.c
+++ b/sys/dev/sfxge/common/siena_mac.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -89,26 +94,29 @@ siena_mac_reconfigure(
__in efx_nic_t *enp)
{
efx_port_t *epp = &(enp->en_port);
- uint8_t payload[MAX(MC_CMD_SET_MAC_IN_LEN,
- MC_CMD_SET_MCAST_HASH_IN_LEN)];
+ efx_oword_t multicast_hash[2];
efx_mcdi_req_t req;
+ uint8_t payload[MAX(MAX(MC_CMD_SET_MAC_IN_LEN,
+ MC_CMD_SET_MAC_OUT_LEN),
+ MAX(MC_CMD_SET_MCAST_HASH_IN_LEN,
+ MC_CMD_SET_MCAST_HASH_OUT_LEN))];
unsigned int fcntl;
int rc;
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_SET_MAC;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_SET_MAC_IN_LEN;
- EFX_STATIC_ASSERT(MC_CMD_SET_MAC_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_SET_MAC_OUT_LEN;
MCDI_IN_SET_DWORD(req, SET_MAC_IN_MTU, epp->ep_mac_pdu);
MCDI_IN_SET_DWORD(req, SET_MAC_IN_DRAIN, epp->ep_mac_drain ? 1 : 0);
EFX_MAC_ADDR_COPY(MCDI_IN2(req, uint8_t, SET_MAC_IN_ADDR),
epp->ep_mac_addr);
MCDI_IN_POPULATE_DWORD_2(req, SET_MAC_IN_REJECT,
- SET_MAC_IN_REJECT_UNCST, !epp->ep_unicst,
- SET_MAC_IN_REJECT_BRDCST, !epp->ep_brdcst);
+ SET_MAC_IN_REJECT_UNCST, !epp->ep_all_unicst,
+ SET_MAC_IN_REJECT_BRDCST, !epp->ep_brdcst);
if (epp->ep_fcntl_autoneg)
/* efx_fcntl_set() has already set the phy capabilities */
@@ -129,19 +137,40 @@ siena_mac_reconfigure(
goto fail1;
}
- /* Push multicast hash. Set the broadcast bit (0xff) appropriately */
+ /* Push multicast hash */
+
+ if (epp->ep_all_mulcst) {
+ /* A hash matching all multicast is all 1s */
+ EFX_SET_OWORD(multicast_hash[0]);
+ EFX_SET_OWORD(multicast_hash[1]);
+ } else if (epp->ep_mulcst) {
+ /* Use the hash set by the multicast list */
+ multicast_hash[0] = epp->ep_multicst_hash[0];
+ multicast_hash[1] = epp->ep_multicst_hash[1];
+ } else {
+ /* A hash matching no traffic is simply 0 */
+ EFX_ZERO_OWORD(multicast_hash[0]);
+ EFX_ZERO_OWORD(multicast_hash[1]);
+ }
+
+ /*
+ * Broadcast packets go through the multicast hash filter.
+ * The IEEE 802.3 CRC32 of the broadcast address is 0xbe2612ff
+ * so we always add bit 0xff to the mask (bit 0x7f in the
+ * second octword).
+ */
+ if (epp->ep_brdcst)
+ EFX_SET_OWORD_BIT(multicast_hash[1], 0x7f);
+
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_SET_MCAST_HASH;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_SET_MCAST_HASH_IN_LEN;
- EFX_STATIC_ASSERT(MC_CMD_SET_MCAST_HASH_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_SET_MCAST_HASH_OUT_LEN;
memcpy(MCDI_IN2(req, uint8_t, SET_MCAST_HASH_IN_HASH0),
- epp->ep_multicst_hash, sizeof (epp->ep_multicst_hash));
- if (epp->ep_brdcst)
- EFX_SET_OWORD_BIT(*MCDI_IN2(req, efx_oword_t,
- SET_MCAST_HASH_IN_HASH1), 0x7f);
+ multicast_hash, sizeof (multicast_hash));
efx_mcdi_execute(enp, &req);
@@ -198,150 +227,6 @@ fail1:
#if EFSYS_OPT_MAC_STATS
- __checkReturn int
-siena_mac_stats_clear(
- __in efx_nic_t *enp)
-{
- uint8_t payload[MC_CMD_MAC_STATS_IN_LEN];
- efx_mcdi_req_t req;
- int rc;
-
- req.emr_cmd = MC_CMD_MAC_STATS;
- req.emr_in_buf = payload;
- req.emr_in_length = sizeof (payload);
- EFX_STATIC_ASSERT(MC_CMD_MAC_STATS_OUT_DMA_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- MCDI_IN_POPULATE_DWORD_3(req, MAC_STATS_IN_CMD,
- MAC_STATS_IN_DMA, 0,
- MAC_STATS_IN_CLEAR, 1,
- MAC_STATS_IN_PERIODIC_CHANGE, 0);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
- __checkReturn int
-siena_mac_stats_upload(
- __in efx_nic_t *enp,
- __in efsys_mem_t *esmp)
-{
- uint8_t payload[MC_CMD_MAC_STATS_IN_LEN];
- efx_mcdi_req_t req;
- size_t bytes;
- int rc;
-
- EFX_STATIC_ASSERT(MC_CMD_MAC_NSTATS * sizeof (uint64_t) <=
- EFX_MAC_STATS_SIZE);
-
- bytes = MC_CMD_MAC_NSTATS * sizeof (uint64_t);
-
- req.emr_cmd = MC_CMD_MAC_STATS;
- req.emr_in_buf = payload;
- req.emr_in_length = sizeof (payload);
- EFX_STATIC_ASSERT(MC_CMD_MAC_STATS_OUT_DMA_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_LO,
- EFSYS_MEM_ADDR(esmp) & 0xffffffff);
- MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_HI,
- EFSYS_MEM_ADDR(esmp) >> 32);
- MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_LEN, bytes);
-
- /*
- * The MC DMAs aggregate statistics for our convinience, so we can
- * avoid having to pull the statistics buffer into the cache to
- * maintain cumulative statistics.
- */
- MCDI_IN_POPULATE_DWORD_3(req, MAC_STATS_IN_CMD,
- MAC_STATS_IN_DMA, 1,
- MAC_STATS_IN_CLEAR, 0,
- MAC_STATS_IN_PERIODIC_CHANGE, 0);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
- __checkReturn int
-siena_mac_stats_periodic(
- __in efx_nic_t *enp,
- __in efsys_mem_t *esmp,
- __in uint16_t period,
- __in boolean_t events)
-{
- uint8_t payload[MC_CMD_MAC_STATS_IN_LEN];
- efx_mcdi_req_t req;
- size_t bytes;
- int rc;
-
- bytes = MC_CMD_MAC_NSTATS * sizeof (uint64_t);
-
- req.emr_cmd = MC_CMD_MAC_STATS;
- req.emr_in_buf = payload;
- req.emr_in_length = sizeof (payload);
- EFX_STATIC_ASSERT(MC_CMD_MAC_STATS_OUT_DMA_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_LO,
- EFSYS_MEM_ADDR(esmp) & 0xffffffff);
- MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_ADDR_HI,
- EFSYS_MEM_ADDR(esmp) >> 32);
- MCDI_IN_SET_DWORD(req, MAC_STATS_IN_DMA_LEN, bytes);
-
- /*
- * The MC DMAs aggregate statistics for our convinience, so we can
- * avoid having to pull the statistics buffer into the cache to
- * maintain cumulative statistics.
- */
- MCDI_IN_POPULATE_DWORD_6(req, MAC_STATS_IN_CMD,
- MAC_STATS_IN_DMA, 0,
- MAC_STATS_IN_CLEAR, 0,
- MAC_STATS_IN_PERIODIC_CHANGE, 1,
- MAC_STATS_IN_PERIODIC_ENABLE, period ? 1 : 0,
- MAC_STATS_IN_PERIODIC_NOEVENT, events ? 0 : 1,
- MAC_STATS_IN_PERIOD_MS, period);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
-
#define SIENA_MAC_STAT_READ(_esmp, _field, _eqp) \
EFSYS_MEM_READQ((_esmp), (_field) * sizeof (efx_qword_t), _eqp)
@@ -352,7 +237,6 @@ siena_mac_stats_update(
__out_ecount(EFX_MAC_NSTATS) efsys_stat_t *stat,
__out_opt uint32_t *generationp)
{
- efx_qword_t rx_pkts;
efx_qword_t value;
efx_qword_t generation_start;
efx_qword_t generation_end;
@@ -360,6 +244,7 @@ siena_mac_stats_update(
_NOTE(ARGUNUSED(enp))
/* Read END first so we don't race with the MC */
+ EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFX_MAC_STATS_SIZE);
SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_END,
&generation_end);
EFSYS_MEM_READ_BARRIER();
@@ -388,7 +273,7 @@ siena_mac_stats_update(
SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_LT64_PKTS, &value);
EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_64_PKTS, &value);
- EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
+ EFSYS_STAT_INCR_QWORD(&(stat[EFX_MAC_TX_LE_64_PKTS]), &value);
SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_TX_65_TO_127_PKTS, &value);
EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_65_TO_127_PKTS]), &value);
@@ -435,8 +320,8 @@ siena_mac_stats_update(
EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_TX_EX_DEF_PKTS]), &value);
/* RX */
- SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BYTES, &rx_pkts);
- EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_OCTETS]), &rx_pkts);
+ SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_BYTES, &value);
+ EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_OCTETS]), &value);
SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_PKTS, &value);
EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_PKTS]), &value);
@@ -529,6 +414,7 @@ siena_mac_stats_update(
SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_RX_NODESC_DROPS, &value);
EFSYS_STAT_SET_QWORD(&(stat[EFX_MAC_RX_NODESC_DROP_CNT]), &value);
+ EFSYS_DMA_SYNC_FOR_KERNEL(esmp, 0, EFX_MAC_STATS_SIZE);
EFSYS_MEM_READ_BARRIER();
SIENA_MAC_STAT_READ(esmp, MC_CMD_MAC_GENERATION_START,
&generation_start);
diff --git a/sys/dev/sfxge/common/siena_mcdi.c b/sys/dev/sfxge/common/siena_mcdi.c
new file mode 100644
index 0000000..b2224ac
--- /dev/null
+++ b/sys/dev/sfxge/common/siena_mcdi.c
@@ -0,0 +1,354 @@
+/*-
+ * Copyright (c) 2012-2015 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "efsys.h"
+#include "efx.h"
+#include "efx_impl.h"
+
+#if EFSYS_OPT_SIENA && EFSYS_OPT_MCDI
+
+#define SIENA_MCDI_PDU(_emip) \
+ (((emip)->emi_port == 1) \
+ ? MC_SMEM_P0_PDU_OFST >> 2 \
+ : MC_SMEM_P1_PDU_OFST >> 2)
+
+#define SIENA_MCDI_DOORBELL(_emip) \
+ (((emip)->emi_port == 1) \
+ ? MC_SMEM_P0_DOORBELL_OFST >> 2 \
+ : MC_SMEM_P1_DOORBELL_OFST >> 2)
+
+#define SIENA_MCDI_STATUS(_emip) \
+ (((emip)->emi_port == 1) \
+ ? MC_SMEM_P0_STATUS_OFST >> 2 \
+ : MC_SMEM_P1_STATUS_OFST >> 2)
+
+
+ void
+siena_mcdi_request_copyin(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp,
+ __in unsigned int seq,
+ __in boolean_t ev_cpl,
+ __in boolean_t new_epoch)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_dword_t dword;
+ unsigned int xflags;
+ unsigned int pdur;
+ unsigned int dbr;
+ unsigned int pos;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
+ _NOTE(ARGUNUSED(new_epoch))
+
+ EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2);
+ pdur = SIENA_MCDI_PDU(emip);
+ dbr = SIENA_MCDI_DOORBELL(emip);
+
+ xflags = 0;
+ if (ev_cpl)
+ xflags |= MCDI_HEADER_XFLAGS_EVREQ;
+
+ /* Construct the header in shared memory */
+ EFX_POPULATE_DWORD_6(dword,
+ MCDI_HEADER_CODE, emrp->emr_cmd,
+ MCDI_HEADER_RESYNC, 1,
+ MCDI_HEADER_DATALEN, emrp->emr_in_length,
+ MCDI_HEADER_SEQ, seq,
+ MCDI_HEADER_RESPONSE, 0,
+ MCDI_HEADER_XFLAGS, xflags);
+ EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, pdur, &dword, B_TRUE);
+
+ for (pos = 0; pos < emrp->emr_in_length; pos += sizeof (efx_dword_t)) {
+ memcpy(&dword, MCDI_IN(*emrp, efx_dword_t, pos),
+ MIN(sizeof (dword), emrp->emr_in_length - pos));
+ EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM,
+ pdur + 1 + (pos >> 2), &dword, B_FALSE);
+ }
+
+ /* Ring the doorbell */
+ EFX_POPULATE_DWORD_1(dword, EFX_DWORD_0, 0xd004be11);
+ EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, dbr, &dword, B_FALSE);
+}
+
+ void
+siena_mcdi_request_copyout(
+ __in efx_nic_t *enp,
+ __in efx_mcdi_req_t *emrp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ unsigned int pos;
+ unsigned int pdur;
+ efx_dword_t data;
+
+ pdur = SIENA_MCDI_PDU(emip);
+
+ /* Copy payload out if caller supplied buffer */
+ if (emrp->emr_out_buf != NULL) {
+ size_t bytes = MIN(emrp->emr_out_length_used,
+ emrp->emr_out_length);
+ for (pos = 0; pos < bytes; pos += sizeof (efx_dword_t)) {
+ EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM,
+ pdur + 1 + (pos >> 2), &data, B_FALSE);
+ memcpy(MCDI_OUT(*emrp, efx_dword_t, pos), &data,
+ MIN(sizeof (data), bytes - pos));
+ }
+ }
+}
+
+ int
+siena_mcdi_poll_reboot(
+ __in efx_nic_t *enp)
+{
+#ifndef EFX_GRACEFUL_MC_REBOOT
+ /*
+ * This function is not being used properly.
+ * Until its callers are fixed, it should always return 0.
+ */
+ _NOTE(ARGUNUSED(enp))
+ return (0);
+#else
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ unsigned int rebootr;
+ efx_dword_t dword;
+ uint32_t value;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
+ EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2);
+ rebootr = SIENA_MCDI_STATUS(emip);
+
+ EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, rebootr, &dword, B_FALSE);
+ value = EFX_DWORD_FIELD(dword, EFX_DWORD_0);
+
+ if (value == 0)
+ return (0);
+
+ EFX_ZERO_DWORD(dword);
+ EFX_BAR_TBL_WRITED(enp, FR_CZ_MC_TREG_SMEM, rebootr, &dword, B_FALSE);
+
+ if (value == MC_STATUS_DWORD_ASSERT)
+ return (EINTR);
+ else
+ return (EIO);
+#endif
+}
+
+ __checkReturn boolean_t
+siena_mcdi_request_poll(
+ __in efx_nic_t *enp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_mcdi_req_t *emrp;
+ efx_dword_t dword;
+ unsigned int pdur;
+ unsigned int seq;
+ unsigned int length;
+ int state;
+ int rc;
+
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
+
+ /* Serialise against post-watchdog efx_mcdi_ev* */
+ EFSYS_LOCK(enp->en_eslp, state);
+
+ EFSYS_ASSERT(emip->emi_pending_req != NULL);
+ EFSYS_ASSERT(!emip->emi_ev_cpl);
+ emrp = emip->emi_pending_req;
+
+ /* Check for reboot atomically w.r.t efx_mcdi_request_start */
+ if (emip->emi_poll_cnt++ == 0) {
+ if ((rc = siena_mcdi_poll_reboot(enp)) != 0) {
+ emip->emi_pending_req = NULL;
+ EFSYS_UNLOCK(enp->en_eslp, state);
+
+ goto fail1;
+ }
+ }
+
+ EFSYS_ASSERT(emip->emi_port == 1 || emip->emi_port == 2);
+ pdur = SIENA_MCDI_PDU(emip);
+
+ /* Read the command header */
+ EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM, pdur, &dword, B_FALSE);
+ if (EFX_DWORD_FIELD(dword, MCDI_HEADER_RESPONSE) == 0) {
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ return (B_FALSE);
+ }
+
+ /* Request complete */
+ emip->emi_pending_req = NULL;
+ seq = (emip->emi_seq - 1) & EFX_MASK32(MCDI_HEADER_SEQ);
+
+ /* Check for synchronous reboot */
+ if (EFX_DWORD_FIELD(dword, MCDI_HEADER_ERROR) != 0 &&
+ EFX_DWORD_FIELD(dword, MCDI_HEADER_DATALEN) == 0) {
+ /* Consume status word */
+ EFSYS_SPIN(EFX_MCDI_STATUS_SLEEP_US);
+ siena_mcdi_poll_reboot(enp);
+ EFSYS_UNLOCK(enp->en_eslp, state);
+ rc = EIO;
+ goto fail2;
+ }
+
+ EFSYS_UNLOCK(enp->en_eslp, state);
+
+ /* Check that the returned data is consistent */
+ if (EFX_DWORD_FIELD(dword, MCDI_HEADER_CODE) != emrp->emr_cmd ||
+ EFX_DWORD_FIELD(dword, MCDI_HEADER_SEQ) != seq) {
+ /* Response is for a different request */
+ rc = EIO;
+ goto fail3;
+ }
+
+ length = EFX_DWORD_FIELD(dword, MCDI_HEADER_DATALEN);
+ if (EFX_DWORD_FIELD(dword, MCDI_HEADER_ERROR)) {
+ efx_dword_t errdword;
+ int errcode;
+
+ EFSYS_ASSERT3U(length, ==, 4);
+ EFX_BAR_TBL_READD(enp, FR_CZ_MC_TREG_SMEM,
+ pdur + 1 + (MC_CMD_ERR_CODE_OFST >> 2),
+ &errdword, B_FALSE);
+ errcode = EFX_DWORD_FIELD(errdword, EFX_DWORD_0);
+ rc = efx_mcdi_request_errcode(errcode);
+ if (!emrp->emr_quiet) {
+ EFSYS_PROBE2(mcdi_err, int, emrp->emr_cmd,
+ int, errcode);
+ }
+ goto fail4;
+
+ } else {
+ emrp->emr_out_length_used = length;
+ emrp->emr_rc = 0;
+ siena_mcdi_request_copyout(enp, emrp);
+ }
+
+ goto out;
+
+fail4:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE(fail4);
+fail3:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE(fail3);
+fail2:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE(fail2);
+fail1:
+ if (!emrp->emr_quiet)
+ EFSYS_PROBE1(fail1, int, rc);
+
+ /* Fill out error state */
+ emrp->emr_rc = rc;
+ emrp->emr_out_length_used = 0;
+
+ /* Reboot/Assertion */
+ if (rc == EIO || rc == EINTR)
+ efx_mcdi_raise_exception(enp, emrp, rc);
+
+out:
+ return (B_TRUE);
+}
+
+ __checkReturn int
+siena_mcdi_init(
+ __in efx_nic_t *enp,
+ __in const efx_mcdi_transport_t *mtp)
+{
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ efx_oword_t oword;
+ unsigned int portnum;
+ int rc;
+
+ EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
+
+ /* Determine the port number to use for MCDI */
+ EFX_BAR_READO(enp, FR_AZ_CS_DEBUG_REG, &oword);
+ portnum = EFX_OWORD_FIELD(oword, FRF_CZ_CS_PORT_NUM);
+
+ if (portnum == 0) {
+ /* Presumably booted from ROM; only MCDI port 1 will work */
+ emip->emi_port = 1;
+ } else if (portnum <= 2) {
+ emip->emi_port = portnum;
+ } else {
+ rc = EINVAL;
+ goto fail1;
+ }
+
+ /*
+ * Wipe the atomic reboot status so subsequent MCDI requests succeed.
+ * BOOT_STATUS is preserved so eno_nic_probe() can boot out of the
+ * assertion handler.
+ */
+ (void) siena_mcdi_poll_reboot(enp);
+
+ return (0);
+
+fail1:
+ EFSYS_PROBE1(fail1, int, rc);
+
+ return (rc);
+}
+
+ void
+siena_mcdi_fini(
+ __in efx_nic_t *enp)
+{
+}
+
+ __checkReturn int
+siena_mcdi_fw_update_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp)
+{
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
+
+ *supportedp = B_TRUE;
+
+ return (0);
+}
+
+ __checkReturn int
+siena_mcdi_macaddr_change_supported(
+ __in efx_nic_t *enp,
+ __out boolean_t *supportedp)
+{
+ EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
+
+ *supportedp = B_TRUE;
+
+ return (0);
+}
+
+#endif /* EFSYS_OPT_SIENA && EFSYS_OPT_MCDI */
diff --git a/sys/dev/sfxge/common/siena_mon.c b/sys/dev/sfxge/common/siena_mon.c
deleted file mode 100644
index 227ff15..0000000
--- a/sys/dev/sfxge/common/siena_mon.c
+++ /dev/null
@@ -1,284 +0,0 @@
-/*-
- * Copyright 2009 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 AUTHOR 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 AUTHOR 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "efsys.h"
-#include "efx.h"
-#include "efx_impl.h"
-
-#if EFSYS_OPT_MON_SIENA
-
- __checkReturn int
-siena_mon_reset(
- __in efx_nic_t *enp)
-{
- _NOTE(ARGUNUSED(enp))
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
-
- return (0);
-}
-
- __checkReturn int
-siena_mon_reconfigure(
- __in efx_nic_t *enp)
-{
- _NOTE(ARGUNUSED(enp))
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
-
- return (0);
-}
-
-#if EFSYS_OPT_MON_STATS
-
-#define SIENA_MON_WRONG_PORT (uint16_t)0xffff
-
-static __cs uint16_t __siena_mon_port0_map[] = {
- EFX_MON_STAT_INT_TEMP, /* MC_CMD_SENSOR_CONTROLLER_TEMP */
- EFX_MON_STAT_EXT_TEMP, /* MC_CMD_SENSOR_PHY_COMMON_TEMP */
- EFX_MON_STAT_INT_COOLING, /* MC_CMD_SENSOR_CONTROLLER_COOLING */
- EFX_MON_STAT_EXT_TEMP, /* MC_CMD_SENSOR_PHY0_TEMP */
- EFX_MON_STAT_EXT_COOLING, /* MC_CMD_SENSOR_PHY0_COOLING */
- SIENA_MON_WRONG_PORT, /* MC_CMD_SENSOR_PHY1_TEMP */
- SIENA_MON_WRONG_PORT, /* MC_CMD_SENSOR_PHY1_COOLING */
- EFX_MON_STAT_1V, /* MC_CMD_SENSOR_IN_1V0 */
- EFX_MON_STAT_1_2V, /* MC_CMD_SENSOR_IN_1V2 */
- EFX_MON_STAT_1_8V, /* MC_CMD_SENSOR_IN_1V8 */
- EFX_MON_STAT_2_5V, /* MC_CMD_SENSOR_IN_2V5 */
- EFX_MON_STAT_3_3V, /* MC_CMD_SENSOR_IN_3V3 */
- EFX_MON_STAT_12V, /* MC_CMD_SENSOR_IN_12V0 */
- EFX_MON_STAT_1_2VA, /* MC_CMD_SENSOR_IN_1V2A */
- EFX_MON_STAT_VREF, /* MC_CMD_SENSOR_IN_VREF */
- EFX_MON_STAT_VAOE, /* MC_CMD_SENSOR_OUT_VAOE */
- EFX_MON_STAT_AOE_TEMP, /* MC_CMD_SENSOR_AOE_TEMP */
- EFX_MON_STAT_PSU_AOE_TEMP, /* MC_CMD_SENSOR_PSU_AOE_TEMP */
- EFX_MON_STAT_PSU_TEMP, /* MC_CMD_SENSOR_PSE_TEMP */
- EFX_MON_STAT_FAN0, /* MC_CMD_SENSOR_FAN_0 */
- EFX_MON_STAT_FAN1, /* MC_CMD_SENSOR_FAN_1 */
- EFX_MON_STAT_FAN2, /* MC_CMD_SENSOR_FAN_2 */
- EFX_MON_STAT_FAN3, /* MC_CMD_SENSOR_FAN_3 */
- EFX_MON_STAT_FAN4, /* MC_CMD_SENSOR_FAN_4 */
- EFX_MON_STAT_VAOE_IN, /* MC_CMD_SENSOR_IN_VAOE */
- EFX_MON_STAT_IAOE, /* MC_CMD_SENSOR_OUT_IAOE */
- EFX_MON_STAT_IAOE_IN, /* MC_CMD_SENSOR_IN_IAOE */
-
-};
-
-static __cs uint16_t __siena_mon_port1_map[] = {
- EFX_MON_STAT_INT_TEMP, /* MC_CMD_SENSOR_CONTROLLER_TEMP */
- EFX_MON_STAT_EXT_TEMP, /* MC_CMD_SENSOR_PHY_COMMON_TEMP */
- EFX_MON_STAT_INT_COOLING, /* MC_CMD_SENSOR_CONTROLLER_COOLING */
- SIENA_MON_WRONG_PORT, /* MC_CMD_SENSOR_PHY0_TEMP */
- SIENA_MON_WRONG_PORT, /* MC_CMD_SENSOR_PHY0_COOLING */
- EFX_MON_STAT_EXT_TEMP, /* MC_CMD_SENSOR_PHY1_TEMP */
- EFX_MON_STAT_EXT_COOLING, /* MC_CMD_SENSOR_PHY1_COOLING */
- EFX_MON_STAT_1V, /* MC_CMD_SENSOR_IN_1V0 */
- EFX_MON_STAT_1_2V, /* MC_CMD_SENSOR_IN_1V2 */
- EFX_MON_STAT_1_8V, /* MC_CMD_SENSOR_IN_1V8 */
- EFX_MON_STAT_2_5V, /* MC_CMD_SENSOR_IN_2V5 */
- EFX_MON_STAT_3_3V, /* MC_CMD_SENSOR_IN_3V3 */
- EFX_MON_STAT_12V, /* MC_CMD_SENSOR_IN_12V0 */
- EFX_MON_STAT_1_2VA, /* MC_CMD_SENSOR_IN_1V2A */
- EFX_MON_STAT_VREF, /* MC_CMD_SENSOR_IN_VREF */
- EFX_MON_STAT_VAOE, /* MC_CMD_SENSOR_OUT_VAOE */
- EFX_MON_STAT_AOE_TEMP, /* MC_CMD_SENSOR_AOE_TEMP */
- EFX_MON_STAT_PSU_AOE_TEMP, /* MC_CMD_SENSOR_PSU_AOE_TEMP */
- EFX_MON_STAT_PSU_TEMP, /* MC_CMD_SENSOR_PSE_TEMP */
- EFX_MON_STAT_FAN0, /* MC_CMD_SENSOR_FAN_0 */
- EFX_MON_STAT_FAN1, /* MC_CMD_SENSOR_FAN_1 */
- EFX_MON_STAT_FAN2, /* MC_CMD_SENSOR_FAN_2 */
- EFX_MON_STAT_FAN3, /* MC_CMD_SENSOR_FAN_3 */
- EFX_MON_STAT_FAN4, /* MC_CMD_SENSOR_FAN_4 */
- EFX_MON_STAT_VAOE_IN, /* MC_CMD_SENSOR_IN_VAOE */
- EFX_MON_STAT_IAOE, /* MC_CMD_SENSOR_OUT_IAOE */
- EFX_MON_STAT_IAOE_IN, /* MC_CMD_SENSOR_IN_IAOE */
-
-};
-
-#define SIENA_STATIC_SENSOR_ASSERT(_field) \
- EFX_STATIC_ASSERT(MC_CMD_SENSOR_STATE_ ## _field \
- == EFX_MON_STAT_STATE_ ## _field)
-
- void
-siena_mon_decode_stats(
- __in efx_nic_t *enp,
- __in uint32_t dmask,
- __in_opt efsys_mem_t *esmp,
- __out_opt uint32_t *vmaskp,
- __out_ecount_opt(EFX_MON_NSTATS) efx_mon_stat_value_t *value)
-{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- uint16_t *sensor_map;
- uint16_t mc_sensor;
- size_t mc_sensor_max;
- uint32_t vmask = 0;
- uint32_t idx = 0;
-
- /* Assert the MC_CMD_SENSOR and EFX_MON_STATE namespaces agree */
- SIENA_STATIC_SENSOR_ASSERT(OK);
- SIENA_STATIC_SENSOR_ASSERT(WARNING);
- SIENA_STATIC_SENSOR_ASSERT(FATAL);
- SIENA_STATIC_SENSOR_ASSERT(BROKEN);
-
- EFX_STATIC_ASSERT(sizeof (__siena_mon_port1_map)
- == sizeof (__siena_mon_port0_map));
- mc_sensor_max = EFX_ARRAY_SIZE(__siena_mon_port0_map);
- sensor_map = (emip->emi_port == 1)
- ? __siena_mon_port0_map
- : __siena_mon_port1_map;
-
- /*
- * dmask may legitimately contain sensors not understood by the driver
- */
- for (mc_sensor = 0; mc_sensor < mc_sensor_max; ++mc_sensor) {
- uint16_t efx_sensor = sensor_map[mc_sensor];
-
- if (~dmask & (1 << mc_sensor))
- continue;
- idx++;
-
- if (efx_sensor == SIENA_MON_WRONG_PORT)
- continue;
- EFSYS_ASSERT(efx_sensor < EFX_MON_NSTATS);
-
- vmask |= (1 << efx_sensor);
- if (value != NULL && esmp != NULL && !EFSYS_MEM_IS_NULL(esmp)) {
- efx_mon_stat_value_t *emsvp = value + efx_sensor;
- efx_dword_t dword;
- EFSYS_MEM_READD(esmp, 4 * (idx - 1), &dword);
- emsvp->emsv_value =
- (uint16_t)EFX_DWORD_FIELD(
- dword,
- MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE);
- emsvp->emsv_state =
- (uint16_t)EFX_DWORD_FIELD(
- dword,
- MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE);
- }
- }
-
- if (vmaskp != NULL)
- *vmaskp = vmask;
-}
-
- __checkReturn int
-siena_mon_ev(
- __in efx_nic_t *enp,
- __in efx_qword_t *eqp,
- __out efx_mon_stat_t *idp,
- __out efx_mon_stat_value_t *valuep)
-{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- uint16_t ev_monitor;
- uint16_t ev_state;
- uint16_t ev_value;
- uint16_t *sensor_map;
- efx_mon_stat_t id;
- int rc;
-
- sensor_map = (emip->emi_port == 1)
- ? __siena_mon_port0_map
- : __siena_mon_port1_map;
-
- ev_monitor = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_MONITOR);
- ev_state = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_STATE);
- ev_value = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_VALUE);
-
- /* Hardware must support this statistic */
- EFSYS_ASSERT((1 << ev_monitor) & encp->enc_siena_mon_stat_mask);
-
- /* But we don't have to understand it */
- if (ev_monitor >= EFX_ARRAY_SIZE(__siena_mon_port0_map)) {
- rc = ENOTSUP;
- goto fail1;
- }
-
- id = sensor_map[ev_monitor];
- if (id == SIENA_MON_WRONG_PORT)
- return (ENODEV);
- EFSYS_ASSERT(id < EFX_MON_NSTATS);
-
- *idp = id;
- valuep->emsv_value = ev_value;
- valuep->emsv_state = ev_state;
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
- __checkReturn int
-siena_mon_stats_update(
- __in efx_nic_t *enp,
- __in efsys_mem_t *esmp,
- __out_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values)
-{
- efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- uint32_t dmask = encp->enc_siena_mon_stat_mask;
- uint32_t vmask;
- uint8_t payload[MC_CMD_READ_SENSORS_IN_LEN];
- efx_mcdi_req_t req;
- int rc;
-
- EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
-
- req.emr_cmd = MC_CMD_READ_SENSORS;
- req.emr_in_buf = payload;
- req.emr_in_length = sizeof (payload);
- EFX_STATIC_ASSERT(MC_CMD_READ_SENSORS_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- MCDI_IN_SET_DWORD(req, READ_SENSORS_IN_DMA_ADDR_LO,
- EFSYS_MEM_ADDR(esmp) & 0xffffffff);
- MCDI_IN_SET_DWORD(req, READ_SENSORS_IN_DMA_ADDR_HI,
- EFSYS_MEM_ADDR(esmp) >> 32);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- siena_mon_decode_stats(enp, dmask, esmp, &vmask, values);
- EFSYS_ASSERT(vmask == encp->enc_mon_stat_mask);
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
-#endif /* EFSYS_OPT_MON_STATS */
-
-#endif /* EFSYS_OPT_MON_SIENA */
diff --git a/sys/dev/sfxge/common/siena_nic.c b/sys/dev/sfxge/common/siena_nic.c
index 1276c93..3dcf48e 100644
--- a/sys/dev/sfxge/common/siena_nic.c
+++ b/sys/dev/sfxge/common/siena_nic.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -29,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include "efsys.h"
#include "efx.h"
#include "efx_impl.h"
+#include "mcdi_mon.h"
#if EFSYS_OPT_SIENA
@@ -38,15 +44,16 @@ siena_nic_get_partn_mask(
__out unsigned int *maskp)
{
efx_mcdi_req_t req;
- uint8_t outbuf[MC_CMD_NVRAM_TYPES_OUT_LEN];
+ uint8_t payload[MAX(MC_CMD_NVRAM_TYPES_IN_LEN,
+ MC_CMD_NVRAM_TYPES_OUT_LEN)];
int rc;
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_NVRAM_TYPES;
- EFX_STATIC_ASSERT(MC_CMD_NVRAM_TYPES_IN_LEN == 0);
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = outbuf;
- req.emr_out_length = sizeof (outbuf);
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_NVRAM_TYPES_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_NVRAM_TYPES_OUT_LEN;
efx_mcdi_execute(enp, &req);
@@ -72,193 +79,17 @@ fail1:
return (rc);
}
-static __checkReturn int
-siena_nic_exit_assertion_handler(
- __in efx_nic_t *enp)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_REBOOT_IN_LEN];
- int rc;
-
- req.emr_cmd = MC_CMD_REBOOT;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_REBOOT_IN_LEN;
- EFX_STATIC_ASSERT(MC_CMD_REBOOT_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- MCDI_IN_SET_DWORD(req, REBOOT_IN_FLAGS,
- MC_CMD_REBOOT_FLAGS_AFTER_ASSERTION);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0 && req.emr_rc != EIO) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
-static __checkReturn int
-siena_nic_read_assertion(
- __in efx_nic_t *enp)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_GET_ASSERTS_IN_LEN,
- MC_CMD_GET_ASSERTS_OUT_LEN)];
- const char *reason;
- unsigned int flags;
- unsigned int index;
- unsigned int ofst;
- int retry;
- int rc;
-
- /*
- * Before we attempt to chat to the MC, we should verify that the MC
- * isn't in it's assertion handler, either due to a previous reboot,
- * or because we're reinitializing due to an eec_exception().
- *
- * Use GET_ASSERTS to read any assertion state that may be present.
- * Retry this command twice. Once because a boot-time assertion failure
- * might cause the 1st MCDI request to fail. And once again because
- * we might race with siena_nic_exit_assertion_handler() running on the
- * other port.
- */
- retry = 2;
- do {
- req.emr_cmd = MC_CMD_GET_ASSERTS;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_GET_ASSERTS_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_GET_ASSERTS_OUT_LEN;
-
- MCDI_IN_SET_DWORD(req, GET_ASSERTS_IN_CLEAR, 1);
- efx_mcdi_execute(enp, &req);
-
- } while ((req.emr_rc == EINTR || req.emr_rc == EIO) && retry-- > 0);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- if (req.emr_out_length_used < MC_CMD_GET_ASSERTS_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- /* Print out any assertion state recorded */
- flags = MCDI_OUT_DWORD(req, GET_ASSERTS_OUT_GLOBAL_FLAGS);
- if (flags == MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS)
- return (0);
-
- reason = (flags == MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL)
- ? "system-level assertion"
- : (flags == MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL)
- ? "thread-level assertion"
- : (flags == MC_CMD_GET_ASSERTS_FLAGS_WDOG_FIRED)
- ? "watchdog reset"
- : "unknown assertion";
- EFSYS_PROBE3(mcpu_assertion,
- const char *, reason, unsigned int,
- MCDI_OUT_DWORD(req, GET_ASSERTS_OUT_SAVED_PC_OFFS),
- unsigned int,
- MCDI_OUT_DWORD(req, GET_ASSERTS_OUT_THREAD_OFFS));
-
- /* Print out the registers */
- ofst = MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST;
- for (index = 1; index < 32; index++) {
- EFSYS_PROBE2(mcpu_register, unsigned int, index, unsigned int,
- EFX_DWORD_FIELD(*MCDI_OUT(req, efx_dword_t, ofst),
- EFX_DWORD_0));
- ofst += sizeof (efx_dword_t);
- }
- EFSYS_ASSERT(ofst <= MC_CMD_GET_ASSERTS_OUT_LEN);
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
-static __checkReturn int
-siena_nic_attach(
- __in efx_nic_t *enp,
- __in boolean_t attach)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_DRV_ATTACH_IN_LEN];
- int rc;
-
- req.emr_cmd = MC_CMD_DRV_ATTACH;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_DRV_ATTACH_IN_LEN;
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- MCDI_IN_SET_DWORD(req, DRV_ATTACH_IN_NEW_STATE, attach ? 1 : 0);
- MCDI_IN_SET_DWORD(req, DRV_ATTACH_IN_UPDATE, 1);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- if (req.emr_out_length_used < MC_CMD_DRV_ATTACH_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
#if EFSYS_OPT_PCIE_TUNE
__checkReturn int
siena_nic_pcie_extended_sync(
__in efx_nic_t *enp)
{
- uint8_t inbuf[MC_CMD_WORKAROUND_IN_LEN];
- efx_mcdi_req_t req;
int rc;
- EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
-
- req.emr_cmd = MC_CMD_WORKAROUND;
- req.emr_in_buf = inbuf;
- req.emr_in_length = sizeof (inbuf);
- EFX_STATIC_ASSERT(MC_CMD_WORKAROUND_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- MCDI_IN_SET_DWORD(req, WORKAROUND_IN_TYPE, MC_CMD_WORKAROUND_BUG17230);
- MCDI_IN_SET_DWORD(req, WORKAROUND_IN_ENABLED, 1);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ if ((rc = efx_mcdi_set_workaround(enp, MC_CMD_WORKAROUND_BUG17230,
+ B_TRUE, NULL) != 0))
goto fail1;
- }
return (0);
@@ -275,58 +106,33 @@ siena_board_cfg(
__in efx_nic_t *enp)
{
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- uint8_t outbuf[MAX(MC_CMD_GET_BOARD_CFG_OUT_LENMIN,
- MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN)];
- efx_mcdi_req_t req;
- uint8_t *mac_addr;
- efx_dword_t *capabilities;
+ uint8_t mac_addr[6];
+ efx_dword_t capabilities;
+ uint32_t board_type;
+ uint32_t nevq, nrxq, ntxq;
int rc;
- /* Board configuration */
- req.emr_cmd = MC_CMD_GET_BOARD_CFG;
- EFX_STATIC_ASSERT(MC_CMD_GET_BOARD_CFG_IN_LEN == 0);
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = outbuf;
- req.emr_out_length = MC_CMD_GET_BOARD_CFG_OUT_LENMIN;
-
- efx_mcdi_execute(enp, &req);
+ /* External port identifier using one-based port numbering */
+ encp->enc_external_port = (uint8_t)enp->en_mcdi.em_emip.emi_port;
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ /* Board configuration */
+ if ((rc = efx_mcdi_get_board_cfg(enp, &board_type,
+ &capabilities, mac_addr)) != 0)
goto fail1;
- }
-
- if (req.emr_out_length_used < MC_CMD_GET_BOARD_CFG_OUT_LENMIN) {
- rc = EMSGSIZE;
- goto fail2;
- }
- if (emip->emi_port == 1) {
- mac_addr = MCDI_OUT2(req, uint8_t,
- GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0);
- capabilities = MCDI_OUT2(req, efx_dword_t,
- GET_BOARD_CFG_OUT_CAPABILITIES_PORT0);
- } else {
- mac_addr = MCDI_OUT2(req, uint8_t,
- GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1);
- capabilities = MCDI_OUT2(req, efx_dword_t,
- GET_BOARD_CFG_OUT_CAPABILITIES_PORT1);
- }
EFX_MAC_ADDR_COPY(encp->enc_mac_addr, mac_addr);
- encp->enc_board_type = MCDI_OUT_DWORD(req,
- GET_BOARD_CFG_OUT_BOARD_TYPE);
+ encp->enc_board_type = board_type;
/* Additional capabilities */
encp->enc_clk_mult = 1;
- if (MCDI_CMD_DWORD_FIELD(capabilities, CAPABILITIES_TURBO)) {
+ if (EFX_DWORD_FIELD(capabilities, MC_CMD_CAPABILITIES_TURBO)) {
enp->en_features |= EFX_FEATURE_TURBO;
- if (MCDI_CMD_DWORD_FIELD(capabilities,
- CAPABILITIES_TURBO_ACTIVE))
+ if (EFX_DWORD_FIELD(capabilities,
+ MC_CMD_CAPABILITIES_TURBO_ACTIVE)) {
encp->enc_clk_mult = 2;
+ }
}
encp->enc_evq_timer_quantum_ns =
@@ -334,48 +140,39 @@ siena_board_cfg(
encp->enc_evq_timer_max_us = (encp->enc_evq_timer_quantum_ns <<
FRF_CZ_TC_TIMER_VAL_WIDTH) / 1000;
- /* Resource limits */
- req.emr_cmd = MC_CMD_GET_RESOURCE_LIMITS;
- EFX_STATIC_ASSERT(MC_CMD_GET_RESOURCE_LIMITS_IN_LEN == 0);
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = outbuf;
- req.emr_out_length = MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN;
+ /* When hash header insertion is enabled, Siena inserts 16 bytes */
+ encp->enc_rx_prefix_size = 16;
- efx_mcdi_execute(enp, &req);
+ /* Alignment for receive packet DMA buffers */
+ encp->enc_rx_buf_align_start = 1;
+ encp->enc_rx_buf_align_end = 1;
- if (req.emr_rc == 0) {
- if (req.emr_out_length_used <
- MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail3;
- }
+ /* Alignment for WPTR updates */
+ encp->enc_rx_push_align = 1;
- encp->enc_evq_limit = MCDI_OUT_DWORD(req,
- GET_RESOURCE_LIMITS_OUT_EVQ);
- encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET,
- MCDI_OUT_DWORD(req, GET_RESOURCE_LIMITS_OUT_TXQ));
- encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET,
- MCDI_OUT_DWORD(req, GET_RESOURCE_LIMITS_OUT_RXQ));
- } else if (req.emr_rc == ENOTSUP) {
- encp->enc_evq_limit = 1024;
- encp->enc_txq_limit = EFX_TXQ_LIMIT_TARGET;
- encp->enc_rxq_limit = EFX_RXQ_LIMIT_TARGET;
- } else {
- rc = req.emr_rc;
- goto fail4;
+ /* Resource limits */
+ rc = efx_mcdi_get_resource_limits(enp, &nevq, &nrxq, &ntxq);
+ if (rc != 0) {
+ if (rc != ENOTSUP)
+ goto fail2;
+
+ nevq = 1024;
+ nrxq = EFX_RXQ_LIMIT_TARGET;
+ ntxq = EFX_TXQ_LIMIT_TARGET;
}
+ encp->enc_evq_limit = nevq;
+ encp->enc_rxq_limit = MIN(EFX_RXQ_LIMIT_TARGET, nrxq);
+ encp->enc_txq_limit = MIN(EFX_TXQ_LIMIT_TARGET, ntxq);
encp->enc_buftbl_limit = SIENA_SRAM_ROWS -
(encp->enc_txq_limit * EFX_TXQ_DC_NDESCS(EFX_TXQ_DC_SIZE)) -
(encp->enc_rxq_limit * EFX_RXQ_DC_NDESCS(EFX_RXQ_DC_SIZE));
+ encp->enc_hw_tx_insert_vlan_enabled = B_FALSE;
+ encp->enc_fw_assisted_tso_enabled = B_FALSE;
+
return (0);
-fail4:
- EFSYS_PROBE(fail4);
-fail3:
- EFSYS_PROBE(fail3);
fail2:
EFSYS_PROBE(fail2);
fail1:
@@ -388,220 +185,27 @@ static __checkReturn int
siena_phy_cfg(
__in efx_nic_t *enp)
{
- efx_port_t *epp = &(enp->en_port);
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- efx_mcdi_req_t req;
- uint8_t outbuf[MC_CMD_GET_PHY_CFG_OUT_LEN];
int rc;
- req.emr_cmd = MC_CMD_GET_PHY_CFG;
- EFX_STATIC_ASSERT(MC_CMD_GET_PHY_CFG_IN_LEN == 0);
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = outbuf;
- req.emr_out_length = sizeof (outbuf);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ /* Fill out fields in enp->en_port and enp->en_nic_cfg from MCDI */
+ if ((rc = efx_mcdi_get_phy_cfg(enp)) != 0)
goto fail1;
- }
-
- if (req.emr_out_length_used < MC_CMD_GET_PHY_CFG_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- encp->enc_phy_type = MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_TYPE);
-#if EFSYS_OPT_NAMES
- (void) strncpy(encp->enc_phy_name,
- MCDI_OUT2(req, char, GET_PHY_CFG_OUT_NAME),
- MIN(sizeof (encp->enc_phy_name) - 1,
- MC_CMD_GET_PHY_CFG_OUT_NAME_LEN));
-#endif /* EFSYS_OPT_NAMES */
- (void) memset(encp->enc_phy_revision, 0,
- sizeof (encp->enc_phy_revision));
- memcpy(encp->enc_phy_revision,
- MCDI_OUT2(req, char, GET_PHY_CFG_OUT_REVISION),
- MIN(sizeof (encp->enc_phy_revision) - 1,
- MC_CMD_GET_PHY_CFG_OUT_REVISION_LEN));
-#if EFSYS_OPT_PHY_LED_CONTROL
- encp->enc_led_mask = ((1 << EFX_PHY_LED_DEFAULT) |
- (1 << EFX_PHY_LED_OFF) |
- (1 << EFX_PHY_LED_ON));
-#endif /* EFSYS_OPT_PHY_LED_CONTROL */
-
-#if EFSYS_OPT_PHY_PROPS
- encp->enc_phy_nprops = 0;
-#endif /* EFSYS_OPT_PHY_PROPS */
-
- /* Get the media type of the fixed port, if recognised. */
- EFX_STATIC_ASSERT(MC_CMD_MEDIA_XAUI == EFX_PHY_MEDIA_XAUI);
- EFX_STATIC_ASSERT(MC_CMD_MEDIA_CX4 == EFX_PHY_MEDIA_CX4);
- EFX_STATIC_ASSERT(MC_CMD_MEDIA_KX4 == EFX_PHY_MEDIA_KX4);
- EFX_STATIC_ASSERT(MC_CMD_MEDIA_XFP == EFX_PHY_MEDIA_XFP);
- EFX_STATIC_ASSERT(MC_CMD_MEDIA_SFP_PLUS == EFX_PHY_MEDIA_SFP_PLUS);
- EFX_STATIC_ASSERT(MC_CMD_MEDIA_BASE_T == EFX_PHY_MEDIA_BASE_T);
- epp->ep_fixed_port_type =
- MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_MEDIA_TYPE);
- if (epp->ep_fixed_port_type >= EFX_PHY_MEDIA_NTYPES)
- epp->ep_fixed_port_type = EFX_PHY_MEDIA_INVALID;
-
- epp->ep_phy_cap_mask =
- MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_SUPPORTED_CAP);
-#if EFSYS_OPT_PHY_FLAGS
- encp->enc_phy_flags_mask = MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_FLAGS);
-#endif /* EFSYS_OPT_PHY_FLAGS */
-
- encp->enc_port = (uint8_t)MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_PRT);
-
- /* Populate internal state */
- encp->enc_siena_channel =
- (uint8_t)MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_CHANNEL);
#if EFSYS_OPT_PHY_STATS
- encp->enc_siena_phy_stat_mask =
- MCDI_OUT_DWORD(req, GET_PHY_CFG_OUT_STATS_MASK);
-
/* Convert the MCDI statistic mask into the EFX_PHY_STAT mask */
- siena_phy_decode_stats(enp, encp->enc_siena_phy_stat_mask,
+ siena_phy_decode_stats(enp, encp->enc_mcdi_phy_stat_mask,
NULL, &encp->enc_phy_stat_mask, NULL);
#endif /* EFSYS_OPT_PHY_STATS */
-#if EFSYS_OPT_PHY_BIST
- encp->enc_bist_mask = 0;
- if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS,
- GET_PHY_CFG_OUT_BIST_CABLE_SHORT))
- encp->enc_bist_mask |= (1 << EFX_PHY_BIST_TYPE_CABLE_SHORT);
- if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS,
- GET_PHY_CFG_OUT_BIST_CABLE_LONG))
- encp->enc_bist_mask |= (1 << EFX_PHY_BIST_TYPE_CABLE_LONG);
- if (MCDI_OUT_DWORD_FIELD(req, GET_PHY_CFG_OUT_FLAGS,
- GET_PHY_CFG_OUT_BIST))
- encp->enc_bist_mask |= (1 << EFX_PHY_BIST_TYPE_NORMAL);
-#endif /* EFSYS_OPT_PHY_BIST */
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
-#if EFSYS_OPT_LOOPBACK
-
-static __checkReturn int
-siena_loopback_cfg(
- __in efx_nic_t *enp)
-{
- efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- efx_mcdi_req_t req;
- uint8_t outbuf[MC_CMD_GET_LOOPBACK_MODES_OUT_LEN];
- int rc;
-
- req.emr_cmd = MC_CMD_GET_LOOPBACK_MODES;
- EFX_STATIC_ASSERT(MC_CMD_GET_LOOPBACK_MODES_IN_LEN == 0);
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = outbuf;
- req.emr_out_length = sizeof (outbuf);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- if (req.emr_out_length_used < MC_CMD_GET_LOOPBACK_MODES_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- /*
- * We assert the MC_CMD_LOOPBACK and EFX_LOOPBACK namespaces agree
- * in siena_phy.c:siena_phy_get_link()
- */
- encp->enc_loopback_types[EFX_LINK_100FDX] = EFX_LOOPBACK_MASK &
- MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_100M) &
- MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_SUGGESTED);
- encp->enc_loopback_types[EFX_LINK_1000FDX] = EFX_LOOPBACK_MASK &
- MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_1G) &
- MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_SUGGESTED);
- encp->enc_loopback_types[EFX_LINK_10000FDX] = EFX_LOOPBACK_MASK &
- MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_10G) &
- MCDI_OUT_DWORD(req, GET_LOOPBACK_MODES_OUT_SUGGESTED);
- encp->enc_loopback_types[EFX_LINK_UNKNOWN] =
- (1 << EFX_LOOPBACK_OFF) |
- encp->enc_loopback_types[EFX_LINK_100FDX] |
- encp->enc_loopback_types[EFX_LINK_1000FDX] |
- encp->enc_loopback_types[EFX_LINK_10000FDX];
-
- return (0);
-
-fail2:
- EFSYS_PROBE(fail2);
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
-#endif /* EFSYS_OPT_LOOPBACK */
-
-#if EFSYS_OPT_MON_STATS
-
-static __checkReturn int
-siena_monitor_cfg(
- __in efx_nic_t *enp)
-{
- efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- efx_mcdi_req_t req;
- uint8_t outbuf[MCDI_CTL_SDU_LEN_MAX];
- int rc;
-
- req.emr_cmd = MC_CMD_SENSOR_INFO;
- EFX_STATIC_ASSERT(MC_CMD_SENSOR_INFO_IN_LEN == 0);
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = outbuf;
- req.emr_out_length = sizeof (outbuf);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- if (req.emr_out_length_used < MC_CMD_SENSOR_INFO_OUT_MASK_OFST + 4) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- encp->enc_siena_mon_stat_mask =
- MCDI_OUT_DWORD(req, SENSOR_INFO_OUT_MASK);
- encp->enc_mon_type = EFX_MON_SFC90X0;
-
- siena_mon_decode_stats(enp, encp->enc_siena_mon_stat_mask,
- NULL, &(encp->enc_mon_stat_mask), NULL);
-
return (0);
-fail2:
- EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, int, rc);
return (rc);
}
-#endif /* EFSYS_OPT_MON_STATS */
-
__checkReturn int
siena_nic_probe(
__in efx_nic_t *enp)
@@ -610,56 +214,69 @@ siena_nic_probe(
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
siena_link_state_t sls;
unsigned int mask;
+ efx_oword_t oword;
int rc;
EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
- /* Read clear any assertion state */
- if ((rc = siena_nic_read_assertion(enp)) != 0)
+ /* Test BIU */
+ if ((rc = efx_nic_biu_test(enp)) != 0)
goto fail1;
- /* Exit the assertion handler */
- if ((rc = siena_nic_exit_assertion_handler(enp)) != 0)
+ /* Clear the region register */
+ EFX_POPULATE_OWORD_4(oword,
+ FRF_AZ_ADR_REGION0, 0,
+ FRF_AZ_ADR_REGION1, (1 << 16),
+ FRF_AZ_ADR_REGION2, (2 << 16),
+ FRF_AZ_ADR_REGION3, (3 << 16));
+ EFX_BAR_WRITEO(enp, FR_AZ_ADR_REGION_REG, &oword);
+
+ /* Read clear any assertion state */
+ if ((rc = efx_mcdi_read_assertion(enp)) != 0)
goto fail2;
- /* Wrestle control from the BMC */
- if ((rc = siena_nic_attach(enp, B_TRUE)) != 0)
+ /* Exit the assertion handler */
+ if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
goto fail3;
- if ((rc = siena_board_cfg(enp)) != 0)
+ /* Wrestle control from the BMC */
+ if ((rc = efx_mcdi_drv_attach(enp, B_TRUE)) != 0)
goto fail4;
- if ((rc = siena_phy_cfg(enp)) != 0)
+ if ((rc = siena_board_cfg(enp)) != 0)
goto fail5;
+ if ((rc = siena_phy_cfg(enp)) != 0)
+ goto fail6;
+
/* Obtain the default PHY advertised capabilities */
if ((rc = siena_nic_reset(enp)) != 0)
- goto fail6;
- if ((rc = siena_phy_get_link(enp, &sls)) != 0)
goto fail7;
+ if ((rc = siena_phy_get_link(enp, &sls)) != 0)
+ goto fail8;
epp->ep_default_adv_cap_mask = sls.sls_adv_cap_mask;
epp->ep_adv_cap_mask = sls.sls_adv_cap_mask;
#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
if ((rc = siena_nic_get_partn_mask(enp, &mask)) != 0)
- goto fail8;
+ goto fail9;
enp->en_u.siena.enu_partn_mask = mask;
#endif
#if EFSYS_OPT_MAC_STATS
/* Wipe the MAC statistics */
- if ((rc = siena_mac_stats_clear(enp)) != 0)
- goto fail9;
+ if ((rc = efx_mcdi_mac_stats_clear(enp)) != 0)
+ goto fail10;
#endif
#if EFSYS_OPT_LOOPBACK
- if ((rc = siena_loopback_cfg(enp)) != 0)
- goto fail10;
+ if ((rc = efx_mcdi_get_loopback_modes(enp)) != 0)
+ goto fail11;
#endif
#if EFSYS_OPT_MON_STATS
- if ((rc = siena_monitor_cfg(enp)) != 0)
- goto fail11;
+ if ((rc = mcdi_mon_cfg_build(enp)) != 0)
+ goto fail12;
#endif
encp->enc_features = enp->en_features;
@@ -667,21 +284,23 @@ siena_nic_probe(
return (0);
#if EFSYS_OPT_MON_STATS
+fail12:
+ EFSYS_PROBE(fail12);
+#endif
+#if EFSYS_OPT_LOOPBACK
fail11:
EFSYS_PROBE(fail11);
#endif
-#if EFSYS_OPT_LOOPBACK
+#if EFSYS_OPT_MAC_STATS
fail10:
EFSYS_PROBE(fail10);
#endif
-#if EFSYS_OPT_MAC_STATS
+#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
fail9:
EFSYS_PROBE(fail9);
#endif
-#if EFSYS_OPT_VPD || EFSYS_OPT_NVRAM
fail8:
EFSYS_PROBE(fail8);
-#endif
fail7:
EFSYS_PROBE(fail7);
fail6:
@@ -710,16 +329,20 @@ siena_nic_reset(
EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
/* siena_nic_reset() is called to recover from BADASSERT failures. */
- if ((rc = siena_nic_read_assertion(enp)) != 0)
+ if ((rc = efx_mcdi_read_assertion(enp)) != 0)
goto fail1;
- if ((rc = siena_nic_exit_assertion_handler(enp)) != 0)
+ if ((rc = efx_mcdi_exit_assertion_handler(enp)) != 0)
goto fail2;
- req.emr_cmd = MC_CMD_PORT_RESET;
- EFX_STATIC_ASSERT(MC_CMD_PORT_RESET_IN_LEN == 0);
+ /*
+ * Bug24908: ENTITY_RESET_IN_LEN is non zero but zero may be supplied
+ * for backwards compatibility with PORT_RESET_IN_LEN.
+ */
+ EFX_STATIC_ASSERT(MC_CMD_ENTITY_RESET_OUT_LEN == 0);
+
+ req.emr_cmd = MC_CMD_ENTITY_RESET;
req.emr_in_buf = NULL;
req.emr_in_length = 0;
- EFX_STATIC_ASSERT(MC_CMD_PORT_RESET_OUT_LEN == 0);
req.emr_out_buf = NULL;
req.emr_out_length = 0;
@@ -742,40 +365,6 @@ fail1:
return (0);
}
-static __checkReturn int
-siena_nic_logging(
- __in efx_nic_t *enp)
-{
- efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_LOG_CTRL_IN_LEN];
- int rc;
-
- req.emr_cmd = MC_CMD_LOG_CTRL;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_LOG_CTRL_IN_LEN;
- EFX_STATIC_ASSERT(MC_CMD_LOG_CTRL_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- MCDI_IN_SET_DWORD(req, LOG_CTRL_IN_LOG_DEST,
- MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ);
- MCDI_IN_SET_DWORD(req, LOG_CTRL_IN_LOG_DEST_EVQ, 0);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
- goto fail1;
- }
-
- return (0);
-
-fail1:
- EFSYS_PROBE1(fail1, int, rc);
-
- return (rc);
-}
-
static void
siena_nic_rx_cfg(
__in efx_nic_t *enp)
@@ -814,7 +403,8 @@ siena_nic_init(
EFSYS_ASSERT3U(enp->en_family, ==, EFX_FAMILY_SIENA);
- if ((rc = siena_nic_logging(enp)) != 0)
+ /* Enable reporting of some events (e.g. link change) */
+ if ((rc = efx_mcdi_log_ctrl(enp)) != 0)
goto fail1;
siena_sram_init(enp);
@@ -850,12 +440,15 @@ siena_nic_fini(
siena_nic_unprobe(
__in efx_nic_t *enp)
{
- (void) siena_nic_attach(enp, B_FALSE);
+#if EFSYS_OPT_MON_STATS
+ mcdi_mon_cfg_free(enp);
+#endif /* EFSYS_OPT_MON_STATS */
+ (void) efx_mcdi_drv_attach(enp, B_FALSE);
}
#if EFSYS_OPT_DIAG
-static efx_register_set_t __cs __siena_registers[] = {
+static efx_register_set_t __siena_registers[] = {
{ FR_AZ_ADR_REGION_REG_OFST, 0, 1 },
{ FR_CZ_USR_EV_CFG_OFST, 0, 1 },
{ FR_AZ_RX_CFG_REG_OFST, 0, 1 },
@@ -871,7 +464,7 @@ static efx_register_set_t __cs __siena_registers[] = {
{ FR_CZ_RX_RSS_IPV6_REG3_OFST, 0, 1}
};
-static const uint32_t __cs __siena_register_masks[] = {
+static const uint32_t __siena_register_masks[] = {
0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF,
0x000103FF, 0x00000000, 0x00000000, 0x00000000,
0xFFFFFFFE, 0xFFFFFFFF, 0x0003FFFF, 0x00000000,
@@ -887,7 +480,7 @@ static const uint32_t __cs __siena_register_masks[] = {
0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000
};
-static efx_register_set_t __cs __siena_tables[] = {
+static efx_register_set_t __siena_tables[] = {
{ FR_AZ_RX_FILTER_TBL0_OFST, FR_AZ_RX_FILTER_TBL0_STEP,
FR_AZ_RX_FILTER_TBL0_ROWS },
{ FR_CZ_RX_MAC_FILTER_TBL0_OFST, FR_CZ_RX_MAC_FILTER_TBL0_STEP,
@@ -903,7 +496,7 @@ static efx_register_set_t __cs __siena_tables[] = {
FR_CZ_TX_MAC_FILTER_TBL0_STEP, FR_CZ_TX_MAC_FILTER_TBL0_ROWS }
};
-static const uint32_t __cs __siena_table_masks[] = {
+static const uint32_t __siena_table_masks[] = {
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x000003FF,
0xFFFF0FFF, 0xFFFFFFFF, 0x00000E7F, 0x00000000,
0xFFFFFFFE, 0x0FFFFFFF, 0x01800000, 0x00000000,
diff --git a/sys/dev/sfxge/common/siena_nvram.c b/sys/dev/sfxge/common/siena_nvram.c
index fa746ab..7d20ec0 100644
--- a/sys/dev/sfxge/common/siena_nvram.c
+++ b/sys/dev/sfxge/common/siena_nvram.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -42,9 +47,6 @@ siena_nvram_partn_size(
__in unsigned int partn,
__out size_t *sizep)
{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_NVRAM_INFO_IN_LEN,
- MC_CMD_NVRAM_INFO_OUT_LEN)];
int rc;
if ((1 << partn) & ~enp->en_u.siena.enu_partn_mask) {
@@ -52,32 +54,12 @@ siena_nvram_partn_size(
goto fail1;
}
- req.emr_cmd = MC_CMD_NVRAM_INFO;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_NVRAM_INFO_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_NVRAM_INFO_OUT_LEN;
-
- MCDI_IN_SET_DWORD(req, NVRAM_INFO_IN_TYPE, partn);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ if ((rc = efx_mcdi_nvram_info(enp, partn, sizep, NULL, NULL)) != 0) {
goto fail2;
}
- if (req.emr_out_length_used < MC_CMD_NVRAM_INFO_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail3;
- }
-
- *sizep = MCDI_OUT_DWORD(req, NVRAM_INFO_OUT_SIZE);
-
return (0);
-fail3:
- EFSYS_PROBE(fail3);
fail2:
EFSYS_PROBE(fail2);
fail1:
@@ -91,23 +73,9 @@ siena_nvram_partn_lock(
__in efx_nic_t *enp,
__in unsigned int partn)
{
- efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_NVRAM_UPDATE_START_IN_LEN];
int rc;
- req.emr_cmd = MC_CMD_NVRAM_UPDATE_START;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_NVRAM_UPDATE_START_IN_LEN;
- EFX_STATIC_ASSERT(MC_CMD_NVRAM_UPDATE_START_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_START_IN_TYPE, partn);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ if ((rc = efx_mcdi_nvram_update_start(enp, partn)) != 0) {
goto fail1;
}
@@ -127,43 +95,17 @@ siena_nvram_partn_read(
__out_bcount(size) caddr_t data,
__in size_t size)
{
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_NVRAM_READ_IN_LEN,
- MC_CMD_NVRAM_READ_OUT_LEN(SIENA_NVRAM_CHUNK))];
size_t chunk;
int rc;
while (size > 0) {
chunk = MIN(size, SIENA_NVRAM_CHUNK);
- req.emr_cmd = MC_CMD_NVRAM_READ;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_NVRAM_READ_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length =
- MC_CMD_NVRAM_READ_OUT_LEN(SIENA_NVRAM_CHUNK);
-
- MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_TYPE, partn);
- MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_OFFSET, offset);
- MCDI_IN_SET_DWORD(req, NVRAM_READ_IN_LENGTH, chunk);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ if ((rc = efx_mcdi_nvram_read(enp, partn, offset,
+ data, chunk)) != 0) {
goto fail1;
}
- if (req.emr_out_length_used <
- MC_CMD_NVRAM_READ_OUT_LEN(chunk)) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- memcpy(data,
- MCDI_OUT2(req, uint8_t, NVRAM_READ_OUT_READ_BUFFER),
- chunk);
-
size -= chunk;
data += chunk;
offset += chunk;
@@ -171,8 +113,6 @@ siena_nvram_partn_read(
return (0);
-fail2:
- EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, int, rc);
@@ -186,25 +126,9 @@ siena_nvram_partn_erase(
__in unsigned int offset,
__in size_t size)
{
- efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_NVRAM_ERASE_IN_LEN];
int rc;
- req.emr_cmd = MC_CMD_NVRAM_ERASE;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_NVRAM_ERASE_IN_LEN;
- EFX_STATIC_ASSERT(MC_CMD_NVRAM_ERASE_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_TYPE, partn);
- MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_OFFSET, offset);
- MCDI_IN_SET_DWORD(req, NVRAM_ERASE_IN_LENGTH, size);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ if ((rc = efx_mcdi_nvram_erase(enp, partn, offset, size)) != 0) {
goto fail1;
}
@@ -224,32 +148,14 @@ siena_nvram_partn_write(
__out_bcount(size) caddr_t data,
__in size_t size)
{
- efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_NVRAM_WRITE_IN_LEN(SIENA_NVRAM_CHUNK)];
size_t chunk;
int rc;
while (size > 0) {
chunk = MIN(size, SIENA_NVRAM_CHUNK);
- req.emr_cmd = MC_CMD_NVRAM_WRITE;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_NVRAM_WRITE_IN_LEN(chunk);
- EFX_STATIC_ASSERT(MC_CMD_NVRAM_WRITE_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_TYPE, partn);
- MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_OFFSET, offset);
- MCDI_IN_SET_DWORD(req, NVRAM_WRITE_IN_LENGTH, chunk);
-
- memcpy(MCDI_IN2(req, uint8_t, NVRAM_WRITE_IN_WRITE_BUFFER),
- data, chunk);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ if ((rc = efx_mcdi_nvram_write(enp, partn, offset,
+ data, chunk)) != 0) {
goto fail1;
}
@@ -271,18 +177,9 @@ siena_nvram_partn_unlock(
__in efx_nic_t *enp,
__in unsigned int partn)
{
- efx_mcdi_req_t req;
- uint8_t payload[MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN];
- uint32_t reboot;
+ boolean_t reboot;
int rc;
- req.emr_cmd = MC_CMD_NVRAM_UPDATE_FINISH;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN;
- EFX_STATIC_ASSERT(MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
/*
* Reboot into the new image only for PHYs. The driver has to
* explicitly cope with an MC reboot after a firmware update.
@@ -291,13 +188,7 @@ siena_nvram_partn_unlock(
partn == MC_CMD_NVRAM_TYPE_PHY_PORT1 ||
partn == MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO);
- MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_IN_TYPE, partn);
- MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_IN_REBOOT, reboot);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ if ((rc = efx_mcdi_nvram_update_finish(enp, partn, reboot)) != 0) {
goto fail1;
}
@@ -338,7 +229,6 @@ static siena_parttbl_entry_t siena_parttbl[] = {
{MC_CMD_NVRAM_TYPE_FC_FW, 2, EFX_NVRAM_FCFW},
{MC_CMD_NVRAM_TYPE_CPLD, 1, EFX_NVRAM_CPLD},
{MC_CMD_NVRAM_TYPE_CPLD, 2, EFX_NVRAM_CPLD},
- {0, 0, 0},
};
static __checkReturn siena_parttbl_entry_t *
@@ -346,12 +236,15 @@ siena_parttbl_entry(
__in efx_nic_t *enp,
__in efx_nvram_type_t type)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
siena_parttbl_entry_t *entry;
+ unsigned int i;
EFSYS_ASSERT3U(type, <, EFX_NVRAM_NTYPES);
- for (entry = siena_parttbl; entry->port > 0; ++entry) {
+ for (i = 0; i < EFX_ARRAY_SIZE(siena_parttbl); i++) {
+ entry = &siena_parttbl[i];
+
if (entry->port == emip->emi_port && entry->nvtype == type)
return (entry);
}
@@ -365,59 +258,29 @@ siena_parttbl_entry(
siena_nvram_test(
__in efx_nic_t *enp)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
siena_parttbl_entry_t *entry;
- efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_NVRAM_TEST_IN_LEN,
- MC_CMD_NVRAM_TEST_OUT_LEN)];
- int result;
+ unsigned int i;
int rc;
- req.emr_cmd = MC_CMD_NVRAM_TEST;
- req.emr_in_buf = payload;
- req.emr_in_length = MC_CMD_NVRAM_TEST_IN_LEN;
- req.emr_out_buf = payload;
- req.emr_out_length = MC_CMD_NVRAM_TEST_OUT_LEN;
-
/*
* Iterate over the list of supported partition types
* applicable to *this* port
*/
- for (entry = siena_parttbl; entry->port > 0; ++entry) {
+ for (i = 0; i < EFX_ARRAY_SIZE(siena_parttbl); i++) {
+ entry = &siena_parttbl[i];
+
if (entry->port != emip->emi_port ||
!(enp->en_u.siena.enu_partn_mask & (1 << entry->partn)))
continue;
- MCDI_IN_SET_DWORD(req, NVRAM_TEST_IN_TYPE, entry->partn);
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ if ((rc = efx_mcdi_nvram_test(enp, entry->partn)) != 0) {
goto fail1;
}
-
- if (req.emr_out_length_used < MC_CMD_NVRAM_TEST_OUT_LEN) {
- rc = EMSGSIZE;
- goto fail2;
- }
-
- result = MCDI_OUT_DWORD(req, NVRAM_TEST_OUT_RESULT);
- if (result == MC_CMD_NVRAM_TEST_FAIL) {
-
- EFSYS_PROBE1(nvram_test_failure, int, entry->partn);
-
- rc = (EINVAL);
- goto fail3;
- }
}
return (0);
-fail3:
- EFSYS_PROBE(fail3);
-fail2:
- EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, int, rc);
@@ -467,7 +330,7 @@ siena_nvram_get_dynamic_cfg(
__out siena_mc_dynamic_config_hdr_t **dcfgp,
__out size_t *sizep)
{
- siena_mc_dynamic_config_hdr_t *dcfg;
+ siena_mc_dynamic_config_hdr_t *dcfg = NULL;
size_t size;
uint8_t cksum;
unsigned int vpd_offset;
@@ -577,34 +440,35 @@ fail4:
EFSYS_PROBE(fail4);
fail3:
EFSYS_PROBE(fail3);
-fail2:
- EFSYS_PROBE(fail2);
EFSYS_KMEM_FREE(enp->en_esip, size, dcfg);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, int, rc);
return (rc);
}
-static __checkReturn int
+ __checkReturn int
siena_nvram_get_subtype(
__in efx_nic_t *enp,
__in unsigned int partn,
__out uint32_t *subtypep)
{
efx_mcdi_req_t req;
- uint8_t outbuf[MC_CMD_GET_BOARD_CFG_OUT_LENMAX];
+ uint8_t payload[MAX(MC_CMD_GET_BOARD_CFG_IN_LEN,
+ MC_CMD_GET_BOARD_CFG_OUT_LENMAX)];
efx_word_t *fw_list;
int rc;
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_BOARD_CFG;
- EFX_STATIC_ASSERT(MC_CMD_GET_BOARD_CFG_IN_LEN == 0);
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = outbuf;
- req.emr_out_length = sizeof (outbuf);
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_BOARD_CFG_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_BOARD_CFG_OUT_LENMAX;
efx_mcdi_execute(enp, &req);
@@ -652,6 +516,7 @@ siena_nvram_get_version(
siena_parttbl_entry_t *entry;
unsigned int dcfg_partn;
unsigned int partn;
+ unsigned int i;
int rc;
if ((entry = siena_parttbl_entry(enp, type)) == NULL) {
@@ -674,11 +539,12 @@ siena_nvram_get_version(
* that have access to this partition.
*/
version[0] = version[1] = version[2] = version[3] = 0;
- for (entry = siena_parttbl; entry->port > 0; ++entry) {
+ for (i = 0; i < EFX_ARRAY_SIZE(siena_parttbl); i++) {
unsigned int nitems;
uint16_t temp[4];
size_t length;
+ entry = &siena_parttbl[i];
if (entry->partn != partn)
continue;
@@ -869,7 +735,7 @@ siena_nvram_rw_finish(
siena_nvram_set_version(
__in efx_nic_t *enp,
__in efx_nvram_type_t type,
- __out uint16_t version[4])
+ __in_ecount(4) uint16_t version[4])
{
siena_mc_dynamic_config_hdr_t *dcfg = NULL;
siena_parttbl_entry_t *entry;
diff --git a/sys/dev/sfxge/common/siena_phy.c b/sys/dev/sfxge/common/siena_phy.c
index 31b5c46..fd0871d 100644
--- a/sys/dev/sfxge/common/siena_phy.c
+++ b/sys/dev/sfxge/common/siena_phy.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -192,15 +197,16 @@ siena_phy_get_link(
__out siena_link_state_t *slsp)
{
efx_mcdi_req_t req;
- uint8_t outbuf[MC_CMD_GET_LINK_OUT_LEN];
+ uint8_t payload[MAX(MC_CMD_GET_LINK_IN_LEN,
+ MC_CMD_GET_LINK_OUT_LEN)];
int rc;
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_LINK;
- EFX_STATIC_ASSERT(MC_CMD_GET_LINK_IN_LEN == 0);
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = outbuf;
- req.emr_out_length = sizeof (outbuf);
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_LINK_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_LINK_OUT_LEN;
efx_mcdi_execute(enp, &req);
@@ -266,19 +272,21 @@ siena_phy_reconfigure(
{
efx_port_t *epp = &(enp->en_port);
efx_mcdi_req_t req;
- uint8_t payload[MAX(MC_CMD_SET_ID_LED_IN_LEN,
- MC_CMD_SET_LINK_IN_LEN)];
+ uint8_t payload[MAX(MAX(MC_CMD_SET_ID_LED_IN_LEN,
+ MC_CMD_SET_ID_LED_OUT_LEN),
+ MAX(MC_CMD_SET_LINK_IN_LEN,
+ MC_CMD_SET_LINK_OUT_LEN))];
uint32_t cap_mask;
unsigned int led_mode;
unsigned int speed;
int rc;
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_SET_LINK;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_SET_LINK_IN_LEN;
- EFX_STATIC_ASSERT(MC_CMD_SET_LINK_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_SET_LINK_OUT_LEN;
cap_mask = epp->ep_adv_cap_mask;
MCDI_IN_POPULATE_DWORD_10(req, SET_LINK_IN_CAP,
@@ -329,12 +337,12 @@ siena_phy_reconfigure(
}
/* And set the blink mode */
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_SET_ID_LED;
req.emr_in_buf = payload;
req.emr_in_length = MC_CMD_SET_ID_LED_IN_LEN;
- EFX_STATIC_ASSERT(MC_CMD_SET_ID_LED_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_SET_ID_LED_OUT_LEN;
#if EFSYS_OPT_PHY_LED_CONTROL
switch (epp->ep_phy_led_mode) {
@@ -379,16 +387,17 @@ siena_phy_verify(
__in efx_nic_t *enp)
{
efx_mcdi_req_t req;
- uint8_t outbuf[MC_CMD_GET_PHY_STATE_OUT_LEN];
+ uint8_t payload[MAX(MC_CMD_GET_PHY_STATE_IN_LEN,
+ MC_CMD_GET_PHY_STATE_OUT_LEN)];
uint32_t state;
int rc;
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_GET_PHY_STATE;
- EFX_STATIC_ASSERT(MC_CMD_GET_PHY_STATE_IN_LEN == 0);
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
- req.emr_out_buf = outbuf;
- req.emr_out_length = sizeof (outbuf);
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_GET_PHY_STATE_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_GET_PHY_STATE_OUT_LEN;
efx_mcdi_execute(enp, &req);
@@ -544,18 +553,19 @@ siena_phy_stats_update(
__out_ecount(EFX_PHY_NSTATS) uint32_t *stat)
{
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- uint32_t vmask = encp->enc_siena_phy_stat_mask;
- uint8_t payload[MC_CMD_PHY_STATS_IN_LEN];
+ uint32_t vmask = encp->enc_mcdi_phy_stat_mask;
uint64_t smask;
efx_mcdi_req_t req;
+ uint8_t payload[MAX(MC_CMD_PHY_STATS_IN_LEN,
+ MC_CMD_PHY_STATS_OUT_DMA_LEN)];
int rc;
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_PHY_STATS;
req.emr_in_buf = payload;
- req.emr_in_length = sizeof (payload);
- EFX_STATIC_ASSERT(MC_CMD_PHY_STATS_OUT_DMA_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
+ req.emr_in_length = MC_CMD_PHY_STATS_IN_LEN;
+ req.emr_out_buf = payload;
+ req.emr_out_length = MC_CMD_PHY_STATS_OUT_DMA_LEN;
MCDI_IN_SET_DWORD(req, PHY_STATS_IN_DMA_ADDR_LO,
EFSYS_MEM_ADDR(esmp) & 0xffffffff);
@@ -587,7 +597,7 @@ fail1:
#if EFSYS_OPT_NAMES
-extern const char __cs *
+extern const char *
siena_phy_prop_name(
__in efx_nic_t *enp,
__in unsigned int id)
@@ -624,46 +634,17 @@ siena_phy_prop_set(
#endif /* EFSYS_OPT_PHY_PROPS */
-#if EFSYS_OPT_PHY_BIST
+#if EFSYS_OPT_BIST
__checkReturn int
siena_phy_bist_start(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type)
+ __in efx_bist_type_t type)
{
- uint8_t payload[MC_CMD_START_BIST_IN_LEN];
- efx_mcdi_req_t req;
int rc;
- req.emr_cmd = MC_CMD_START_BIST;
- req.emr_in_buf = payload;
- req.emr_in_length = sizeof (payload);
- EFX_STATIC_ASSERT(MC_CMD_START_BIST_OUT_LEN == 0);
- req.emr_out_buf = NULL;
- req.emr_out_length = 0;
-
- switch (type) {
- case EFX_PHY_BIST_TYPE_NORMAL:
- MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE, MC_CMD_PHY_BIST);
- break;
- case EFX_PHY_BIST_TYPE_CABLE_SHORT:
- MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE,
- MC_CMD_PHY_BIST_CABLE_SHORT);
- break;
- case EFX_PHY_BIST_TYPE_CABLE_LONG:
- MCDI_IN_SET_DWORD(req, START_BIST_IN_TYPE,
- MC_CMD_PHY_BIST_CABLE_LONG);
- break;
- default:
- EFSYS_ASSERT(0);
- }
-
- efx_mcdi_execute(enp, &req);
-
- if (req.emr_rc != 0) {
- rc = req.emr_rc;
+ if ((rc = efx_mcdi_bist_start(enp, type)) != 0)
goto fail1;
- }
return (0);
@@ -696,8 +677,8 @@ siena_phy_sft9001_bist_status(
__checkReturn int
siena_phy_bist_poll(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type,
- __out efx_phy_bist_result_t *resultp,
+ __in efx_bist_type_t type,
+ __out efx_bist_result_t *resultp,
__out_opt __drv_when(count > 0, __notnull)
uint32_t *value_maskp,
__out_ecount_opt(count) __drv_when(count > 0, __notnull)
@@ -705,19 +686,19 @@ siena_phy_bist_poll(
__in size_t count)
{
efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
- uint8_t payload[MCDI_CTL_SDU_LEN_MAX];
+ uint8_t payload[MAX(MC_CMD_POLL_BIST_IN_LEN,
+ MCDI_CTL_SDU_LEN_MAX)];
uint32_t value_mask = 0;
efx_mcdi_req_t req;
uint32_t result;
int rc;
+ (void) memset(payload, 0, sizeof (payload));
req.emr_cmd = MC_CMD_POLL_BIST;
- _NOTE(CONSTANTCONDITION)
- EFSYS_ASSERT(MC_CMD_POLL_BIST_IN_LEN == 0);
- req.emr_in_buf = NULL;
- req.emr_in_length = 0;
+ req.emr_in_buf = payload;
+ req.emr_in_length = MC_CMD_POLL_BIST_IN_LEN;
req.emr_out_buf = payload;
- req.emr_out_length = sizeof (payload);
+ req.emr_out_length = MCDI_CTL_SDU_LEN_MAX;
efx_mcdi_execute(enp, &req);
@@ -740,90 +721,90 @@ siena_phy_bist_poll(
if (result == MC_CMD_POLL_BIST_PASSED &&
encp->enc_phy_type == EFX_PHY_SFT9001B &&
req.emr_out_length_used >= MC_CMD_POLL_BIST_OUT_SFT9001_LEN &&
- (type == EFX_PHY_BIST_TYPE_CABLE_SHORT ||
- type == EFX_PHY_BIST_TYPE_CABLE_LONG)) {
+ (type == EFX_BIST_TYPE_PHY_CABLE_SHORT ||
+ type == EFX_BIST_TYPE_PHY_CABLE_LONG)) {
uint16_t word;
- if (count > EFX_PHY_BIST_CABLE_LENGTH_A) {
+ if (count > EFX_BIST_PHY_CABLE_LENGTH_A) {
if (valuesp != NULL)
- valuesp[EFX_PHY_BIST_CABLE_LENGTH_A] =
+ valuesp[EFX_BIST_PHY_CABLE_LENGTH_A] =
MCDI_OUT_DWORD(req,
POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A);
- value_mask |= (1 << EFX_PHY_BIST_CABLE_LENGTH_A);
+ value_mask |= (1 << EFX_BIST_PHY_CABLE_LENGTH_A);
}
- if (count > EFX_PHY_BIST_CABLE_LENGTH_B) {
+ if (count > EFX_BIST_PHY_CABLE_LENGTH_B) {
if (valuesp != NULL)
- valuesp[EFX_PHY_BIST_CABLE_LENGTH_B] =
+ valuesp[EFX_BIST_PHY_CABLE_LENGTH_B] =
MCDI_OUT_DWORD(req,
POLL_BIST_OUT_SFT9001_CABLE_LENGTH_B);
- value_mask |= (1 << EFX_PHY_BIST_CABLE_LENGTH_B);
+ value_mask |= (1 << EFX_BIST_PHY_CABLE_LENGTH_B);
}
- if (count > EFX_PHY_BIST_CABLE_LENGTH_C) {
+ if (count > EFX_BIST_PHY_CABLE_LENGTH_C) {
if (valuesp != NULL)
- valuesp[EFX_PHY_BIST_CABLE_LENGTH_C] =
+ valuesp[EFX_BIST_PHY_CABLE_LENGTH_C] =
MCDI_OUT_DWORD(req,
POLL_BIST_OUT_SFT9001_CABLE_LENGTH_C);
- value_mask |= (1 << EFX_PHY_BIST_CABLE_LENGTH_C);
+ value_mask |= (1 << EFX_BIST_PHY_CABLE_LENGTH_C);
}
- if (count > EFX_PHY_BIST_CABLE_LENGTH_D) {
+ if (count > EFX_BIST_PHY_CABLE_LENGTH_D) {
if (valuesp != NULL)
- valuesp[EFX_PHY_BIST_CABLE_LENGTH_D] =
+ valuesp[EFX_BIST_PHY_CABLE_LENGTH_D] =
MCDI_OUT_DWORD(req,
POLL_BIST_OUT_SFT9001_CABLE_LENGTH_D);
- value_mask |= (1 << EFX_PHY_BIST_CABLE_LENGTH_D);
+ value_mask |= (1 << EFX_BIST_PHY_CABLE_LENGTH_D);
}
- if (count > EFX_PHY_BIST_CABLE_STATUS_A) {
+ if (count > EFX_BIST_PHY_CABLE_STATUS_A) {
if (valuesp != NULL) {
word = MCDI_OUT_WORD(req,
POLL_BIST_OUT_SFT9001_CABLE_STATUS_A);
- valuesp[EFX_PHY_BIST_CABLE_STATUS_A] =
+ valuesp[EFX_BIST_PHY_CABLE_STATUS_A] =
siena_phy_sft9001_bist_status(word);
}
- value_mask |= (1 << EFX_PHY_BIST_CABLE_STATUS_A);
+ value_mask |= (1 << EFX_BIST_PHY_CABLE_STATUS_A);
}
- if (count > EFX_PHY_BIST_CABLE_STATUS_B) {
+ if (count > EFX_BIST_PHY_CABLE_STATUS_B) {
if (valuesp != NULL) {
word = MCDI_OUT_WORD(req,
POLL_BIST_OUT_SFT9001_CABLE_STATUS_B);
- valuesp[EFX_PHY_BIST_CABLE_STATUS_B] =
+ valuesp[EFX_BIST_PHY_CABLE_STATUS_B] =
siena_phy_sft9001_bist_status(word);
}
- value_mask |= (1 << EFX_PHY_BIST_CABLE_STATUS_B);
+ value_mask |= (1 << EFX_BIST_PHY_CABLE_STATUS_B);
}
- if (count > EFX_PHY_BIST_CABLE_STATUS_C) {
+ if (count > EFX_BIST_PHY_CABLE_STATUS_C) {
if (valuesp != NULL) {
word = MCDI_OUT_WORD(req,
POLL_BIST_OUT_SFT9001_CABLE_STATUS_C);
- valuesp[EFX_PHY_BIST_CABLE_STATUS_C] =
+ valuesp[EFX_BIST_PHY_CABLE_STATUS_C] =
siena_phy_sft9001_bist_status(word);
}
- value_mask |= (1 << EFX_PHY_BIST_CABLE_STATUS_C);
+ value_mask |= (1 << EFX_BIST_PHY_CABLE_STATUS_C);
}
- if (count > EFX_PHY_BIST_CABLE_STATUS_D) {
+ if (count > EFX_BIST_PHY_CABLE_STATUS_D) {
if (valuesp != NULL) {
word = MCDI_OUT_WORD(req,
POLL_BIST_OUT_SFT9001_CABLE_STATUS_D);
- valuesp[EFX_PHY_BIST_CABLE_STATUS_D] =
+ valuesp[EFX_BIST_PHY_CABLE_STATUS_D] =
siena_phy_sft9001_bist_status(word);
}
- value_mask |= (1 << EFX_PHY_BIST_CABLE_STATUS_D);
+ value_mask |= (1 << EFX_BIST_PHY_CABLE_STATUS_D);
}
} else if (result == MC_CMD_POLL_BIST_FAILED &&
encp->enc_phy_type == EFX_PHY_QLX111V &&
req.emr_out_length >= MC_CMD_POLL_BIST_OUT_MRSFP_LEN &&
- count > EFX_PHY_BIST_FAULT_CODE) {
+ count > EFX_BIST_FAULT_CODE) {
if (valuesp != NULL)
- valuesp[EFX_PHY_BIST_FAULT_CODE] =
+ valuesp[EFX_BIST_FAULT_CODE] =
MCDI_OUT_DWORD(req, POLL_BIST_OUT_MRSFP_TEST);
- value_mask |= 1 << EFX_PHY_BIST_FAULT_CODE;
+ value_mask |= 1 << EFX_BIST_FAULT_CODE;
}
if (value_maskp != NULL)
@@ -831,11 +812,11 @@ siena_phy_bist_poll(
EFSYS_ASSERT(resultp != NULL);
if (result == MC_CMD_POLL_BIST_RUNNING)
- *resultp = EFX_PHY_BIST_RESULT_RUNNING;
+ *resultp = EFX_BIST_RESULT_RUNNING;
else if (result == MC_CMD_POLL_BIST_PASSED)
- *resultp = EFX_PHY_BIST_RESULT_PASSED;
+ *resultp = EFX_BIST_RESULT_PASSED;
else
- *resultp = EFX_PHY_BIST_RESULT_FAILED;
+ *resultp = EFX_BIST_RESULT_FAILED;
return (0);
@@ -850,12 +831,12 @@ fail1:
void
siena_phy_bist_stop(
__in efx_nic_t *enp,
- __in efx_phy_bist_type_t type)
+ __in efx_bist_type_t type)
{
/* There is no way to stop BIST on Siena */
_NOTE(ARGUNUSED(enp, type))
}
-#endif /* EFSYS_OPT_PHY_BIST */
+#endif /* EFSYS_OPT_BIST */
#endif /* EFSYS_OPT_SIENA */
diff --git a/sys/dev/sfxge/common/siena_sram.c b/sys/dev/sfxge/common/siena_sram.c
index 3137e5b..cf36067 100644
--- a/sys/dev/sfxge/common/siena_sram.c
+++ b/sys/dev/sfxge/common/siena_sram.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
diff --git a/sys/dev/sfxge/common/siena_vpd.c b/sys/dev/sfxge/common/siena_vpd.c
index 3f1008b..4d4b825 100644
--- a/sys/dev/sfxge/common/siena_vpd.c
+++ b/sys/dev/sfxge/common/siena_vpd.c
@@ -1,26 +1,31 @@
/*-
- * Copyright 2009 Solarflare Communications Inc. All rights reserved.
+ * Copyright (c) 2009-2015 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -141,11 +146,11 @@ fail4:
EFSYS_PROBE(fail4);
fail3:
EFSYS_PROBE(fail3);
-fail2:
- EFSYS_PROBE(fail2);
EFSYS_KMEM_FREE(enp->en_esip, size, scfg);
+fail2:
+ EFSYS_PROBE(fail2);
fail1:
EFSYS_PROBE1(fail1, int, rc);
@@ -156,7 +161,7 @@ fail1:
siena_vpd_init(
__in efx_nic_t *enp)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
caddr_t svpd = NULL;
unsigned partn;
size_t size = 0;
@@ -201,7 +206,7 @@ siena_vpd_size(
__in efx_nic_t *enp,
__out size_t *sizep)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
unsigned int partn;
int rc;
@@ -236,8 +241,8 @@ siena_vpd_read(
__out_bcount(size) caddr_t data,
__in size_t size)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- siena_mc_dynamic_config_hdr_t *dcfg;
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ siena_mc_dynamic_config_hdr_t *dcfg = NULL;
unsigned int vpd_length;
unsigned int vpd_offset;
unsigned int dcfg_partn;
@@ -499,8 +504,8 @@ siena_vpd_write(
__in_bcount(size) caddr_t data,
__in size_t size)
{
- efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
- siena_mc_dynamic_config_hdr_t *dcfg;
+ efx_mcdi_iface_t *emip = &(enp->en_mcdi.em_emip);
+ siena_mc_dynamic_config_hdr_t *dcfg = NULL;
unsigned int vpd_offset;
unsigned int dcfg_partn;
unsigned int hdr_length;
@@ -525,18 +530,18 @@ siena_vpd_write(
goto fail2;
if ((rc = siena_nvram_partn_lock(enp, dcfg_partn)) != 0)
- goto fail2;
+ goto fail3;
if ((rc = siena_nvram_get_dynamic_cfg(enp, dcfg_partn,
B_FALSE, &dcfg, &dcfg_size)) != 0)
- goto fail3;
+ goto fail4;
hdr_length = EFX_WORD_FIELD(dcfg->length, EFX_WORD_0);
/* Allocated memory should have room for the new VPD */
if (hdr_length + vpd_length > dcfg_size) {
rc = ENOSPC;
- goto fail3;
+ goto fail5;
}
/* Copy in new vpd and update header */
@@ -553,12 +558,12 @@ siena_vpd_write(
/* Erase and write the new sector */
if ((rc = siena_nvram_partn_erase(enp, dcfg_partn, 0, partn_size)) != 0)
- goto fail4;
+ goto fail6;
/* Write out the new structure to nvram */
if ((rc = siena_nvram_partn_write(enp, dcfg_partn, 0, (caddr_t)dcfg,
vpd_offset + vpd_length)) != 0)
- goto fail5;
+ goto fail7;
EFSYS_KMEM_FREE(enp->en_esip, dcfg_size, dcfg);
@@ -566,18 +571,22 @@ siena_vpd_write(
return (0);
+fail7:
+ EFSYS_PROBE(fail7);
+fail6:
+ EFSYS_PROBE(fail6);
fail5:
EFSYS_PROBE(fail5);
+
+ EFSYS_KMEM_FREE(enp->en_esip, dcfg_size, dcfg);
fail4:
EFSYS_PROBE(fail4);
+
+ siena_nvram_partn_unlock(enp, dcfg_partn);
fail3:
EFSYS_PROBE(fail3);
-
- EFSYS_KMEM_FREE(enp->en_esip, dcfg_size, dcfg);
fail2:
EFSYS_PROBE(fail2);
-
- siena_nvram_partn_unlock(enp, dcfg_partn);
fail1:
EFSYS_PROBE1(fail1, int, rc);
diff --git a/sys/dev/sfxge/sfxge.c b/sys/dev/sfxge/sfxge.c
index b504d5e..5e5d3dc 100644
--- a/sys/dev/sfxge/sfxge.c
+++ b/sys/dev/sfxge/sfxge.c
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -42,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <sys/taskqueue.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
+#include <sys/priv.h>
#include <sys/syslog.h>
#include <dev/pci/pcireg.h>
@@ -56,6 +61,7 @@ __FBSDID("$FreeBSD$");
#include "sfxge.h"
#include "sfxge_rx.h"
+#include "sfxge_ioc.h"
#include "sfxge_version.h"
#define SFXGE_CAP (IFCAP_VLAN_MTU | IFCAP_VLAN_HWCSUM | \
@@ -92,6 +98,83 @@ static void
sfxge_reset(void *arg, int npending);
static int
+sfxge_estimate_rsrc_limits(struct sfxge_softc *sc)
+{
+ efx_drv_limits_t limits;
+ int rc;
+ unsigned int evq_max;
+ uint32_t evq_allocated;
+ uint32_t rxq_allocated;
+ uint32_t txq_allocated;
+
+ /*
+ * Limit the number of event queues to:
+ * - number of CPUs
+ * - hardwire maximum RSS channels
+ * - administratively specified maximum RSS channels
+ */
+ evq_max = MIN(mp_ncpus, EFX_MAXRSS);
+ if (sc->max_rss_channels > 0)
+ evq_max = MIN(evq_max, sc->max_rss_channels);
+
+ memset(&limits, 0, sizeof(limits));
+
+ limits.edl_min_evq_count = 1;
+ limits.edl_max_evq_count = evq_max;
+ limits.edl_min_txq_count = SFXGE_TXQ_NTYPES;
+ limits.edl_max_txq_count = evq_max + SFXGE_TXQ_NTYPES - 1;
+ limits.edl_min_rxq_count = 1;
+ limits.edl_max_rxq_count = evq_max;
+
+ efx_nic_set_drv_limits(sc->enp, &limits);
+
+ if ((rc = efx_nic_init(sc->enp)) != 0)
+ return (rc);
+
+ rc = efx_nic_get_vi_pool(sc->enp, &evq_allocated, &rxq_allocated,
+ &txq_allocated);
+ if (rc != 0) {
+ efx_nic_fini(sc->enp);
+ return (rc);
+ }
+
+ KASSERT(txq_allocated >= SFXGE_TXQ_NTYPES,
+ ("txq_allocated < SFXGE_TXQ_NTYPES"));
+
+ sc->evq_max = MIN(evq_allocated, evq_max);
+ sc->evq_max = MIN(rxq_allocated, sc->evq_max);
+ sc->evq_max = MIN(txq_allocated - (SFXGE_TXQ_NTYPES - 1),
+ sc->evq_max);
+
+ KASSERT(sc->evq_max <= evq_max,
+ ("allocated more than maximum requested"));
+
+ /*
+ * NIC is kept initialized in the case of success to be able to
+ * initialize port to find out media types.
+ */
+ return (0);
+}
+
+static int
+sfxge_set_drv_limits(struct sfxge_softc *sc)
+{
+ efx_drv_limits_t limits;
+
+ memset(&limits, 0, sizeof(limits));
+
+ /* Limits are strict since take into account initial estimation */
+ limits.edl_min_evq_count = limits.edl_max_evq_count =
+ sc->intr.n_alloc;
+ limits.edl_min_txq_count = limits.edl_max_txq_count =
+ sc->intr.n_alloc + SFXGE_TXQ_NTYPES - 1;
+ limits.edl_min_rxq_count = limits.edl_max_rxq_count =
+ sc->intr.n_alloc;
+
+ return (efx_nic_set_drv_limits(sc->enp, &limits));
+}
+
+static int
sfxge_start(struct sfxge_softc *sc)
{
int rc;
@@ -106,6 +189,10 @@ sfxge_start(struct sfxge_softc *sc)
goto fail;
}
+ /* Set required resource limits */
+ if ((rc = sfxge_set_drv_limits(sc)) != 0)
+ goto fail;
+
if ((rc = efx_nic_init(sc->enp)) != 0)
goto fail;
@@ -117,16 +204,16 @@ sfxge_start(struct sfxge_softc *sc)
if ((rc = sfxge_ev_start(sc)) != 0)
goto fail3;
+ /* Fire up the port. */
+ if ((rc = sfxge_port_start(sc)) != 0)
+ goto fail4;
+
/* Start the receiver side. */
if ((rc = sfxge_rx_start(sc)) != 0)
- goto fail4;
+ goto fail5;
/* Start the transmitter side. */
if ((rc = sfxge_tx_start(sc)) != 0)
- goto fail5;
-
- /* Fire up the port. */
- if ((rc = sfxge_port_start(sc)) != 0)
goto fail6;
sc->init_state = SFXGE_STARTED;
@@ -138,10 +225,10 @@ sfxge_start(struct sfxge_softc *sc)
return (0);
fail6:
- sfxge_tx_stop(sc);
+ sfxge_rx_stop(sc);
fail5:
- sfxge_rx_stop(sc);
+ sfxge_port_stop(sc);
fail4:
sfxge_ev_stop(sc);
@@ -180,15 +267,15 @@ sfxge_stop(struct sfxge_softc *sc)
sc->init_state = SFXGE_REGISTERED;
- /* Stop the port. */
- sfxge_port_stop(sc);
-
/* Stop the transmitter. */
sfxge_tx_stop(sc);
/* Stop the receiver. */
sfxge_rx_stop(sc);
+ /* Stop the port. */
+ sfxge_port_stop(sc);
+
/* Stop processing events. */
sfxge_ev_stop(sc);
@@ -200,11 +287,73 @@ sfxge_stop(struct sfxge_softc *sc)
sc->ifnet->if_drv_flags &= ~IFF_DRV_RUNNING;
}
+
+static int
+sfxge_vpd_ioctl(struct sfxge_softc *sc, sfxge_ioc_t *ioc)
+{
+ efx_vpd_value_t value;
+ int rc = 0;
+
+ switch (ioc->u.vpd.op) {
+ case SFXGE_VPD_OP_GET_KEYWORD:
+ value.evv_tag = ioc->u.vpd.tag;
+ value.evv_keyword = ioc->u.vpd.keyword;
+ rc = efx_vpd_get(sc->enp, sc->vpd_data, sc->vpd_size, &value);
+ if (rc != 0)
+ break;
+ ioc->u.vpd.len = MIN(ioc->u.vpd.len, value.evv_length);
+ if (ioc->u.vpd.payload != 0) {
+ rc = copyout(value.evv_value, ioc->u.vpd.payload,
+ ioc->u.vpd.len);
+ }
+ break;
+ case SFXGE_VPD_OP_SET_KEYWORD:
+ if (ioc->u.vpd.len > sizeof(value.evv_value))
+ return (EINVAL);
+ value.evv_tag = ioc->u.vpd.tag;
+ value.evv_keyword = ioc->u.vpd.keyword;
+ value.evv_length = ioc->u.vpd.len;
+ rc = copyin(ioc->u.vpd.payload, value.evv_value, value.evv_length);
+ if (rc != 0)
+ break;
+ rc = efx_vpd_set(sc->enp, sc->vpd_data, sc->vpd_size, &value);
+ if (rc != 0)
+ break;
+ rc = efx_vpd_verify(sc->enp, sc->vpd_data, sc->vpd_size);
+ if (rc != 0)
+ break;
+ rc = efx_vpd_write(sc->enp, sc->vpd_data, sc->vpd_size);
+ break;
+ default:
+ rc = EOPNOTSUPP;
+ break;
+ }
+
+ return (rc);
+}
+
+static int
+sfxge_private_ioctl(struct sfxge_softc *sc, sfxge_ioc_t *ioc)
+{
+ switch (ioc->op) {
+ case SFXGE_MCDI_IOC:
+ return (sfxge_mcdi_ioctl(sc, ioc));
+ case SFXGE_NVRAM_IOC:
+ return (sfxge_nvram_ioctl(sc, ioc));
+ case SFXGE_VPD_IOC:
+ return (sfxge_vpd_ioctl(sc, ioc));
+ default:
+ return (EOPNOTSUPP);
+ }
+}
+
+
static int
sfxge_if_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data)
{
struct sfxge_softc *sc;
struct ifreq *ifr;
+ sfxge_ioc_t ioc;
int error;
ifr = (struct ifreq *)data;
@@ -273,7 +422,8 @@ sfxge_if_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data)
* can't (yet) disable.
*/
KASSERT((reqcap & ~ifp->if_capabilities) == 0,
- ("Unsupported capabilities %x requested %x vs %x",
+ ("Unsupported capabilities 0x%x requested 0x%x vs "
+ "supported 0x%x",
reqcap & ~ifp->if_capabilities,
reqcap , ifp->if_capabilities));
if (capchg_mask & SFXGE_CAP_FIXED) {
@@ -336,6 +486,18 @@ sfxge_if_ioctl(struct ifnet *ifp, unsigned long command, caddr_t data)
case SIOCGIFMEDIA:
error = ifmedia_ioctl(ifp, ifr, &sc->media, command);
break;
+ case SIOCGPRIVATE_0:
+ error = priv_check(curthread, PRIV_DRIVER);
+ if (error != 0)
+ break;
+ error = copyin(ifr->ifr_data, &ioc, sizeof(ioc));
+ if (error != 0)
+ return (error);
+ error = sfxge_private_ioctl(sc, &ioc);
+ if (error == 0) {
+ error = copyout(&ioc, ifr->ifr_data, sizeof(ioc));
+ }
+ break;
default:
error = ether_ioctl(ifp, command, data);
}
@@ -381,6 +543,10 @@ sfxge_ifnet_init(struct ifnet *ifp, struct sfxge_softc *sc)
ifp->if_capenable |= IFCAP_LRO;
#endif
+ if (encp->enc_hw_tx_insert_vlan_enabled) {
+ ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
+ ifp->if_capenable |= IFCAP_VLAN_HWTAGGING;
+ }
ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO |
CSUM_TCP_IPV6 | CSUM_UDP_IPV6;
@@ -389,6 +555,7 @@ sfxge_ifnet_init(struct ifnet *ifp, struct sfxge_softc *sc)
ifp->if_transmit = sfxge_if_transmit;
ifp->if_qflush = sfxge_if_qflush;
+ DBGPRINT(sc->dev, "ifmedia_init");
if ((rc = sfxge_port_ifmedia_init(sc)) != 0)
goto fail;
@@ -472,10 +639,12 @@ sfxge_create(struct sfxge_softc *sc)
(void) pci_enable_busmaster(dev);
/* Initialize DMA mappings. */
+ DBGPRINT(sc->dev, "dma_init...");
if ((error = sfxge_dma_init(sc)) != 0)
goto fail;
/* Map the device registers. */
+ DBGPRINT(sc->dev, "bar_init...");
if ((error = sfxge_bar_init(sc)) != 0)
goto fail;
@@ -483,6 +652,8 @@ sfxge_create(struct sfxge_softc *sc)
&sc->family);
KASSERT(error == 0, ("Family should be filtered by sfxge_probe()"));
+ DBGPRINT(sc->dev, "nic_create...");
+
/* Create the common code nic object. */
SFXGE_EFSYS_LOCK_INIT(&sc->enp_lock,
device_get_nameunit(sc->dev), "nic");
@@ -492,7 +663,8 @@ sfxge_create(struct sfxge_softc *sc)
sc->enp = enp;
if (!ISP2(sfxge_rx_ring_entries) ||
- !(sfxge_rx_ring_entries & EFX_RXQ_NDESCS_MASK)) {
+ (sfxge_rx_ring_entries < EFX_RXQ_MINNDESCS) ||
+ (sfxge_rx_ring_entries > EFX_RXQ_MAXNDESCS)) {
log(LOG_ERR, "%s=%d must be power of 2 from %u to %u",
SFXGE_PARAM_RX_RING, sfxge_rx_ring_entries,
EFX_RXQ_MINNDESCS, EFX_RXQ_MAXNDESCS);
@@ -502,20 +674,23 @@ sfxge_create(struct sfxge_softc *sc)
sc->rxq_entries = sfxge_rx_ring_entries;
if (!ISP2(sfxge_tx_ring_entries) ||
- !(sfxge_tx_ring_entries & EFX_TXQ_NDESCS_MASK)) {
+ (sfxge_tx_ring_entries < EFX_TXQ_MINNDESCS) ||
+ (sfxge_tx_ring_entries > EFX_TXQ_MAXNDESCS(efx_nic_cfg_get(enp)))) {
log(LOG_ERR, "%s=%d must be power of 2 from %u to %u",
SFXGE_PARAM_TX_RING, sfxge_tx_ring_entries,
- EFX_TXQ_MINNDESCS, EFX_TXQ_MAXNDESCS);
+ EFX_TXQ_MINNDESCS, EFX_TXQ_MAXNDESCS(efx_nic_cfg_get(enp)));
error = EINVAL;
goto fail_tx_ring_entries;
}
sc->txq_entries = sfxge_tx_ring_entries;
/* Initialize MCDI to talk to the microcontroller. */
+ DBGPRINT(sc->dev, "mcdi_init...");
if ((error = sfxge_mcdi_init(sc)) != 0)
goto fail4;
/* Probe the NIC and build the configuration data area. */
+ DBGPRINT(sc->dev, "nic_probe...");
if ((error = efx_nic_probe(enp)) != 0)
goto fail5;
@@ -525,50 +700,75 @@ sfxge_create(struct sfxge_softc *sc)
SFXGE_VERSION_STRING, 0,
"Driver version");
+ SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
+ OID_AUTO, "phy_type", CTLFLAG_RD,
+ NULL, efx_nic_cfg_get(enp)->enc_phy_type,
+ "PHY type");
+
/* Initialize the NVRAM. */
+ DBGPRINT(sc->dev, "nvram_init...");
if ((error = efx_nvram_init(enp)) != 0)
goto fail6;
/* Initialize the VPD. */
+ DBGPRINT(sc->dev, "vpd_init...");
if ((error = efx_vpd_init(enp)) != 0)
goto fail7;
+ efx_mcdi_new_epoch(enp);
+
/* Reset the NIC. */
+ DBGPRINT(sc->dev, "nic_reset...");
if ((error = efx_nic_reset(enp)) != 0)
goto fail8;
/* Initialize buffer table allocation. */
sc->buffer_table_next = 0;
+ /*
+ * Guarantee minimum and estimate maximum number of event queues
+ * to take it into account when MSI-X interrupts are allocated.
+ * It initializes NIC and keeps it initialized on success.
+ */
+ if ((error = sfxge_estimate_rsrc_limits(sc)) != 0)
+ goto fail8;
+
/* Set up interrupts. */
+ DBGPRINT(sc->dev, "intr_init...");
if ((error = sfxge_intr_init(sc)) != 0)
- goto fail8;
+ goto fail9;
/* Initialize event processing state. */
+ DBGPRINT(sc->dev, "ev_init...");
if ((error = sfxge_ev_init(sc)) != 0)
goto fail11;
+ /* Initialize port state. */
+ DBGPRINT(sc->dev, "port_init...");
+ if ((error = sfxge_port_init(sc)) != 0)
+ goto fail12;
+
/* Initialize receive state. */
+ DBGPRINT(sc->dev, "rx_init...");
if ((error = sfxge_rx_init(sc)) != 0)
- goto fail12;
+ goto fail13;
/* Initialize transmit state. */
+ DBGPRINT(sc->dev, "tx_init...");
if ((error = sfxge_tx_init(sc)) != 0)
- goto fail13;
-
- /* Initialize port state. */
- if ((error = sfxge_port_init(sc)) != 0)
goto fail14;
sc->init_state = SFXGE_INITIALIZED;
+ DBGPRINT(sc->dev, "success");
return (0);
fail14:
- sfxge_tx_fini(sc);
+ sfxge_rx_fini(sc);
fail13:
- sfxge_rx_fini(sc);
+ sfxge_port_fini(sc);
fail12:
sfxge_ev_fini(sc);
@@ -576,6 +776,9 @@ fail12:
fail11:
sfxge_intr_fini(sc);
+fail9:
+ efx_nic_fini(sc->enp);
+
fail8:
efx_vpd_fini(enp);
@@ -600,6 +803,7 @@ fail3:
(void) pci_disable_busmaster(sc->dev);
fail:
+ DBGPRINT(sc->dev, "failed %d", error);
sc->dev = NULL;
SFXGE_ADAPTER_LOCK_DESTROY(sc);
return (error);
@@ -610,15 +814,15 @@ sfxge_destroy(struct sfxge_softc *sc)
{
efx_nic_t *enp;
- /* Clean up port state. */
- sfxge_port_fini(sc);
-
/* Clean up transmit state. */
sfxge_tx_fini(sc);
/* Clean up receive state. */
sfxge_rx_fini(sc);
+ /* Clean up port state. */
+ sfxge_port_fini(sc);
+
/* Clean up event processing state. */
sfxge_ev_fini(sc);
@@ -747,6 +951,7 @@ sfxge_reset(void *arg, int npending)
{
struct sfxge_softc *sc;
int rc;
+ unsigned attempt;
(void)npending;
@@ -759,10 +964,15 @@ sfxge_reset(void *arg, int npending)
sfxge_stop(sc);
efx_nic_reset(sc->enp);
- if ((rc = sfxge_start(sc)) != 0)
- device_printf(sc->dev,
- "reset failed (%d); interface is now stopped\n",
- rc);
+ for (attempt = 0; attempt < 3; ++attempt) {
+ if ((rc = sfxge_start(sc)) == 0)
+ goto done;
+
+ device_printf(sc->dev, "start on reset failed (%d)\n", rc);
+ DELAY(100000);
+ }
+
+ device_printf(sc->dev, "reset failed; interface is now stopped\n");
done:
SFXGE_ADAPTER_UNLOCK(sc);
@@ -794,29 +1004,42 @@ sfxge_attach(device_t dev)
sc->ifnet = ifp;
/* Initialize hardware. */
+ DBGPRINT(sc->dev, "create nic");
if ((error = sfxge_create(sc)) != 0)
goto fail2;
/* Create the ifnet for the port. */
+ DBGPRINT(sc->dev, "init ifnet");
if ((error = sfxge_ifnet_init(ifp, sc)) != 0)
goto fail3;
+ DBGPRINT(sc->dev, "init vpd");
if ((error = sfxge_vpd_init(sc)) != 0)
goto fail4;
+ /*
+ * NIC is initialized inside sfxge_create() and kept inialized
+ * to be able to initialize port to discover media types in
+ * sfxge_ifnet_init().
+ */
+ efx_nic_fini(sc->enp);
+
sc->init_state = SFXGE_REGISTERED;
+ DBGPRINT(sc->dev, "success");
return (0);
fail4:
sfxge_ifnet_fini(ifp);
fail3:
+ efx_nic_fini(sc->enp);
sfxge_destroy(sc);
fail2:
if_free(sc->ifnet);
fail:
+ DBGPRINT(sc->dev, "failed %d", error);
return (error);
}
@@ -849,13 +1072,25 @@ sfxge_probe(device_t dev)
pci_vendor_id = pci_get_vendor(dev);
pci_device_id = pci_get_device(dev);
+ DBGPRINT(dev, "PCI ID %04x:%04x", pci_vendor_id, pci_device_id);
rc = efx_family(pci_vendor_id, pci_device_id, &family);
- if (rc != 0)
+ if (rc != 0) {
+ DBGPRINT(dev, "efx_family fail %d", rc);
return (ENXIO);
+ }
- KASSERT(family == EFX_FAMILY_SIENA, ("impossible controller family"));
- device_set_desc(dev, "Solarflare SFC9000 family");
- return (0);
+ if (family == EFX_FAMILY_SIENA) {
+ device_set_desc(dev, "Solarflare SFC9000 family");
+ return (0);
+ }
+
+ if (family == EFX_FAMILY_HUNTINGTON) {
+ device_set_desc(dev, "Solarflare SFC9100 family");
+ return (0);
+ }
+
+ DBGPRINT(dev, "impossible controller family %d", family);
+ return (ENXIO);
}
static device_method_t sfxge_methods[] = {
diff --git a/sys/dev/sfxge/sfxge.h b/sys/dev/sfxge/sfxge.h
index e8e65f8..aa1830d 100644
--- a/sys/dev/sfxge/sfxge.h
+++ b/sys/dev/sfxge/sfxge.h
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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.
*
* $FreeBSD$
*/
@@ -34,7 +38,6 @@
#include <sys/param.h>
#include <sys/kernel.h>
-#include <sys/condvar.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/sx.h>
@@ -45,6 +48,18 @@
#include <net/if_media.h>
#include <net/if_types.h>
+#include "sfxge_ioc.h"
+
+/*
+ * Debugging
+ */
+#if 0
+#define DBGPRINT(dev, fmt, args...) \
+ device_printf(dev, "%s: " fmt "\n", __func__, ## args)
+#else
+#define DBGPRINT(dev, fmt, args...)
+#endif
+
/*
* Backward-compatibility
*/
@@ -71,6 +86,10 @@
#define IFM_10G_KX4 IFM_10G_CX4
#endif
+#ifndef IFM_40G_CR4
+#define IFM_40G_CR4 IFM_UNKNOWN
+#endif
+
#if (__FreeBSD_version >= 800501 && __FreeBSD_version < 900000) || \
__FreeBSD_version >= 900003
#define SFXGE_HAVE_DESCRIBE_INTR
@@ -160,7 +179,7 @@ enum sfxge_mcdi_state {
struct sfxge_mcdi {
struct mtx lock;
- struct cv cv;
+ efsys_mem_t mem;
enum sfxge_mcdi_state state;
efx_mcdi_transport_t transport;
@@ -190,6 +209,9 @@ struct sfxge_port {
struct sfxge_hw_stats phy_stats;
struct sfxge_hw_stats mac_stats;
efx_link_mode_t link_mode;
+ uint8_t mcast_addrs[EFX_MAC_MULTICAST_LIST_MAX *
+ EFX_MAC_ADDR_LEN];
+ unsigned int mcast_count;
/* Only used in debugging output */
char lock_name[SFXGE_LOCK_NAME_MAX];
@@ -249,11 +271,15 @@ struct sfxge_softc {
size_t rx_prefix_size;
size_t rx_buffer_size;
+ size_t rx_buffer_align;
uma_zone_t rx_buffer_zone;
+ unsigned int evq_max;
unsigned int evq_count;
unsigned int rxq_count;
unsigned int txq_count;
+
+ int tso_fw_assisted;
};
#define SFXGE_LINK_UP(sc) ((sc)->port.link_mode != EFX_LINK_DOWN)
@@ -276,10 +302,12 @@ extern void sfxge_sram_buf_tbl_alloc(struct sfxge_softc *sc, size_t n,
extern int sfxge_dma_init(struct sfxge_softc *sc);
extern void sfxge_dma_fini(struct sfxge_softc *sc);
extern int sfxge_dma_alloc(struct sfxge_softc *sc, bus_size_t len,
- efsys_mem_t *esmp);
+ efsys_mem_t *esmp);
extern void sfxge_dma_free(efsys_mem_t *esmp);
extern int sfxge_dma_map_sg_collapse(bus_dma_tag_t tag, bus_dmamap_t map,
- struct mbuf **mp, bus_dma_segment_t *segs, int *nsegs, int maxsegs);
+ struct mbuf **mp,
+ bus_dma_segment_t *segs,
+ int *nsegs, int maxsegs);
/*
* From sfxge_ev.c.
@@ -303,6 +331,12 @@ extern void sfxge_intr_stop(struct sfxge_softc *sc);
*/
extern int sfxge_mcdi_init(struct sfxge_softc *sc);
extern void sfxge_mcdi_fini(struct sfxge_softc *sc);
+extern int sfxge_mcdi_ioctl(struct sfxge_softc *sc, sfxge_ioc_t *ip);
+
+/*
+ * From sfxge_nvram.c.
+ */
+extern int sfxge_nvram_ioctl(struct sfxge_softc *sc, sfxge_ioc_t *ip);
/*
* From sfxge_port.c.
@@ -312,7 +346,7 @@ extern void sfxge_port_fini(struct sfxge_softc *sc);
extern int sfxge_port_start(struct sfxge_softc *sc);
extern void sfxge_port_stop(struct sfxge_softc *sc);
extern void sfxge_mac_link_update(struct sfxge_softc *sc,
- efx_link_mode_t mode);
+ efx_link_mode_t mode);
extern int sfxge_mac_filter_set(struct sfxge_softc *sc);
extern int sfxge_port_ifmedia_init(struct sfxge_softc *sc);
diff --git a/sys/dev/sfxge/sfxge_dma.c b/sys/dev/sfxge/sfxge_dma.c
index 5eceab2..4f9f749 100644
--- a/sys/dev/sfxge/sfxge_dma.c
+++ b/sys/dev/sfxge/sfxge_dma.c
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -56,7 +60,8 @@ sfxge_dma_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
int
sfxge_dma_map_sg_collapse(bus_dma_tag_t tag, bus_dmamap_t map,
- struct mbuf **mp, bus_dma_segment_t *segs, int *nsegs, int maxsegs)
+ struct mbuf **mp, bus_dma_segment_t *segs,
+ int *nsegs, int maxsegs)
{
bus_dma_segment_t *psegs;
struct mbuf *m;
diff --git a/sys/dev/sfxge/sfxge_ev.c b/sys/dev/sfxge/sfxge_ev.c
index 14ed008..1c4afbd 100644
--- a/sys/dev/sfxge/sfxge_ev.c
+++ b/sys/dev/sfxge/sfxge_ev.c
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -77,12 +81,13 @@ sfxge_ev_qcomplete(struct sfxge_evq *evq, boolean_t eop)
static boolean_t
sfxge_ev_rx(void *arg, uint32_t label, uint32_t id, uint32_t size,
- uint16_t flags)
+ uint16_t flags)
{
struct sfxge_evq *evq;
struct sfxge_softc *sc;
struct sfxge_rxq *rxq;
- unsigned int expected;
+ unsigned int stop;
+ unsigned int delta;
struct sfxge_rx_sw_desc *rx_desc;
evq = arg;
@@ -101,28 +106,40 @@ sfxge_ev_rx(void *arg, uint32_t label, uint32_t id, uint32_t size,
if (__predict_false(rxq->init_state != SFXGE_RXQ_STARTED))
goto done;
- expected = rxq->pending++ & rxq->ptr_mask;
- if (id != expected) {
- evq->exception = B_TRUE;
+ stop = (id + 1) & rxq->ptr_mask;
+ id = rxq->pending & rxq->ptr_mask;
+ delta = (stop >= id) ? (stop - id) : (rxq->entries - id + stop);
+ rxq->pending += delta;
- device_printf(sc->dev, "RX completion out of order"
- " (id=%#x expected=%#x flags=%#x); resetting\n",
- id, expected, flags);
- sfxge_schedule_reset(sc);
+ if (delta != 1) {
+ if ((!efx_nic_cfg_get(sc->enp)->enc_rx_batching_enabled) ||
+ (delta <= 0) ||
+ (delta > efx_nic_cfg_get(sc->enp)->enc_rx_batch_max)) {
+ evq->exception = B_TRUE;
- goto done;
+ device_printf(sc->dev, "RX completion out of order"
+ " (id=%#x delta=%u flags=%#x); resetting\n",
+ id, delta, flags);
+ sfxge_schedule_reset(sc);
+
+ goto done;
+ }
}
rx_desc = &rxq->queue[id];
- KASSERT(rx_desc->flags == EFX_DISCARD,
- ("rx_desc->flags != EFX_DISCARD"));
- rx_desc->flags = flags;
-
- KASSERT(size < (1 << 16), ("size > (1 << 16)"));
- rx_desc->size = (uint16_t)size;
prefetch_read_many(rx_desc->mbuf);
+ for (; id != stop; id = (id + 1) & rxq->ptr_mask) {
+ rx_desc = &rxq->queue[id];
+ KASSERT(rx_desc->flags == EFX_DISCARD,
+ ("rx_desc->flags != EFX_DISCARD"));
+ rx_desc->flags = flags;
+
+ KASSERT(size < (1 << 16), ("size > (1 << 16)"));
+ rx_desc->size = (uint16_t)size;
+ }
+
evq->rx_done++;
if (rxq->pending - rxq->completed >= SFXGE_RX_BATCH)
@@ -143,6 +160,18 @@ sfxge_ev_exception(void *arg, uint32_t code, uint32_t data)
sc = evq->sc;
+ DBGPRINT(sc->dev, "[%d] %s", evq->index,
+ (code == EFX_EXCEPTION_RX_RECOVERY) ? "RX_RECOVERY" :
+ (code == EFX_EXCEPTION_RX_DSC_ERROR) ? "RX_DSC_ERROR" :
+ (code == EFX_EXCEPTION_TX_DSC_ERROR) ? "TX_DSC_ERROR" :
+ (code == EFX_EXCEPTION_UNKNOWN_SENSOREVT) ? "UNKNOWN_SENSOREVT" :
+ (code == EFX_EXCEPTION_FWALERT_SRAM) ? "FWALERT_SRAM" :
+ (code == EFX_EXCEPTION_UNKNOWN_FWALERT) ? "UNKNOWN_FWALERT" :
+ (code == EFX_EXCEPTION_RX_ERROR) ? "RX_ERROR" :
+ (code == EFX_EXCEPTION_TX_ERROR) ? "TX_ERROR" :
+ (code == EFX_EXCEPTION_EV_ERROR) ? "EV_ERROR" :
+ "UNKNOWN");
+
evq->exception = B_TRUE;
if (code != EFX_EXCEPTION_UNKNOWN_SENSOREVT) {
@@ -175,6 +204,11 @@ sfxge_ev_rxq_flush_done(void *arg, uint32_t rxq_index)
/* Resend a software event on the correct queue */
index = rxq->index;
+ if (index == evq->index) {
+ sfxge_rx_qflush_done(rxq);
+ return (B_FALSE);
+ }
+
evq = sc->evq[index];
label = rxq_index;
@@ -294,6 +328,11 @@ sfxge_ev_txq_flush_done(void *arg, uint32_t txq_index)
KASSERT(txq->init_state == SFXGE_TXQ_INITIALIZED,
("txq not initialized"));
+ if (txq->evq_index == evq->index) {
+ sfxge_tx_qflush_done(txq);
+ return (B_FALSE);
+ }
+
/* Resend a software event on the correct queue */
evq = sc->evq[txq->evq_index];
@@ -546,7 +585,9 @@ sfxge_ev_initialized(void *arg)
evq = (struct sfxge_evq *)arg;
SFXGE_EVQ_LOCK_ASSERT_OWNED(evq);
- KASSERT(evq->init_state == SFXGE_EVQ_STARTING,
+ /* Init done events may be duplicated on 7xxx */
+ KASSERT(evq->init_state == SFXGE_EVQ_STARTING ||
+ evq->init_state == SFXGE_EVQ_STARTED,
("evq not starting"));
evq->init_state = SFXGE_EVQ_STARTED;
diff --git a/sys/dev/sfxge/sfxge_intr.c b/sys/dev/sfxge/sfxge_intr.c
index acb21d3..20f4d53 100644
--- a/sys/dev/sfxge/sfxge_intr.c
+++ b/sys/dev/sfxge/sfxge_intr.c
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -33,7 +37,6 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/rman.h>
-#include <sys/smp.h>
#include <sys/syslog.h>
#include <machine/bus.h>
@@ -290,16 +293,9 @@ sfxge_intr_setup_msix(struct sfxge_softc *sc)
if (count == 0)
return (EINVAL);
- /* Limit the number of interrupts to the number of CPUs. */
- if (count > mp_ncpus)
- count = mp_ncpus;
-
- /* Not very likely these days... */
- if (count > EFX_MAXRSS)
- count = EFX_MAXRSS;
-
- if (sc->max_rss_channels > 0 && count > sc->max_rss_channels)
- count = sc->max_rss_channels;
+ /* Do not try to allocate more than already estimated EVQ maximum */
+ KASSERT(sc->evq_max > 0, ("evq_max is zero"));
+ count = MIN(count, sc->evq_max);
rid = PCIR_BAR(4);
resp = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
@@ -408,7 +404,7 @@ static const char *const __sfxge_err[] = {
void
sfxge_err(efsys_identifier_t *arg, unsigned int code, uint32_t dword0,
- uint32_t dword1)
+ uint32_t dword1)
{
struct sfxge_softc *sc = (struct sfxge_softc *)arg;
device_t dev = sc->dev;
diff --git a/sys/dev/sfxge/sfxge_ioc.h b/sys/dev/sfxge/sfxge_ioc.h
new file mode 100644
index 0000000..bf079c8
--- /dev/null
+++ b/sys/dev/sfxge/sfxge_ioc.h
@@ -0,0 +1,112 @@
+/*-
+ * Copyright (c) 2014-2015 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_SFXGE_IOC_H
+#define _SYS_SFXGE_IOC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/types.h>
+
+/* More codes may be added if necessary */
+enum sfxge_ioc_codes {
+ SFXGE_MCDI_IOC,
+ SFXGE_NVRAM_IOC,
+ SFXGE_VPD_IOC
+};
+
+enum sfxge_nvram_ops {
+ SFXGE_NVRAM_OP_SIZE,
+ SFXGE_NVRAM_OP_READ,
+ SFXGE_NVRAM_OP_WRITE,
+ SFXGE_NVRAM_OP_ERASE,
+ SFXGE_NVRAM_OP_GET_VER,
+ SFXGE_NVRAM_OP_SET_VER
+};
+
+enum sfxge_nvram_types {
+ SFXGE_NVRAM_TYPE_BOOTROM,
+ SFXGE_NVRAM_TYPE_BOOTROM_CFG,
+ SFXGE_NVRAM_TYPE_MC,
+ SFXGE_NVRAM_TYPE_MC_GOLDEN,
+ SFXGE_NVRAM_TYPE_PHY,
+ SFXGE_NVRAM_TYPE_NULL_PHY,
+ SFXGE_NVRAM_TYPE_FPGA,
+ SFXGE_NVRAM_TYPE_FCFW,
+ SFXGE_NVRAM_TYPE_CPLD,
+ SFXGE_NVRAM_TYPE_FPGA_BACKUP,
+ SFXGE_NVRAM_TYPE_DYNAMIC_CFG
+};
+
+enum sfxge_vpd_ops {
+ SFXGE_VPD_OP_GET_KEYWORD,
+ SFXGE_VPD_OP_SET_KEYWORD
+};
+
+#define SFXGE_MCDI_MAX_PAYLOAD 0x400
+#define SFXGE_VPD_MAX_PAYLOAD 0x100
+
+typedef struct sfxge_ioc_s {
+ uint32_t op;
+ union {
+ struct {
+ caddr_t payload;
+ uint32_t cmd;
+ size_t len; /* In and out */
+ uint32_t rc;
+ } mcdi;
+ struct {
+ uint32_t op;
+ uint32_t type;
+ uint32_t offset;
+ uint32_t size;
+ uint32_t subtype;
+ uint16_t version[4]; /* get/set_ver */
+ caddr_t data;
+ } nvram;
+ struct {
+ uint8_t op;
+ uint8_t tag;
+ uint16_t keyword;
+ uint16_t len; /* In or out */
+ caddr_t payload;
+ } vpd;
+ } u;
+} __packed sfxge_ioc_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_SFXGE_IOC_H */
diff --git a/sys/dev/sfxge/sfxge_mcdi.c b/sys/dev/sfxge/sfxge_mcdi.c
index a1bc857..fb9f650 100644
--- a/sys/dev/sfxge/sfxge_mcdi.c
+++ b/sys/dev/sfxge/sfxge_mcdi.c
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -37,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/syslog.h>
#include <sys/taskqueue.h>
+#include <sys/malloc.h>
#include "common/efx.h"
#include "common/efx_mcdi.h"
@@ -48,36 +53,6 @@ __FBSDID("$FreeBSD$");
#define SFXGE_MCDI_POLL_INTERVAL_MAX 100000 /* 100ms in 1us units */
#define SFXGE_MCDI_WATCHDOG_INTERVAL 10000000 /* 10s in 1us units */
-/* Acquire exclusive access to MCDI for the duration of a request. */
-static void
-sfxge_mcdi_acquire(struct sfxge_mcdi *mcdi)
-{
- SFXGE_MCDI_LOCK(mcdi);
- KASSERT(mcdi->state != SFXGE_MCDI_UNINITIALIZED,
- ("MCDI not initialized"));
-
- while (mcdi->state != SFXGE_MCDI_INITIALIZED)
- (void)cv_wait_sig(&mcdi->cv, &mcdi->lock);
- mcdi->state = SFXGE_MCDI_BUSY;
-
- SFXGE_MCDI_UNLOCK(mcdi);
-}
-
-/* Release ownership of MCDI on request completion. */
-static void
-sfxge_mcdi_release(struct sfxge_mcdi *mcdi)
-{
- SFXGE_MCDI_LOCK(mcdi);
- KASSERT((mcdi->state == SFXGE_MCDI_BUSY ||
- mcdi->state == SFXGE_MCDI_COMPLETED),
- ("MCDI not busy or task not completed"));
-
- mcdi->state = SFXGE_MCDI_INITIALIZED;
- cv_broadcast(&mcdi->cv);
-
- SFXGE_MCDI_UNLOCK(mcdi);
-}
-
static void
sfxge_mcdi_timeout(struct sfxge_softc *sc)
{
@@ -140,13 +115,16 @@ sfxge_mcdi_execute(void *arg, efx_mcdi_req_t *emrp)
sc = (struct sfxge_softc *)arg;
mcdi = &sc->mcdi;
- sfxge_mcdi_acquire(mcdi);
+ SFXGE_MCDI_LOCK(mcdi);
+
+ KASSERT(mcdi->state == SFXGE_MCDI_INITIALIZED,
+ ("MCDI not initialized"));
/* Issue request and poll for completion. */
efx_mcdi_request_start(sc->enp, emrp, B_FALSE);
sfxge_mcdi_poll(sc);
- sfxge_mcdi_release(mcdi);
+ SFXGE_MCDI_UNLOCK(mcdi);
}
static void
@@ -158,11 +136,10 @@ sfxge_mcdi_ev_cpl(void *arg)
sc = (struct sfxge_softc *)arg;
mcdi = &sc->mcdi;
- SFXGE_MCDI_LOCK(mcdi);
- KASSERT(mcdi->state == SFXGE_MCDI_BUSY, ("MCDI not busy"));
- mcdi->state = SFXGE_MCDI_COMPLETED;
- cv_broadcast(&mcdi->cv);
- SFXGE_MCDI_UNLOCK(mcdi);
+ KASSERT(mcdi->state == SFXGE_MCDI_INITIALIZED,
+ ("MCDI not initialized"));
+
+ /* We do not use MCDI completion, MCDI is simply polled */
}
static void
@@ -187,16 +164,95 @@ sfxge_mcdi_exception(void *arg, efx_mcdi_exception_t eme)
}
int
+sfxge_mcdi_ioctl(struct sfxge_softc *sc, sfxge_ioc_t *ip)
+{
+ const efx_nic_cfg_t *encp = efx_nic_cfg_get(sc->enp);
+ struct sfxge_mcdi *mp = &(sc->mcdi);
+ efx_mcdi_req_t emr;
+ uint8_t *mcdibuf;
+ int rc;
+
+ if (mp->state == SFXGE_MCDI_UNINITIALIZED) {
+ rc = ENODEV;
+ goto fail1;
+ }
+
+ if (!(encp->enc_features & EFX_FEATURE_MCDI)) {
+ rc = ENOTSUP;
+ goto fail2;
+ }
+
+ if (ip->u.mcdi.len > SFXGE_MCDI_MAX_PAYLOAD) {
+ rc = EINVAL;
+ goto fail3;
+ }
+
+ mcdibuf = malloc(SFXGE_MCDI_MAX_PAYLOAD, M_TEMP, M_WAITOK | M_ZERO);
+ if (mcdibuf == NULL) {
+ rc = ENOMEM;
+ goto fail4;
+ }
+ if ((rc = copyin(ip->u.mcdi.payload, mcdibuf, ip->u.mcdi.len)) != 0) {
+ goto fail5;
+ }
+
+ emr.emr_cmd = ip->u.mcdi.cmd;
+ emr.emr_in_buf = mcdibuf;
+ emr.emr_in_length = ip->u.mcdi.len;
+
+ emr.emr_out_buf = mcdibuf;
+ emr.emr_out_length = SFXGE_MCDI_MAX_PAYLOAD;
+
+ sfxge_mcdi_execute(sc, &emr);
+
+ ip->u.mcdi.rc = emr.emr_rc;
+ ip->u.mcdi.cmd = emr.emr_cmd;
+ ip->u.mcdi.len = emr.emr_out_length_used;
+ if ((rc = copyout(mcdibuf, ip->u.mcdi.payload, ip->u.mcdi.len)) != 0) {
+ goto fail6;
+ }
+
+ /*
+ * Helpfully trigger a device reset in response to an MCDI_CMD_REBOOT
+ * Both ports will see ->emt_exception callbacks on the next MCDI poll
+ */
+ if (ip->u.mcdi.cmd == MC_CMD_REBOOT) {
+
+ EFSYS_PROBE(mcdi_ioctl_mc_reboot);
+ /* sfxge_t->s_state_lock held */
+ (void) sfxge_schedule_reset(sc);
+ }
+
+ free(mcdibuf, M_TEMP);
+
+ return (0);
+
+fail6:
+fail5:
+ free(mcdibuf, M_TEMP);
+fail4:
+fail3:
+fail2:
+fail1:
+ return (rc);
+}
+
+
+int
sfxge_mcdi_init(struct sfxge_softc *sc)
{
efx_nic_t *enp;
struct sfxge_mcdi *mcdi;
efx_mcdi_transport_t *emtp;
+ efsys_mem_t *esmp;
+ int max_msg_size;
int rc;
enp = sc->enp;
mcdi = &sc->mcdi;
emtp = &mcdi->transport;
+ esmp = &mcdi->mem;
+ max_msg_size = sizeof (uint32_t) + MCDI_CTL_SDU_LEN_MAX_V2;
KASSERT(mcdi->state == SFXGE_MCDI_UNINITIALIZED,
("MCDI already initialized"));
@@ -205,13 +261,15 @@ sfxge_mcdi_init(struct sfxge_softc *sc)
mcdi->state = SFXGE_MCDI_INITIALIZED;
+ if ((rc = sfxge_dma_alloc(sc, max_msg_size, esmp)) != 0)
+ goto fail;
+
emtp->emt_context = sc;
+ emtp->emt_dma_mem = esmp;
emtp->emt_execute = sfxge_mcdi_execute;
emtp->emt_ev_cpl = sfxge_mcdi_ev_cpl;
emtp->emt_exception = sfxge_mcdi_exception;
- cv_init(&mcdi->cv, "sfxge_mcdi");
-
if ((rc = efx_mcdi_init(enp, emtp)) != 0)
goto fail;
@@ -229,10 +287,12 @@ sfxge_mcdi_fini(struct sfxge_softc *sc)
struct sfxge_mcdi *mcdi;
efx_nic_t *enp;
efx_mcdi_transport_t *emtp;
+ efsys_mem_t *esmp;
enp = sc->enp;
mcdi = &sc->mcdi;
emtp = &mcdi->transport;
+ esmp = &mcdi->mem;
SFXGE_MCDI_LOCK(mcdi);
KASSERT(mcdi->state == SFXGE_MCDI_INITIALIZED,
@@ -241,8 +301,9 @@ sfxge_mcdi_fini(struct sfxge_softc *sc)
efx_mcdi_fini(enp);
bzero(emtp, sizeof(*emtp));
- cv_destroy(&mcdi->cv);
SFXGE_MCDI_UNLOCK(mcdi);
+ sfxge_dma_free(esmp);
+
SFXGE_MCDI_LOCK_DESTROY(mcdi);
}
diff --git a/sys/dev/sfxge/sfxge_nvram.c b/sys/dev/sfxge/sfxge_nvram.c
new file mode 100644
index 0000000..c4fa224
--- /dev/null
+++ b/sys/dev/sfxge/sfxge_nvram.c
@@ -0,0 +1,203 @@
+/*-
+ * Copyright (c) 2010-2015 Solarflare Communications, Inc.
+ * All rights reserved.
+ *
+ * This software was developed in part by OKTET Labs Ltd. under contract for
+ * Solarflare Communications, Inc.
+ *
+ * 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 AUTHOR 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 AUTHOR 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+
+#include <sys/types.h>
+#include <sys/malloc.h>
+
+#include "common/efx.h"
+#include "sfxge.h"
+
+/* These data make no real sense, they are here just to make sfupdate happy.
+ * Any code that would rely on it is broken.
+ */
+static const uint8_t fake_dynamic_cfg_nvram[] = {
+ 0x7a, 0xda, 0x10, 0xef, 0x0c, 0x00, 0x00, 0x00,
+ 0x00, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10,
+ 0x08, 0x00, 0x00, 0x00, 0x90, 0x04, 0x00, 0x52,
+ 0x56, 0x01, 0xc3, 0x78, 0x01, 0x00, 0x03, 0x10,
+ 0x08, 0x00, 0x00, 0x00, 0x90, 0x04, 0x00, 0x52,
+ 0x56, 0x01, 0xc3, 0x78, 0x57, 0x1a, 0x10, 0xef,
+ 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x02, 0x0b, 0x64, 0x7d, 0xee, 0xee, 0xee, 0xee
+};
+
+static int
+sfxge_nvram_rw(struct sfxge_softc *sc, sfxge_ioc_t *ip, efx_nvram_type_t type,
+ boolean_t write)
+{
+ efx_nic_t *enp = sc->enp;
+ size_t total_size = ip->u.nvram.size;
+ size_t chunk_size;
+ off_t off;
+ int rc = 0;
+ uint8_t *buf;
+
+ if (type == EFX_NVRAM_DYNAMIC_CFG && sc->family == EFX_FAMILY_SIENA) {
+ if (write)
+ return (0);
+ rc = copyout(fake_dynamic_cfg_nvram, ip->u.nvram.data,
+ MIN(total_size, sizeof(fake_dynamic_cfg_nvram)));
+ return (rc);
+ }
+
+ if ((rc = efx_nvram_rw_start(enp, type, &chunk_size)) != 0)
+ goto fail1;
+
+ buf = malloc(chunk_size, M_TEMP, M_WAITOK);
+ if (buf == NULL) {
+ rc = ENOMEM;
+ goto fail2;
+ }
+
+ off = 0;
+ while (total_size) {
+ size_t len = MIN(chunk_size, total_size);
+
+ if (write) {
+ rc = copyin(ip->u.nvram.data + off, buf, len);
+ if (rc != 0)
+ goto fail3;
+ rc = efx_nvram_write_chunk(enp, type,
+ ip->u.nvram.offset + off, buf, len);
+ if (rc != 0)
+ goto fail3;
+ } else {
+ rc = efx_nvram_read_chunk(enp, type,
+ ip->u.nvram.offset + off, buf, len);
+ if (rc != 0)
+ goto fail3;
+ rc = copyout(buf, ip->u.nvram.data + off, len);
+ if (rc != 0)
+ goto fail3;
+ }
+
+ total_size -= len;
+ off += len;
+ }
+
+fail3:
+ free(buf, M_TEMP);
+fail2:
+ efx_nvram_rw_finish(enp, type);
+fail1:
+ return (rc);
+}
+
+
+static int
+sfxge_nvram_erase(struct sfxge_softc *sc, efx_nvram_type_t type)
+{
+ efx_nic_t *enp = sc->enp;
+ size_t chunk_size;
+ int rc = 0;
+
+ if (type == EFX_NVRAM_DYNAMIC_CFG && sc->family == EFX_FAMILY_SIENA)
+ return (0);
+
+ if ((rc = efx_nvram_rw_start(enp, type, &chunk_size)) != 0)
+ return (rc);
+
+ rc = efx_nvram_erase(enp, type);
+
+ efx_nvram_rw_finish(enp, type);
+ return (rc);
+}
+
+int
+sfxge_nvram_ioctl(struct sfxge_softc *sc, sfxge_ioc_t *ip)
+{
+ static const efx_nvram_type_t nvram_types[] = {
+ [SFXGE_NVRAM_TYPE_BOOTROM] = EFX_NVRAM_BOOTROM,
+ [SFXGE_NVRAM_TYPE_BOOTROM_CFG] = EFX_NVRAM_BOOTROM_CFG,
+ [SFXGE_NVRAM_TYPE_MC] = EFX_NVRAM_MC_FIRMWARE,
+ [SFXGE_NVRAM_TYPE_MC_GOLDEN] = EFX_NVRAM_MC_GOLDEN,
+ [SFXGE_NVRAM_TYPE_PHY] = EFX_NVRAM_PHY,
+ [SFXGE_NVRAM_TYPE_NULL_PHY] = EFX_NVRAM_NULLPHY,
+ [SFXGE_NVRAM_TYPE_FPGA] = EFX_NVRAM_FPGA,
+ [SFXGE_NVRAM_TYPE_FCFW] = EFX_NVRAM_FCFW,
+ [SFXGE_NVRAM_TYPE_CPLD] = EFX_NVRAM_CPLD,
+ [SFXGE_NVRAM_TYPE_FPGA_BACKUP] = EFX_NVRAM_FPGA_BACKUP,
+ [SFXGE_NVRAM_TYPE_DYNAMIC_CFG] = EFX_NVRAM_DYNAMIC_CFG,
+ };
+
+ efx_nic_t *enp = sc->enp;
+ efx_nvram_type_t type;
+ int rc = 0;
+
+ if (ip->u.nvram.type > SFXGE_NVRAM_TYPE_DYNAMIC_CFG)
+ return (EINVAL);
+ type = nvram_types[ip->u.nvram.type];
+ if (type == EFX_NVRAM_MC_GOLDEN &&
+ (ip->u.nvram.op == SFXGE_NVRAM_OP_WRITE ||
+ ip->u.nvram.op == SFXGE_NVRAM_OP_ERASE ||
+ ip->u.nvram.op == SFXGE_NVRAM_OP_SET_VER))
+ return (EOPNOTSUPP);
+
+ switch (ip->u.nvram.op) {
+ case SFXGE_NVRAM_OP_SIZE:
+ {
+ size_t size;
+
+ if (type == EFX_NVRAM_DYNAMIC_CFG && sc->family == EFX_FAMILY_SIENA) {
+ ip->u.nvram.size = sizeof(fake_dynamic_cfg_nvram);
+ } else {
+ if ((rc = efx_nvram_size(enp, type, &size)) != 0)
+ return (rc);
+ ip->u.nvram.size = size;
+ }
+ break;
+ }
+ case SFXGE_NVRAM_OP_READ:
+ rc = sfxge_nvram_rw(sc, ip, type, B_FALSE);
+ break;
+ case SFXGE_NVRAM_OP_WRITE:
+ rc = sfxge_nvram_rw(sc, ip, type, B_TRUE);
+ break;
+ case SFXGE_NVRAM_OP_ERASE:
+ rc = sfxge_nvram_erase(sc, type);
+ break;
+ case SFXGE_NVRAM_OP_GET_VER:
+ rc = efx_nvram_get_version(enp, type, &ip->u.nvram.subtype,
+ &ip->u.nvram.version[0]);
+ break;
+ case SFXGE_NVRAM_OP_SET_VER:
+ rc = efx_nvram_set_version(enp, type, &ip->u.nvram.version[0]);
+ break;
+ default:
+ rc = EOPNOTSUPP;
+ break;
+ }
+
+ return (rc);
+}
diff --git a/sys/dev/sfxge/sfxge_port.c b/sys/dev/sfxge/sfxge_port.c
index 8559dc0..420aaad 100644
--- a/sys/dev/sfxge/sfxge_port.c
+++ b/sys/dev/sfxge/sfxge_port.c
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -70,10 +74,6 @@ sfxge_mac_stat_update(struct sfxge_softc *sc)
for (count = 0; count < 100; ++count) {
EFSYS_PROBE1(wait, unsigned int, count);
- /* Synchronize the DMA memory for reading */
- bus_dmamap_sync(esmp->esm_tag, esmp->esm_map,
- BUS_DMASYNC_POSTREAD);
-
/* Try to update the cached counters */
if ((rc = efx_mac_stats_update(sc->enp, esmp,
port->mac_stats.decode_buf, NULL)) != EAGAIN)
@@ -232,6 +232,7 @@ static const uint64_t sfxge_link_baudrate[EFX_LINK_NMODES] = {
[EFX_LINK_1000HDX] = IF_Gbps(1),
[EFX_LINK_1000FDX] = IF_Gbps(1),
[EFX_LINK_10000FDX] = IF_Gbps(10),
+ [EFX_LINK_40000FDX] = IF_Gbps(40),
};
void
@@ -280,42 +281,68 @@ done:
}
static int
-sfxge_mac_filter_set_locked(struct sfxge_softc *sc)
+sfxge_mac_multicast_list_set(struct sfxge_softc *sc)
{
- unsigned int bucket[EFX_MAC_HASH_BITS];
struct ifnet *ifp = sc->ifnet;
+ struct sfxge_port *port = &sc->port;
+ uint8_t *mcast_addr = port->mcast_addrs;
struct ifmultiaddr *ifma;
struct sockaddr_dl *sa;
- efx_nic_t *enp = sc->enp;
- unsigned int index;
- int rc;
-
- /* Set promisc-unicast and broadcast filter bits */
- if ((rc = efx_mac_filter_set(enp, !!(ifp->if_flags & IFF_PROMISC),
- B_TRUE)) != 0)
- return (rc);
-
- /* Set multicast hash filter */
- if (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) {
- for (index = 0; index < EFX_MAC_HASH_BITS; index++)
- bucket[index] = 1;
- } else {
- /* Broadcast frames also go through the multicast
- * filter, and the broadcast address hashes to
- * 0xff. */
- bucket[0xff] = 1;
-
- if_maddr_rlock(ifp);
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
- if (ifma->ifma_addr->sa_family == AF_LINK) {
- sa = (struct sockaddr_dl *)ifma->ifma_addr;
- index = ether_crc32_le(LLADDR(sa), 6) & 0xff;
- bucket[index] = 1;
+ int rc = 0;
+
+ mtx_assert(&port->lock, MA_OWNED);
+
+ port->mcast_count = 0;
+ if_maddr_rlock(ifp);
+ TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+ if (ifma->ifma_addr->sa_family == AF_LINK) {
+ if (port->mcast_count == EFX_MAC_MULTICAST_LIST_MAX) {
+ device_printf(sc->dev,
+ "Too many multicast addresses\n");
+ rc = EINVAL;
+ break;
}
+
+ sa = (struct sockaddr_dl *)ifma->ifma_addr;
+ memcpy(mcast_addr, LLADDR(sa), EFX_MAC_ADDR_LEN);
+ mcast_addr += EFX_MAC_ADDR_LEN;
+ ++port->mcast_count;
}
- if_maddr_runlock(ifp);
}
- return (efx_mac_hash_set(enp, bucket));
+ if_maddr_runlock(ifp);
+
+ if (rc == 0) {
+ rc = efx_mac_multicast_list_set(sc->enp, port->mcast_addrs,
+ port->mcast_count);
+ if (rc != 0)
+ device_printf(sc->dev,
+ "Cannot set multicast address list\n");
+ }
+
+ return (rc);
+}
+
+static int
+sfxge_mac_filter_set_locked(struct sfxge_softc *sc)
+{
+ struct ifnet *ifp = sc->ifnet;
+ struct sfxge_port *port = &sc->port;
+ boolean_t all_mulcst;
+ int rc;
+
+ mtx_assert(&port->lock, MA_OWNED);
+
+ all_mulcst = !!(ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI));
+
+ rc = sfxge_mac_multicast_list_set(sc);
+ /* Fallback to all multicast if cannot set multicast list */
+ if (rc != 0)
+ all_mulcst = B_TRUE;
+
+ rc = efx_mac_filter_set(sc->enp, !!(ifp->if_flags & IFF_PROMISC),
+ (port->mcast_count > 0), all_mulcst, B_TRUE);
+
+ return (rc);
}
int
@@ -369,7 +396,9 @@ sfxge_port_stop(struct sfxge_softc *sc)
port->link_mode = EFX_LINK_UNKNOWN;
/* Destroy the common code port object. */
- efx_port_fini(sc->enp);
+ efx_port_fini(enp);
+
+ efx_filter_fini(enp);
SFXGE_PORT_UNLOCK(port);
}
@@ -393,6 +422,10 @@ sfxge_port_start(struct sfxge_softc *sc)
KASSERT(port->init_state == SFXGE_PORT_INITIALIZED,
("port not initialized"));
+ /* Initialise the required filtering */
+ if ((rc = efx_filter_init(enp)) != 0)
+ goto fail_filter_init;
+
/* Initialize the port object in the common code. */
if ((rc = efx_port_init(sc->enp)) != 0)
goto fail;
@@ -404,7 +437,7 @@ sfxge_port_start(struct sfxge_softc *sc)
if ((rc = efx_mac_fcntl_set(enp, sfxge_port_wanted_fc(sc), B_TRUE))
!= 0)
- goto fail2;
+ goto fail3;
/* Set the unicast address */
if_addr_rlock(ifp);
@@ -412,24 +445,24 @@ sfxge_port_start(struct sfxge_softc *sc)
mac_addr, sizeof(mac_addr));
if_addr_runlock(ifp);
if ((rc = efx_mac_addr_set(enp, mac_addr)) != 0)
- goto fail;
+ goto fail4;
sfxge_mac_filter_set_locked(sc);
/* Update MAC stats by DMA every second */
if ((rc = efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf,
- 1000, B_FALSE)) != 0)
- goto fail2;
+ 1000, B_FALSE)) != 0)
+ goto fail6;
if ((rc = efx_mac_drain(enp, B_FALSE)) != 0)
- goto fail3;
+ goto fail8;
if ((rc = sfxge_phy_cap_mask(sc, sc->media.ifm_cur->ifm_media,
&phy_cap_mask)) != 0)
- goto fail4;
+ goto fail9;
if ((rc = efx_phy_adv_cap_set(sc->enp, phy_cap_mask)) != 0)
- goto fail5;
+ goto fail10;
port->init_state = SFXGE_PORT_STARTED;
@@ -439,15 +472,20 @@ sfxge_port_start(struct sfxge_softc *sc)
return (0);
-fail5:
-fail4:
+fail10:
+fail9:
(void)efx_mac_drain(enp, B_TRUE);
+fail8:
+ (void)efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf, 0, B_FALSE);
+fail6:
+fail4:
fail3:
- (void)efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf,
- 0, B_FALSE);
+
fail2:
- efx_port_fini(sc->enp);
+ efx_port_fini(enp);
fail:
+ efx_filter_fini(enp);
+fail_filter_init:
SFXGE_PORT_UNLOCK(port);
return (rc);
@@ -590,12 +628,14 @@ sfxge_port_init(struct sfxge_softc *sc)
SFXGE_PORT_LOCK_INIT(port, device_get_nameunit(sc->dev));
+ DBGPRINT(sc->dev, "alloc PHY stats");
port->phy_stats.decode_buf = malloc(EFX_PHY_NSTATS * sizeof(uint32_t),
M_SFXGE, M_WAITOK | M_ZERO);
if ((rc = sfxge_dma_alloc(sc, EFX_PHY_STATS_SIZE, phy_stats_buf)) != 0)
goto fail;
sfxge_phy_stat_init(sc);
+ DBGPRINT(sc->dev, "init sysctl");
sysctl_ctx = device_get_sysctl_ctx(sc->dev);
sysctl_tree = device_get_sysctl_tree(sc->dev);
@@ -611,6 +651,7 @@ sfxge_port_init(struct sfxge_softc *sc)
sfxge_port_link_fc_handler, "IU", "link flow control mode");
#endif
+ DBGPRINT(sc->dev, "alloc MAC stats");
port->mac_stats.decode_buf = malloc(EFX_MAC_NSTATS * sizeof(uint64_t),
M_SFXGE, M_WAITOK | M_ZERO);
if ((rc = sfxge_dma_alloc(sc, EFX_MAC_STATS_SIZE, mac_stats_buf)) != 0)
@@ -619,6 +660,7 @@ sfxge_port_init(struct sfxge_softc *sc)
port->init_state = SFXGE_PORT_INITIALIZED;
+ DBGPRINT(sc->dev, "success");
return (0);
fail2:
@@ -628,6 +670,7 @@ fail:
free(port->phy_stats.decode_buf, M_SFXGE);
SFXGE_PORT_LOCK_DESTROY(port);
port->sc = NULL;
+ DBGPRINT(sc->dev, "failed %d", rc);
return (rc);
}
@@ -642,6 +685,11 @@ static const int sfxge_link_mode[EFX_PHY_MEDIA_NTYPES][EFX_LINK_NMODES] = {
/* Don't know the module type, but assume SR for now. */
[EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_SR,
},
+ [EFX_PHY_MEDIA_QSFP_PLUS] = {
+ /* Don't know the module type, but assume SR for now. */
+ [EFX_LINK_10000FDX] = IFM_ETHER | IFM_FDX | IFM_10G_SR,
+ [EFX_LINK_40000FDX] = IFM_ETHER | IFM_FDX | IFM_40G_CR4,
+ },
[EFX_PHY_MEDIA_SFP_PLUS] = {
/* Don't know the module type, but assume SX/SR for now. */
[EFX_LINK_1000FDX] = IFM_ETHER | IFM_FDX | IFM_1000_SX,
@@ -701,6 +749,8 @@ sfxge_link_mode_to_phy_cap(efx_link_mode_t mode)
return (EFX_PHY_CAP_1000FDX);
case EFX_LINK_10000FDX:
return (EFX_PHY_CAP_10000FDX);
+ case EFX_LINK_40000FDX:
+ return (EFX_PHY_CAP_40000FDX);
default:
EFSYS_ASSERT(B_FALSE);
return (EFX_PHY_CAP_INVALID);
@@ -808,9 +858,13 @@ int sfxge_port_ifmedia_init(struct sfxge_softc *sc)
int mode_ifm, best_mode_ifm = 0;
int rc;
- /* We need port state to initialise the ifmedia list. */
- if ((rc = efx_nic_init(sc->enp)) != 0)
- goto out;
+ /*
+ * We need port state to initialise the ifmedia list.
+ * It requires initialized NIC what is already done in
+ * sfxge_create() when resources are estimated.
+ */
+ if ((rc = efx_filter_init(sc->enp)) != 0)
+ goto out1;
if ((rc = efx_port_init(sc->enp)) != 0)
goto out2;
@@ -880,7 +934,7 @@ int sfxge_port_ifmedia_init(struct sfxge_softc *sc)
/* Now discard port state until interface is started. */
efx_port_fini(sc->enp);
out2:
- efx_nic_fini(sc->enp);
-out:
+ efx_filter_fini(sc->enp);
+out1:
return (rc);
}
diff --git a/sys/dev/sfxge/sfxge_rx.c b/sys/dev/sfxge/sfxge_rx.c
index 1637db9..0d8398f 100644
--- a/sys/dev/sfxge/sfxge_rx.c
+++ b/sys/dev/sfxge/sfxge_rx.c
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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 <sys/cdefs.h>
@@ -35,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include <sys/smp.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
+#include <sys/syslog.h>
#include <sys/limits.h>
#include <sys/syslog.h>
@@ -256,7 +261,7 @@ sfxge_rx_qfill(struct sfxge_rxq *rxq, unsigned int target, boolean_t retrying)
return;
batch = 0;
- mblksize = sc->rx_buffer_size;
+ mblksize = sc->rx_buffer_size - sc->rx_buffer_align;
while (ntodo-- > 0) {
unsigned int id;
struct sfxge_rx_sw_desc *rx_desc;
@@ -271,6 +276,12 @@ sfxge_rx_qfill(struct sfxge_rxq *rxq, unsigned int target, boolean_t retrying)
m = rx_desc->mbuf = sfxge_rx_alloc_mbuf(sc);
if (m == NULL)
break;
+
+ /* m_len specifies length of area to be mapped for DMA */
+ m->m_len = mblksize;
+ m->m_data = (caddr_t)P2ROUNDUP((uintptr_t)m->m_data, CACHE_LINE_SIZE);
+ m->m_data += sc->rx_buffer_align;
+
sfxge_map_mbuf_fast(rxq->mem.esm_tag, rxq->mem.esm_map, m, &seg);
addr[batch++] = seg.ds_addr;
@@ -295,7 +306,15 @@ sfxge_rx_qfill(struct sfxge_rxq *rxq, unsigned int target, boolean_t retrying)
bus_dmamap_sync(rxq->mem.esm_tag, rxq->mem.esm_map,
BUS_DMASYNC_PREWRITE);
- efx_rx_qpush(rxq->common, rxq->added);
+ efx_rx_qpush(rxq->common, rxq->added, &rxq->pushed);
+
+ /* The queue could still be empty if no descriptors were actually
+ * pushed, in which case there will be no event to cause the next
+ * refill, so we must schedule a refill ourselves.
+ */
+ if(rxq->pushed == rxq->completed) {
+ sfxge_rx_schedule_refill(rxq, retrying);
+ }
}
void
@@ -333,8 +352,10 @@ sfxge_rx_deliver(struct sfxge_softc *sc, struct sfxge_rx_sw_desc *rx_desc)
/* The hash covers a 4-tuple for TCP only */
if (flags & EFX_PKT_TCP) {
- m->m_pkthdr.flowid = EFX_RX_HASH_VALUE(EFX_RX_HASHALG_TOEPLITZ,
- mtod(m, uint8_t *));
+ m->m_pkthdr.flowid =
+ efx_psuedo_hdr_hash_get(sc->enp,
+ EFX_RX_HASHALG_TOEPLITZ,
+ mtod(m, uint8_t *));
M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE);
}
m->m_data += sc->rx_prefix_size;
@@ -659,8 +680,9 @@ sfxge_lro(struct sfxge_rxq *rxq, struct sfxge_rx_sw_desc *rx_buf)
unsigned bucket;
/* Get the hardware hash */
- conn_hash = EFX_RX_HASH_VALUE(EFX_RX_HASHALG_TOEPLITZ,
- mtod(m, uint8_t *));
+ conn_hash = efx_psuedo_hdr_hash_get(sc->enp,
+ EFX_RX_HASHALG_TOEPLITZ,
+ mtod(m, uint8_t *));
eh = (struct ether_header *)(m->m_data + sc->rx_prefix_size);
if (eh->ether_type == htons(ETHERTYPE_VLAN)) {
@@ -817,6 +839,17 @@ sfxge_rx_qcomplete(struct sfxge_rxq *rxq, boolean_t eop)
if (rx_desc->flags & (EFX_ADDR_MISMATCH | EFX_DISCARD))
goto discard;
+ /* Read the length from the psuedo header if required */
+ if (rx_desc->flags & EFX_PKT_PREFIX_LEN) {
+ uint16_t tmp_size;
+ int rc;
+ rc = efx_psuedo_hdr_pkt_length_get(sc->enp,
+ mtod(m, uint8_t *),
+ &tmp_size);
+ KASSERT(rc == 0, ("cannot get packet length: %d", rc));
+ rx_desc->size = (int)tmp_size + sc->rx_prefix_size;
+ }
+
prefetch_read_many(mtod(m, caddr_t));
switch (rx_desc->flags & (EFX_PKT_IPV4 | EFX_PKT_IPV6)) {
@@ -901,6 +934,9 @@ sfxge_rx_qstop(struct sfxge_softc *sc, unsigned int index)
struct sfxge_rxq *rxq;
struct sfxge_evq *evq;
unsigned int count;
+ unsigned int retry = 3;
+
+ SFXGE_ADAPTER_LOCK_ASSERT_OWNED(sc);
rxq = sc->rxq[index];
evq = sc->evq[index];
@@ -914,30 +950,43 @@ sfxge_rx_qstop(struct sfxge_softc *sc, unsigned int index)
callout_stop(&rxq->refill_callout);
-again:
- rxq->flush_state = SFXGE_FLUSH_PENDING;
+ while (rxq->flush_state != SFXGE_FLUSH_DONE && retry != 0) {
+ rxq->flush_state = SFXGE_FLUSH_PENDING;
- /* Flush the receive queue */
- efx_rx_qflush(rxq->common);
+ SFXGE_EVQ_UNLOCK(evq);
- SFXGE_EVQ_UNLOCK(evq);
-
- count = 0;
- do {
- /* Spin for 100 ms */
- DELAY(100000);
-
- if (rxq->flush_state != SFXGE_FLUSH_PENDING)
+ /* Flush the receive queue */
+ if (efx_rx_qflush(rxq->common) != 0) {
+ SFXGE_EVQ_LOCK(evq);
+ rxq->flush_state = SFXGE_FLUSH_FAILED;
break;
+ }
- } while (++count < 20);
+ count = 0;
+ do {
+ /* Spin for 100 ms */
+ DELAY(100000);
- SFXGE_EVQ_LOCK(evq);
+ if (rxq->flush_state != SFXGE_FLUSH_PENDING)
+ break;
- if (rxq->flush_state == SFXGE_FLUSH_FAILED)
- goto again;
+ } while (++count < 20);
- rxq->flush_state = SFXGE_FLUSH_DONE;
+ SFXGE_EVQ_LOCK(evq);
+
+ if (rxq->flush_state == SFXGE_FLUSH_PENDING) {
+ /* Flush timeout - neither done nor failed */
+ log(LOG_ERR, "%s: Cannot flush Rx queue %u\n",
+ device_get_nameunit(sc->dev), index);
+ rxq->flush_state = SFXGE_FLUSH_DONE;
+ }
+ retry--;
+ }
+ if (rxq->flush_state == SFXGE_FLUSH_FAILED) {
+ log(LOG_ERR, "%s: Flushing Rx queue %u failed\n",
+ device_get_nameunit(sc->dev), index);
+ rxq->flush_state = SFXGE_FLUSH_DONE;
+ }
rxq->pending = rxq->added;
sfxge_rx_qcomplete(rxq, B_TRUE);
@@ -946,6 +995,7 @@ again:
("rxq->completed != rxq->pending"));
rxq->added = 0;
+ rxq->pushed = 0;
rxq->pending = 0;
rxq->completed = 0;
rxq->loopback = 0;
@@ -967,6 +1017,8 @@ sfxge_rx_qstart(struct sfxge_softc *sc, unsigned int index)
struct sfxge_evq *evq;
int rc;
+ SFXGE_ADAPTER_LOCK_ASSERT_OWNED(sc);
+
rxq = sc->rxq[index];
esmp = &rxq->mem;
evq = sc->evq[index];
@@ -993,6 +1045,7 @@ sfxge_rx_qstart(struct sfxge_softc *sc, unsigned int index)
efx_rx_qenable(rxq->common);
rxq->init_state = SFXGE_RXQ_STARTED;
+ rxq->flush_state = SFXGE_FLUSH_REQUIRED;
/* Try to fill the queue from the pool. */
sfxge_rx_qfill(rxq, EFX_RXQ_LIMIT(sc->rxq_entries), B_FALSE);
@@ -1012,6 +1065,8 @@ sfxge_rx_stop(struct sfxge_softc *sc)
{
int index;
+ efx_mac_filter_default_rxq_clear(sc->enp);
+
/* Stop the receive queue(s) */
index = sc->rxq_count;
while (--index >= 0)
@@ -1027,6 +1082,8 @@ int
sfxge_rx_start(struct sfxge_softc *sc)
{
struct sfxge_intr *intr;
+ const efx_nic_cfg_t *encp;
+ size_t hdrlen, align, reserved;
int index;
int rc;
@@ -1036,17 +1093,35 @@ sfxge_rx_start(struct sfxge_softc *sc)
if ((rc = efx_rx_init(sc->enp)) != 0)
return (rc);
- /* Calculate the receive packet buffer size. */
- sc->rx_prefix_size = EFX_RX_PREFIX_SIZE;
- sc->rx_buffer_size = (EFX_MAC_PDU(sc->ifnet->if_mtu) +
- sc->rx_prefix_size);
+ encp = efx_nic_cfg_get(sc->enp);
+ sc->rx_buffer_size = EFX_MAC_PDU(sc->ifnet->if_mtu);
+
+ /* Calculate the receive packet buffer size. */
+ sc->rx_prefix_size = encp->enc_rx_prefix_size;
+
+ /* Ensure IP headers are 32bit aligned */
+ hdrlen = sc->rx_prefix_size + sizeof (struct ether_header);
+ sc->rx_buffer_align = P2ROUNDUP(hdrlen, 4) - hdrlen;
+
+ sc->rx_buffer_size += sc->rx_buffer_align;
+
+ /* Align end of packet buffer for RX DMA end padding */
+ align = MAX(1, encp->enc_rx_buf_align_end);
+ EFSYS_ASSERT(ISP2(align));
+ sc->rx_buffer_size = P2ROUNDUP(sc->rx_buffer_size, align);
+
+ /*
+ * Standard mbuf zones only guarantee pointer-size alignment;
+ * we need extra space to align to the cache line
+ */
+ reserved = sc->rx_buffer_size + CACHE_LINE_SIZE;
/* Select zone for packet buffers */
- if (sc->rx_buffer_size <= MCLBYTES)
+ if (reserved <= MCLBYTES)
sc->rx_buffer_zone = zone_clust;
- else if (sc->rx_buffer_size <= MJUMPAGESIZE)
+ else if (reserved <= MJUMPAGESIZE)
sc->rx_buffer_zone = zone_jumbop;
- else if (sc->rx_buffer_size <= MJUM9BYTES)
+ else if (reserved <= MJUM9BYTES)
sc->rx_buffer_zone = zone_jumbo9;
else
sc->rx_buffer_zone = zone_jumbo16;
@@ -1063,8 +1138,8 @@ sfxge_rx_start(struct sfxge_softc *sc)
(1 << EFX_RX_HASH_IPV4) | (1 << EFX_RX_HASH_TCPIPV4) |
(1 << EFX_RX_HASH_IPV6) | (1 << EFX_RX_HASH_TCPIPV6), B_TRUE);
- if ((rc = efx_rx_scale_toeplitz_ipv4_key_set(sc->enp, toep_key,
- sizeof(toep_key))) != 0)
+ if ((rc = efx_rx_scale_key_set(sc->enp, toep_key,
+ sizeof(toep_key))) != 0)
goto fail;
/* Start the receive queue(s). */
@@ -1073,8 +1148,14 @@ sfxge_rx_start(struct sfxge_softc *sc)
goto fail2;
}
+ rc = efx_mac_filter_default_rxq_set(sc->enp, sc->rxq[0]->common,
+ sc->intr.n_alloc > 1);
+ if (rc != 0)
+ goto fail3;
+
return (0);
+fail3:
fail2:
while (--index >= 0)
sfxge_rx_qstop(sc, index);
diff --git a/sys/dev/sfxge/sfxge_rx.h b/sys/dev/sfxge/sfxge_rx.h
index dae7e08..e870ed5 100644
--- a/sys/dev/sfxge/sfxge_rx.h
+++ b/sys/dev/sfxge/sfxge_rx.h
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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.
*
* $FreeBSD$
*/
@@ -39,22 +43,22 @@
#define SFXGE_LRO 1
#endif
-#define SFXGE_MAGIC_RESERVED 0x8000
+#define SFXGE_MAGIC_RESERVED 0x8000
#define SFXGE_MAGIC_DMAQ_LABEL_WIDTH 6
-#define SFXGE_MAGIC_DMAQ_LABEL_MASK \
+#define SFXGE_MAGIC_DMAQ_LABEL_MASK \
((1 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH) - 1)
-#define SFXGE_MAGIC_RX_QFLUSH_DONE \
+#define SFXGE_MAGIC_RX_QFLUSH_DONE \
(SFXGE_MAGIC_RESERVED | (1 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH))
-#define SFXGE_MAGIC_RX_QFLUSH_FAILED \
+#define SFXGE_MAGIC_RX_QFLUSH_FAILED \
(SFXGE_MAGIC_RESERVED | (2 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH))
-#define SFXGE_MAGIC_RX_QREFILL \
+#define SFXGE_MAGIC_RX_QREFILL \
(SFXGE_MAGIC_RESERVED | (3 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH))
-#define SFXGE_MAGIC_TX_QFLUSH_DONE \
+#define SFXGE_MAGIC_TX_QFLUSH_DONE \
(SFXGE_MAGIC_RESERVED | (4 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH))
#define SFXGE_RX_SCALE_MAX EFX_MAXRSS
@@ -152,6 +156,7 @@ struct sfxge_lro_state {
enum sfxge_flush_state {
SFXGE_FLUSH_DONE = 0,
+ SFXGE_FLUSH_REQUIRED,
SFXGE_FLUSH_PENDING,
SFXGE_FLUSH_FAILED
};
@@ -175,6 +180,7 @@ struct sfxge_rxq {
struct sfxge_rx_sw_desc *queue __aligned(CACHE_LINE_SIZE);
unsigned int added;
+ unsigned int pushed;
unsigned int pending;
unsigned int completed;
unsigned int loopback;
diff --git a/sys/dev/sfxge/sfxge_tx.c b/sys/dev/sfxge/sfxge_tx.c
index 054e36f..9579975 100644
--- a/sys/dev/sfxge/sfxge_tx.c
+++ b/sys/dev/sfxge/sfxge_tx.c
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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.
*/
/* Theory of operation:
@@ -67,23 +71,6 @@ __FBSDID("$FreeBSD$");
#include "sfxge.h"
#include "sfxge_tx.h"
-/*
- * Estimate maximum number of Tx descriptors required for TSO packet.
- * With minimum MSS and maximum mbuf length we might need more (even
- * than a ring-ful of descriptors), but this should not happen in
- * practice except due to deliberate attack. In that case we will
- * truncate the output at a packet boundary.
- */
-#define SFXGE_TSO_MAX_DESC \
- (SFXGE_TSO_MAX_SEGS * 2 + SFXGE_TX_MAPPING_MAX_SEG - 1)
-
-/*
- * Set the block level to ensure there is space to generate a
- * large number of descriptors for TSO.
- */
-#define SFXGE_TXQ_BLOCK_LEVEL(_entries) \
- (EFX_TXQ_LIMIT(_entries) - SFXGE_TSO_MAX_DESC)
-
#define SFXGE_PARAM_TX_DPL_GET_MAX SFXGE_PARAM(tx_dpl_get_max)
static int sfxge_tx_dpl_get_max = SFXGE_TX_DPL_GET_PKT_LIMIT_DEFAULT;
@@ -108,6 +95,13 @@ SYSCTL_INT(_hw_sfxge, OID_AUTO, tx_dpl_put_max, CTLFLAG_RDTUN,
&sfxge_tx_dpl_put_max, 0,
"Maximum number of any packets in deferred packet put-list");
+#define SFXGE_PARAM_TSO_FW_ASSISTED SFXGE_PARAM(tso_fw_assisted)
+static int sfxge_tso_fw_assisted = 1;
+TUNABLE_INT(SFXGE_PARAM_TSO_FW_ASSISTED, &sfxge_tso_fw_assisted);
+SYSCTL_INT(_hw_sfxge, OID_AUTO, tso_fw_assisted, CTLFLAG_RDTUN,
+ &sfxge_tso_fw_assisted, 0,
+ "Use FW-assisted TSO if supported by NIC firmware");
+
static const struct {
const char *name;
@@ -134,7 +128,38 @@ static void sfxge_tx_qdpl_service(struct sfxge_txq *txq);
static void sfxge_tx_qlist_post(struct sfxge_txq *txq);
static void sfxge_tx_qunblock(struct sfxge_txq *txq);
static int sfxge_tx_queue_tso(struct sfxge_txq *txq, struct mbuf *mbuf,
- const bus_dma_segment_t *dma_seg, int n_dma_seg);
+ const bus_dma_segment_t *dma_seg, int n_dma_seg,
+ int vlan_tagged);
+
+static int
+sfxge_tx_maybe_insert_tag(struct sfxge_txq *txq, struct mbuf *mbuf)
+{
+ uint16_t this_tag = ((mbuf->m_flags & M_VLANTAG) ?
+ mbuf->m_pkthdr.ether_vtag :
+ 0);
+
+ if (this_tag == txq->hw_vlan_tci)
+ return (0);
+
+ efx_tx_qdesc_vlantci_create(txq->common,
+ bswap16(this_tag),
+ &txq->pend_desc[0]);
+ txq->n_pend_desc = 1;
+ txq->hw_vlan_tci = this_tag;
+ return (1);
+}
+
+static inline void
+sfxge_next_stmp(struct sfxge_txq *txq, struct sfxge_tx_mapping **pstmp)
+{
+ KASSERT((*pstmp)->flags == 0, ("stmp flags are not 0"));
+ if (__predict_false(*pstmp ==
+ &txq->stmp[txq->ptr_mask]))
+ *pstmp = &txq->stmp[0];
+ else
+ (*pstmp)++;
+}
+
void
sfxge_tx_qcomplete(struct sfxge_txq *txq, struct sfxge_evq *evq)
@@ -252,29 +277,30 @@ static void
sfxge_tx_qlist_post(struct sfxge_txq *txq)
{
unsigned int old_added;
+ unsigned int block_level;
unsigned int level;
int rc;
SFXGE_TXQ_LOCK_ASSERT_OWNED(txq);
KASSERT(txq->n_pend_desc != 0, ("txq->n_pend_desc == 0"));
- KASSERT(txq->n_pend_desc <= SFXGE_TSO_MAX_DESC,
+ KASSERT(txq->n_pend_desc <= txq->max_pkt_desc,
("txq->n_pend_desc too large"));
KASSERT(!txq->blocked, ("txq->blocked"));
old_added = txq->added;
/* Post the fragment list. */
- rc = efx_tx_qpost(txq->common, txq->pend_desc, txq->n_pend_desc,
+ rc = efx_tx_qdesc_post(txq->common, txq->pend_desc, txq->n_pend_desc,
txq->reaped, &txq->added);
- KASSERT(rc == 0, ("efx_tx_qpost() failed"));
+ KASSERT(rc == 0, ("efx_tx_qdesc_post() failed"));
- /* If efx_tx_qpost() had to refragment, our information about
+ /* If efx_tx_qdesc_post() had to refragment, our information about
* buffers to free may be associated with the wrong
* descriptors.
*/
KASSERT(txq->added - old_added == txq->n_pend_desc,
- ("efx_tx_qpost() refragmented descriptors"));
+ ("efx_tx_qdesc_post() refragmented descriptors"));
level = txq->added - txq->reaped;
KASSERT(level <= txq->entries, ("overfilled TX queue"));
@@ -282,14 +308,20 @@ sfxge_tx_qlist_post(struct sfxge_txq *txq)
/* Clear the fragment list. */
txq->n_pend_desc = 0;
+ /*
+ * Set the block level to ensure there is space to generate a
+ * large number of descriptors for TSO.
+ */
+ block_level = EFX_TXQ_LIMIT(txq->entries) - txq->max_pkt_desc;
+
/* Have we reached the block level? */
- if (level < SFXGE_TXQ_BLOCK_LEVEL(txq->entries))
+ if (level < block_level)
return;
/* Reap, and check again */
sfxge_tx_qreap(txq);
level = txq->added - txq->reaped;
- if (level < SFXGE_TXQ_BLOCK_LEVEL(txq->entries))
+ if (level < block_level)
return;
txq->blocked = 1;
@@ -301,7 +333,7 @@ sfxge_tx_qlist_post(struct sfxge_txq *txq)
mb();
sfxge_tx_qreap(txq);
level = txq->added - txq->reaped;
- if (level < SFXGE_TXQ_BLOCK_LEVEL(txq->entries)) {
+ if (level < block_level) {
mb();
txq->blocked = 0;
}
@@ -314,10 +346,12 @@ static int sfxge_tx_queue_mbuf(struct sfxge_txq *txq, struct mbuf *mbuf)
bus_dma_segment_t dma_seg[SFXGE_TX_MAPPING_MAX_SEG];
unsigned int id;
struct sfxge_tx_mapping *stmp;
- efx_buffer_t *desc;
+ efx_desc_t *desc;
int n_dma_seg;
int rc;
int i;
+ int eop;
+ int vlan_tagged;
KASSERT(!txq->blocked, ("txq->blocked"));
@@ -354,35 +388,35 @@ static int sfxge_tx_queue_mbuf(struct sfxge_txq *txq, struct mbuf *mbuf)
used_map = &stmp->map;
+ vlan_tagged = sfxge_tx_maybe_insert_tag(txq, mbuf);
+ if (vlan_tagged) {
+ sfxge_next_stmp(txq, &stmp);
+ }
if (mbuf->m_pkthdr.csum_flags & CSUM_TSO) {
- rc = sfxge_tx_queue_tso(txq, mbuf, dma_seg, n_dma_seg);
+ rc = sfxge_tx_queue_tso(txq, mbuf, dma_seg, n_dma_seg, vlan_tagged);
if (rc < 0)
goto reject_mapped;
- stmp = &txq->stmp[rc];
+ stmp = &txq->stmp[(rc - 1) & txq->ptr_mask];
} else {
/* Add the mapping to the fragment list, and set flags
* for the buffer.
*/
+
i = 0;
for (;;) {
- desc = &txq->pend_desc[i];
- desc->eb_addr = dma_seg[i].ds_addr;
- desc->eb_size = dma_seg[i].ds_len;
- if (i == n_dma_seg - 1) {
- desc->eb_eop = 1;
+ desc = &txq->pend_desc[i + vlan_tagged];
+ eop = (i == n_dma_seg - 1);
+ efx_tx_qdesc_dma_create(txq->common,
+ dma_seg[i].ds_addr,
+ dma_seg[i].ds_len,
+ eop,
+ desc);
+ if (eop)
break;
- }
- desc->eb_eop = 0;
i++;
-
- stmp->flags = 0;
- if (__predict_false(stmp ==
- &txq->stmp[txq->ptr_mask]))
- stmp = &txq->stmp[0];
- else
- stmp++;
+ sfxge_next_stmp(txq, &stmp);
}
- txq->n_pend_desc = n_dma_seg;
+ txq->n_pend_desc = n_dma_seg + vlan_tagged;
}
/*
@@ -469,7 +503,7 @@ sfxge_tx_qdpl_drain(struct sfxge_txq *txq)
/* Push the fragments to the hardware in batches. */
if (txq->added - pushed >= SFXGE_TX_BATCH) {
- efx_tx_qpush(txq->common, txq->added);
+ efx_tx_qpush(txq->common, txq->added, pushed);
pushed = txq->added;
}
}
@@ -489,14 +523,13 @@ sfxge_tx_qdpl_drain(struct sfxge_txq *txq)
}
if (txq->added != pushed)
- efx_tx_qpush(txq->common, txq->added);
+ efx_tx_qpush(txq->common, txq->added, pushed);
KASSERT(txq->blocked || stdp->std_get_count == 0,
("queue unblocked but count is non-zero"));
}
-#define SFXGE_TX_QDPL_PENDING(_txq) \
- ((_txq)->dpl.std_put != 0)
+#define SFXGE_TX_QDPL_PENDING(_txq) ((_txq)->dpl.std_put != 0)
/*
* Service the deferred packet list.
@@ -599,7 +632,7 @@ sfxge_tx_qdpl_put_unlocked(struct sfxge_txq *txq, struct mbuf *mbuf)
* Called from if_transmit - will try to grab the txq lock and enqueue to the
* put list if it succeeds, otherwise try to push onto the defer list if space.
*/
-int
+static int
sfxge_tx_packet_add(struct sfxge_txq *txq, struct mbuf *m)
{
int rc;
@@ -746,6 +779,10 @@ struct sfxge_tso_state {
ssize_t tcph_off; /* Offset of TCP header */
unsigned header_len; /* Number of bytes of header */
unsigned seg_size; /* TCP segment size */
+ int fw_assisted; /* Use FW-assisted TSO */
+ u_short packet_id; /* IPv4 packet ID from the original packet */
+ efx_desc_t header_desc; /* Precomputed header descriptor for
+ * FW-assisted TSO */
};
static const struct ip *tso_iph(const struct sfxge_tso_state *tso)
@@ -816,12 +853,16 @@ static void tso_fini(struct sfxge_txq *txq)
}
}
-static void tso_start(struct sfxge_tso_state *tso, struct mbuf *mbuf)
+static void tso_start(struct sfxge_txq *txq, struct sfxge_tso_state *tso,
+ const bus_dma_segment_t *hdr_dma_seg,
+ struct mbuf *mbuf)
{
struct ether_header *eh = mtod(mbuf, struct ether_header *);
+ const efx_nic_cfg_t *encp = efx_nic_cfg_get(txq->sc->enp);
const struct tcphdr *th;
struct tcphdr th_copy;
+ tso->fw_assisted = txq->sc->tso_fw_assisted;
tso->mbuf = mbuf;
/* Find network protocol and header */
@@ -840,12 +881,19 @@ static void tso_start(struct sfxge_tso_state *tso, struct mbuf *mbuf)
KASSERT(tso_iph(tso)->ip_p == IPPROTO_TCP,
("TSO required on non-TCP packet"));
tso->tcph_off = tso->nh_off + 4 * tso_iph(tso)->ip_hl;
+ tso->packet_id = tso_iph(tso)->ip_id;
} else {
KASSERT(tso->protocol == htons(ETHERTYPE_IPV6),
("TSO required on non-IP packet"));
KASSERT(tso_ip6h(tso)->ip6_nxt == IPPROTO_TCP,
("TSO required on non-TCP packet"));
tso->tcph_off = tso->nh_off + sizeof(struct ip6_hdr);
+ tso->packet_id = 0;
+ }
+ if (tso->fw_assisted &&
+ __predict_false(tso->tcph_off >
+ encp->enc_tx_tso_tcp_header_offset_limit)) {
+ tso->fw_assisted = 0;
}
KASSERT(mbuf->m_len >= tso->tcph_off,
@@ -875,6 +923,17 @@ static void tso_start(struct sfxge_tso_state *tso, struct mbuf *mbuf)
th->th_flags & (TH_URG | TH_SYN)));
tso->out_len = mbuf->m_pkthdr.len - tso->header_len;
+
+ if (tso->fw_assisted) {
+ if (hdr_dma_seg->ds_len >= tso->header_len)
+ efx_tx_qdesc_dma_create(txq->common,
+ hdr_dma_seg->ds_addr,
+ tso->header_len,
+ B_FALSE,
+ &tso->header_desc);
+ else
+ tso->fw_assisted = 0;
+ }
}
/*
@@ -887,7 +946,7 @@ static void tso_start(struct sfxge_tso_state *tso, struct mbuf *mbuf)
static void tso_fill_packet_with_fragment(struct sfxge_txq *txq,
struct sfxge_tso_state *tso)
{
- efx_buffer_t *desc;
+ efx_desc_t *desc;
int n;
if (tso->in_len == 0 || tso->packet_space == 0)
@@ -903,9 +962,11 @@ static void tso_fill_packet_with_fragment(struct sfxge_txq *txq,
tso->in_len -= n;
desc = &txq->pend_desc[txq->n_pend_desc++];
- desc->eb_addr = tso->dma_addr;
- desc->eb_size = n;
- desc->eb_eop = tso->out_len == 0 || tso->packet_space == 0;
+ efx_tx_qdesc_dma_create(txq->common,
+ tso->dma_addr,
+ n,
+ tso->out_len == 0 || tso->packet_space == 0,
+ desc);
tso->dma_addr += n;
}
@@ -928,107 +989,139 @@ static void tso_map_long_header(void *dma_addr_ret,
*/
static int tso_start_new_packet(struct sfxge_txq *txq,
struct sfxge_tso_state *tso,
- unsigned int id)
+ unsigned int *idp)
{
- struct sfxge_tx_mapping *stmp = &txq->stmp[id];
+ unsigned int id = *idp;
struct tcphdr *tsoh_th;
unsigned ip_length;
caddr_t header;
uint64_t dma_addr;
bus_dmamap_t map;
- efx_buffer_t *desc;
+ efx_desc_t *desc;
int rc;
- /* Allocate a DMA-mapped header buffer. */
- if (__predict_true(tso->header_len <= TSOH_STD_SIZE)) {
- unsigned int page_index = (id / 2) / TSOH_PER_PAGE;
- unsigned int buf_index = (id / 2) % TSOH_PER_PAGE;
+ if (tso->fw_assisted) {
+ uint8_t tcp_flags = tso_tcph(tso)->th_flags;
+
+ if (tso->out_len > tso->seg_size)
+ tcp_flags &= ~(TH_FIN | TH_PUSH);
+
+ /* TSO option descriptor */
+ desc = &txq->pend_desc[txq->n_pend_desc++];
+ efx_tx_qdesc_tso_create(txq->common,
+ tso->packet_id,
+ tso->seqnum,
+ tcp_flags,
+ desc++);
+ KASSERT(txq->stmp[id].flags == 0, ("stmp flags are not 0"));
+ id = (id + 1) & txq->ptr_mask;
- header = (txq->tsoh_buffer[page_index].esm_base +
- buf_index * TSOH_STD_SIZE);
- dma_addr = (txq->tsoh_buffer[page_index].esm_addr +
- buf_index * TSOH_STD_SIZE);
- map = txq->tsoh_buffer[page_index].esm_map;
+ /* Header DMA descriptor */
+ *desc = tso->header_desc;
+ txq->n_pend_desc++;
+ KASSERT(txq->stmp[id].flags == 0, ("stmp flags are not 0"));
+ id = (id + 1) & txq->ptr_mask;
- stmp->flags = 0;
+ tso->seqnum += tso->seg_size;
} else {
- /* We cannot use bus_dmamem_alloc() as that may sleep */
- header = malloc(tso->header_len, M_SFXGE, M_NOWAIT);
- if (__predict_false(!header))
- return (ENOMEM);
- rc = bus_dmamap_load(txq->packet_dma_tag, stmp->map,
- header, tso->header_len,
- tso_map_long_header, &dma_addr,
- BUS_DMA_NOWAIT);
- if (__predict_false(dma_addr == 0)) {
- if (rc == 0) {
- /* Succeeded but got >1 segment */
- bus_dmamap_unload(txq->packet_dma_tag,
- stmp->map);
- rc = EINVAL;
+ /* Allocate a DMA-mapped header buffer. */
+ if (__predict_true(tso->header_len <= TSOH_STD_SIZE)) {
+ unsigned int page_index = (id / 2) / TSOH_PER_PAGE;
+ unsigned int buf_index = (id / 2) % TSOH_PER_PAGE;
+
+ header = (txq->tsoh_buffer[page_index].esm_base +
+ buf_index * TSOH_STD_SIZE);
+ dma_addr = (txq->tsoh_buffer[page_index].esm_addr +
+ buf_index * TSOH_STD_SIZE);
+ map = txq->tsoh_buffer[page_index].esm_map;
+
+ KASSERT(txq->stmp[id].flags == 0,
+ ("stmp flags are not 0"));
+ } else {
+ struct sfxge_tx_mapping *stmp = &txq->stmp[id];
+
+ /* We cannot use bus_dmamem_alloc() as that may sleep */
+ header = malloc(tso->header_len, M_SFXGE, M_NOWAIT);
+ if (__predict_false(!header))
+ return (ENOMEM);
+ rc = bus_dmamap_load(txq->packet_dma_tag, stmp->map,
+ header, tso->header_len,
+ tso_map_long_header, &dma_addr,
+ BUS_DMA_NOWAIT);
+ if (__predict_false(dma_addr == 0)) {
+ if (rc == 0) {
+ /* Succeeded but got >1 segment */
+ bus_dmamap_unload(txq->packet_dma_tag,
+ stmp->map);
+ rc = EINVAL;
+ }
+ free(header, M_SFXGE);
+ return (rc);
}
- free(header, M_SFXGE);
- return (rc);
- }
- map = stmp->map;
+ map = stmp->map;
- txq->tso_long_headers++;
- stmp->u.heap_buf = header;
- stmp->flags = TX_BUF_UNMAP;
- }
+ txq->tso_long_headers++;
+ stmp->u.heap_buf = header;
+ stmp->flags = TX_BUF_UNMAP;
+ }
- tsoh_th = (struct tcphdr *)(header + tso->tcph_off);
+ tsoh_th = (struct tcphdr *)(header + tso->tcph_off);
- /* Copy and update the headers. */
- m_copydata(tso->mbuf, 0, tso->header_len, header);
+ /* Copy and update the headers. */
+ m_copydata(tso->mbuf, 0, tso->header_len, header);
- tsoh_th->th_seq = htonl(tso->seqnum);
- tso->seqnum += tso->seg_size;
- if (tso->out_len > tso->seg_size) {
- /* This packet will not finish the TSO burst. */
- ip_length = tso->header_len - tso->nh_off + tso->seg_size;
- tsoh_th->th_flags &= ~(TH_FIN | TH_PUSH);
- } else {
- /* This packet will be the last in the TSO burst. */
- ip_length = tso->header_len - tso->nh_off + tso->out_len;
- }
+ tsoh_th->th_seq = htonl(tso->seqnum);
+ tso->seqnum += tso->seg_size;
+ if (tso->out_len > tso->seg_size) {
+ /* This packet will not finish the TSO burst. */
+ ip_length = tso->header_len - tso->nh_off + tso->seg_size;
+ tsoh_th->th_flags &= ~(TH_FIN | TH_PUSH);
+ } else {
+ /* This packet will be the last in the TSO burst. */
+ ip_length = tso->header_len - tso->nh_off + tso->out_len;
+ }
- if (tso->protocol == htons(ETHERTYPE_IP)) {
- struct ip *tsoh_iph = (struct ip *)(header + tso->nh_off);
- tsoh_iph->ip_len = htons(ip_length);
- /* XXX We should increment ip_id, but FreeBSD doesn't
- * currently allocate extra IDs for multiple segments.
- */
- } else {
- struct ip6_hdr *tsoh_iph =
- (struct ip6_hdr *)(header + tso->nh_off);
- tsoh_iph->ip6_plen = htons(ip_length - sizeof(*tsoh_iph));
- }
+ if (tso->protocol == htons(ETHERTYPE_IP)) {
+ struct ip *tsoh_iph = (struct ip *)(header + tso->nh_off);
+ tsoh_iph->ip_len = htons(ip_length);
+ /* XXX We should increment ip_id, but FreeBSD doesn't
+ * currently allocate extra IDs for multiple segments.
+ */
+ } else {
+ struct ip6_hdr *tsoh_iph =
+ (struct ip6_hdr *)(header + tso->nh_off);
+ tsoh_iph->ip6_plen = htons(ip_length - sizeof(*tsoh_iph));
+ }
- /* Make the header visible to the hardware. */
- bus_dmamap_sync(txq->packet_dma_tag, map, BUS_DMASYNC_PREWRITE);
+ /* Make the header visible to the hardware. */
+ bus_dmamap_sync(txq->packet_dma_tag, map, BUS_DMASYNC_PREWRITE);
+ /* Form a descriptor for this header. */
+ desc = &txq->pend_desc[txq->n_pend_desc++];
+ efx_tx_qdesc_dma_create(txq->common,
+ dma_addr,
+ tso->header_len,
+ 0,
+ desc);
+ id = (id + 1) & txq->ptr_mask;
+ }
tso->packet_space = tso->seg_size;
txq->tso_packets++;
-
- /* Form a descriptor for this header. */
- desc = &txq->pend_desc[txq->n_pend_desc++];
- desc->eb_addr = dma_addr;
- desc->eb_size = tso->header_len;
- desc->eb_eop = 0;
+ *idp = id;
return (0);
}
static int
sfxge_tx_queue_tso(struct sfxge_txq *txq, struct mbuf *mbuf,
- const bus_dma_segment_t *dma_seg, int n_dma_seg)
+ const bus_dma_segment_t *dma_seg, int n_dma_seg,
+ int vlan_tagged)
{
struct sfxge_tso_state tso;
- unsigned int id, next_id;
+ unsigned int id;
unsigned skipped = 0;
- tso_start(&tso, mbuf);
+ tso_start(txq, &tso, dma_seg, mbuf);
while (dma_seg->ds_len + skipped <= tso.header_len) {
skipped += dma_seg->ds_len;
@@ -1039,13 +1132,15 @@ sfxge_tx_queue_tso(struct sfxge_txq *txq, struct mbuf *mbuf,
tso.in_len = dma_seg->ds_len - (tso.header_len - skipped);
tso.dma_addr = dma_seg->ds_addr + (tso.header_len - skipped);
- id = txq->added & txq->ptr_mask;
- if (__predict_false(tso_start_new_packet(txq, &tso, id)))
+ id = (txq->added + vlan_tagged) & txq->ptr_mask;
+ if (__predict_false(tso_start_new_packet(txq, &tso, &id)))
return (-1);
while (1) {
- id = (id + 1) & txq->ptr_mask;
tso_fill_packet_with_fragment(txq, &tso);
+ /* Exactly one DMA descriptor is added */
+ KASSERT(txq->stmp[id].flags == 0, ("stmp flags are not 0"));
+ id = (id + 1) & txq->ptr_mask;
/* Move onto the next fragment? */
if (tso.in_len == 0) {
@@ -1064,18 +1159,17 @@ sfxge_tx_queue_tso(struct sfxge_txq *txq, struct mbuf *mbuf,
* the remainder of the input mbuf but do not
* roll back the work we have done.
*/
- if (txq->n_pend_desc + 1 /* header */ + n_dma_seg >
- SFXGE_TSO_MAX_DESC) {
+ if (txq->n_pend_desc + tso.fw_assisted +
+ 1 /* header */ + n_dma_seg >
+ txq->max_pkt_desc) {
txq->tso_pdrop_too_many++;
break;
}
- next_id = (id + 1) & txq->ptr_mask;
if (__predict_false(tso_start_new_packet(txq, &tso,
- next_id))) {
+ &id))) {
txq->tso_pdrop_no_rsrc++;
break;
}
- id = next_id;
}
}
@@ -1128,38 +1222,52 @@ sfxge_tx_qstop(struct sfxge_softc *sc, unsigned int index)
struct sfxge_evq *evq;
unsigned int count;
+ SFXGE_ADAPTER_LOCK_ASSERT_OWNED(sc);
+
txq = sc->txq[index];
evq = sc->evq[txq->evq_index];
+ SFXGE_EVQ_LOCK(evq);
SFXGE_TXQ_LOCK(txq);
KASSERT(txq->init_state == SFXGE_TXQ_STARTED,
("txq->init_state != SFXGE_TXQ_STARTED"));
txq->init_state = SFXGE_TXQ_INITIALIZED;
- txq->flush_state = SFXGE_FLUSH_PENDING;
-
- /* Flush the transmit queue. */
- efx_tx_qflush(txq->common);
-
- SFXGE_TXQ_UNLOCK(txq);
- count = 0;
- do {
- /* Spin for 100ms. */
- DELAY(100000);
+ if (txq->flush_state != SFXGE_FLUSH_DONE) {
+ txq->flush_state = SFXGE_FLUSH_PENDING;
- if (txq->flush_state != SFXGE_FLUSH_PENDING)
- break;
- } while (++count < 20);
+ SFXGE_EVQ_UNLOCK(evq);
+ SFXGE_TXQ_UNLOCK(txq);
- SFXGE_EVQ_LOCK(evq);
- SFXGE_TXQ_LOCK(txq);
+ /* Flush the transmit queue. */
+ if (efx_tx_qflush(txq->common) != 0) {
+ log(LOG_ERR, "%s: Flushing Tx queue %u failed\n",
+ device_get_nameunit(sc->dev), index);
+ txq->flush_state = SFXGE_FLUSH_DONE;
+ } else {
+ count = 0;
+ do {
+ /* Spin for 100ms. */
+ DELAY(100000);
+ if (txq->flush_state != SFXGE_FLUSH_PENDING)
+ break;
+ } while (++count < 20);
+ }
+ SFXGE_EVQ_LOCK(evq);
+ SFXGE_TXQ_LOCK(txq);
- KASSERT(txq->flush_state != SFXGE_FLUSH_FAILED,
- ("txq->flush_state == SFXGE_FLUSH_FAILED"));
+ KASSERT(txq->flush_state != SFXGE_FLUSH_FAILED,
+ ("txq->flush_state == SFXGE_FLUSH_FAILED"));
- txq->flush_state = SFXGE_FLUSH_DONE;
+ if (txq->flush_state != SFXGE_FLUSH_DONE) {
+ /* Flush timeout */
+ log(LOG_ERR, "%s: Cannot flush Tx queue %u\n",
+ device_get_nameunit(sc->dev), index);
+ txq->flush_state = SFXGE_FLUSH_DONE;
+ }
+ }
txq->blocked = 0;
txq->pending = txq->added;
@@ -1195,8 +1303,11 @@ sfxge_tx_qstart(struct sfxge_softc *sc, unsigned int index)
efsys_mem_t *esmp;
uint16_t flags;
struct sfxge_evq *evq;
+ unsigned int desc_index;
int rc;
+ SFXGE_ADAPTER_LOCK_ASSERT_OWNED(sc);
+
txq = sc->txq[index];
esmp = &txq->mem;
evq = sc->evq[txq->evq_index];
@@ -1231,15 +1342,19 @@ sfxge_tx_qstart(struct sfxge_softc *sc, unsigned int index)
/* Create the common code transmit queue. */
if ((rc = efx_tx_qcreate(sc->enp, index, txq->type, esmp,
sc->txq_entries, txq->buf_base_id, flags, evq->common,
- &txq->common)) != 0)
+ &txq->common, &desc_index)) != 0)
goto fail;
+ /* Initialise queue descriptor indexes */
+ txq->added = txq->pending = txq->completed = txq->reaped = desc_index;
+
SFXGE_TXQ_LOCK(txq);
/* Enable the transmit queue. */
efx_tx_qenable(txq->common);
txq->init_state = SFXGE_TXQ_STARTED;
+ txq->flush_state = SFXGE_FLUSH_REQUIRED;
SFXGE_TXQ_UNLOCK(txq);
@@ -1348,9 +1463,41 @@ sfxge_tx_qfini(struct sfxge_softc *sc, unsigned int index)
free(txq, M_SFXGE);
}
+/*
+ * Estimate maximum number of Tx descriptors required for TSO packet.
+ * With minimum MSS and maximum mbuf length we might need more (even
+ * than a ring-ful of descriptors), but this should not happen in
+ * practice except due to deliberate attack. In that case we will
+ * truncate the output at a packet boundary.
+ */
+static unsigned int
+sfxge_tx_max_pkt_desc(const struct sfxge_softc *sc, enum sfxge_txq_type type)
+{
+ /* One descriptor for every input fragment */
+ unsigned int max_descs = SFXGE_TX_MAPPING_MAX_SEG;
+
+ /* VLAN tagging Tx option descriptor may be required */
+ if (efx_nic_cfg_get(sc->enp)->enc_hw_tx_insert_vlan_enabled)
+ max_descs++;
+
+ if (type == SFXGE_TXQ_IP_TCP_UDP_CKSUM) {
+ /*
+ * Plus header and payload descriptor for each output segment.
+ * Minus one since header fragment is already counted.
+ */
+ max_descs += SFXGE_TSO_MAX_SEGS * 2 - 1;
+
+ /* FW assisted TSO requires one more descriptor per segment */
+ if (sc->tso_fw_assisted)
+ max_descs += SFXGE_TSO_MAX_SEGS;
+ }
+
+ return (max_descs);
+}
+
static int
sfxge_tx_qinit(struct sfxge_softc *sc, unsigned int txq_index,
- enum sfxge_txq_type type, unsigned int evq_index)
+ enum sfxge_txq_type type, unsigned int evq_index)
{
char name[16];
struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
@@ -1392,7 +1539,7 @@ sfxge_tx_qinit(struct sfxge_softc *sc, unsigned int txq_index,
}
/* Allocate pending descriptor array for batching writes. */
- txq->pend_desc = malloc(sizeof(efx_buffer_t) * sc->txq_entries,
+ txq->pend_desc = malloc(sizeof(efx_desc_t) * sc->txq_entries,
M_SFXGE, M_ZERO | M_WAITOK);
/* Allocate and initialise mbuf DMA mapping array. */
@@ -1475,6 +1622,9 @@ sfxge_tx_qinit(struct sfxge_softc *sc, unsigned int txq_index,
txq->evq_index = evq_index;
txq->txq_index = txq_index;
txq->init_state = SFXGE_TXQ_INITIALIZED;
+ txq->hw_vlan_tci = 0;
+
+ txq->max_pkt_desc = sfxge_tx_max_pkt_desc(sc, type);
return (0);
@@ -1549,6 +1699,7 @@ sfxge_tx_fini(struct sfxge_softc *sc)
int
sfxge_tx_init(struct sfxge_softc *sc)
{
+ const efx_nic_cfg_t *encp = efx_nic_cfg_get(sc->enp);
struct sfxge_intr *intr;
int index;
int rc;
@@ -1560,6 +1711,12 @@ sfxge_tx_init(struct sfxge_softc *sc)
sc->txq_count = SFXGE_TXQ_NTYPES - 1 + sc->intr.n_alloc;
+ sc->tso_fw_assisted = sfxge_tso_fw_assisted;
+ if (sc->tso_fw_assisted)
+ sc->tso_fw_assisted =
+ (encp->enc_features & EFX_FEATURE_FW_ASSISTED_TSO) &&
+ (encp->enc_fw_assisted_tso_enabled);
+
sc->txqs_node = SYSCTL_ADD_NODE(
device_get_sysctl_ctx(sc->dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)),
diff --git a/sys/dev/sfxge/sfxge_tx.h b/sys/dev/sfxge/sfxge_tx.h
index fe53186..67bedc2 100644
--- a/sys/dev/sfxge/sfxge_tx.h
+++ b/sys/dev/sfxge/sfxge_tx.h
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2010-2011 Solarflare Communications, Inc.
+ * Copyright (c) 2010-2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by Philip Paeps under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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.
*
* $FreeBSD$
*/
@@ -164,10 +168,11 @@ struct sfxge_txq {
unsigned int buf_base_id;
unsigned int entries;
unsigned int ptr_mask;
+ unsigned int max_pkt_desc;
struct sfxge_tx_mapping *stmp; /* Packets in flight. */
bus_dma_tag_t packet_dma_tag;
- efx_buffer_t *pend_desc;
+ efx_desc_t *pend_desc;
efx_txq_t *common;
efsys_mem_t *tsoh_buffer;
@@ -187,6 +192,11 @@ struct sfxge_txq {
unsigned int n_pend_desc;
unsigned int added;
unsigned int reaped;
+
+ /* The last VLAN TCI seen on the queue if FW-assisted tagging is
+ used */
+ uint16_t hw_vlan_tci;
+
/* Statistics */
unsigned long tso_bursts;
unsigned long tso_packets;
@@ -210,7 +220,6 @@ struct sfxge_txq {
struct sfxge_evq;
-extern int sfxge_tx_packet_add(struct sfxge_txq *, struct mbuf *);
extern int sfxge_tx_init(struct sfxge_softc *sc);
extern void sfxge_tx_fini(struct sfxge_softc *sc);
diff --git a/sys/dev/sfxge/sfxge_version.h b/sys/dev/sfxge/sfxge_version.h
index e23ce14..5228fff 100644
--- a/sys/dev/sfxge/sfxge_version.h
+++ b/sys/dev/sfxge/sfxge_version.h
@@ -1,30 +1,34 @@
/*-
- * Copyright (c) 2015 Solarflare Communications, Inc.
+ * Copyright (c) 2015 Solarflare Communications Inc.
* All rights reserved.
*
* This software was developed in part by OKTET Labs under contract for
* Solarflare Communications, Inc.
*
* 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.
+ * modification, are permitted provided that the following conditions are met:
*
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ * 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.
*
* $FreeBSD$
*/
@@ -32,6 +36,6 @@
#ifndef _SFXGE_VERSION_H
#define _SFXGE_VERSION_H
-#define SFXGE_VERSION_STRING "v3.3.4.6363"
+#define SFXGE_VERSION_STRING "v4.5.1.1018"
#endif /* _SFXGE_DRIVER_VERSION_H */
diff --git a/sys/modules/sfxge/Makefile b/sys/modules/sfxge/Makefile
index c627a57..f6d5f07 100644
--- a/sys/modules/sfxge/Makefile
+++ b/sys/modules/sfxge/Makefile
@@ -11,22 +11,31 @@ SRCS+= opt_inet.h opt_inet6.h opt_sched.h
.PATH: ${.CURDIR}/../../dev/sfxge
SRCS+= sfxge.c sfxge_dma.c sfxge_ev.c
-SRCS+= sfxge_intr.c sfxge_mcdi.c
+SRCS+= sfxge_intr.c sfxge_mcdi.c sfxge_nvram.c
SRCS+= sfxge_port.c sfxge_rx.c sfxge_tx.c
SRCS+= sfxge.h sfxge_rx.h sfxge_tx.h sfxge_version.h
.PATH: ${.CURDIR}/../../dev/sfxge/common
-SRCS+= efx_ev.c efx_intr.c efx_mac.c efx_mcdi.c efx_nic.c
+SRCS+= efx_bootcfg.c efx_crc32.c efx_ev.c efx_intr.c efx_mac.c
+SRCS+= efx_mcdi.c efx_mon.c efx_nic.c
SRCS+= efx_nvram.c efx_phy.c efx_port.c efx_rx.c efx_sram.c efx_tx.c
-SRCS+= efx_vpd.c efx_wol.c
+SRCS+= efx_vpd.c efx_wol.c efx_filter.c efx_hash.c
SRCS+= efsys.h
-SRCS+= efx.h efx_impl.h efx_mcdi.h efx_regs.h efx_regs_ef10.h
-SRCS+= efx_regs_mcdi.h efx_regs_pci.h efx_types.h
+SRCS+= efx.h efx_check.h efx_impl.h efx_mcdi.h efx_regs.h efx_regs_ef10.h
+SRCS+= efx_regs_mcdi.h efx_regs_pci.h efx_types.h efx_phy_ids.h
+SRCS+= ef10_tlv_layout.h
-SRCS+= siena_mac.c siena_nic.c siena_nvram.c siena_phy.c
+SRCS+= mcdi_mon.c mcdi_mon.h
+
+SRCS+= siena_mac.c siena_mcdi.c siena_nic.c siena_nvram.c siena_phy.c
SRCS+= siena_sram.c siena_vpd.c
SRCS+= siena_flash.h siena_impl.h
+SRCS+= hunt_ev.c hunt_intr.c hunt_mac.c hunt_mcdi.c hunt_nic.c
+SRCS+= hunt_nvram.c hunt_rx.c hunt_phy.c hunt_sram.c hunt_tx.c hunt_vpd.c
+SRCS+= hunt_filter.c
+SRCS+= hunt_impl.h
+
DEBUG_FLAGS= -DDEBUG=1
.if !defined(KERNBUILDDIR)
OpenPOWER on IntegriCloud