diff options
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) |