summaryrefslogtreecommitdiff
path: root/drivers/net/iavf
diff options
context:
space:
mode:
authorLeyi Rong <leyi.rong@intel.com>2019-02-26 01:18:51 +0800
committerFerruh Yigit <ferruh.yigit@intel.com>2019-03-01 18:17:35 +0100
commit3ded348378a76622e22a9017455de02c8c4048b5 (patch)
tree306060c8b59ce2d2c49690fd776d85061d167aaf /drivers/net/iavf
parent4bcb9b7686043fe9a4e669f2d7f5acee603f5409 (diff)
downloaddpdk-next-eventdev-3ded348378a76622e22a9017455de02c8c4048b5.zip
dpdk-next-eventdev-3ded348378a76622e22a9017455de02c8c4048b5.tar.gz
dpdk-next-eventdev-3ded348378a76622e22a9017455de02c8c4048b5.tar.xz
net/iavf: rename avf to iavf
Rename Intel Ethernet Adaptive Virtual Function driver avf to iavf. This is the first patch which will only renames the directory name, lib name, filenames and updates the new name in makefile and meson files. Also updates the #include files in source files. Signed-off-by: Leyi Rong <leyi.rong@intel.com> Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
Diffstat (limited to 'drivers/net/iavf')
-rw-r--r--drivers/net/iavf/Makefile54
-rw-r--r--drivers/net/iavf/base/README19
-rw-r--r--drivers/net/iavf/base/iavf_adminq.c1010
-rw-r--r--drivers/net/iavf/base/iavf_adminq.h166
-rw-r--r--drivers/net/iavf/base/iavf_adminq_cmd.h2841
-rw-r--r--drivers/net/iavf/base/iavf_alloc.h65
-rw-r--r--drivers/net/iavf/base/iavf_common.c1845
-rw-r--r--drivers/net/iavf/base/iavf_devids.h43
-rw-r--r--drivers/net/iavf/base/iavf_hmc.h245
-rw-r--r--drivers/net/iavf/base/iavf_lan_hmc.h200
-rw-r--r--drivers/net/iavf/base/iavf_osdep.h187
-rw-r--r--drivers/net/iavf/base/iavf_prototype.h206
-rw-r--r--drivers/net/iavf/base/iavf_register.h346
-rw-r--r--drivers/net/iavf/base/iavf_status.h108
-rw-r--r--drivers/net/iavf/base/iavf_type.h2024
-rw-r--r--drivers/net/iavf/base/meson.build23
-rw-r--r--drivers/net/iavf/base/virtchnl.h787
-rw-r--r--drivers/net/iavf/iavf.h216
-rw-r--r--drivers/net/iavf/iavf_ethdev.c1428
-rw-r--r--drivers/net/iavf/iavf_log.h44
-rw-r--r--drivers/net/iavf/iavf_rxtx.c1955
-rw-r--r--drivers/net/iavf/iavf_rxtx.h268
-rw-r--r--drivers/net/iavf/iavf_rxtx_vec_common.h210
-rw-r--r--drivers/net/iavf/iavf_rxtx_vec_sse.c656
-rw-r--r--drivers/net/iavf/iavf_vchnl.c810
-rw-r--r--drivers/net/iavf/meson.build20
-rw-r--r--drivers/net/iavf/rte_pmd_iavf_version.map4
27 files changed, 15780 insertions, 0 deletions
diff --git a/drivers/net/iavf/Makefile b/drivers/net/iavf/Makefile
new file mode 100644
index 0000000..29ff3c2
--- /dev/null
+++ b/drivers/net/iavf/Makefile
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2017 Intel Corporation
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_iavf.a
+
+CFLAGS += -O3 $(WERROR_FLAGS) -Wno-strict-aliasing -DALLOW_EXPERIMENTAL_API
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
+LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
+LDLIBS += -lrte_bus_pci
+
+# used to dump HW descriptor for debugging
+# CFLAGS += -DDEBUG_DUMP_DESC
+
+EXPORT_MAP := rte_pmd_iavf_version.map
+
+LIBABIVER := 1
+
+#
+# Add extra flags for base driver files (also known as shared code)
+# to disable warnings
+#
+ifeq ($(CONFIG_RTE_TOOLCHAIN_ICC),y)
+CFLAGS_BASE_DRIVER =
+else ifeq ($(CONFIG_RTE_TOOLCHAIN_CLANG),y)
+CFLAGS_BASE_DRIVER = -Wno-pointer-to-int-cast
+else
+CFLAGS_BASE_DRIVER = -Wno-pointer-to-int-cast
+
+endif
+OBJS_BASE_DRIVER=$(sort $(patsubst %.c,%.o,$(notdir $(wildcard $(SRCDIR)/base/*.c))))
+$(foreach obj, $(OBJS_BASE_DRIVER), $(eval CFLAGS_$(obj)+=$(CFLAGS_BASE_DRIVER)))
+
+
+VPATH += $(SRCDIR)/base
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_AVF_PMD) += iavf_adminq.c
+SRCS-$(CONFIG_RTE_LIBRTE_AVF_PMD) += iavf_common.c
+
+SRCS-$(CONFIG_RTE_LIBRTE_AVF_PMD) += iavf_ethdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_AVF_PMD) += iavf_vchnl.c
+SRCS-$(CONFIG_RTE_LIBRTE_AVF_PMD) += iavf_rxtx.c
+ifeq ($(CONFIG_RTE_ARCH_X86), y)
+SRCS-$(CONFIG_RTE_LIBRTE_AVF_INC_VECTOR) += iavf_rxtx_vec_sse.c
+endif
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/iavf/base/README b/drivers/net/iavf/base/README
new file mode 100644
index 0000000..4710ae2
--- /dev/null
+++ b/drivers/net/iavf/base/README
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017 Intel Corporation
+ */
+
+IntelĀ® AVF driver
+=================
+
+This directory contains source code of FreeBSD AVF driver of version
+cid-avf.2018.01.02.tar.gz released by the team which develops
+basic drivers for any AVF NIC. The directory of base/ contains the
+original source package.
+
+Updating the driver
+===================
+
+NOTE: The source code in this directory should not be modified apart from
+the following file(s):
+
+ avf_osdep.h
diff --git a/drivers/net/iavf/base/iavf_adminq.c b/drivers/net/iavf/base/iavf_adminq.c
new file mode 100644
index 0000000..9d16f0f
--- /dev/null
+++ b/drivers/net/iavf/base/iavf_adminq.c
@@ -0,0 +1,1010 @@
+/*******************************************************************************
+
+Copyright (c) 2013 - 2015, Intel Corporation
+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.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+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.
+
+***************************************************************************/
+
+#include "iavf_status.h"
+#include "iavf_type.h"
+#include "iavf_register.h"
+#include "iavf_adminq.h"
+#include "iavf_prototype.h"
+
+/**
+ * avf_adminq_init_regs - Initialize AdminQ registers
+ * @hw: pointer to the hardware structure
+ *
+ * This assumes the alloc_asq and alloc_arq functions have already been called
+ **/
+STATIC void avf_adminq_init_regs(struct avf_hw *hw)
+{
+ /* set head and tail registers in our local struct */
+ if (avf_is_vf(hw)) {
+ hw->aq.asq.tail = AVF_ATQT1;
+ hw->aq.asq.head = AVF_ATQH1;
+ hw->aq.asq.len = AVF_ATQLEN1;
+ hw->aq.asq.bal = AVF_ATQBAL1;
+ hw->aq.asq.bah = AVF_ATQBAH1;
+ hw->aq.arq.tail = AVF_ARQT1;
+ hw->aq.arq.head = AVF_ARQH1;
+ hw->aq.arq.len = AVF_ARQLEN1;
+ hw->aq.arq.bal = AVF_ARQBAL1;
+ hw->aq.arq.bah = AVF_ARQBAH1;
+ }
+}
+
+/**
+ * avf_alloc_adminq_asq_ring - Allocate Admin Queue send rings
+ * @hw: pointer to the hardware structure
+ **/
+enum avf_status_code avf_alloc_adminq_asq_ring(struct avf_hw *hw)
+{
+ enum avf_status_code ret_code;
+
+ ret_code = avf_allocate_dma_mem(hw, &hw->aq.asq.desc_buf,
+ avf_mem_atq_ring,
+ (hw->aq.num_asq_entries *
+ sizeof(struct avf_aq_desc)),
+ AVF_ADMINQ_DESC_ALIGNMENT);
+ if (ret_code)
+ return ret_code;
+
+ ret_code = avf_allocate_virt_mem(hw, &hw->aq.asq.cmd_buf,
+ (hw->aq.num_asq_entries *
+ sizeof(struct avf_asq_cmd_details)));
+ if (ret_code) {
+ avf_free_dma_mem(hw, &hw->aq.asq.desc_buf);
+ return ret_code;
+ }
+
+ return ret_code;
+}
+
+/**
+ * avf_alloc_adminq_arq_ring - Allocate Admin Queue receive rings
+ * @hw: pointer to the hardware structure
+ **/
+enum avf_status_code avf_alloc_adminq_arq_ring(struct avf_hw *hw)
+{
+ enum avf_status_code ret_code;
+
+ ret_code = avf_allocate_dma_mem(hw, &hw->aq.arq.desc_buf,
+ avf_mem_arq_ring,
+ (hw->aq.num_arq_entries *
+ sizeof(struct avf_aq_desc)),
+ AVF_ADMINQ_DESC_ALIGNMENT);
+
+ return ret_code;
+}
+
+/**
+ * avf_free_adminq_asq - Free Admin Queue send rings
+ * @hw: pointer to the hardware structure
+ *
+ * This assumes the posted send buffers have already been cleaned
+ * and de-allocated
+ **/
+void avf_free_adminq_asq(struct avf_hw *hw)
+{
+ avf_free_dma_mem(hw, &hw->aq.asq.desc_buf);
+}
+
+/**
+ * avf_free_adminq_arq - Free Admin Queue receive rings
+ * @hw: pointer to the hardware structure
+ *
+ * This assumes the posted receive buffers have already been cleaned
+ * and de-allocated
+ **/
+void avf_free_adminq_arq(struct avf_hw *hw)
+{
+ avf_free_dma_mem(hw, &hw->aq.arq.desc_buf);
+}
+
+/**
+ * avf_alloc_arq_bufs - Allocate pre-posted buffers for the receive queue
+ * @hw: pointer to the hardware structure
+ **/
+STATIC enum avf_status_code avf_alloc_arq_bufs(struct avf_hw *hw)
+{
+ enum avf_status_code ret_code;
+ struct avf_aq_desc *desc;
+ struct avf_dma_mem *bi;
+ int i;
+
+ /* We'll be allocating the buffer info memory first, then we can
+ * allocate the mapped buffers for the event processing
+ */
+
+ /* buffer_info structures do not need alignment */
+ ret_code = avf_allocate_virt_mem(hw, &hw->aq.arq.dma_head,
+ (hw->aq.num_arq_entries * sizeof(struct avf_dma_mem)));
+ if (ret_code)
+ goto alloc_arq_bufs;
+ hw->aq.arq.r.arq_bi = (struct avf_dma_mem *)hw->aq.arq.dma_head.va;
+
+ /* allocate the mapped buffers */
+ for (i = 0; i < hw->aq.num_arq_entries; i++) {
+ bi = &hw->aq.arq.r.arq_bi[i];
+ ret_code = avf_allocate_dma_mem(hw, bi,
+ avf_mem_arq_buf,
+ hw->aq.arq_buf_size,
+ AVF_ADMINQ_DESC_ALIGNMENT);
+ if (ret_code)
+ goto unwind_alloc_arq_bufs;
+
+ /* now configure the descriptors for use */
+ desc = AVF_ADMINQ_DESC(hw->aq.arq, i);
+
+ desc->flags = CPU_TO_LE16(AVF_AQ_FLAG_BUF);
+ if (hw->aq.arq_buf_size > AVF_AQ_LARGE_BUF)
+ desc->flags |= CPU_TO_LE16(AVF_AQ_FLAG_LB);
+ desc->opcode = 0;
+ /* This is in accordance with Admin queue design, there is no
+ * register for buffer size configuration
+ */
+ desc->datalen = CPU_TO_LE16((u16)bi->size);
+ desc->retval = 0;
+ desc->cookie_high = 0;
+ desc->cookie_low = 0;
+ desc->params.external.addr_high =
+ CPU_TO_LE32(AVF_HI_DWORD(bi->pa));
+ desc->params.external.addr_low =
+ CPU_TO_LE32(AVF_LO_DWORD(bi->pa));
+ desc->params.external.param0 = 0;
+ desc->params.external.param1 = 0;
+ }
+
+alloc_arq_bufs:
+ return ret_code;
+
+unwind_alloc_arq_bufs:
+ /* don't try to free the one that failed... */
+ i--;
+ for (; i >= 0; i--)
+ avf_free_dma_mem(hw, &hw->aq.arq.r.arq_bi[i]);
+ avf_free_virt_mem(hw, &hw->aq.arq.dma_head);
+
+ return ret_code;
+}
+
+/**
+ * avf_alloc_asq_bufs - Allocate empty buffer structs for the send queue
+ * @hw: pointer to the hardware structure
+ **/
+STATIC enum avf_status_code avf_alloc_asq_bufs(struct avf_hw *hw)
+{
+ enum avf_status_code ret_code;
+ struct avf_dma_mem *bi;
+ int i;
+
+ /* No mapped memory needed yet, just the buffer info structures */
+ ret_code = avf_allocate_virt_mem(hw, &hw->aq.asq.dma_head,
+ (hw->aq.num_asq_entries * sizeof(struct avf_dma_mem)));
+ if (ret_code)
+ goto alloc_asq_bufs;
+ hw->aq.asq.r.asq_bi = (struct avf_dma_mem *)hw->aq.asq.dma_head.va;
+
+ /* allocate the mapped buffers */
+ for (i = 0; i < hw->aq.num_asq_entries; i++) {
+ bi = &hw->aq.asq.r.asq_bi[i];
+ ret_code = avf_allocate_dma_mem(hw, bi,
+ avf_mem_asq_buf,
+ hw->aq.asq_buf_size,
+ AVF_ADMINQ_DESC_ALIGNMENT);
+ if (ret_code)
+ goto unwind_alloc_asq_bufs;
+ }
+alloc_asq_bufs:
+ return ret_code;
+
+unwind_alloc_asq_bufs:
+ /* don't try to free the one that failed... */
+ i--;
+ for (; i >= 0; i--)
+ avf_free_dma_mem(hw, &hw->aq.asq.r.asq_bi[i]);
+ avf_free_virt_mem(hw, &hw->aq.asq.dma_head);
+
+ return ret_code;
+}
+
+/**
+ * avf_free_arq_bufs - Free receive queue buffer info elements
+ * @hw: pointer to the hardware structure
+ **/
+STATIC void avf_free_arq_bufs(struct avf_hw *hw)
+{
+ int i;
+
+ /* free descriptors */
+ for (i = 0; i < hw->aq.num_arq_entries; i++)
+ avf_free_dma_mem(hw, &hw->aq.arq.r.arq_bi[i]);
+
+ /* free the descriptor memory */
+ avf_free_dma_mem(hw, &hw->aq.arq.desc_buf);
+
+ /* free the dma header */
+ avf_free_virt_mem(hw, &hw->aq.arq.dma_head);
+}
+
+/**
+ * avf_free_asq_bufs - Free send queue buffer info elements
+ * @hw: pointer to the hardware structure
+ **/
+STATIC void avf_free_asq_bufs(struct avf_hw *hw)
+{
+ int i;
+
+ /* only unmap if the address is non-NULL */
+ for (i = 0; i < hw->aq.num_asq_entries; i++)
+ if (hw->aq.asq.r.asq_bi[i].pa)
+ avf_free_dma_mem(hw, &hw->aq.asq.r.asq_bi[i]);
+
+ /* free the buffer info list */
+ avf_free_virt_mem(hw, &hw->aq.asq.cmd_buf);
+
+ /* free the descriptor memory */
+ avf_free_dma_mem(hw, &hw->aq.asq.desc_buf);
+
+ /* free the dma header */
+ avf_free_virt_mem(hw, &hw->aq.asq.dma_head);
+}
+
+/**
+ * avf_config_asq_regs - configure ASQ registers
+ * @hw: pointer to the hardware structure
+ *
+ * Configure base address and length registers for the transmit queue
+ **/
+STATIC enum avf_status_code avf_config_asq_regs(struct avf_hw *hw)
+{
+ enum avf_status_code ret_code = AVF_SUCCESS;
+ u32 reg = 0;
+
+ /* Clear Head and Tail */
+ wr32(hw, hw->aq.asq.head, 0);
+ wr32(hw, hw->aq.asq.tail, 0);
+
+ /* set starting point */
+#ifdef INTEGRATED_VF
+ if (avf_is_vf(hw))
+ wr32(hw, hw->aq.asq.len, (hw->aq.num_asq_entries |
+ AVF_ATQLEN1_ATQENABLE_MASK));
+#else
+ wr32(hw, hw->aq.asq.len, (hw->aq.num_asq_entries |
+ AVF_ATQLEN1_ATQENABLE_MASK));
+#endif /* INTEGRATED_VF */
+ wr32(hw, hw->aq.asq.bal, AVF_LO_DWORD(hw->aq.asq.desc_buf.pa));
+ wr32(hw, hw->aq.asq.bah, AVF_HI_DWORD(hw->aq.asq.desc_buf.pa));
+
+ /* Check one register to verify that config was applied */
+ reg = rd32(hw, hw->aq.asq.bal);
+ if (reg != AVF_LO_DWORD(hw->aq.asq.desc_buf.pa))
+ ret_code = AVF_ERR_ADMIN_QUEUE_ERROR;
+
+ return ret_code;
+}
+
+/**
+ * avf_config_arq_regs - ARQ register configuration
+ * @hw: pointer to the hardware structure
+ *
+ * Configure base address and length registers for the receive (event queue)
+ **/
+STATIC enum avf_status_code avf_config_arq_regs(struct avf_hw *hw)
+{
+ enum avf_status_code ret_code = AVF_SUCCESS;
+ u32 reg = 0;
+
+ /* Clear Head and Tail */
+ wr32(hw, hw->aq.arq.head, 0);
+ wr32(hw, hw->aq.arq.tail, 0);
+
+ /* set starting point */
+#ifdef INTEGRATED_VF
+ if (avf_is_vf(hw))
+ wr32(hw, hw->aq.arq.len, (hw->aq.num_arq_entries |
+ AVF_ARQLEN1_ARQENABLE_MASK));
+#else
+ wr32(hw, hw->aq.arq.len, (hw->aq.num_arq_entries |
+ AVF_ARQLEN1_ARQENABLE_MASK));
+#endif /* INTEGRATED_VF */
+ wr32(hw, hw->aq.arq.bal, AVF_LO_DWORD(hw->aq.arq.desc_buf.pa));
+ wr32(hw, hw->aq.arq.bah, AVF_HI_DWORD(hw->aq.arq.desc_buf.pa));
+
+ /* Update tail in the HW to post pre-allocated buffers */
+ wr32(hw, hw->aq.arq.tail, hw->aq.num_arq_entries - 1);
+
+ /* Check one register to verify that config was applied */
+ reg = rd32(hw, hw->aq.arq.bal);
+ if (reg != AVF_LO_DWORD(hw->aq.arq.desc_buf.pa))
+ ret_code = AVF_ERR_ADMIN_QUEUE_ERROR;
+
+ return ret_code;
+}
+
+/**
+ * avf_init_asq - main initialization routine for ASQ
+ * @hw: pointer to the hardware structure
+ *
+ * This is the main initialization routine for the Admin Send Queue
+ * Prior to calling this function, drivers *MUST* set the following fields
+ * in the hw->aq structure:
+ * - hw->aq.num_asq_entries
+ * - hw->aq.arq_buf_size
+ *
+ * Do *NOT* hold the lock when calling this as the memory allocation routines
+ * called are not going to be atomic context safe
+ **/
+enum avf_status_code avf_init_asq(struct avf_hw *hw)
+{
+ enum avf_status_code ret_code = AVF_SUCCESS;
+
+ if (hw->aq.asq.count > 0) {
+ /* queue already initialized */
+ ret_code = AVF_ERR_NOT_READY;
+ goto init_adminq_exit;
+ }
+
+ /* verify input for valid configuration */
+ if ((hw->aq.num_asq_entries == 0) ||
+ (hw->aq.asq_buf_size == 0)) {
+ ret_code = AVF_ERR_CONFIG;
+ goto init_adminq_exit;
+ }
+
+ hw->aq.asq.next_to_use = 0;
+ hw->aq.asq.next_to_clean = 0;
+
+ /* allocate the ring memory */
+ ret_code = avf_alloc_adminq_asq_ring(hw);
+ if (ret_code != AVF_SUCCESS)
+ goto init_adminq_exit;
+
+ /* allocate buffers in the rings */
+ ret_code = avf_alloc_asq_bufs(hw);
+ if (ret_code != AVF_SUCCESS)
+ goto init_adminq_free_rings;
+
+ /* initialize base registers */
+ ret_code = avf_config_asq_regs(hw);
+ if (ret_code != AVF_SUCCESS)
+ goto init_adminq_free_rings;
+
+ /* success! */
+ hw->aq.asq.count = hw->aq.num_asq_entries;
+ goto init_adminq_exit;
+
+init_adminq_free_rings:
+ avf_free_adminq_asq(hw);
+
+init_adminq_exit:
+ return ret_code;
+}
+
+/**
+ * avf_init_arq - initialize ARQ
+ * @hw: pointer to the hardware structure
+ *
+ * The main initialization routine for the Admin Receive (Event) Queue.
+ * Prior to calling this function, drivers *MUST* set the following fields
+ * in the hw->aq structure:
+ * - hw->aq.num_asq_entries
+ * - hw->aq.arq_buf_size
+ *
+ * Do *NOT* hold the lock when calling this as the memory allocation routines
+ * called are not going to be atomic context safe
+ **/
+enum avf_status_code avf_init_arq(struct avf_hw *hw)
+{
+ enum avf_status_code ret_code = AVF_SUCCESS;
+
+ if (hw->aq.arq.count > 0) {
+ /* queue already initialized */
+ ret_code = AVF_ERR_NOT_READY;
+ goto init_adminq_exit;
+ }
+
+ /* verify input for valid configuration */
+ if ((hw->aq.num_arq_entries == 0) ||
+ (hw->aq.arq_buf_size == 0)) {
+ ret_code = AVF_ERR_CONFIG;
+ goto init_adminq_exit;
+ }
+
+ hw->aq.arq.next_to_use = 0;
+ hw->aq.arq.next_to_clean = 0;
+
+ /* allocate the ring memory */
+ ret_code = avf_alloc_adminq_arq_ring(hw);
+ if (ret_code != AVF_SUCCESS)
+ goto init_adminq_exit;
+
+ /* allocate buffers in the rings */
+ ret_code = avf_alloc_arq_bufs(hw);
+ if (ret_code != AVF_SUCCESS)
+ goto init_adminq_free_rings;
+
+ /* initialize base registers */
+ ret_code = avf_config_arq_regs(hw);
+ if (ret_code != AVF_SUCCESS)
+ goto init_adminq_free_rings;
+
+ /* success! */
+ hw->aq.arq.count = hw->aq.num_arq_entries;
+ goto init_adminq_exit;
+
+init_adminq_free_rings:
+ avf_free_adminq_arq(hw);
+
+init_adminq_exit:
+ return ret_code;
+}
+
+/**
+ * avf_shutdown_asq - shutdown the ASQ
+ * @hw: pointer to the hardware structure
+ *
+ * The main shutdown routine for the Admin Send Queue
+ **/
+enum avf_status_code avf_shutdown_asq(struct avf_hw *hw)
+{
+ enum avf_status_code ret_code = AVF_SUCCESS;
+
+ avf_acquire_spinlock(&hw->aq.asq_spinlock);
+
+ if (hw->aq.asq.count == 0) {
+ ret_code = AVF_ERR_NOT_READY;
+ goto shutdown_asq_out;
+ }
+
+ /* Stop firmware AdminQ processing */
+ wr32(hw, hw->aq.asq.head, 0);
+ wr32(hw, hw->aq.asq.tail, 0);
+ wr32(hw, hw->aq.asq.len, 0);
+ wr32(hw, hw->aq.asq.bal, 0);
+ wr32(hw, hw->aq.asq.bah, 0);
+
+ hw->aq.asq.count = 0; /* to indicate uninitialized queue */
+
+ /* free ring buffers */
+ avf_free_asq_bufs(hw);
+
+shutdown_asq_out:
+ avf_release_spinlock(&hw->aq.asq_spinlock);
+ return ret_code;
+}
+
+/**
+ * avf_shutdown_arq - shutdown ARQ
+ * @hw: pointer to the hardware structure
+ *
+ * The main shutdown routine for the Admin Receive Queue
+ **/
+enum avf_status_code avf_shutdown_arq(struct avf_hw *hw)
+{
+ enum avf_status_code ret_code = AVF_SUCCESS;
+
+ avf_acquire_spinlock(&hw->aq.arq_spinlock);
+
+ if (hw->aq.arq.count == 0) {
+ ret_code = AVF_ERR_NOT_READY;
+ goto shutdown_arq_out;
+ }
+
+ /* Stop firmware AdminQ processing */
+ wr32(hw, hw->aq.arq.head, 0);
+ wr32(hw, hw->aq.arq.tail, 0);
+ wr32(hw, hw->aq.arq.len, 0);
+ wr32(hw, hw->aq.arq.bal, 0);
+ wr32(hw, hw->aq.arq.bah, 0);
+
+ hw->aq.arq.count = 0; /* to indicate uninitialized queue */
+
+ /* free ring buffers */
+ avf_free_arq_bufs(hw);
+
+shutdown_arq_out:
+ avf_release_spinlock(&hw->aq.arq_spinlock);
+ return ret_code;
+}
+
+/**
+ * avf_init_adminq - main initialization routine for Admin Queue
+ * @hw: pointer to the hardware structure
+ *
+ * Prior to calling this function, drivers *MUST* set the following fields
+ * in the hw->aq structure:
+ * - hw->aq.num_asq_entries
+ * - hw->aq.num_arq_entries
+ * - hw->aq.arq_buf_size
+ * - hw->aq.asq_buf_size
+ **/
+enum avf_status_code avf_init_adminq(struct avf_hw *hw)
+{
+ enum avf_status_code ret_code;
+
+ /* verify input for valid configuration */
+ if ((hw->aq.num_arq_entries == 0) ||
+ (hw->aq.num_asq_entries == 0) ||
+ (hw->aq.arq_buf_size == 0) ||
+ (hw->aq.asq_buf_size == 0)) {
+ ret_code = AVF_ERR_CONFIG;
+ goto init_adminq_exit;
+ }
+ avf_init_spinlock(&hw->aq.asq_spinlock);
+ avf_init_spinlock(&hw->aq.arq_spinlock);
+
+ /* Set up register offsets */
+ avf_adminq_init_regs(hw);
+
+ /* setup ASQ command write back timeout */
+ hw->aq.asq_cmd_timeout = AVF_ASQ_CMD_TIMEOUT;
+
+ /* allocate the ASQ */
+ ret_code = avf_init_asq(hw);
+ if (ret_code != AVF_SUCCESS)
+ goto init_adminq_destroy_spinlocks;
+
+ /* allocate the ARQ */
+ ret_code = avf_init_arq(hw);
+ if (ret_code != AVF_SUCCESS)
+ goto init_adminq_free_asq;
+
+ ret_code = AVF_SUCCESS;
+
+ /* success! */
+ goto init_adminq_exit;
+
+init_adminq_free_asq:
+ avf_shutdown_asq(hw);
+init_adminq_destroy_spinlocks:
+ avf_destroy_spinlock(&hw->aq.asq_spinlock);
+ avf_destroy_spinlock(&hw->aq.arq_spinlock);
+
+init_adminq_exit:
+ return ret_code;
+}
+
+/**
+ * avf_shutdown_adminq - shutdown routine for the Admin Queue
+ * @hw: pointer to the hardware structure
+ **/
+enum avf_status_code avf_shutdown_adminq(struct avf_hw *hw)
+{
+ enum avf_status_code ret_code = AVF_SUCCESS;
+
+ if (avf_check_asq_alive(hw))
+ avf_aq_queue_shutdown(hw, true);
+
+ avf_shutdown_asq(hw);
+ avf_shutdown_arq(hw);
+ avf_destroy_spinlock(&hw->aq.asq_spinlock);
+ avf_destroy_spinlock(&hw->aq.arq_spinlock);
+
+ if (hw->nvm_buff.va)
+ avf_free_virt_mem(hw, &hw->nvm_buff);
+
+ return ret_code;
+}
+
+/**
+ * avf_clean_asq - cleans Admin send queue
+ * @hw: pointer to the hardware structure
+ *
+ * returns the number of free desc
+ **/
+u16 avf_clean_asq(struct avf_hw *hw)
+{
+ struct avf_adminq_ring *asq = &(hw->aq.asq);
+ struct avf_asq_cmd_details *details;
+ u16 ntc = asq->next_to_clean;
+ struct avf_aq_desc desc_cb;
+ struct avf_aq_desc *desc;
+
+ desc = AVF_ADMINQ_DESC(*asq, ntc);
+ details = AVF_ADMINQ_DETAILS(*asq, ntc);
+ while (rd32(hw, hw->aq.asq.head) != ntc) {
+ avf_debug(hw, AVF_DEBUG_AQ_MESSAGE,
+ "ntc %d head %d.\n", ntc, rd32(hw, hw->aq.asq.head));
+
+ if (details->callback) {
+ AVF_ADMINQ_CALLBACK cb_func =
+ (AVF_ADMINQ_CALLBACK)details->callback;
+ avf_memcpy(&desc_cb, desc, sizeof(struct avf_aq_desc),
+ AVF_DMA_TO_DMA);
+ cb_func(hw, &desc_cb);
+ }
+ avf_memset(desc, 0, sizeof(*desc), AVF_DMA_MEM);
+ avf_memset(details, 0, sizeof(*details), AVF_NONDMA_MEM);
+ ntc++;
+ if (ntc == asq->count)
+ ntc = 0;
+ desc = AVF_ADMINQ_DESC(*asq, ntc);
+ details = AVF_ADMINQ_DETAILS(*asq, ntc);
+ }
+
+ asq->next_to_clean = ntc;
+
+ return AVF_DESC_UNUSED(asq);
+}
+
+/**
+ * avf_asq_done - check if FW has processed the Admin Send Queue
+ * @hw: pointer to the hw struct
+ *
+ * Returns true if the firmware has processed all descriptors on the
+ * admin send queue. Returns false if there are still requests pending.
+ **/
+bool avf_asq_done(struct avf_hw *hw)
+{
+ /* AQ designers suggest use of head for better
+ * timing reliability than DD bit
+ */
+ return rd32(hw, hw->aq.asq.head) == hw->aq.asq.next_to_use;
+
+}
+
+/**
+ * avf_asq_send_command - send command to Admin Queue
+ * @hw: pointer to the hw struct
+ * @desc: prefilled descriptor describing the command (non DMA mem)
+ * @buff: buffer to use for indirect commands
+ * @buff_size: size of buffer for indirect commands
+ * @cmd_details: pointer to command details structure
+ *
+ * This is the main send command driver routine for the Admin Queue send
+ * queue. It runs the queue, cleans the queue, etc
+ **/
+enum avf_status_code avf_asq_send_command(struct avf_hw *hw,
+ struct avf_aq_desc *desc,
+ void *buff, /* can be NULL */
+ u16 buff_size,
+ struct avf_asq_cmd_details *cmd_details)
+{
+ enum avf_status_code status = AVF_SUCCESS;
+ struct avf_dma_mem *dma_buff = NULL;
+ struct avf_asq_cmd_details *details;
+ struct avf_aq_desc *desc_on_ring;
+ bool cmd_completed = false;
+ u16 retval = 0;
+ u32 val = 0;
+
+ avf_acquire_spinlock(&hw->aq.asq_spinlock);
+
+ hw->aq.asq_last_status = AVF_AQ_RC_OK;
+
+ if (hw->aq.asq.count == 0) {
+ avf_debug(hw, AVF_DEBUG_AQ_MESSAGE,
+ "AQTX: Admin queue not initialized.\n");
+ status = AVF_ERR_QUEUE_EMPTY;
+ goto asq_send_command_error;
+ }
+
+ val = rd32(hw, hw->aq.asq.head);
+ if (val >= hw->aq.num_asq_entries) {
+ avf_debug(hw, AVF_DEBUG_AQ_MESSAGE,
+ "AQTX: head overrun at %d\n", val);
+ status = AVF_ERR_QUEUE_EMPTY;
+ goto asq_send_command_error;
+ }
+
+ details = AVF_ADMINQ_DETAILS(hw->aq.asq, hw->aq.asq.next_to_use);
+ if (cmd_details) {
+ avf_memcpy(details,
+ cmd_details,
+ sizeof(struct avf_asq_cmd_details),
+ AVF_NONDMA_TO_NONDMA);
+
+ /* If the cmd_details are defined copy the cookie. The
+ * CPU_TO_LE32 is not needed here because the data is ignored
+ * by the FW, only used by the driver
+ */
+ if (details->cookie) {
+ desc->cookie_high =
+ CPU_TO_LE32(AVF_HI_DWORD(details->cookie));
+ desc->cookie_low =
+ CPU_TO_LE32(AVF_LO_DWORD(details->cookie));
+ }
+ } else {
+ avf_memset(details, 0,
+ sizeof(struct avf_asq_cmd_details),
+ AVF_NONDMA_MEM);
+ }
+
+ /* clear requested flags and then set additional flags if defined */
+ desc->flags &= ~CPU_TO_LE16(details->flags_dis);
+ desc->flags |= CPU_TO_LE16(details->flags_ena);
+
+ if (buff_size > hw->aq.asq_buf_size) {
+ avf_debug(hw,
+ AVF_DEBUG_AQ_MESSAGE,
+ "AQTX: Invalid buffer size: %d.\n",
+ buff_size);
+ status = AVF_ERR_INVALID_SIZE;
+ goto asq_send_command_error;
+ }
+
+ if (details->postpone && !details->async) {
+ avf_debug(hw,
+ AVF_DEBUG_AQ_MESSAGE,
+ "AQTX: Async flag not set along with postpone flag");
+ status = AVF_ERR_PARAM;
+ goto asq_send_command_error;
+ }
+
+ /* call clean and check queue available function to reclaim the
+ * descriptors that were processed by FW, the function returns the
+ * number of desc available
+ */
+ /* the clean function called here could be called in a separate thread
+ * in case of asynchronous completions
+ */
+ if (avf_clean_asq(hw) == 0) {
+ avf_debug(hw,
+ AVF_DEBUG_AQ_MESSAGE,
+ "AQTX: Error queue is full.\n");
+ status = AVF_ERR_ADMIN_QUEUE_FULL;
+ goto asq_send_command_error;
+ }
+
+ /* initialize the temp desc pointer with the right desc */
+ desc_on_ring = AVF_ADMINQ_DESC(hw->aq.asq, hw->aq.asq.next_to_use);
+
+ /* if the desc is available copy the temp desc to the right place */
+ avf_memcpy(desc_on_ring, desc, sizeof(struct avf_aq_desc),
+ AVF_NONDMA_TO_DMA);
+
+ /* if buff is not NULL assume indirect command */
+ if (buff != NULL) {
+ dma_buff = &(hw->aq.asq.r.asq_bi[hw->aq.asq.next_to_use]);
+ /* copy the user buff into the respective DMA buff */
+ avf_memcpy(dma_buff->va, buff, buff_size,
+ AVF_NONDMA_TO_DMA);
+ desc_on_ring->datalen = CPU_TO_LE16(buff_size);
+
+ /* Update the address values in the desc with the pa value
+ * for respective buffer
+ */
+ desc_on_ring->params.external.addr_high =
+ CPU_TO_LE32(AVF_HI_DWORD(dma_buff->pa));
+ desc_on_ring->params.external.addr_low =
+ CPU_TO_LE32(AVF_LO_DWORD(dma_buff->pa));
+ }
+
+ /* bump the tail */
+ avf_debug(hw, AVF_DEBUG_AQ_MESSAGE, "AQTX: desc and buffer:\n");
+ avf_debug_aq(hw, AVF_DEBUG_AQ_COMMAND, (void *)desc_on_ring,
+ buff, buff_size);
+ (hw->aq.asq.next_to_use)++;
+ if (hw->aq.asq.next_to_use == hw->aq.asq.count)
+ hw->aq.asq.next_to_use = 0;
+ if (!details->postpone)
+ wr32(hw, hw->aq.asq.tail, hw->aq.asq.next_to_use);
+
+ /* if cmd_details are not defined or async flag is not set,
+ * we need to wait for desc write back
+ */
+ if (!details->async && !details->postpone) {
+ u32 total_delay = 0;
+
+ do {
+ /* AQ designers suggest use of head for better
+ * timing reliability than DD bit
+ */
+ if (avf_asq_done(hw))
+ break;
+ avf_usec_delay(50);
+ total_delay += 50;
+ } while (total_delay < hw->aq.asq_cmd_timeout);
+ }
+
+ /* if ready, copy the desc back to temp */
+ if (avf_asq_done(hw)) {
+ avf_memcpy(desc, desc_on_ring, sizeof(struct avf_aq_desc),
+ AVF_DMA_TO_NONDMA);
+ if (buff != NULL)
+ avf_memcpy(buff, dma_buff->va, buff_size,
+ AVF_DMA_TO_NONDMA);
+ retval = LE16_TO_CPU(desc->retval);
+ if (retval != 0) {
+ avf_debug(hw,
+ AVF_DEBUG_AQ_MESSAGE,
+ "AQTX: Command completed with error 0x%X.\n",
+ retval);
+
+ /* strip off FW internal code */
+ retval &= 0xff;
+ }
+ cmd_completed = true;
+ if ((enum avf_admin_queue_err)retval == AVF_AQ_RC_OK)
+ status = AVF_SUCCESS;
+ else
+ status = AVF_ERR_ADMIN_QUEUE_ERROR;
+ hw->aq.asq_last_status = (enum avf_admin_queue_err)retval;
+ }
+
+ avf_debug(hw, AVF_DEBUG_AQ_MESSAGE,
+ "AQTX: desc and buffer writeback:\n");
+ avf_debug_aq(hw, AVF_DEBUG_AQ_COMMAND, (void *)desc, buff, buff_size);
+
+ /* save writeback aq if requested */
+ if (details->wb_desc)
+ avf_memcpy(details->wb_desc, desc_on_ring,
+ sizeof(struct avf_aq_desc), AVF_DMA_TO_NONDMA);
+
+ /* update the error if time out occurred */
+ if ((!cmd_completed) &&
+ (!details->async && !details->postpone)) {
+ if (rd32(hw, hw->aq.asq.len) & AVF_ATQLEN1_ATQCRIT_MASK) {
+ avf_debug(hw, AVF_DEBUG_AQ_MESSAGE,
+ "AQTX: AQ Critical error.\n");
+ status = AVF_ERR_ADMIN_QUEUE_CRITICAL_ERROR;
+ } else {
+ avf_debug(hw, AVF_DEBUG_AQ_MESSAGE,
+ "AQTX: Writeback timeout.\n");
+ status = AVF_ERR_ADMIN_QUEUE_TIMEOUT;
+ }
+ }
+
+asq_send_command_error:
+ avf_release_spinlock(&hw->aq.asq_spinlock);
+ return status;
+}
+
+/**
+ * avf_fill_default_direct_cmd_desc - AQ descriptor helper function
+ * @desc: pointer to the temp descriptor (non DMA mem)
+ * @opcode: the opcode can be used to decide which flags to turn off or on
+ *
+ * Fill the desc with default values
+ **/
+void avf_fill_default_direct_cmd_desc(struct avf_aq_desc *desc,
+ u16 opcode)
+{
+ /* zero out the desc */
+ avf_memset((void *)desc, 0, sizeof(struct avf_aq_desc),
+ AVF_NONDMA_MEM);
+ desc->opcode = CPU_TO_LE16(opcode);
+ desc->flags = CPU_TO_LE16(AVF_AQ_FLAG_SI);
+}
+
+/**
+ * avf_clean_arq_element
+ * @hw: pointer to the hw struct
+ * @e: event info from the receive descriptor, includes any buffers
+ * @pending: number of events that could be left to process
+ *
+ * This function cleans one Admin Receive Queue element and returns
+ * the contents through e. It can also return how many events are
+ * left to process through 'pending'
+ **/
+enum avf_status_code avf_clean_arq_element(struct avf_hw *hw,
+ struct avf_arq_event_info *e,
+ u16 *pending)
+{
+ enum avf_status_code ret_code = AVF_SUCCESS;
+ u16 ntc = hw->aq.arq.next_to_clean;
+ struct avf_aq_desc *desc;
+ struct avf_dma_mem *bi;
+ u16 desc_idx;
+ u16 datalen;
+ u16 flags;
+ u16 ntu;
+
+ /* pre-clean the event info */
+ avf_memset(&e->desc, 0, sizeof(e->desc), AVF_NONDMA_MEM);
+
+ /* take the lock before we start messing with the ring */
+ avf_acquire_spinlock(&hw->aq.arq_spinlock);
+
+ if (hw->aq.arq.count == 0) {
+ avf_debug(hw, AVF_DEBUG_AQ_MESSAGE,
+ "AQRX: Admin queue not initialized.\n");
+ ret_code = AVF_ERR_QUEUE_EMPTY;
+ goto clean_arq_element_err;
+ }
+
+ /* set next_to_use to head */
+#ifdef INTEGRATED_VF
+ if (!avf_is_vf(hw))
+ ntu = rd32(hw, hw->aq.arq.head) & AVF_PF_ARQH_ARQH_MASK;
+ else
+ ntu = rd32(hw, hw->aq.arq.head) & AVF_ARQH1_ARQH_MASK;
+#else
+ ntu = rd32(hw, hw->aq.arq.head) & AVF_ARQH1_ARQH_MASK;
+#endif /* INTEGRATED_VF */
+ if (ntu == ntc) {
+ /* nothing to do - shouldn't need to update ring's values */
+ ret_code = AVF_ERR_ADMIN_QUEUE_NO_WORK;
+ goto clean_arq_element_out;
+ }
+
+ /* now clean the next descriptor */
+ desc = AVF_ADMINQ_DESC(hw->aq.arq, ntc);
+ desc_idx = ntc;
+
+ hw->aq.arq_last_status =
+ (enum avf_admin_queue_err)LE16_TO_CPU(desc->retval);
+ flags = LE16_TO_CPU(desc->flags);
+ if (flags & AVF_AQ_FLAG_ERR) {
+ ret_code = AVF_ERR_ADMIN_QUEUE_ERROR;
+ avf_debug(hw,
+ AVF_DEBUG_AQ_MESSAGE,
+ "AQRX: Event received with error 0x%X.\n",
+ hw->aq.arq_last_status);
+ }
+
+ avf_memcpy(&e->desc, desc, sizeof(struct avf_aq_desc),
+ AVF_DMA_TO_NONDMA);
+ datalen = LE16_TO_CPU(desc->datalen);
+ e->msg_len = min(datalen, e->buf_len);
+ if (e->msg_buf != NULL && (e->msg_len != 0))
+ avf_memcpy(e->msg_buf,
+ hw->aq.arq.r.arq_bi[desc_idx].va,
+ e->msg_len, AVF_DMA_TO_NONDMA);
+
+ avf_debug(hw, AVF_DEBUG_AQ_MESSAGE, "AQRX: desc and buffer:\n");
+ avf_debug_aq(hw, AVF_DEBUG_AQ_COMMAND, (void *)desc, e->msg_buf,
+ hw->aq.arq_buf_size);
+
+ /* Restore the original datalen and buffer address in the desc,
+ * FW updates datalen to indicate the event message
+ * size
+ */
+ bi = &hw->aq.arq.r.arq_bi[ntc];
+ avf_memset((void *)desc, 0, sizeof(struct avf_aq_desc), AVF_DMA_MEM);
+
+ desc->flags = CPU_TO_LE16(AVF_AQ_FLAG_BUF);
+ if (hw->aq.arq_buf_size > AVF_AQ_LARGE_BUF)
+ desc->flags |= CPU_TO_LE16(AVF_AQ_FLAG_LB);
+ desc->datalen = CPU_TO_LE16((u16)bi->size);
+ desc->params.external.addr_high = CPU_TO_LE32(AVF_HI_DWORD(bi->pa));
+ desc->params.external.addr_low = CPU_TO_LE32(AVF_LO_DWORD(bi->pa));
+
+ /* set tail = the last cleaned desc index. */
+ wr32(hw, hw->aq.arq.tail, ntc);
+ /* ntc is updated to tail + 1 */
+ ntc++;
+ if (ntc == hw->aq.num_arq_entries)
+ ntc = 0;
+ hw->aq.arq.next_to_clean = ntc;
+ hw->aq.arq.next_to_use = ntu;
+
+clean_arq_element_out:
+ /* Set pending if needed, unlock and return */
+ if (pending != NULL)
+ *pending = (ntc > ntu ? hw->aq.arq.count : 0) + (ntu - ntc);
+clean_arq_element_err:
+ avf_release_spinlock(&hw->aq.arq_spinlock);
+
+ return ret_code;
+}
+
diff --git a/drivers/net/iavf/base/iavf_adminq.h b/drivers/net/iavf/base/iavf_adminq.h
new file mode 100644
index 0000000..ce72fb5
--- /dev/null
+++ b/drivers/net/iavf/base/iavf_adminq.h
@@ -0,0 +1,166 @@
+/*******************************************************************************
+
+Copyright (c) 2013 - 2015, Intel Corporation
+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.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+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.
+
+***************************************************************************/
+
+#ifndef _AVF_ADMINQ_H_
+#define _AVF_ADMINQ_H_
+
+#include "iavf_osdep.h"
+#include "iavf_status.h"
+#include "iavf_adminq_cmd.h"
+
+#define AVF_ADMINQ_DESC(R, i) \
+ (&(((struct avf_aq_desc *)((R).desc_buf.va))[i]))
+
+#define AVF_ADMINQ_DESC_ALIGNMENT 4096
+
+struct avf_adminq_ring {
+ struct avf_virt_mem dma_head; /* space for dma structures */
+ struct avf_dma_mem desc_buf; /* descriptor ring memory */
+ struct avf_virt_mem cmd_buf; /* command buffer memory */
+
+ union {
+ struct avf_dma_mem *asq_bi;
+ struct avf_dma_mem *arq_bi;
+ } r;
+
+ u16 count; /* Number of descriptors */
+ u16 rx_buf_len; /* Admin Receive Queue buffer length */
+
+ /* used for interrupt processing */
+ u16 next_to_use;
+ u16 next_to_clean;
+
+ /* used for queue tracking */
+ u32 head;
+ u32 tail;
+ u32 len;
+ u32 bah;
+ u32 bal;
+};
+
+/* ASQ transaction details */
+struct avf_asq_cmd_details {
+ void *callback; /* cast from type AVF_ADMINQ_CALLBACK */
+ u64 cookie;
+ u16 flags_ena;
+ u16 flags_dis;
+ bool async;
+ bool postpone;
+ struct avf_aq_desc *wb_desc;
+};
+
+#define AVF_ADMINQ_DETAILS(R, i) \
+ (&(((struct avf_asq_cmd_details *)((R).cmd_buf.va))[i]))
+
+/* ARQ event information */
+struct avf_arq_event_info {
+ struct avf_aq_desc desc;
+ u16 msg_len;
+ u16 buf_len;
+ u8 *msg_buf;
+};
+
+/* Admin Queue information */
+struct avf_adminq_info {
+ struct avf_adminq_ring arq; /* receive queue */
+ struct avf_adminq_ring asq; /* send queue */
+ u32 asq_cmd_timeout; /* send queue cmd write back timeout*/
+ u16 num_arq_entries; /* receive queue depth */
+ u16 num_asq_entries; /* send queue depth */
+ u16 arq_buf_size; /* receive queue buffer size */
+ u16 asq_buf_size; /* send queue buffer size */
+ u16 fw_maj_ver; /* firmware major version */
+ u16 fw_min_ver; /* firmware minor version */
+ u32 fw_build; /* firmware build number */
+ u16 api_maj_ver; /* api major version */
+ u16 api_min_ver; /* api minor version */
+
+ struct avf_spinlock asq_spinlock; /* Send queue spinlock */
+ struct avf_spinlock arq_spinlock; /* Receive queue spinlock */
+
+ /* last status values on send and receive queues */
+ enum avf_admin_queue_err asq_last_status;
+ enum avf_admin_queue_err arq_last_status;
+};
+
+/**
+ * avf_aq_rc_to_posix - convert errors to user-land codes
+ * aq_ret: AdminQ handler error code can override aq_rc
+ * aq_rc: AdminQ firmware error code to convert
+ **/
+STATIC INLINE int avf_aq_rc_to_posix(int aq_ret, int aq_rc)
+{
+ int aq_to_posix[] = {
+ 0, /* AVF_AQ_RC_OK */
+ -EPERM, /* AVF_AQ_RC_EPERM */
+ -ENOENT, /* AVF_AQ_RC_ENOENT */
+ -ESRCH, /* AVF_AQ_RC_ESRCH */
+ -EINTR, /* AVF_AQ_RC_EINTR */
+ -EIO, /* AVF_AQ_RC_EIO */
+ -ENXIO, /* AVF_AQ_RC_ENXIO */
+ -E2BIG, /* AVF_AQ_RC_E2BIG */
+ -EAGAIN, /* AVF_AQ_RC_EAGAIN */
+ -ENOMEM, /* AVF_AQ_RC_ENOMEM */
+ -EACCES, /* AVF_AQ_RC_EACCES */
+ -EFAULT, /* AVF_AQ_RC_EFAULT */
+ -EBUSY, /* AVF_AQ_RC_EBUSY */
+ -EEXIST, /* AVF_AQ_RC_EEXIST */
+ -EINVAL, /* AVF_AQ_RC_EINVAL */
+ -ENOTTY, /* AVF_AQ_RC_ENOTTY */
+ -ENOSPC, /* AVF_AQ_RC_ENOSPC */
+ -ENOSYS, /* AVF_AQ_RC_ENOSYS */
+ -ERANGE, /* AVF_AQ_RC_ERANGE */
+ -EPIPE, /* AVF_AQ_RC_EFLUSHED */
+ -ESPIPE, /* AVF_AQ_RC_BAD_ADDR */
+ -EROFS, /* AVF_AQ_RC_EMODE */
+ -EFBIG, /* AVF_AQ_RC_EFBIG */
+ };
+
+ /* aq_rc is invalid if AQ timed out */
+ if (aq_ret == AVF_ERR_ADMIN_QUEUE_TIMEOUT)
+ return -EAGAIN;
+
+ if (!((u32)aq_rc < (sizeof(aq_to_posix) / sizeof((aq_to_posix)[0]))))
+ return -ERANGE;
+
+ return aq_to_posix[aq_rc];
+}
+
+/* general information */
+#define AVF_AQ_LARGE_BUF 512
+#define AVF_ASQ_CMD_TIMEOUT 250000 /* usecs */
+
+void avf_fill_default_direct_cmd_desc(struct avf_aq_desc *desc,
+ u16 opcode);
+
+#endif /* _AVF_ADMINQ_H_ */
diff --git a/drivers/net/iavf/base/iavf_adminq_cmd.h b/drivers/net/iavf/base/iavf_adminq_cmd.h
new file mode 100644
index 0000000..7954911
--- /dev/null
+++ b/drivers/net/iavf/base/iavf_adminq_cmd.h
@@ -0,0 +1,2841 @@
+/*******************************************************************************
+
+Copyright (c) 2013 - 2015, Intel Corporation
+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.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+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.
+
+***************************************************************************/
+
+#ifndef _AVF_ADMINQ_CMD_H_
+#define _AVF_ADMINQ_CMD_H_
+
+/* This header file defines the avf Admin Queue commands and is shared between
+ * avf Firmware and Software.
+ *
+ * This file needs to comply with the Linux Kernel coding style.
+ */
+
+
+#define AVF_FW_API_VERSION_MAJOR 0x0001
+#define AVF_FW_API_VERSION_MINOR_X722 0x0005
+#define AVF_FW_API_VERSION_MINOR_X710 0x0007
+
+#define AVF_FW_MINOR_VERSION(_h) ((_h)->mac.type == AVF_MAC_XL710 ? \
+ AVF_FW_API_VERSION_MINOR_X710 : \
+ AVF_FW_API_VERSION_MINOR_X722)
+
+/* API version 1.7 implements additional link and PHY-specific APIs */
+#define AVF_MINOR_VER_GET_LINK_INFO_XL710 0x0007
+
+struct avf_aq_desc {
+ __le16 flags;
+ __le16 opcode;
+ __le16 datalen;
+ __le16 retval;
+ __le32 cookie_high;
+ __le32 cookie_low;
+ union {
+ struct {
+ __le32 param0;
+ __le32 param1;
+ __le32 param2;
+ __le32 param3;
+ } internal;
+ struct {
+ __le32 param0;
+ __le32 param1;
+ __le32 addr_high;
+ __le32 addr_low;
+ } external;
+ u8 raw[16];
+ } params;
+};
+
+/* Flags sub-structure
+ * |0 |1 |2 |3 |4 |5 |6 |7 |8 |9 |10 |11 |12 |13 |14 |15 |
+ * |DD |CMP|ERR|VFE| * * RESERVED * * |LB |RD |VFC|BUF|SI |EI |FE |
+ */
+
+/* command flags and offsets*/
+#define AVF_AQ_FLAG_DD_SHIFT 0
+#define AVF_AQ_FLAG_CMP_SHIFT 1
+#define AVF_AQ_FLAG_ERR_SHIFT 2
+#define AVF_AQ_FLAG_VFE_SHIFT 3
+#define AVF_AQ_FLAG_LB_SHIFT 9
+#define AVF_AQ_FLAG_RD_SHIFT 10
+#define AVF_AQ_FLAG_VFC_SHIFT 11
+#define AVF_AQ_FLAG_BUF_SHIFT 12
+#define AVF_AQ_FLAG_SI_SHIFT 13
+#define AVF_AQ_FLAG_EI_SHIFT 14
+#define AVF_AQ_FLAG_FE_SHIFT 15
+
+#define AVF_AQ_FLAG_DD (1 << AVF_AQ_FLAG_DD_SHIFT) /* 0x1 */
+#define AVF_AQ_FLAG_CMP (1 << AVF_AQ_FLAG_CMP_SHIFT) /* 0x2 */
+#define AVF_AQ_FLAG_ERR (1 << AVF_AQ_FLAG_ERR_SHIFT) /* 0x4 */
+#define AVF_AQ_FLAG_VFE (1 << AVF_AQ_FLAG_VFE_SHIFT) /* 0x8 */
+#define AVF_AQ_FLAG_LB (1 << AVF_AQ_FLAG_LB_SHIFT) /* 0x200 */
+#define AVF_AQ_FLAG_RD (1 << AVF_AQ_FLAG_RD_SHIFT) /* 0x400 */
+#define AVF_AQ_FLAG_VFC (1 << AVF_AQ_FLAG_VFC_SHIFT) /* 0x800 */
+#define AVF_AQ_FLAG_BUF (1 << AVF_AQ_FLAG_BUF_SHIFT) /* 0x1000 */
+#define AVF_AQ_FLAG_SI (1 << AVF_AQ_FLAG_SI_SHIFT) /* 0x2000 */
+#define AVF_AQ_FLAG_EI (1 << AVF_AQ_FLAG_EI_SHIFT) /* 0x4000 */
+#define AVF_AQ_FLAG_FE (1 << AVF_AQ_FLAG_FE_SHIFT) /* 0x8000 */
+
+/* error codes */
+enum avf_admin_queue_err {
+ AVF_AQ_RC_OK = 0, /* success */
+ AVF_AQ_RC_EPERM = 1, /* Operation not permitted */
+ AVF_AQ_RC_ENOENT = 2, /* No such element */
+ AVF_AQ_RC_ESRCH = 3, /* Bad opcode */
+ AVF_AQ_RC_EINTR = 4, /* operation interrupted */
+ AVF_AQ_RC_EIO = 5, /* I/O error */
+ AVF_AQ_RC_ENXIO = 6, /* No such resource */
+ AVF_AQ_RC_E2BIG = 7, /* Arg too long */
+ AVF_AQ_RC_EAGAIN = 8, /* Try again */
+ AVF_AQ_RC_ENOMEM = 9, /* Out of memory */
+ AVF_AQ_RC_EACCES = 10, /* Permission denied */
+ AVF_AQ_RC_EFAULT = 11, /* Bad address */
+ AVF_AQ_RC_EBUSY = 12, /* Device or resource busy */
+ AVF_AQ_RC_EEXIST = 13, /* object already exists */
+ AVF_AQ_RC_EINVAL = 14, /* Invalid argument */
+ AVF_AQ_RC_ENOTTY = 15, /* Not a typewriter */
+ AVF_AQ_RC_ENOSPC = 16, /* No space left or alloc failure */
+ AVF_AQ_RC_ENOSYS = 17, /* Function not implemented */
+ AVF_AQ_RC_ERANGE = 18, /* Parameter out of range */
+ AVF_AQ_RC_EFLUSHED = 19, /* Cmd flushed due to prev cmd error */
+ AVF_AQ_RC_BAD_ADDR = 20, /* Descriptor contains a bad pointer */
+ AVF_AQ_RC_EMODE = 21, /* Op not allowed in current dev mode */
+ AVF_AQ_RC_EFBIG = 22, /* File too large */
+};
+
+/* Admin Queue command opcodes */
+enum avf_admin_queue_opc {
+ /* aq commands */
+ avf_aqc_opc_get_version = 0x0001,
+ avf_aqc_opc_driver_version = 0x0002,
+ avf_aqc_opc_queue_shutdown = 0x0003,
+ avf_aqc_opc_set_pf_context = 0x0004,
+
+ /* resource ownership */
+ avf_aqc_opc_request_resource = 0x0008,
+ avf_aqc_opc_release_resource = 0x0009,
+
+ avf_aqc_opc_list_func_capabilities = 0x000A,
+ avf_aqc_opc_list_dev_capabilities = 0x000B,
+
+ /* Proxy commands */
+ avf_aqc_opc_set_proxy_config = 0x0104,
+ avf_aqc_opc_set_ns_proxy_table_entry = 0x0105,
+
+ /* LAA */
+ avf_aqc_opc_mac_address_read = 0x0107,
+ avf_aqc_opc_mac_address_write = 0x0108,
+
+ /* PXE */
+ avf_aqc_opc_clear_pxe_mode = 0x0110,
+
+ /* WoL commands */
+ avf_aqc_opc_set_wol_filter = 0x0120,
+ avf_aqc_opc_get_wake_reason = 0x0121,
+ avf_aqc_opc_clear_all_wol_filters = 0x025E,
+
+ /* internal switch commands */
+ avf_aqc_opc_get_switch_config = 0x0200,
+ avf_aqc_opc_add_statistics = 0x0201,
+ avf_aqc_opc_remove_statistics = 0x0202,
+ avf_aqc_opc_set_port_parameters = 0x0203,
+ avf_aqc_opc_get_switch_resource_alloc = 0x0204,
+ avf_aqc_opc_set_switch_config = 0x0205,
+ avf_aqc_opc_rx_ctl_reg_read = 0x0206,
+ avf_aqc_opc_rx_ctl_reg_write = 0x0207,
+
+ avf_aqc_opc_add_vsi = 0x0210,
+ avf_aqc_opc_update_vsi_parameters = 0x0211,
+ avf_aqc_opc_get_vsi_parameters = 0x0212,
+
+ avf_aqc_opc_add_pv = 0x0220,
+ avf_aqc_opc_update_pv_parameters = 0x0221,
+ avf_aqc_opc_get_pv_parameters = 0x0222,
+
+ avf_aqc_opc_add_veb = 0x0230,
+ avf_aqc_opc_update_veb_parameters = 0x0231,
+ avf_aqc_opc_get_veb_parameters = 0x0232,
+
+ avf_aqc_opc_delete_element = 0x0243,
+
+ avf_aqc_opc_add_macvlan = 0x0250,
+ avf_aqc_opc_remove_macvlan = 0x0251,
+ avf_aqc_opc_add_vlan = 0x0252,
+ avf_aqc_opc_remove_vlan = 0x0253,
+ avf_aqc_opc_set_vsi_promiscuous_modes = 0x0254,
+ avf_aqc_opc_add_tag = 0x0255,
+ avf_aqc_opc_remove_tag = 0x0256,
+ avf_aqc_opc_add_multicast_etag = 0x0257,
+ avf_aqc_opc_remove_multicast_etag = 0x0258,
+ avf_aqc_opc_update_tag = 0x0259,
+ avf_aqc_opc_add_control_packet_filter = 0x025A,
+ avf_aqc_opc_remove_control_packet_filter = 0x025B,
+ avf_aqc_opc_add_cloud_filters = 0x025C,
+ avf_aqc_opc_remove_cloud_filters = 0x025D,
+ avf_aqc_opc_clear_wol_switch_filters = 0x025E,
+ avf_aqc_opc_replace_cloud_filters = 0x025F,
+
+ avf_aqc_opc_add_mirror_rule = 0x0260,
+ avf_aqc_opc_delete_mirror_rule = 0x0261,
+
+ /* Dynamic Device Personalization */
+ avf_aqc_opc_write_personalization_profile = 0x0270,
+ avf_aqc_opc_get_personalization_profile_list = 0x0271,
+
+ /* DCB commands */
+ avf_aqc_opc_dcb_ignore_pfc = 0x0301,
+ avf_aqc_opc_dcb_updated = 0x0302,
+ avf_aqc_opc_set_dcb_parameters = 0x0303,
+
+ /* TX scheduler */
+ avf_aqc_opc_configure_vsi_bw_limit = 0x0400,
+ avf_aqc_opc_configure_vsi_ets_sla_bw_limit = 0x0406,
+ avf_aqc_opc_configure_vsi_tc_bw = 0x0407,
+ avf_aqc_opc_query_vsi_bw_config = 0x0408,
+ avf_aqc_opc_query_vsi_ets_sla_config = 0x040A,
+ avf_aqc_opc_configure_switching_comp_bw_limit = 0x0410,
+
+ avf_aqc_opc_enable_switching_comp_ets = 0x0413,
+ avf_aqc_opc_modify_switching_comp_ets = 0x0414,
+ avf_aqc_opc_disable_switching_comp_ets = 0x0415,
+ avf_aqc_opc_configure_switching_comp_ets_bw_limit = 0x0416,
+ avf_aqc_opc_configure_switching_comp_bw_config = 0x0417,
+ avf_aqc_opc_query_switching_comp_ets_config = 0x0418,
+ avf_aqc_opc_query_port_ets_config = 0x0419,
+ avf_aqc_opc_query_switching_comp_bw_config = 0x041A,
+ avf_aqc_opc_suspend_port_tx = 0x041B,
+ avf_aqc_opc_resume_port_tx = 0x041C,
+ avf_aqc_opc_configure_partition_bw = 0x041D,
+ /* hmc */
+ avf_aqc_opc_query_hmc_resource_profile = 0x0500,
+ avf_aqc_opc_set_hmc_resource_profile = 0x0501,
+
+ /* phy commands*/
+
+ /* phy commands*/
+ avf_aqc_opc_get_phy_abilities = 0x0600,
+ avf_aqc_opc_set_phy_config = 0x0601,
+ avf_aqc_opc_set_mac_config = 0x0603,
+ avf_aqc_opc_set_link_restart_an = 0x0605,
+ avf_aqc_opc_get_link_status = 0x0607,
+ avf_aqc_opc_set_phy_int_mask = 0x0613,
+ avf_aqc_opc_get_local_advt_reg = 0x0614,
+ avf_aqc_opc_set_local_advt_reg = 0x0615,
+ avf_aqc_opc_get_partner_advt = 0x0616,
+ avf_aqc_opc_set_lb_modes = 0x0618,
+ avf_aqc_opc_get_phy_wol_caps = 0x0621,
+ avf_aqc_opc_set_phy_debug = 0x0622,
+ avf_aqc_opc_upload_ext_phy_fm = 0x0625,
+ avf_aqc_opc_run_phy_activity = 0x0626,
+ avf_aqc_opc_set_phy_register = 0x0628,
+ avf_aqc_opc_get_phy_register = 0x0629,
+
+ /* NVM commands */
+ avf_aqc_opc_nvm_read = 0x0701,
+ avf_aqc_opc_nvm_erase = 0x0702,
+ avf_aqc_opc_nvm_update = 0x0703,
+ avf_aqc_opc_nvm_config_read = 0x0704,
+ avf_aqc_opc_nvm_config_write = 0x0705,
+ avf_aqc_opc_nvm_progress = 0x0706,
+ avf_aqc_opc_oem_post_update = 0x0720,
+ avf_aqc_opc_thermal_sensor = 0x0721,
+
+ /* virtualization commands */
+ avf_aqc_opc_send_msg_to_pf = 0x0801,
+ avf_aqc_opc_send_msg_to_vf = 0x0802,
+ avf_aqc_opc_send_msg_to_peer = 0x0803,
+
+ /* alternate structure */
+ avf_aqc_opc_alternate_write = 0x0900,
+ avf_aqc_opc_alternate_write_indirect = 0x0901,
+ avf_aqc_opc_alternate_read = 0x0902,
+ avf_aqc_opc_alternate_read_indirect = 0x0903,
+ avf_aqc_opc_alternate_write_done = 0x0904,
+ avf_aqc_opc_alternate_set_mode = 0x0905,
+ avf_aqc_opc_alternate_clear_port = 0x0906,
+
+ /* LLDP commands */
+ avf_aqc_opc_lldp_get_mib = 0x0A00,
+ avf_aqc_opc_lldp_update_mib = 0x0A01,
+ avf_aqc_opc_lldp_add_tlv = 0x0A02,
+ avf_aqc_opc_lldp_update_tlv = 0x0A03,
+ avf_aqc_opc_lldp_delete_tlv = 0x0A04,
+ avf_aqc_opc_lldp_stop = 0x0A05,
+ avf_aqc_opc_lldp_start = 0x0A06,
+ avf_aqc_opc_get_cee_dcb_cfg = 0x0A07,
+ avf_aqc_opc_lldp_set_local_mib = 0x0A08,
+ avf_aqc_opc_lldp_stop_start_spec_agent = 0x0A09,
+
+ /* Tunnel commands */
+ avf_aqc_opc_add_udp_tunnel = 0x0B00,
+ avf_aqc_opc_del_udp_tunnel = 0x0B01,
+ avf_aqc_opc_set_rss_key = 0x0B02,
+ avf_aqc_opc_set_rss_lut = 0x0B03,
+ avf_aqc_opc_get_rss_key = 0x0B04,
+ avf_aqc_opc_get_rss_lut = 0x0B05,
+
+ /* Async Events */
+ avf_aqc_opc_event_lan_overflow = 0x1001,
+
+ /* OEM commands */
+ avf_aqc_opc_oem_parameter_change = 0xFE00,
+ avf_aqc_opc_oem_device_status_change = 0xFE01,
+ avf_aqc_opc_oem_ocsd_initialize = 0xFE02,
+ avf_aqc_opc_oem_ocbb_initialize = 0xFE03,
+
+ /* debug commands */
+ avf_aqc_opc_debug_read_reg = 0xFF03,
+ avf_aqc_opc_debug_write_reg = 0xFF04,
+ avf_aqc_opc_debug_modify_reg = 0xFF07,
+ avf_aqc_opc_debug_dump_internals = 0xFF08,
+};
+
+/* command structures and indirect data structures */
+
+/* Structure naming conventions:
+ * - no suffix for direct command descriptor structures
+ * - _data for indirect sent data
+ * - _resp for indirect return data (data which is both will use _data)
+ * - _completion for direct return data
+ * - _element_ for repeated elements (may also be _data or _resp)
+ *
+ * Command structures are expected to overlay the params.raw member of the basic
+ * descriptor, and as such cannot exceed 16 bytes in length.
+ */
+
+/* This macro is used to generate a compilation error if a structure
+ * is not exactly the correct length. It gives a divide by zero error if the
+ * structure is not of the correct size, otherwise it creates an enum that is
+ * never used.
+ */
+#define AVF_CHECK_STRUCT_LEN(n, X) enum avf_static_assert_enum_##X \
+ { avf_static_assert_##X = (n)/((sizeof(struct X) == (n)) ? 1 : 0) }
+
+/* This macro is used extensively to ensure that command structures are 16
+ * bytes in length as they have to map to the raw array of that size.
+ */
+#define AVF_CHECK_CMD_LENGTH(X) AVF_CHECK_STRUCT_LEN(16, X)
+
+/* internal (0x00XX) commands */
+
+/* Get version (direct 0x0001) */
+struct avf_aqc_get_version {
+ __le32 rom_ver;
+ __le32 fw_build;
+ __le16 fw_major;
+ __le16 fw_minor;
+ __le16 api_major;
+ __le16 api_minor;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_get_version);
+
+/* Send driver version (indirect 0x0002) */
+struct avf_aqc_driver_version {
+ u8 driver_major_ver;
+ u8 driver_minor_ver;
+ u8 driver_build_ver;
+ u8 driver_subbuild_ver;
+ u8 reserved[4];
+ __le32 address_high;
+ __le32 address_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_driver_version);
+
+/* Queue Shutdown (direct 0x0003) */
+struct avf_aqc_queue_shutdown {
+ __le32 driver_unloading;
+#define AVF_AQ_DRIVER_UNLOADING 0x1
+ u8 reserved[12];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_queue_shutdown);
+
+/* Set PF context (0x0004, direct) */
+struct avf_aqc_set_pf_context {
+ u8 pf_id;
+ u8 reserved[15];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_set_pf_context);
+
+/* Request resource ownership (direct 0x0008)
+ * Release resource ownership (direct 0x0009)
+ */
+#define AVF_AQ_RESOURCE_NVM 1
+#define AVF_AQ_RESOURCE_SDP 2
+#define AVF_AQ_RESOURCE_ACCESS_READ 1
+#define AVF_AQ_RESOURCE_ACCESS_WRITE 2
+#define AVF_AQ_RESOURCE_NVM_READ_TIMEOUT 3000
+#define AVF_AQ_RESOURCE_NVM_WRITE_TIMEOUT 180000
+
+struct avf_aqc_request_resource {
+ __le16 resource_id;
+ __le16 access_type;
+ __le32 timeout;
+ __le32 resource_number;
+ u8 reserved[4];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_request_resource);
+
+/* Get function capabilities (indirect 0x000A)
+ * Get device capabilities (indirect 0x000B)
+ */
+struct avf_aqc_list_capabilites {
+ u8 command_flags;
+#define AVF_AQ_LIST_CAP_PF_INDEX_EN 1
+ u8 pf_index;
+ u8 reserved[2];
+ __le32 count;
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_list_capabilites);
+
+struct avf_aqc_list_capabilities_element_resp {
+ __le16 id;
+ u8 major_rev;
+ u8 minor_rev;
+ __le32 number;
+ __le32 logical_id;
+ __le32 phys_id;
+ u8 reserved[16];
+};
+
+/* list of caps */
+
+#define AVF_AQ_CAP_ID_SWITCH_MODE 0x0001
+#define AVF_AQ_CAP_ID_MNG_MODE 0x0002
+#define AVF_AQ_CAP_ID_NPAR_ACTIVE 0x0003
+#define AVF_AQ_CAP_ID_OS2BMC_CAP 0x0004
+#define AVF_AQ_CAP_ID_FUNCTIONS_VALID 0x0005
+#define AVF_AQ_CAP_ID_ALTERNATE_RAM 0x0006
+#define AVF_AQ_CAP_ID_WOL_AND_PROXY 0x0008
+#define AVF_AQ_CAP_ID_SRIOV 0x0012
+#define AVF_AQ_CAP_ID_VF 0x0013
+#define AVF_AQ_CAP_ID_VMDQ 0x0014
+#define AVF_AQ_CAP_ID_8021QBG 0x0015
+#define AVF_AQ_CAP_ID_8021QBR 0x0016
+#define AVF_AQ_CAP_ID_VSI 0x0017
+#define AVF_AQ_CAP_ID_DCB 0x0018
+#define AVF_AQ_CAP_ID_FCOE 0x0021
+#define AVF_AQ_CAP_ID_ISCSI 0x0022
+#define AVF_AQ_CAP_ID_RSS 0x0040
+#define AVF_AQ_CAP_ID_RXQ 0x0041
+#define AVF_AQ_CAP_ID_TXQ 0x0042
+#define AVF_AQ_CAP_ID_MSIX 0x0043
+#define AVF_AQ_CAP_ID_VF_MSIX 0x0044
+#define AVF_AQ_CAP_ID_FLOW_DIRECTOR 0x0045
+#define AVF_AQ_CAP_ID_1588 0x0046
+#define AVF_AQ_CAP_ID_IWARP 0x0051
+#define AVF_AQ_CAP_ID_LED 0x0061
+#define AVF_AQ_CAP_ID_SDP 0x0062
+#define AVF_AQ_CAP_ID_MDIO 0x0063
+#define AVF_AQ_CAP_ID_WSR_PROT 0x0064
+#define AVF_AQ_CAP_ID_NVM_MGMT 0x0080
+#define AVF_AQ_CAP_ID_FLEX10 0x00F1
+#define AVF_AQ_CAP_ID_CEM 0x00F2
+
+/* Set CPPM Configuration (direct 0x0103) */
+struct avf_aqc_cppm_configuration {
+ __le16 command_flags;
+#define AVF_AQ_CPPM_EN_LTRC 0x0800
+#define AVF_AQ_CPPM_EN_DMCTH 0x1000
+#define AVF_AQ_CPPM_EN_DMCTLX 0x2000
+#define AVF_AQ_CPPM_EN_HPTC 0x4000
+#define AVF_AQ_CPPM_EN_DMARC 0x8000
+ __le16 ttlx;
+ __le32 dmacr;
+ __le16 dmcth;
+ u8 hptc;
+ u8 reserved;
+ __le32 pfltrc;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_cppm_configuration);
+
+/* Set ARP Proxy command / response (indirect 0x0104) */
+struct avf_aqc_arp_proxy_data {
+ __le16 command_flags;
+#define AVF_AQ_ARP_INIT_IPV4 0x0800
+#define AVF_AQ_ARP_UNSUP_CTL 0x1000
+#define AVF_AQ_ARP_ENA 0x2000
+#define AVF_AQ_ARP_ADD_IPV4 0x4000
+#define AVF_AQ_ARP_DEL_IPV4 0x8000
+ __le16 table_id;
+ __le32 enabled_offloads;
+#define AVF_AQ_ARP_DIRECTED_OFFLOAD_ENABLE 0x00000020
+#define AVF_AQ_ARP_OFFLOAD_ENABLE 0x00000800
+ __le32 ip_addr;
+ u8 mac_addr[6];
+ u8 reserved[2];
+};
+
+AVF_CHECK_STRUCT_LEN(0x14, avf_aqc_arp_proxy_data);
+
+/* Set NS Proxy Table Entry Command (indirect 0x0105) */
+struct avf_aqc_ns_proxy_data {
+ __le16 table_idx_mac_addr_0;
+ __le16 table_idx_mac_addr_1;
+ __le16 table_idx_ipv6_0;
+ __le16 table_idx_ipv6_1;
+ __le16 control;
+#define AVF_AQ_NS_PROXY_ADD_0 0x0001
+#define AVF_AQ_NS_PROXY_DEL_0 0x0002
+#define AVF_AQ_NS_PROXY_ADD_1 0x0004
+#define AVF_AQ_NS_PROXY_DEL_1 0x0008
+#define AVF_AQ_NS_PROXY_ADD_IPV6_0 0x0010
+#define AVF_AQ_NS_PROXY_DEL_IPV6_0 0x0020
+#define AVF_AQ_NS_PROXY_ADD_IPV6_1 0x0040
+#define AVF_AQ_NS_PROXY_DEL_IPV6_1 0x0080
+#define AVF_AQ_NS_PROXY_COMMAND_SEQ 0x0100
+#define AVF_AQ_NS_PROXY_INIT_IPV6_TBL 0x0200
+#define AVF_AQ_NS_PROXY_INIT_MAC_TBL 0x0400
+#define AVF_AQ_NS_PROXY_OFFLOAD_ENABLE 0x0800
+#define AVF_AQ_NS_PROXY_DIRECTED_OFFLOAD_ENABLE 0x1000
+ u8 mac_addr_0[6];
+ u8 mac_addr_1[6];
+ u8 local_mac_addr[6];
+ u8 ipv6_addr_0[16]; /* Warning! spec specifies BE byte order */
+ u8 ipv6_addr_1[16];
+};
+
+AVF_CHECK_STRUCT_LEN(0x3c, avf_aqc_ns_proxy_data);
+
+/* Manage LAA Command (0x0106) - obsolete */
+struct avf_aqc_mng_laa {
+ __le16 command_flags;
+#define AVF_AQ_LAA_FLAG_WR 0x8000
+ u8 reserved[2];
+ __le32 sal;
+ __le16 sah;
+ u8 reserved2[6];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_mng_laa);
+
+/* Manage MAC Address Read Command (indirect 0x0107) */
+struct avf_aqc_mac_address_read {
+ __le16 command_flags;
+#define AVF_AQC_LAN_ADDR_VALID 0x10
+#define AVF_AQC_SAN_ADDR_VALID 0x20
+#define AVF_AQC_PORT_ADDR_VALID 0x40
+#define AVF_AQC_WOL_ADDR_VALID 0x80
+#define AVF_AQC_MC_MAG_EN_VALID 0x100
+#define AVF_AQC_WOL_PRESERVE_STATUS 0x200
+#define AVF_AQC_ADDR_VALID_MASK 0x3F0
+ u8 reserved[6];
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_mac_address_read);
+
+struct avf_aqc_mac_address_read_data {
+ u8 pf_lan_mac[6];
+ u8 pf_san_mac[6];
+ u8 port_mac[6];
+ u8 pf_wol_mac[6];
+};
+
+AVF_CHECK_STRUCT_LEN(24, avf_aqc_mac_address_read_data);
+
+/* Manage MAC Address Write Command (0x0108) */
+struct avf_aqc_mac_address_write {
+ __le16 command_flags;
+#define AVF_AQC_MC_MAG_EN 0x0100
+#define AVF_AQC_WOL_PRESERVE_ON_PFR 0x0200
+#define AVF_AQC_WRITE_TYPE_LAA_ONLY 0x0000
+#define AVF_AQC_WRITE_TYPE_LAA_WOL 0x4000
+#define AVF_AQC_WRITE_TYPE_PORT 0x8000
+#define AVF_AQC_WRITE_TYPE_UPDATE_MC_MAG 0xC000
+#define AVF_AQC_WRITE_TYPE_MASK 0xC000
+
+ __le16 mac_sah;
+ __le32 mac_sal;
+ u8 reserved[8];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_mac_address_write);
+
+/* PXE commands (0x011x) */
+
+/* Clear PXE Command and response (direct 0x0110) */
+struct avf_aqc_clear_pxe {
+ u8 rx_cnt;
+ u8 reserved[15];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_clear_pxe);
+
+/* Set WoL Filter (0x0120) */
+
+struct avf_aqc_set_wol_filter {
+ __le16 filter_index;
+#define AVF_AQC_MAX_NUM_WOL_FILTERS 8
+#define AVF_AQC_SET_WOL_FILTER_TYPE_MAGIC_SHIFT 15
+#define AVF_AQC_SET_WOL_FILTER_TYPE_MAGIC_MASK (0x1 << \
+ AVF_AQC_SET_WOL_FILTER_TYPE_MAGIC_SHIFT)
+
+#define AVF_AQC_SET_WOL_FILTER_INDEX_SHIFT 0
+#define AVF_AQC_SET_WOL_FILTER_INDEX_MASK (0x7 << \
+ AVF_AQC_SET_WOL_FILTER_INDEX_SHIFT)
+ __le16 cmd_flags;
+#define AVF_AQC_SET_WOL_FILTER 0x8000
+#define AVF_AQC_SET_WOL_FILTER_NO_TCO_WOL 0x4000
+#define AVF_AQC_SET_WOL_FILTER_WOL_PRESERVE_ON_PFR 0x2000
+#define AVF_AQC_SET_WOL_FILTER_ACTION_CLEAR 0
+#define AVF_AQC_SET_WOL_FILTER_ACTION_SET 1
+ __le16 valid_flags;
+#define AVF_AQC_SET_WOL_FILTER_ACTION_VALID 0x8000
+#define AVF_AQC_SET_WOL_FILTER_NO_TCO_ACTION_VALID 0x4000
+ u8 reserved[2];
+ __le32 address_high;
+ __le32 address_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_set_wol_filter);
+
+struct avf_aqc_set_wol_filter_data {
+ u8 filter[128];
+ u8 mask[16];
+};
+
+AVF_CHECK_STRUCT_LEN(0x90, avf_aqc_set_wol_filter_data);
+
+/* Get Wake Reason (0x0121) */
+
+struct avf_aqc_get_wake_reason_completion {
+ u8 reserved_1[2];
+ __le16 wake_reason;
+#define AVF_AQC_GET_WAKE_UP_REASON_WOL_REASON_MATCHED_INDEX_SHIFT 0
+#define AVF_AQC_GET_WAKE_UP_REASON_WOL_REASON_MATCHED_INDEX_MASK (0xFF << \
+ AVF_AQC_GET_WAKE_UP_REASON_WOL_REASON_MATCHED_INDEX_SHIFT)
+#define AVF_AQC_GET_WAKE_UP_REASON_WOL_REASON_RESERVED_SHIFT 8
+#define AVF_AQC_GET_WAKE_UP_REASON_WOL_REASON_RESERVED_MASK (0xFF << \
+ AVF_AQC_GET_WAKE_UP_REASON_WOL_REASON_RESERVED_SHIFT)
+ u8 reserved_2[12];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_get_wake_reason_completion);
+
+/* Switch configuration commands (0x02xx) */
+
+/* Used by many indirect commands that only pass an seid and a buffer in the
+ * command
+ */
+struct avf_aqc_switch_seid {
+ __le16 seid;
+ u8 reserved[6];
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_switch_seid);
+
+/* Get Switch Configuration command (indirect 0x0200)
+ * uses avf_aqc_switch_seid for the descriptor
+ */
+struct avf_aqc_get_switch_config_header_resp {
+ __le16 num_reported;
+ __le16 num_total;
+ u8 reserved[12];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_get_switch_config_header_resp);
+
+struct avf_aqc_switch_config_element_resp {
+ u8 element_type;
+#define AVF_AQ_SW_ELEM_TYPE_MAC 1
+#define AVF_AQ_SW_ELEM_TYPE_PF 2
+#define AVF_AQ_SW_ELEM_TYPE_VF 3
+#define AVF_AQ_SW_ELEM_TYPE_EMP 4
+#define AVF_AQ_SW_ELEM_TYPE_BMC 5
+#define AVF_AQ_SW_ELEM_TYPE_PV 16
+#define AVF_AQ_SW_ELEM_TYPE_VEB 17
+#define AVF_AQ_SW_ELEM_TYPE_PA 18
+#define AVF_AQ_SW_ELEM_TYPE_VSI 19
+ u8 revision;
+#define AVF_AQ_SW_ELEM_REV_1 1
+ __le16 seid;
+ __le16 uplink_seid;
+ __le16 downlink_seid;
+ u8 reserved[3];
+ u8 connection_type;
+#define AVF_AQ_CONN_TYPE_REGULAR 0x1
+#define AVF_AQ_CONN_TYPE_DEFAULT 0x2
+#define AVF_AQ_CONN_TYPE_CASCADED 0x3
+ __le16 scheduler_id;
+ __le16 element_info;
+};
+
+AVF_CHECK_STRUCT_LEN(0x10, avf_aqc_switch_config_element_resp);
+
+/* Get Switch Configuration (indirect 0x0200)
+ * an array of elements are returned in the response buffer
+ * the first in the array is the header, remainder are elements
+ */
+struct avf_aqc_get_switch_config_resp {
+ struct avf_aqc_get_switch_config_header_resp header;
+ struct avf_aqc_switch_config_element_resp element[1];
+};
+
+AVF_CHECK_STRUCT_LEN(0x20, avf_aqc_get_switch_config_resp);
+
+/* Add Statistics (direct 0x0201)
+ * Remove Statistics (direct 0x0202)
+ */
+struct avf_aqc_add_remove_statistics {
+ __le16 seid;
+ __le16 vlan;
+ __le16 stat_index;
+ u8 reserved[10];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_add_remove_statistics);
+
+/* Set Port Parameters command (direct 0x0203) */
+struct avf_aqc_set_port_parameters {
+ __le16 command_flags;
+#define AVF_AQ_SET_P_PARAMS_SAVE_BAD_PACKETS 1
+#define AVF_AQ_SET_P_PARAMS_PAD_SHORT_PACKETS 2 /* must set! */
+#define AVF_AQ_SET_P_PARAMS_DOUBLE_VLAN_ENA 4
+ __le16 bad_frame_vsi;
+#define AVF_AQ_SET_P_PARAMS_BFRAME_SEID_SHIFT 0x0
+#define AVF_AQ_SET_P_PARAMS_BFRAME_SEID_MASK 0x3FF
+ __le16 default_seid; /* reserved for command */
+ u8 reserved[10];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_set_port_parameters);
+
+/* Get Switch Resource Allocation (indirect 0x0204) */
+struct avf_aqc_get_switch_resource_alloc {
+ u8 num_entries; /* reserved for command */
+ u8 reserved[7];
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_get_switch_resource_alloc);
+
+/* expect an array of these structs in the response buffer */
+struct avf_aqc_switch_resource_alloc_element_resp {
+ u8 resource_type;
+#define AVF_AQ_RESOURCE_TYPE_VEB 0x0
+#define AVF_AQ_RESOURCE_TYPE_VSI 0x1
+#define AVF_AQ_RESOURCE_TYPE_MACADDR 0x2
+#define AVF_AQ_RESOURCE_TYPE_STAG 0x3
+#define AVF_AQ_RESOURCE_TYPE_ETAG 0x4
+#define AVF_AQ_RESOURCE_TYPE_MULTICAST_HASH 0x5
+#define AVF_AQ_RESOURCE_TYPE_UNICAST_HASH 0x6
+#define AVF_AQ_RESOURCE_TYPE_VLAN 0x7
+#define AVF_AQ_RESOURCE_TYPE_VSI_LIST_ENTRY 0x8
+#define AVF_AQ_RESOURCE_TYPE_ETAG_LIST_ENTRY 0x9
+#define AVF_AQ_RESOURCE_TYPE_VLAN_STAT_POOL 0xA
+#define AVF_AQ_RESOURCE_TYPE_MIRROR_RULE 0xB
+#define AVF_AQ_RESOURCE_TYPE_QUEUE_SETS 0xC
+#define AVF_AQ_RESOURCE_TYPE_VLAN_FILTERS 0xD
+#define AVF_AQ_RESOURCE_TYPE_INNER_MAC_FILTERS 0xF
+#define AVF_AQ_RESOURCE_TYPE_IP_FILTERS 0x10
+#define AVF_AQ_RESOURCE_TYPE_GRE_VN_KEYS 0x11
+#define AVF_AQ_RESOURCE_TYPE_VN2_KEYS 0x12
+#define AVF_AQ_RESOURCE_TYPE_TUNNEL_PORTS 0x13
+ u8 reserved1;
+ __le16 guaranteed;
+ __le16 total;
+ __le16 used;
+ __le16 total_unalloced;
+ u8 reserved2[6];
+};
+
+AVF_CHECK_STRUCT_LEN(0x10, avf_aqc_switch_resource_alloc_element_resp);
+
+/* Set Switch Configuration (direct 0x0205) */
+struct avf_aqc_set_switch_config {
+ __le16 flags;
+/* flags used for both fields below */
+#define AVF_AQ_SET_SWITCH_CFG_PROMISC 0x0001
+#define AVF_AQ_SET_SWITCH_CFG_L2_FILTER 0x0002
+#define AVF_AQ_SET_SWITCH_CFG_HW_ATR_EVICT 0x0004
+ __le16 valid_flags;
+ /* The ethertype in switch_tag is dropped on ingress and used
+ * internally by the switch. Set this to zero for the default
+ * of 0x88a8 (802.1ad). Should be zero for firmware API
+ * versions lower than 1.7.
+ */
+ __le16 switch_tag;
+ /* The ethertypes in first_tag and second_tag are used to
+ * match the outer and inner VLAN tags (respectively) when HW
+ * double VLAN tagging is enabled via the set port parameters
+ * AQ command. Otherwise these are both ignored. Set them to
+ * zero for their defaults of 0x8100 (802.1Q). Should be zero
+ * for firmware API versions lower than 1.7.
+ */
+ __le16 first_tag;
+ __le16 second_tag;
+ u8 reserved[6];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_set_switch_config);
+
+/* Read Receive control registers (direct 0x0206)
+ * Write Receive control registers (direct 0x0207)
+ * used for accessing Rx control registers that can be
+ * slow and need special handling when under high Rx load
+ */
+struct avf_aqc_rx_ctl_reg_read_write {
+ __le32 reserved1;
+ __le32 address;
+ __le32 reserved2;
+ __le32 value;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_rx_ctl_reg_read_write);
+
+/* Add VSI (indirect 0x0210)
+ * this indirect command uses struct avf_aqc_vsi_properties_data
+ * as the indirect buffer (128 bytes)
+ *
+ * Update VSI (indirect 0x211)
+ * uses the same data structure as Add VSI
+ *
+ * Get VSI (indirect 0x0212)
+ * uses the same completion and data structure as Add VSI
+ */
+struct avf_aqc_add_get_update_vsi {
+ __le16 uplink_seid;
+ u8 connection_type;
+#define AVF_AQ_VSI_CONN_TYPE_NORMAL 0x1
+#define AVF_AQ_VSI_CONN_TYPE_DEFAULT 0x2
+#define AVF_AQ_VSI_CONN_TYPE_CASCADED 0x3
+ u8 reserved1;
+ u8 vf_id;
+ u8 reserved2;
+ __le16 vsi_flags;
+#define AVF_AQ_VSI_TYPE_SHIFT 0x0
+#define AVF_AQ_VSI_TYPE_MASK (0x3 << AVF_AQ_VSI_TYPE_SHIFT)
+#define AVF_AQ_VSI_TYPE_VF 0x0
+#define AVF_AQ_VSI_TYPE_VMDQ2 0x1
+#define AVF_AQ_VSI_TYPE_PF 0x2
+#define AVF_AQ_VSI_TYPE_EMP_MNG 0x3
+#define AVF_AQ_VSI_FLAG_CASCADED_PV 0x4
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_add_get_update_vsi);
+
+struct avf_aqc_add_get_update_vsi_completion {
+ __le16 seid;
+ __le16 vsi_number;
+ __le16 vsi_used;
+ __le16 vsi_free;
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_add_get_update_vsi_completion);
+
+struct avf_aqc_vsi_properties_data {
+ /* first 96 byte are written by SW */
+ __le16 valid_sections;
+#define AVF_AQ_VSI_PROP_SWITCH_VALID 0x0001
+#define AVF_AQ_VSI_PROP_SECURITY_VALID 0x0002
+#define AVF_AQ_VSI_PROP_VLAN_VALID 0x0004
+#define AVF_AQ_VSI_PROP_CAS_PV_VALID 0x0008
+#define AVF_AQ_VSI_PROP_INGRESS_UP_VALID 0x0010
+#define AVF_AQ_VSI_PROP_EGRESS_UP_VALID 0x0020
+#define AVF_AQ_VSI_PROP_QUEUE_MAP_VALID 0x0040
+#define AVF_AQ_VSI_PROP_QUEUE_OPT_VALID 0x0080
+#define AVF_AQ_VSI_PROP_OUTER_UP_VALID 0x0100
+#define AVF_AQ_VSI_PROP_SCHED_VALID 0x0200
+ /* switch section */
+ __le16 switch_id; /* 12bit id combined with flags below */
+#define AVF_AQ_VSI_SW_ID_SHIFT 0x0000
+#define AVF_AQ_VSI_SW_ID_MASK (0xFFF << AVF_AQ_VSI_SW_ID_SHIFT)
+#define AVF_AQ_VSI_SW_ID_FLAG_NOT_STAG 0x1000
+#define AVF_AQ_VSI_SW_ID_FLAG_ALLOW_LB 0x2000
+#define AVF_AQ_VSI_SW_ID_FLAG_LOCAL_LB 0x4000
+ u8 sw_reserved[2];
+ /* security section */
+ u8 sec_flags;
+#define AVF_AQ_VSI_SEC_FLAG_ALLOW_DEST_OVRD 0x01
+#define AVF_AQ_VSI_SEC_FLAG_ENABLE_VLAN_CHK 0x02
+#define AVF_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK 0x04
+ u8 sec_reserved;
+ /* VLAN section */
+ __le16 pvid; /* VLANS include priority bits */
+ __le16 fcoe_pvid;
+ u8 port_vlan_flags;
+#define AVF_AQ_VSI_PVLAN_MODE_SHIFT 0x00
+#define AVF_AQ_VSI_PVLAN_MODE_MASK (0x03 << \
+ AVF_AQ_VSI_PVLAN_MODE_SHIFT)
+#define AVF_AQ_VSI_PVLAN_MODE_TAGGED 0x01
+#define AVF_AQ_VSI_PVLAN_MODE_UNTAGGED 0x02
+#define AVF_AQ_VSI_PVLAN_MODE_ALL 0x03
+#define AVF_AQ_VSI_PVLAN_INSERT_PVID 0x04
+#define AVF_AQ_VSI_PVLAN_EMOD_SHIFT 0x03
+#define AVF_AQ_VSI_PVLAN_EMOD_MASK (0x3 << \
+ AVF_AQ_VSI_PVLAN_EMOD_SHIFT)
+#define AVF_AQ_VSI_PVLAN_EMOD_STR_BOTH 0x0
+#define AVF_AQ_VSI_PVLAN_EMOD_STR_UP 0x08
+#define AVF_AQ_VSI_PVLAN_EMOD_STR 0x10
+#define AVF_AQ_VSI_PVLAN_EMOD_NOTHING 0x18
+ u8 pvlan_reserved[3];
+ /* ingress egress up sections */
+ __le32 ingress_table; /* bitmap, 3 bits per up */
+#define AVF_AQ_VSI_UP_TABLE_UP0_SHIFT 0
+#define AVF_AQ_VSI_UP_TABLE_UP0_MASK (0x7 << \
+ AVF_AQ_VSI_UP_TABLE_UP0_SHIFT)
+#define AVF_AQ_VSI_UP_TABLE_UP1_SHIFT 3
+#define AVF_AQ_VSI_UP_TABLE_UP1_MASK (0x7 << \
+ AVF_AQ_VSI_UP_TABLE_UP1_SHIFT)
+#define AVF_AQ_VSI_UP_TABLE_UP2_SHIFT 6
+#define AVF_AQ_VSI_UP_TABLE_UP2_MASK (0x7 << \
+ AVF_AQ_VSI_UP_TABLE_UP2_SHIFT)
+#define AVF_AQ_VSI_UP_TABLE_UP3_SHIFT 9
+#define AVF_AQ_VSI_UP_TABLE_UP3_MASK (0x7 << \
+ AVF_AQ_VSI_UP_TABLE_UP3_SHIFT)
+#define AVF_AQ_VSI_UP_TABLE_UP4_SHIFT 12
+#define AVF_AQ_VSI_UP_TABLE_UP4_MASK (0x7 << \
+ AVF_AQ_VSI_UP_TABLE_UP4_SHIFT)
+#define AVF_AQ_VSI_UP_TABLE_UP5_SHIFT 15
+#define AVF_AQ_VSI_UP_TABLE_UP5_MASK (0x7 << \
+ AVF_AQ_VSI_UP_TABLE_UP5_SHIFT)
+#define AVF_AQ_VSI_UP_TABLE_UP6_SHIFT 18
+#define AVF_AQ_VSI_UP_TABLE_UP6_MASK (0x7 << \
+ AVF_AQ_VSI_UP_TABLE_UP6_SHIFT)
+#define AVF_AQ_VSI_UP_TABLE_UP7_SHIFT 21
+#define AVF_AQ_VSI_UP_TABLE_UP7_MASK (0x7 << \
+ AVF_AQ_VSI_UP_TABLE_UP7_SHIFT)
+ __le32 egress_table; /* same defines as for ingress table */
+ /* cascaded PV section */
+ __le16 cas_pv_tag;
+ u8 cas_pv_flags;
+#define AVF_AQ_VSI_CAS_PV_TAGX_SHIFT 0x00
+#define AVF_AQ_VSI_CAS_PV_TAGX_MASK (0x03 << \
+ AVF_AQ_VSI_CAS_PV_TAGX_SHIFT)
+#define AVF_AQ_VSI_CAS_PV_TAGX_LEAVE 0x00
+#define AVF_AQ_VSI_CAS_PV_TAGX_REMOVE 0x01
+#define AVF_AQ_VSI_CAS_PV_TAGX_COPY 0x02
+#define AVF_AQ_VSI_CAS_PV_INSERT_TAG 0x10
+#define AVF_AQ_VSI_CAS_PV_ETAG_PRUNE 0x20
+#define AVF_AQ_VSI_CAS_PV_ACCEPT_HOST_TAG 0x40
+ u8 cas_pv_reserved;
+ /* queue mapping section */
+ __le16 mapping_flags;
+#define AVF_AQ_VSI_QUE_MAP_CONTIG 0x0
+#define AVF_AQ_VSI_QUE_MAP_NONCONTIG 0x1
+ __le16 queue_mapping[16];
+#define AVF_AQ_VSI_QUEUE_SHIFT 0x0
+#define AVF_AQ_VSI_QUEUE_MASK (0x7FF << AVF_AQ_VSI_QUEUE_SHIFT)
+ __le16 tc_mapping[8];
+#define AVF_AQ_VSI_TC_QUE_OFFSET_SHIFT 0
+#define AVF_AQ_VSI_TC_QUE_OFFSET_MASK (0x1FF << \
+ AVF_AQ_VSI_TC_QUE_OFFSET_SHIFT)
+#define AVF_AQ_VSI_TC_QUE_NUMBER_SHIFT 9
+#define AVF_AQ_VSI_TC_QUE_NUMBER_MASK (0x7 << \
+ AVF_AQ_VSI_TC_QUE_NUMBER_SHIFT)
+ /* queueing option section */
+ u8 queueing_opt_flags;
+#define AVF_AQ_VSI_QUE_OPT_MULTICAST_UDP_ENA 0x04
+#define AVF_AQ_VSI_QUE_OPT_UNICAST_UDP_ENA 0x08
+#define AVF_AQ_VSI_QUE_OPT_TCP_ENA 0x10
+#define AVF_AQ_VSI_QUE_OPT_FCOE_ENA 0x20
+#define AVF_AQ_VSI_QUE_OPT_RSS_LUT_PF 0x00
+#define AVF_AQ_VSI_QUE_OPT_RSS_LUT_VSI 0x40
+ u8 queueing_opt_reserved[3];
+ /* scheduler section */
+ u8 up_enable_bits;
+ u8 sched_reserved;
+ /* outer up section */
+ __le32 outer_up_table; /* same structure and defines as ingress tbl */
+ u8 cmd_reserved[8];
+ /* last 32 bytes are written by FW */
+ __le16 qs_handle[8];
+#define AVF_AQ_VSI_QS_HANDLE_INVALID 0xFFFF
+ __le16 stat_counter_idx;
+ __le16 sched_id;
+ u8 resp_reserved[12];
+};
+
+AVF_CHECK_STRUCT_LEN(128, avf_aqc_vsi_properties_data);
+
+/* Add Port Virtualizer (direct 0x0220)
+ * also used for update PV (direct 0x0221) but only flags are used
+ * (IS_CTRL_PORT only works on add PV)
+ */
+struct avf_aqc_add_update_pv {
+ __le16 command_flags;
+#define AVF_AQC_PV_FLAG_PV_TYPE 0x1
+#define AVF_AQC_PV_FLAG_FWD_UNKNOWN_STAG_EN 0x2
+#define AVF_AQC_PV_FLAG_FWD_UNKNOWN_ETAG_EN 0x4
+#define AVF_AQC_PV_FLAG_IS_CTRL_PORT 0x8
+ __le16 uplink_seid;
+ __le16 connected_seid;
+ u8 reserved[10];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_add_update_pv);
+
+struct avf_aqc_add_update_pv_completion {
+ /* reserved for update; for add also encodes error if rc == ENOSPC */
+ __le16 pv_seid;
+#define AVF_AQC_PV_ERR_FLAG_NO_PV 0x1
+#define AVF_AQC_PV_ERR_FLAG_NO_SCHED 0x2
+#define AVF_AQC_PV_ERR_FLAG_NO_COUNTER 0x4
+#define AVF_AQC_PV_ERR_FLAG_NO_ENTRY 0x8
+ u8 reserved[14];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_add_update_pv_completion);
+
+/* Get PV Params (direct 0x0222)
+ * uses avf_aqc_switch_seid for the descriptor
+ */
+
+struct avf_aqc_get_pv_params_completion {
+ __le16 seid;
+ __le16 default_stag;
+ __le16 pv_flags; /* same flags as add_pv */
+#define AVF_AQC_GET_PV_PV_TYPE 0x1
+#define AVF_AQC_GET_PV_FRWD_UNKNOWN_STAG 0x2
+#define AVF_AQC_GET_PV_FRWD_UNKNOWN_ETAG 0x4
+ u8 reserved[8];
+ __le16 default_port_seid;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_get_pv_params_completion);
+
+/* Add VEB (direct 0x0230) */
+struct avf_aqc_add_veb {
+ __le16 uplink_seid;
+ __le16 downlink_seid;
+ __le16 veb_flags;
+#define AVF_AQC_ADD_VEB_FLOATING 0x1
+#define AVF_AQC_ADD_VEB_PORT_TYPE_SHIFT 1
+#define AVF_AQC_ADD_VEB_PORT_TYPE_MASK (0x3 << \
+ AVF_AQC_ADD_VEB_PORT_TYPE_SHIFT)
+#define AVF_AQC_ADD_VEB_PORT_TYPE_DEFAULT 0x2
+#define AVF_AQC_ADD_VEB_PORT_TYPE_DATA 0x4
+#define AVF_AQC_ADD_VEB_ENABLE_L2_FILTER 0x8 /* deprecated */
+#define AVF_AQC_ADD_VEB_ENABLE_DISABLE_STATS 0x10
+ u8 enable_tcs;
+ u8 reserved[9];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_add_veb);
+
+struct avf_aqc_add_veb_completion {
+ u8 reserved[6];
+ __le16 switch_seid;
+ /* also encodes error if rc == ENOSPC; codes are the same as add_pv */
+ __le16 veb_seid;
+#define AVF_AQC_VEB_ERR_FLAG_NO_VEB 0x1
+#define AVF_AQC_VEB_ERR_FLAG_NO_SCHED 0x2
+#define AVF_AQC_VEB_ERR_FLAG_NO_COUNTER 0x4
+#define AVF_AQC_VEB_ERR_FLAG_NO_ENTRY 0x8
+ __le16 statistic_index;
+ __le16 vebs_used;
+ __le16 vebs_free;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_add_veb_completion);
+
+/* Get VEB Parameters (direct 0x0232)
+ * uses avf_aqc_switch_seid for the descriptor
+ */
+struct avf_aqc_get_veb_parameters_completion {
+ __le16 seid;
+ __le16 switch_id;
+ __le16 veb_flags; /* only the first/last flags from 0x0230 is valid */
+ __le16 statistic_index;
+ __le16 vebs_used;
+ __le16 vebs_free;
+ u8 reserved[4];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_get_veb_parameters_completion);
+
+/* Delete Element (direct 0x0243)
+ * uses the generic avf_aqc_switch_seid
+ */
+
+/* Add MAC-VLAN (indirect 0x0250) */
+
+/* used for the command for most vlan commands */
+struct avf_aqc_macvlan {
+ __le16 num_addresses;
+ __le16 seid[3];
+#define AVF_AQC_MACVLAN_CMD_SEID_NUM_SHIFT 0
+#define AVF_AQC_MACVLAN_CMD_SEID_NUM_MASK (0x3FF << \
+ AVF_AQC_MACVLAN_CMD_SEID_NUM_SHIFT)
+#define AVF_AQC_MACVLAN_CMD_SEID_VALID 0x8000
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_macvlan);
+
+/* indirect data for command and response */
+struct avf_aqc_add_macvlan_element_data {
+ u8 mac_addr[6];
+ __le16 vlan_tag;
+ __le16 flags;
+#define AVF_AQC_MACVLAN_ADD_PERFECT_MATCH 0x0001
+#define AVF_AQC_MACVLAN_ADD_HASH_MATCH 0x0002
+#define AVF_AQC_MACVLAN_ADD_IGNORE_VLAN 0x0004
+#define AVF_AQC_MACVLAN_ADD_TO_QUEUE 0x0008
+#define AVF_AQC_MACVLAN_ADD_USE_SHARED_MAC 0x0010
+ __le16 queue_number;
+#define AVF_AQC_MACVLAN_CMD_QUEUE_SHIFT 0
+#define AVF_AQC_MACVLAN_CMD_QUEUE_MASK (0x7FF << \
+ AVF_AQC_MACVLAN_CMD_SEID_NUM_SHIFT)
+ /* response section */
+ u8 match_method;
+#define AVF_AQC_MM_PERFECT_MATCH 0x01
+#define AVF_AQC_MM_HASH_MATCH 0x02
+#define AVF_AQC_MM_ERR_NO_RES 0xFF
+ u8 reserved1[3];
+};
+
+struct avf_aqc_add_remove_macvlan_completion {
+ __le16 perfect_mac_used;
+ __le16 perfect_mac_free;
+ __le16 unicast_hash_free;
+ __le16 multicast_hash_free;
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_add_remove_macvlan_completion);
+
+/* Remove MAC-VLAN (indirect 0x0251)
+ * uses avf_aqc_macvlan for the descriptor
+ * data points to an array of num_addresses of elements
+ */
+
+struct avf_aqc_remove_macvlan_element_data {
+ u8 mac_addr[6];
+ __le16 vlan_tag;
+ u8 flags;
+#define AVF_AQC_MACVLAN_DEL_PERFECT_MATCH 0x01
+#define AVF_AQC_MACVLAN_DEL_HASH_MATCH 0x02
+#define AVF_AQC_MACVLAN_DEL_IGNORE_VLAN 0x08
+#define AVF_AQC_MACVLAN_DEL_ALL_VSIS 0x10
+ u8 reserved[3];
+ /* reply section */
+ u8 error_code;
+#define AVF_AQC_REMOVE_MACVLAN_SUCCESS 0x0
+#define AVF_AQC_REMOVE_MACVLAN_FAIL 0xFF
+ u8 reply_reserved[3];
+};
+
+/* Add VLAN (indirect 0x0252)
+ * Remove VLAN (indirect 0x0253)
+ * use the generic avf_aqc_macvlan for the command
+ */
+struct avf_aqc_add_remove_vlan_element_data {
+ __le16 vlan_tag;
+ u8 vlan_flags;
+/* flags for add VLAN */
+#define AVF_AQC_ADD_VLAN_LOCAL 0x1
+#define AVF_AQC_ADD_PVLAN_TYPE_SHIFT 1
+#define AVF_AQC_ADD_PVLAN_TYPE_MASK (0x3 << AVF_AQC_ADD_PVLAN_TYPE_SHIFT)
+#define AVF_AQC_ADD_PVLAN_TYPE_REGULAR 0x0
+#define AVF_AQC_ADD_PVLAN_TYPE_PRIMARY 0x2
+#define AVF_AQC_ADD_PVLAN_TYPE_SECONDARY 0x4
+#define AVF_AQC_VLAN_PTYPE_SHIFT 3
+#define AVF_AQC_VLAN_PTYPE_MASK (0x3 << AVF_AQC_VLAN_PTYPE_SHIFT)
+#define AVF_AQC_VLAN_PTYPE_REGULAR_VSI 0x0
+#define AVF_AQC_VLAN_PTYPE_PROMISC_VSI 0x8
+#define AVF_AQC_VLAN_PTYPE_COMMUNITY_VSI 0x10
+#define AVF_AQC_VLAN_PTYPE_ISOLATED_VSI 0x18
+/* flags for remove VLAN */
+#define AVF_AQC_REMOVE_VLAN_ALL 0x1
+ u8 reserved;
+ u8 result;
+/* flags for add VLAN */
+#define AVF_AQC_ADD_VLAN_SUCCESS 0x0
+#define AVF_AQC_ADD_VLAN_FAIL_REQUEST 0xFE
+#define AVF_AQC_ADD_VLAN_FAIL_RESOURCE 0xFF
+/* flags for remove VLAN */
+#define AVF_AQC_REMOVE_VLAN_SUCCESS 0x0
+#define AVF_AQC_REMOVE_VLAN_FAIL 0xFF
+ u8 reserved1[3];
+};
+
+struct avf_aqc_add_remove_vlan_completion {
+ u8 reserved[4];
+ __le16 vlans_used;
+ __le16 vlans_free;
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+/* Set VSI Promiscuous Modes (direct 0x0254) */
+struct avf_aqc_set_vsi_promiscuous_modes {
+ __le16 promiscuous_flags;
+ __le16 valid_flags;
+/* flags used for both fields above */
+#define AVF_AQC_SET_VSI_PROMISC_UNICAST 0x01
+#define AVF_AQC_SET_VSI_PROMISC_MULTICAST 0x02
+#define AVF_AQC_SET_VSI_PROMISC_BROADCAST 0x04
+#define AVF_AQC_SET_VSI_DEFAULT 0x08
+#define AVF_AQC_SET_VSI_PROMISC_VLAN 0x10
+#define AVF_AQC_SET_VSI_PROMISC_TX 0x8000
+ __le16 seid;
+#define AVF_AQC_VSI_PROM_CMD_SEID_MASK 0x3FF
+ __le16 vlan_tag;
+#define AVF_AQC_SET_VSI_VLAN_MASK 0x0FFF
+#define AVF_AQC_SET_VSI_VLAN_VALID 0x8000
+ u8 reserved[8];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_set_vsi_promiscuous_modes);
+
+/* Add S/E-tag command (direct 0x0255)
+ * Uses generic avf_aqc_add_remove_tag_completion for completion
+ */
+struct avf_aqc_add_tag {
+ __le16 flags;
+#define AVF_AQC_ADD_TAG_FLAG_TO_QUEUE 0x0001
+ __le16 seid;
+#define AVF_AQC_ADD_TAG_CMD_SEID_NUM_SHIFT 0
+#define AVF_AQC_ADD_TAG_CMD_SEID_NUM_MASK (0x3FF << \
+ AVF_AQC_ADD_TAG_CMD_SEID_NUM_SHIFT)
+ __le16 tag;
+ __le16 queue_number;
+ u8 reserved[8];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_add_tag);
+
+struct avf_aqc_add_remove_tag_completion {
+ u8 reserved[12];
+ __le16 tags_used;
+ __le16 tags_free;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_add_remove_tag_completion);
+
+/* Remove S/E-tag command (direct 0x0256)
+ * Uses generic avf_aqc_add_remove_tag_completion for completion
+ */
+struct avf_aqc_remove_tag {
+ __le16 seid;
+#define AVF_AQC_REMOVE_TAG_CMD_SEID_NUM_SHIFT 0
+#define AVF_AQC_REMOVE_TAG_CMD_SEID_NUM_MASK (0x3FF << \
+ AVF_AQC_REMOVE_TAG_CMD_SEID_NUM_SHIFT)
+ __le16 tag;
+ u8 reserved[12];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_remove_tag);
+
+/* Add multicast E-Tag (direct 0x0257)
+ * del multicast E-Tag (direct 0x0258) only uses pv_seid and etag fields
+ * and no external data
+ */
+struct avf_aqc_add_remove_mcast_etag {
+ __le16 pv_seid;
+ __le16 etag;
+ u8 num_unicast_etags;
+ u8 reserved[3];
+ __le32 addr_high; /* address of array of 2-byte s-tags */
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_add_remove_mcast_etag);
+
+struct avf_aqc_add_remove_mcast_etag_completion {
+ u8 reserved[4];
+ __le16 mcast_etags_used;
+ __le16 mcast_etags_free;
+ __le32 addr_high;
+ __le32 addr_low;
+
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_add_remove_mcast_etag_completion);
+
+/* Update S/E-Tag (direct 0x0259) */
+struct avf_aqc_update_tag {
+ __le16 seid;
+#define AVF_AQC_UPDATE_TAG_CMD_SEID_NUM_SHIFT 0
+#define AVF_AQC_UPDATE_TAG_CMD_SEID_NUM_MASK (0x3FF << \
+ AVF_AQC_UPDATE_TAG_CMD_SEID_NUM_SHIFT)
+ __le16 old_tag;
+ __le16 new_tag;
+ u8 reserved[10];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_update_tag);
+
+struct avf_aqc_update_tag_completion {
+ u8 reserved[12];
+ __le16 tags_used;
+ __le16 tags_free;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_update_tag_completion);
+
+/* Add Control Packet filter (direct 0x025A)
+ * Remove Control Packet filter (direct 0x025B)
+ * uses the avf_aqc_add_oveb_cloud,
+ * and the generic direct completion structure
+ */
+struct avf_aqc_add_remove_control_packet_filter {
+ u8 mac[6];
+ __le16 etype;
+ __le16 flags;
+#define AVF_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC 0x0001
+#define AVF_AQC_ADD_CONTROL_PACKET_FLAGS_DROP 0x0002
+#define AVF_AQC_ADD_CONTROL_PACKET_FLAGS_TO_QUEUE 0x0004
+#define AVF_AQC_ADD_CONTROL_PACKET_FLAGS_TX 0x0008
+#define AVF_AQC_ADD_CONTROL_PACKET_FLAGS_RX 0x0000
+ __le16 seid;
+#define AVF_AQC_ADD_CONTROL_PACKET_CMD_SEID_NUM_SHIFT 0
+#define AVF_AQC_ADD_CONTROL_PACKET_CMD_SEID_NUM_MASK (0x3FF << \
+ AVF_AQC_ADD_CONTROL_PACKET_CMD_SEID_NUM_SHIFT)
+ __le16 queue;
+ u8 reserved[2];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_add_remove_control_packet_filter);
+
+struct avf_aqc_add_remove_control_packet_filter_completion {
+ __le16 mac_etype_used;
+ __le16 etype_used;
+ __le16 mac_etype_free;
+ __le16 etype_free;
+ u8 reserved[8];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_add_remove_control_packet_filter_completion);
+
+/* Add Cloud filters (indirect 0x025C)
+ * Remove Cloud filters (indirect 0x025D)
+ * uses the avf_aqc_add_remove_cloud_filters,
+ * and the generic indirect completion structure
+ */
+struct avf_aqc_add_remove_cloud_filters {
+ u8 num_filters;
+ u8 reserved;
+ __le16 seid;
+#define AVF_AQC_ADD_CLOUD_CMD_SEID_NUM_SHIFT 0
+#define AVF_AQC_ADD_CLOUD_CMD_SEID_NUM_MASK (0x3FF << \
+ AVF_AQC_ADD_CLOUD_CMD_SEID_NUM_SHIFT)
+ u8 big_buffer_flag;
+#define AVF_AQC_ADD_REM_CLOUD_CMD_BIG_BUFFER 1
+ u8 reserved2[3];
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_add_remove_cloud_filters);
+
+struct avf_aqc_add_remove_cloud_filters_element_data {
+ u8 outer_mac[6];
+ u8 inner_mac[6];
+ __le16 inner_vlan;
+ union {
+ struct {
+ u8 reserved[12];
+ u8 data[4];
+ } v4;
+ struct {
+ u8 data[16];
+ } v6;
+ } ipaddr;
+ __le16 flags;
+#define AVF_AQC_ADD_CLOUD_FILTER_SHIFT 0
+#define AVF_AQC_ADD_CLOUD_FILTER_MASK (0x3F << \
+ AVF_AQC_ADD_CLOUD_FILTER_SHIFT)
+/* 0x0000 reserved */
+#define AVF_AQC_ADD_CLOUD_FILTER_OIP 0x0001
+/* 0x0002 reserved */
+#define AVF_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN 0x0003
+#define AVF_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_TEN_ID 0x0004
+/* 0x0005 reserved */
+#define AVF_AQC_ADD_CLOUD_FILTER_IMAC_TEN_ID 0x0006
+/* 0x0007 reserved */
+/* 0x0008 reserved */
+#define AVF_AQC_ADD_CLOUD_FILTER_OMAC 0x0009
+#define AVF_AQC_ADD_CLOUD_FILTER_IMAC 0x000A
+#define AVF_AQC_ADD_CLOUD_FILTER_OMAC_TEN_ID_IMAC 0x000B
+#define AVF_AQC_ADD_CLOUD_FILTER_IIP 0x000C
+/* 0x0010 to 0x0017 is for custom filters */
+
+#define AVF_AQC_ADD_CLOUD_FLAGS_TO_QUEUE 0x0080
+#define AVF_AQC_ADD_CLOUD_VNK_SHIFT 6
+#define AVF_AQC_ADD_CLOUD_VNK_MASK 0x00C0
+#define AVF_AQC_ADD_CLOUD_FLAGS_IPV4 0
+#define AVF_AQC_ADD_CLOUD_FLAGS_IPV6 0x0100
+
+#define AVF_AQC_ADD_CLOUD_TNL_TYPE_SHIFT 9
+#define AVF_AQC_ADD_CLOUD_TNL_TYPE_MASK 0x1E00
+#define AVF_AQC_ADD_CLOUD_TNL_TYPE_VXLAN 0
+#define AVF_AQC_ADD_CLOUD_TNL_TYPE_NVGRE_OMAC 1
+#define AVF_AQC_ADD_CLOUD_TNL_TYPE_GENEVE 2
+#define AVF_AQC_ADD_CLOUD_TNL_TYPE_IP 3
+#define AVF_AQC_ADD_CLOUD_TNL_TYPE_RESERVED 4
+#define AVF_AQC_ADD_CLOUD_TNL_TYPE_VXLAN_GPE 5
+
+#define AVF_AQC_ADD_CLOUD_FLAGS_SHARED_OUTER_MAC 0x2000
+#define AVF_AQC_ADD_CLOUD_FLAGS_SHARED_INNER_MAC 0x4000
+#define AVF_AQC_ADD_CLOUD_FLAGS_SHARED_OUTER_IP 0x8000
+
+ __le32 tenant_id;
+ u8 reserved[4];
+ __le16 queue_number;
+#define AVF_AQC_ADD_CLOUD_QUEUE_SHIFT 0
+#define AVF_AQC_ADD_CLOUD_QUEUE_MASK (0x7FF << \
+ AVF_AQC_ADD_CLOUD_QUEUE_SHIFT)
+ u8 reserved2[14];
+ /* response section */
+ u8 allocation_result;
+#define AVF_AQC_ADD_CLOUD_FILTER_SUCCESS 0x0
+#define AVF_AQC_ADD_CLOUD_FILTER_FAIL 0xFF
+ u8 response_reserved[7];
+};
+
+/* avf_aqc_add_rm_cloud_filt_elem_ext is used when
+ * AVF_AQC_ADD_REM_CLOUD_CMD_BIG_BUFFER flag is set.
+ */
+struct avf_aqc_add_rm_cloud_filt_elem_ext {
+ struct avf_aqc_add_remove_cloud_filters_element_data element;
+ u16 general_fields[32];
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X10_WORD0 0
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X10_WORD1 1
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X10_WORD2 2
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X11_WORD0 3
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X11_WORD1 4
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X11_WORD2 5
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X12_WORD0 6
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X12_WORD1 7
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X12_WORD2 8
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X13_WORD0 9
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X13_WORD1 10
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X13_WORD2 11
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X14_WORD0 12
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X14_WORD1 13
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X14_WORD2 14
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X16_WORD0 15
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X16_WORD1 16
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X16_WORD2 17
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X16_WORD3 18
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X16_WORD4 19
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X16_WORD5 20
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X16_WORD6 21
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X16_WORD7 22
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X17_WORD0 23
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X17_WORD1 24
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X17_WORD2 25
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X17_WORD3 26
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X17_WORD4 27
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X17_WORD5 28
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X17_WORD6 29
+#define AVF_AQC_ADD_CLOUD_FV_FLU_0X17_WORD7 30
+};
+
+struct avf_aqc_remove_cloud_filters_completion {
+ __le16 perfect_ovlan_used;
+ __le16 perfect_ovlan_free;
+ __le16 vlan_used;
+ __le16 vlan_free;
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_remove_cloud_filters_completion);
+
+/* Replace filter Command 0x025F
+ * uses the avf_aqc_replace_cloud_filters,
+ * and the generic indirect completion structure
+ */
+struct avf_filter_data {
+ u8 filter_type;
+ u8 input[3];
+};
+
+struct avf_aqc_replace_cloud_filters_cmd {
+ u8 valid_flags;
+#define AVF_AQC_REPLACE_L1_FILTER 0x0
+#define AVF_AQC_REPLACE_CLOUD_FILTER 0x1
+#define AVF_AQC_GET_CLOUD_FILTERS 0x2
+#define AVF_AQC_MIRROR_CLOUD_FILTER 0x4
+#define AVF_AQC_HIGH_PRIORITY_CLOUD_FILTER 0x8
+ u8 old_filter_type;
+ u8 new_filter_type;
+ u8 tr_bit;
+ u8 reserved[4];
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+struct avf_aqc_replace_cloud_filters_cmd_buf {
+ u8 data[32];
+/* Filter type INPUT codes*/
+#define AVF_AQC_REPLACE_CLOUD_CMD_INPUT_ENTRIES_MAX 3
+#define AVF_AQC_REPLACE_CLOUD_CMD_INPUT_VALIDATED (1 << 7UL)
+
+/* Field Vector offsets */
+#define AVF_AQC_REPLACE_CLOUD_CMD_INPUT_FV_MAC_DA 0
+#define AVF_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG_ETH 6
+#define AVF_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG 7
+#define AVF_AQC_REPLACE_CLOUD_CMD_INPUT_FV_VLAN 8
+#define AVF_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG_OVLAN 9
+#define AVF_AQC_REPLACE_CLOUD_CMD_INPUT_FV_STAG_IVLAN 10
+#define AVF_AQC_REPLACE_CLOUD_CMD_INPUT_FV_TUNNLE_KEY 11
+#define AVF_AQC_REPLACE_CLOUD_CMD_INPUT_FV_IMAC 12
+/* big FLU */
+#define AVF_AQC_REPLACE_CLOUD_CMD_INPUT_FV_IP_DA 14
+/* big FLU */
+#define AVF_AQC_REPLACE_CLOUD_CMD_INPUT_FV_OIP_DA 15
+
+#define AVF_AQC_REPLACE_CLOUD_CMD_INPUT_FV_INNER_VLAN 37
+ struct avf_filter_data filters[8];
+};
+
+/* Add Mirror Rule (indirect or direct 0x0260)
+ * Delete Mirror Rule (indirect or direct 0x0261)
+ * note: some rule types (4,5) do not use an external buffer.
+ * take care to set the flags correctly.
+ */
+struct avf_aqc_add_delete_mirror_rule {
+ __le16 seid;
+ __le16 rule_type;
+#define AVF_AQC_MIRROR_RULE_TYPE_SHIFT 0
+#define AVF_AQC_MIRROR_RULE_TYPE_MASK (0x7 << \
+ AVF_AQC_MIRROR_RULE_TYPE_SHIFT)
+#define AVF_AQC_MIRROR_RULE_TYPE_VPORT_INGRESS 1
+#define AVF_AQC_MIRROR_RULE_TYPE_VPORT_EGRESS 2
+#define AVF_AQC_MIRROR_RULE_TYPE_VLAN 3
+#define AVF_AQC_MIRROR_RULE_TYPE_ALL_INGRESS 4
+#define AVF_AQC_MIRROR_RULE_TYPE_ALL_EGRESS 5
+ __le16 num_entries;
+ __le16 destination; /* VSI for add, rule id for delete */
+ __le32 addr_high; /* address of array of 2-byte VSI or VLAN ids */
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_add_delete_mirror_rule);
+
+struct avf_aqc_add_delete_mirror_rule_completion {
+ u8 reserved[2];
+ __le16 rule_id; /* only used on add */
+ __le16 mirror_rules_used;
+ __le16 mirror_rules_free;
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_add_delete_mirror_rule_completion);
+
+/* Dynamic Device Personalization */
+struct avf_aqc_write_personalization_profile {
+ u8 flags;
+ u8 reserved[3];
+ __le32 profile_track_id;
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_write_personalization_profile);
+
+struct avf_aqc_write_ddp_resp {
+ __le32 error_offset;
+ __le32 error_info;
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+struct avf_aqc_get_applied_profiles {
+ u8 flags;
+#define AVF_AQC_GET_DDP_GET_CONF 0x1
+#define AVF_AQC_GET_DDP_GET_RDPU_CONF 0x2
+ u8 rsv[3];
+ __le32 reserved;
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_get_applied_profiles);
+
+/* DCB 0x03xx*/
+
+/* PFC Ignore (direct 0x0301)
+ * the command and response use the same descriptor structure
+ */
+struct avf_aqc_pfc_ignore {
+ u8 tc_bitmap;
+ u8 command_flags; /* unused on response */
+#define AVF_AQC_PFC_IGNORE_SET 0x80
+#define AVF_AQC_PFC_IGNORE_CLEAR 0x0
+ u8 reserved[14];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_pfc_ignore);
+
+/* DCB Update (direct 0x0302) uses the avf_aq_desc structure
+ * with no parameters
+ */
+
+/* TX scheduler 0x04xx */
+
+/* Almost all the indirect commands use
+ * this generic struct to pass the SEID in param0
+ */
+struct avf_aqc_tx_sched_ind {
+ __le16 vsi_seid;
+ u8 reserved[6];
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_tx_sched_ind);
+
+/* Several commands respond with a set of queue set handles */
+struct avf_aqc_qs_handles_resp {
+ __le16 qs_handles[8];
+};
+
+/* Configure VSI BW limits (direct 0x0400) */
+struct avf_aqc_configure_vsi_bw_limit {
+ __le16 vsi_seid;
+ u8 reserved[2];
+ __le16 credit;
+ u8 reserved1[2];
+ u8 max_credit; /* 0-3, limit = 2^max */
+ u8 reserved2[7];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_configure_vsi_bw_limit);
+
+/* Configure VSI Bandwidth Limit per Traffic Type (indirect 0x0406)
+ * responds with avf_aqc_qs_handles_resp
+ */
+struct avf_aqc_configure_vsi_ets_sla_bw_data {
+ u8 tc_valid_bits;
+ u8 reserved[15];
+ __le16 tc_bw_credits[8]; /* FW writesback QS handles here */
+
+ /* 4 bits per tc 0-7, 4th bit is reserved, limit = 2^max */
+ __le16 tc_bw_max[2];
+ u8 reserved1[28];
+};
+
+AVF_CHECK_STRUCT_LEN(0x40, avf_aqc_configure_vsi_ets_sla_bw_data);
+
+/* Configure VSI Bandwidth Allocation per Traffic Type (indirect 0x0407)
+ * responds with avf_aqc_qs_handles_resp
+ */
+struct avf_aqc_configure_vsi_tc_bw_data {
+ u8 tc_valid_bits;
+ u8 reserved[3];
+ u8 tc_bw_credits[8];
+ u8 reserved1[4];
+ __le16 qs_handles[8];
+};
+
+AVF_CHECK_STRUCT_LEN(0x20, avf_aqc_configure_vsi_tc_bw_data);
+
+/* Query vsi bw configuration (indirect 0x0408) */
+struct avf_aqc_query_vsi_bw_config_resp {
+ u8 tc_valid_bits;
+ u8 tc_suspended_bits;
+ u8 reserved[14];
+ __le16 qs_handles[8];
+ u8 reserved1[4];
+ __le16 port_bw_limit;
+ u8 reserved2[2];
+ u8 max_bw; /* 0-3, limit = 2^max */
+ u8 reserved3[23];
+};
+
+AVF_CHECK_STRUCT_LEN(0x40, avf_aqc_query_vsi_bw_config_resp);
+
+/* Query VSI Bandwidth Allocation per Traffic Type (indirect 0x040A) */
+struct avf_aqc_query_vsi_ets_sla_config_resp {
+ u8 tc_valid_bits;
+ u8 reserved[3];
+ u8 share_credits[8];
+ __le16 credits[8];
+
+ /* 4 bits per tc 0-7, 4th bit is reserved, limit = 2^max */
+ __le16 tc_bw_max[2];
+};
+
+AVF_CHECK_STRUCT_LEN(0x20, avf_aqc_query_vsi_ets_sla_config_resp);
+
+/* Configure Switching Component Bandwidth Limit (direct 0x0410) */
+struct avf_aqc_configure_switching_comp_bw_limit {
+ __le16 seid;
+ u8 reserved[2];
+ __le16 credit;
+ u8 reserved1[2];
+ u8 max_bw; /* 0-3, limit = 2^max */
+ u8 reserved2[7];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_configure_switching_comp_bw_limit);
+
+/* Enable Physical Port ETS (indirect 0x0413)
+ * Modify Physical Port ETS (indirect 0x0414)
+ * Disable Physical Port ETS (indirect 0x0415)
+ */
+struct avf_aqc_configure_switching_comp_ets_data {
+ u8 reserved[4];
+ u8 tc_valid_bits;
+ u8 seepage;
+#define AVF_AQ_ETS_SEEPAGE_EN_MASK 0x1
+ u8 tc_strict_priority_flags;
+ u8 reserved1[17];
+ u8 tc_bw_share_credits[8];
+ u8 reserved2[96];
+};
+
+AVF_CHECK_STRUCT_LEN(0x80, avf_aqc_configure_switching_comp_ets_data);
+
+/* Configure Switching Component Bandwidth Limits per Tc (indirect 0x0416) */
+struct avf_aqc_configure_switching_comp_ets_bw_limit_data {
+ u8 tc_valid_bits;
+ u8 reserved[15];
+ __le16 tc_bw_credit[8];
+
+ /* 4 bits per tc 0-7, 4th bit is reserved, limit = 2^max */
+ __le16 tc_bw_max[2];
+ u8 reserved1[28];
+};
+
+AVF_CHECK_STRUCT_LEN(0x40,
+ avf_aqc_configure_switching_comp_ets_bw_limit_data);
+
+/* Configure Switching Component Bandwidth Allocation per Tc
+ * (indirect 0x0417)
+ */
+struct avf_aqc_configure_switching_comp_bw_config_data {
+ u8 tc_valid_bits;
+ u8 reserved[2];
+ u8 absolute_credits; /* bool */
+ u8 tc_bw_share_credits[8];
+ u8 reserved1[20];
+};
+
+AVF_CHECK_STRUCT_LEN(0x20, avf_aqc_configure_switching_comp_bw_config_data);
+
+/* Query Switching Component Configuration (indirect 0x0418) */
+struct avf_aqc_query_switching_comp_ets_config_resp {
+ u8 tc_valid_bits;
+ u8 reserved[35];
+ __le16 port_bw_limit;
+ u8 reserved1[2];
+ u8 tc_bw_max; /* 0-3, limit = 2^max */
+ u8 reserved2[23];
+};
+
+AVF_CHECK_STRUCT_LEN(0x40, avf_aqc_query_switching_comp_ets_config_resp);
+
+/* Query PhysicalPort ETS Configuration (indirect 0x0419) */
+struct avf_aqc_query_port_ets_config_resp {
+ u8 reserved[4];
+ u8 tc_valid_bits;
+ u8 reserved1;
+ u8 tc_strict_priority_bits;
+ u8 reserved2;
+ u8 tc_bw_share_credits[8];
+ __le16 tc_bw_limits[8];
+
+ /* 4 bits per tc 0-7, 4th bit reserved, limit = 2^max */
+ __le16 tc_bw_max[2];
+ u8 reserved3[32];
+};
+
+AVF_CHECK_STRUCT_LEN(0x44, avf_aqc_query_port_ets_config_resp);
+
+/* Query Switching Component Bandwidth Allocation per Traffic Type
+ * (indirect 0x041A)
+ */
+struct avf_aqc_query_switching_comp_bw_config_resp {
+ u8 tc_valid_bits;
+ u8 reserved[2];
+ u8 absolute_credits_enable; /* bool */
+ u8 tc_bw_share_credits[8];
+ __le16 tc_bw_limits[8];
+
+ /* 4 bits per tc 0-7, 4th bit is reserved, limit = 2^max */
+ __le16 tc_bw_max[2];
+};
+
+AVF_CHECK_STRUCT_LEN(0x20, avf_aqc_query_switching_comp_bw_config_resp);
+
+/* Suspend/resume port TX traffic
+ * (direct 0x041B and 0x041C) uses the generic SEID struct
+ */
+
+/* Configure partition BW
+ * (indirect 0x041D)
+ */
+struct avf_aqc_configure_partition_bw_data {
+ __le16 pf_valid_bits;
+ u8 min_bw[16]; /* guaranteed bandwidth */
+ u8 max_bw[16]; /* bandwidth limit */
+};
+
+AVF_CHECK_STRUCT_LEN(0x22, avf_aqc_configure_partition_bw_data);
+
+/* Get and set the active HMC resource profile and status.
+ * (direct 0x0500) and (direct 0x0501)
+ */
+struct avf_aq_get_set_hmc_resource_profile {
+ u8 pm_profile;
+ u8 pe_vf_enabled;
+ u8 reserved[14];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aq_get_set_hmc_resource_profile);
+
+enum avf_aq_hmc_profile {
+ /* AVF_HMC_PROFILE_NO_CHANGE = 0, reserved */
+ AVF_HMC_PROFILE_DEFAULT = 1,
+ AVF_HMC_PROFILE_FAVOR_VF = 2,
+ AVF_HMC_PROFILE_EQUAL = 3,
+};
+
+/* Get PHY Abilities (indirect 0x0600) uses the generic indirect struct */
+
+/* set in param0 for get phy abilities to report qualified modules */
+#define AVF_AQ_PHY_REPORT_QUALIFIED_MODULES 0x0001
+#define AVF_AQ_PHY_REPORT_INITIAL_VALUES 0x0002
+
+enum avf_aq_phy_type {
+ AVF_PHY_TYPE_SGMII = 0x0,
+ AVF_PHY_TYPE_1000BASE_KX = 0x1,
+ AVF_PHY_TYPE_10GBASE_KX4 = 0x2,
+ AVF_PHY_TYPE_10GBASE_KR = 0x3,
+ AVF_PHY_TYPE_40GBASE_KR4 = 0x4,
+ AVF_PHY_TYPE_XAUI = 0x5,
+ AVF_PHY_TYPE_XFI = 0x6,
+ AVF_PHY_TYPE_SFI = 0x7,
+ AVF_PHY_TYPE_XLAUI = 0x8,
+ AVF_PHY_TYPE_XLPPI = 0x9,
+ AVF_PHY_TYPE_40GBASE_CR4_CU = 0xA,
+ AVF_PHY_TYPE_10GBASE_CR1_CU = 0xB,
+ AVF_PHY_TYPE_10GBASE_AOC = 0xC,
+ AVF_PHY_TYPE_40GBASE_AOC = 0xD,
+ AVF_PHY_TYPE_UNRECOGNIZED = 0xE,
+ AVF_PHY_TYPE_UNSUPPORTED = 0xF,
+ AVF_PHY_TYPE_100BASE_TX = 0x11,
+ AVF_PHY_TYPE_1000BASE_T = 0x12,
+ AVF_PHY_TYPE_10GBASE_T = 0x13,
+ AVF_PHY_TYPE_10GBASE_SR = 0x14,
+ AVF_PHY_TYPE_10GBASE_LR = 0x15,
+ AVF_PHY_TYPE_10GBASE_SFPP_CU = 0x16,
+ AVF_PHY_TYPE_10GBASE_CR1 = 0x17,
+ AVF_PHY_TYPE_40GBASE_CR4 = 0x18,
+ AVF_PHY_TYPE_40GBASE_SR4 = 0x19,
+ AVF_PHY_TYPE_40GBASE_LR4 = 0x1A,
+ AVF_PHY_TYPE_1000BASE_SX = 0x1B,
+ AVF_PHY_TYPE_1000BASE_LX = 0x1C,
+ AVF_PHY_TYPE_1000BASE_T_OPTICAL = 0x1D,
+ AVF_PHY_TYPE_20GBASE_KR2 = 0x1E,
+ AVF_PHY_TYPE_25GBASE_KR = 0x1F,
+ AVF_PHY_TYPE_25GBASE_CR = 0x20,
+ AVF_PHY_TYPE_25GBASE_SR = 0x21,
+ AVF_PHY_TYPE_25GBASE_LR = 0x22,
+ AVF_PHY_TYPE_25GBASE_AOC = 0x23,
+ AVF_PHY_TYPE_25GBASE_ACC = 0x24,
+ AVF_PHY_TYPE_MAX,
+ AVF_PHY_TYPE_NOT_SUPPORTED_HIGH_TEMP = 0xFD,
+ AVF_PHY_TYPE_EMPTY = 0xFE,
+ AVF_PHY_TYPE_DEFAULT = 0xFF,
+};
+
+#define AVF_LINK_SPEED_100MB_SHIFT 0x1
+#define AVF_LINK_SPEED_1000MB_SHIFT 0x2
+#define AVF_LINK_SPEED_10GB_SHIFT 0x3
+#define AVF_LINK_SPEED_40GB_SHIFT 0x4
+#define AVF_LINK_SPEED_20GB_SHIFT 0x5
+#define AVF_LINK_SPEED_25GB_SHIFT 0x6
+
+enum avf_aq_link_speed {
+ AVF_LINK_SPEED_UNKNOWN = 0,
+ AVF_LINK_SPEED_100MB = (1 << AVF_LINK_SPEED_100MB_SHIFT),
+ AVF_LINK_SPEED_1GB = (1 << AVF_LINK_SPEED_1000MB_SHIFT),
+ AVF_LINK_SPEED_10GB = (1 << AVF_LINK_SPEED_10GB_SHIFT),
+ AVF_LINK_SPEED_40GB = (1 << AVF_LINK_SPEED_40GB_SHIFT),
+ AVF_LINK_SPEED_20GB = (1 << AVF_LINK_SPEED_20GB_SHIFT),
+ AVF_LINK_SPEED_25GB = (1 << AVF_LINK_SPEED_25GB_SHIFT),
+};
+
+struct avf_aqc_module_desc {
+ u8 oui[3];
+ u8 reserved1;
+ u8 part_number[16];
+ u8 revision[4];
+ u8 reserved2[8];
+};
+
+AVF_CHECK_STRUCT_LEN(0x20, avf_aqc_module_desc);
+
+struct avf_aq_get_phy_abilities_resp {
+ __le32 phy_type; /* bitmap using the above enum for offsets */
+ u8 link_speed; /* bitmap using the above enum bit patterns */
+ u8 abilities;
+#define AVF_AQ_PHY_FLAG_PAUSE_TX 0x01
+#define AVF_AQ_PHY_FLAG_PAUSE_RX 0x02
+#define AVF_AQ_PHY_FLAG_LOW_POWER 0x04
+#define AVF_AQ_PHY_LINK_ENABLED 0x08
+#define AVF_AQ_PHY_AN_ENABLED 0x10
+#define AVF_AQ_PHY_FLAG_MODULE_QUAL 0x20
+#define AVF_AQ_PHY_FEC_ABILITY_KR 0x40
+#define AVF_AQ_PHY_FEC_ABILITY_RS 0x80
+ __le16 eee_capability;
+#define AVF_AQ_EEE_100BASE_TX 0x0002
+#define AVF_AQ_EEE_1000BASE_T 0x0004
+#define AVF_AQ_EEE_10GBASE_T 0x0008
+#define AVF_AQ_EEE_1000BASE_KX 0x0010
+#define AVF_AQ_EEE_10GBASE_KX4 0x0020
+#define AVF_AQ_EEE_10GBASE_KR 0x0040
+ __le32 eeer_val;
+ u8 d3_lpan;
+#define AVF_AQ_SET_PHY_D3_LPAN_ENA 0x01
+ u8 phy_type_ext;
+#define AVF_AQ_PHY_TYPE_EXT_25G_KR 0x01
+#define AVF_AQ_PHY_TYPE_EXT_25G_CR 0x02
+#define AVF_AQ_PHY_TYPE_EXT_25G_SR 0x04
+#define AVF_AQ_PHY_TYPE_EXT_25G_LR 0x08
+#define AVF_AQ_PHY_TYPE_EXT_25G_AOC 0x10
+#define AVF_AQ_PHY_TYPE_EXT_25G_ACC 0x20
+ u8 fec_cfg_curr_mod_ext_info;
+#define AVF_AQ_ENABLE_FEC_KR 0x01
+#define AVF_AQ_ENABLE_FEC_RS 0x02
+#define AVF_AQ_REQUEST_FEC_KR 0x04
+#define AVF_AQ_REQUEST_FEC_RS 0x08
+#define AVF_AQ_ENABLE_FEC_AUTO 0x10
+#define AVF_AQ_FEC
+#define AVF_AQ_MODULE_TYPE_EXT_MASK 0xE0
+#define AVF_AQ_MODULE_TYPE_EXT_SHIFT 5
+
+ u8 ext_comp_code;
+ u8 phy_id[4];
+ u8 module_type[3];
+ u8 qualified_module_count;
+#define AVF_AQ_PHY_MAX_QMS 16
+ struct avf_aqc_module_desc qualified_module[AVF_AQ_PHY_MAX_QMS];
+};
+
+AVF_CHECK_STRUCT_LEN(0x218, avf_aq_get_phy_abilities_resp);
+
+/* Set PHY Config (direct 0x0601) */
+struct avf_aq_set_phy_config { /* same bits as above in all */
+ __le32 phy_type;
+ u8 link_speed;
+ u8 abilities;
+/* bits 0-2 use the values from get_phy_abilities_resp */
+#define AVF_AQ_PHY_ENABLE_LINK 0x08
+#define AVF_AQ_PHY_ENABLE_AN 0x10
+#define AVF_AQ_PHY_ENABLE_ATOMIC_LINK 0x20
+ __le16 eee_capability;
+ __le32 eeer;
+ u8 low_power_ctrl;
+ u8 phy_type_ext;
+ u8 fec_config;
+#define AVF_AQ_SET_FEC_ABILITY_KR BIT(0)
+#define AVF_AQ_SET_FEC_ABILITY_RS BIT(1)
+#define AVF_AQ_SET_FEC_REQUEST_KR BIT(2)
+#define AVF_AQ_SET_FEC_REQUEST_RS BIT(3)
+#define AVF_AQ_SET_FEC_AUTO BIT(4)
+#define AVF_AQ_PHY_FEC_CONFIG_SHIFT 0x0
+#define AVF_AQ_PHY_FEC_CONFIG_MASK (0x1F << AVF_AQ_PHY_FEC_CONFIG_SHIFT)
+ u8 reserved;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aq_set_phy_config);
+
+/* Set MAC Config command data structure (direct 0x0603) */
+struct avf_aq_set_mac_config {
+ __le16 max_frame_size;
+ u8 params;
+#define AVF_AQ_SET_MAC_CONFIG_CRC_EN 0x04
+#define AVF_AQ_SET_MAC_CONFIG_PACING_MASK 0x78
+#define AVF_AQ_SET_MAC_CONFIG_PACING_SHIFT 3
+#define AVF_AQ_SET_MAC_CONFIG_PACING_NONE 0x0
+#define AVF_AQ_SET_MAC_CONFIG_PACING_1B_13TX 0xF
+#define AVF_AQ_SET_MAC_CONFIG_PACING_1DW_9TX 0x9
+#define AVF_AQ_SET_MAC_CONFIG_PACING_1DW_4TX 0x8
+#define AVF_AQ_SET_MAC_CONFIG_PACING_3DW_7TX 0x7
+#define AVF_AQ_SET_MAC_CONFIG_PACING_2DW_3TX 0x6
+#define AVF_AQ_SET_MAC_CONFIG_PACING_1DW_1TX 0x5
+#define AVF_AQ_SET_MAC_CONFIG_PACING_3DW_2TX 0x4
+#define AVF_AQ_SET_MAC_CONFIG_PACING_7DW_3TX 0x3
+#define AVF_AQ_SET_MAC_CONFIG_PACING_4DW_1TX 0x2
+#define AVF_AQ_SET_MAC_CONFIG_PACING_9DW_1TX 0x1
+ u8 tx_timer_priority; /* bitmap */
+ __le16 tx_timer_value;
+ __le16 fc_refresh_threshold;
+ u8 reserved[8];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aq_set_mac_config);
+
+/* Restart Auto-Negotiation (direct 0x605) */
+struct avf_aqc_set_link_restart_an {
+ u8 command;
+#define AVF_AQ_PHY_RESTART_AN 0x02
+#define AVF_AQ_PHY_LINK_ENABLE 0x04
+ u8 reserved[15];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_set_link_restart_an);
+
+/* Get Link Status cmd & response data structure (direct 0x0607) */
+struct avf_aqc_get_link_status {
+ __le16 command_flags; /* only field set on command */
+#define AVF_AQ_LSE_MASK 0x3
+#define AVF_AQ_LSE_NOP 0x0
+#define AVF_AQ_LSE_DISABLE 0x2
+#define AVF_AQ_LSE_ENABLE 0x3
+/* only response uses this flag */
+#define AVF_AQ_LSE_IS_ENABLED 0x1
+ u8 phy_type; /* avf_aq_phy_type */
+ u8 link_speed; /* avf_aq_link_speed */
+ u8 link_info;
+#define AVF_AQ_LINK_UP 0x01 /* obsolete */
+#define AVF_AQ_LINK_UP_FUNCTION 0x01
+#define AVF_AQ_LINK_FAULT 0x02
+#define AVF_AQ_LINK_FAULT_TX 0x04
+#define AVF_AQ_LINK_FAULT_RX 0x08
+#define AVF_AQ_LINK_FAULT_REMOTE 0x10
+#define AVF_AQ_LINK_UP_PORT 0x20
+#define AVF_AQ_MEDIA_AVAILABLE 0x40
+#define AVF_AQ_SIGNAL_DETECT 0x80
+ u8 an_info;
+#define AVF_AQ_AN_COMPLETED 0x01
+#define AVF_AQ_LP_AN_ABILITY 0x02
+#define AVF_AQ_PD_FAULT 0x04
+#define AVF_AQ_FEC_EN 0x08
+#define AVF_AQ_PHY_LOW_POWER 0x10
+#define AVF_AQ_LINK_PAUSE_TX 0x20
+#define AVF_AQ_LINK_PAUSE_RX 0x40
+#define AVF_AQ_QUALIFIED_MODULE 0x80
+ u8 ext_info;
+#define AVF_AQ_LINK_PHY_TEMP_ALARM 0x01
+#define AVF_AQ_LINK_XCESSIVE_ERRORS 0x02
+#define AVF_AQ_LINK_TX_SHIFT 0x02
+#define AVF_AQ_LINK_TX_MASK (0x03 << AVF_AQ_LINK_TX_SHIFT)
+#define AVF_AQ_LINK_TX_ACTIVE 0x00
+#define AVF_AQ_LINK_TX_DRAINED 0x01
+#define AVF_AQ_LINK_TX_FLUSHED 0x03
+#define AVF_AQ_LINK_FORCED_40G 0x10
+/* 25G Error Codes */
+#define AVF_AQ_25G_NO_ERR 0X00
+#define AVF_AQ_25G_NOT_PRESENT 0X01
+#define AVF_AQ_25G_NVM_CRC_ERR 0X02
+#define AVF_AQ_25G_SBUS_UCODE_ERR 0X03
+#define AVF_AQ_25G_SERDES_UCODE_ERR 0X04
+#define AVF_AQ_25G_NIMB_UCODE_ERR 0X05
+ u8 loopback; /* use defines from avf_aqc_set_lb_mode */
+/* Since firmware API 1.7 loopback field keeps power class info as well */
+#define AVF_AQ_LOOPBACK_MASK 0x07
+#define AVF_AQ_PWR_CLASS_SHIFT_LB 6
+#define AVF_AQ_PWR_CLASS_MASK_LB (0x03 << AVF_AQ_PWR_CLASS_SHIFT_LB)
+ __le16 max_frame_size;
+ u8 config;
+#define AVF_AQ_CONFIG_FEC_KR_ENA 0x01
+#define AVF_AQ_CONFIG_FEC_RS_ENA 0x02
+#define AVF_AQ_CONFIG_CRC_ENA 0x04
+#define AVF_AQ_CONFIG_PACING_MASK 0x78
+ union {
+ struct {
+ u8 power_desc;
+#define AVF_AQ_LINK_POWER_CLASS_1 0x00
+#define AVF_AQ_LINK_POWER_CLASS_2 0x01
+#define AVF_AQ_LINK_POWER_CLASS_3 0x02
+#define AVF_AQ_LINK_POWER_CLASS_4 0x03
+#define AVF_AQ_PWR_CLASS_MASK 0x03
+ u8 reserved[4];
+ };
+ struct {
+ u8 link_type[4];
+ u8 link_type_ext;
+ };
+ };
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_get_link_status);
+
+/* Set event mask command (direct 0x613) */
+struct avf_aqc_set_phy_int_mask {
+ u8 reserved[8];
+ __le16 event_mask;
+#define AVF_AQ_EVENT_LINK_UPDOWN 0x0002
+#define AVF_AQ_EVENT_MEDIA_NA 0x0004
+#define AVF_AQ_EVENT_LINK_FAULT 0x0008
+#define AVF_AQ_EVENT_PHY_TEMP_ALARM 0x0010
+#define AVF_AQ_EVENT_EXCESSIVE_ERRORS 0x0020
+#define AVF_AQ_EVENT_SIGNAL_DETECT 0x0040
+#define AVF_AQ_EVENT_AN_COMPLETED 0x0080
+#define AVF_AQ_EVENT_MODULE_QUAL_FAIL 0x0100
+#define AVF_AQ_EVENT_PORT_TX_SUSPENDED 0x0200
+ u8 reserved1[6];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_set_phy_int_mask);
+
+/* Get Local AN advt register (direct 0x0614)
+ * Set Local AN advt register (direct 0x0615)
+ * Get Link Partner AN advt register (direct 0x0616)
+ */
+struct avf_aqc_an_advt_reg {
+ __le32 local_an_reg0;
+ __le16 local_an_reg1;
+ u8 reserved[10];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_an_advt_reg);
+
+/* Set Loopback mode (0x0618) */
+struct avf_aqc_set_lb_mode {
+ u8 lb_level;
+#define AVF_AQ_LB_NONE 0
+#define AVF_AQ_LB_MAC 1
+#define AVF_AQ_LB_SERDES 2
+#define AVF_AQ_LB_PHY_INT 3
+#define AVF_AQ_LB_PHY_EXT 4
+#define AVF_AQ_LB_CPVL_PCS 5
+#define AVF_AQ_LB_CPVL_EXT 6
+#define AVF_AQ_LB_PHY_LOCAL 0x01
+#define AVF_AQ_LB_PHY_REMOTE 0x02
+#define AVF_AQ_LB_MAC_LOCAL 0x04
+ u8 lb_type;
+#define AVF_AQ_LB_LOCAL 0
+#define AVF_AQ_LB_FAR 0x01
+ u8 speed;
+#define AVF_AQ_LB_SPEED_NONE 0
+#define AVF_AQ_LB_SPEED_1G 1
+#define AVF_AQ_LB_SPEED_10G 2
+#define AVF_AQ_LB_SPEED_40G 3
+#define AVF_AQ_LB_SPEED_20G 4
+ u8 force_speed;
+ u8 reserved[12];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_set_lb_mode);
+
+/* Set PHY Debug command (0x0622) */
+struct avf_aqc_set_phy_debug {
+ u8 command_flags;
+#define AVF_AQ_PHY_DEBUG_RESET_INTERNAL 0x02
+#define AVF_AQ_PHY_DEBUG_RESET_EXTERNAL_SHIFT 2
+#define AVF_AQ_PHY_DEBUG_RESET_EXTERNAL_MASK (0x03 << \
+ AVF_AQ_PHY_DEBUG_RESET_EXTERNAL_SHIFT)
+#define AVF_AQ_PHY_DEBUG_RESET_EXTERNAL_NONE 0x00
+#define AVF_AQ_PHY_DEBUG_RESET_EXTERNAL_HARD 0x01
+#define AVF_AQ_PHY_DEBUG_RESET_EXTERNAL_SOFT 0x02
+/* Disable link manageability on a single port */
+#define AVF_AQ_PHY_DEBUG_DISABLE_LINK_FW 0x10
+/* Disable link manageability on all ports needs both bits 4 and 5 */
+#define AVF_AQ_PHY_DEBUG_DISABLE_ALL_LINK_FW 0x20
+ u8 reserved[15];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_set_phy_debug);
+
+enum avf_aq_phy_reg_type {
+ AVF_AQC_PHY_REG_INTERNAL = 0x1,
+ AVF_AQC_PHY_REG_EXERNAL_BASET = 0x2,
+ AVF_AQC_PHY_REG_EXERNAL_MODULE = 0x3
+};
+
+/* Run PHY Activity (0x0626) */
+struct avf_aqc_run_phy_activity {
+ __le16 activity_id;
+ u8 flags;
+ u8 reserved1;
+ __le32 control;
+ __le32 data;
+ u8 reserved2[4];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_run_phy_activity);
+
+/* Set PHY Register command (0x0628) */
+/* Get PHY Register command (0x0629) */
+struct avf_aqc_phy_register_access {
+ u8 phy_interface;
+#define AVF_AQ_PHY_REG_ACCESS_INTERNAL 0
+#define AVF_AQ_PHY_REG_ACCESS_EXTERNAL 1
+#define AVF_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE 2
+ u8 dev_addres;
+ u8 reserved1[2];
+ __le32 reg_address;
+ __le32 reg_value;
+ u8 reserved2[4];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_phy_register_access);
+
+/* NVM Read command (indirect 0x0701)
+ * NVM Erase commands (direct 0x0702)
+ * NVM Update commands (indirect 0x0703)
+ */
+struct avf_aqc_nvm_update {
+ u8 command_flags;
+#define AVF_AQ_NVM_LAST_CMD 0x01
+#define AVF_AQ_NVM_FLASH_ONLY 0x80
+#define AVF_AQ_NVM_PRESERVATION_FLAGS_SHIFT 1
+#define AVF_AQ_NVM_PRESERVATION_FLAGS_MASK 0x03
+#define AVF_AQ_NVM_PRESERVATION_FLAGS_SELECTED 0x03
+#define AVF_AQ_NVM_PRESERVATION_FLAGS_ALL 0x01
+ u8 module_pointer;
+ __le16 length;
+ __le32 offset;
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_nvm_update);
+
+/* NVM Config Read (indirect 0x0704) */
+struct avf_aqc_nvm_config_read {
+ __le16 cmd_flags;
+#define AVF_AQ_ANVM_SINGLE_OR_MULTIPLE_FEATURES_MASK 1
+#define AVF_AQ_ANVM_READ_SINGLE_FEATURE 0
+#define AVF_AQ_ANVM_READ_MULTIPLE_FEATURES 1
+ __le16 element_count;
+ __le16 element_id; /* Feature/field ID */
+ __le16 element_id_msw; /* MSWord of field ID */
+ __le32 address_high;
+ __le32 address_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_nvm_config_read);
+
+/* NVM Config Write (indirect 0x0705) */
+struct avf_aqc_nvm_config_write {
+ __le16 cmd_flags;
+ __le16 element_count;
+ u8 reserved[4];
+ __le32 address_high;
+ __le32 address_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_nvm_config_write);
+
+/* Used for 0x0704 as well as for 0x0705 commands */
+#define AVF_AQ_ANVM_FEATURE_OR_IMMEDIATE_SHIFT 1
+#define AVF_AQ_ANVM_FEATURE_OR_IMMEDIATE_MASK \
+ (1 << AVF_AQ_ANVM_FEATURE_OR_IMMEDIATE_SHIFT)
+#define AVF_AQ_ANVM_FEATURE 0
+#define AVF_AQ_ANVM_IMMEDIATE_FIELD (1 << FEATURE_OR_IMMEDIATE_SHIFT)
+struct avf_aqc_nvm_config_data_feature {
+ __le16 feature_id;
+#define AVF_AQ_ANVM_FEATURE_OPTION_OEM_ONLY 0x01
+#define AVF_AQ_ANVM_FEATURE_OPTION_DWORD_MAP 0x08
+#define AVF_AQ_ANVM_FEATURE_OPTION_POR_CSR 0x10
+ __le16 feature_options;
+ __le16 feature_selection;
+};
+
+AVF_CHECK_STRUCT_LEN(0x6, avf_aqc_nvm_config_data_feature);
+
+struct avf_aqc_nvm_config_data_immediate_field {
+ __le32 field_id;
+ __le32 field_value;
+ __le16 field_options;
+ __le16 reserved;
+};
+
+AVF_CHECK_STRUCT_LEN(0xc, avf_aqc_nvm_config_data_immediate_field);
+
+/* OEM Post Update (indirect 0x0720)
+ * no command data struct used
+ */
+struct avf_aqc_nvm_oem_post_update {
+#define AVF_AQ_NVM_OEM_POST_UPDATE_EXTERNAL_DATA 0x01
+ u8 sel_data;
+ u8 reserved[7];
+};
+
+AVF_CHECK_STRUCT_LEN(0x8, avf_aqc_nvm_oem_post_update);
+
+struct avf_aqc_nvm_oem_post_update_buffer {
+ u8 str_len;
+ u8 dev_addr;
+ __le16 eeprom_addr;
+ u8 data[36];
+};
+
+AVF_CHECK_STRUCT_LEN(0x28, avf_aqc_nvm_oem_post_update_buffer);
+
+/* Thermal Sensor (indirect 0x0721)
+ * read or set thermal sensor configs and values
+ * takes a sensor and command specific data buffer, not detailed here
+ */
+struct avf_aqc_thermal_sensor {
+ u8 sensor_action;
+#define AVF_AQ_THERMAL_SENSOR_READ_CONFIG 0
+#define AVF_AQ_THERMAL_SENSOR_SET_CONFIG 1
+#define AVF_AQ_THERMAL_SENSOR_READ_TEMP 2
+ u8 reserved[7];
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_thermal_sensor);
+
+/* Send to PF command (indirect 0x0801) id is only used by PF
+ * Send to VF command (indirect 0x0802) id is only used by PF
+ * Send to Peer PF command (indirect 0x0803)
+ */
+struct avf_aqc_pf_vf_message {
+ __le32 id;
+ u8 reserved[4];
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_pf_vf_message);
+
+/* Alternate structure */
+
+/* Direct write (direct 0x0900)
+ * Direct read (direct 0x0902)
+ */
+struct avf_aqc_alternate_write {
+ __le32 address0;
+ __le32 data0;
+ __le32 address1;
+ __le32 data1;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_alternate_write);
+
+/* Indirect write (indirect 0x0901)
+ * Indirect read (indirect 0x0903)
+ */
+
+struct avf_aqc_alternate_ind_write {
+ __le32 address;
+ __le32 length;
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_alternate_ind_write);
+
+/* Done alternate write (direct 0x0904)
+ * uses avf_aq_desc
+ */
+struct avf_aqc_alternate_write_done {
+ __le16 cmd_flags;
+#define AVF_AQ_ALTERNATE_MODE_BIOS_MASK 1
+#define AVF_AQ_ALTERNATE_MODE_BIOS_LEGACY 0
+#define AVF_AQ_ALTERNATE_MODE_BIOS_UEFI 1
+#define AVF_AQ_ALTERNATE_RESET_NEEDED 2
+ u8 reserved[14];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_alternate_write_done);
+
+/* Set OEM mode (direct 0x0905) */
+struct avf_aqc_alternate_set_mode {
+ __le32 mode;
+#define AVF_AQ_ALTERNATE_MODE_NONE 0
+#define AVF_AQ_ALTERNATE_MODE_OEM 1
+ u8 reserved[12];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_alternate_set_mode);
+
+/* Clear port Alternate RAM (direct 0x0906) uses avf_aq_desc */
+
+/* async events 0x10xx */
+
+/* Lan Queue Overflow Event (direct, 0x1001) */
+struct avf_aqc_lan_overflow {
+ __le32 prtdcb_rupto;
+ __le32 otx_ctl;
+ u8 reserved[8];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_lan_overflow);
+
+/* Get LLDP MIB (indirect 0x0A00) */
+struct avf_aqc_lldp_get_mib {
+ u8 type;
+ u8 reserved1;
+#define AVF_AQ_LLDP_MIB_TYPE_MASK 0x3
+#define AVF_AQ_LLDP_MIB_LOCAL 0x0
+#define AVF_AQ_LLDP_MIB_REMOTE 0x1
+#define AVF_AQ_LLDP_MIB_LOCAL_AND_REMOTE 0x2
+#define AVF_AQ_LLDP_BRIDGE_TYPE_MASK 0xC
+#define AVF_AQ_LLDP_BRIDGE_TYPE_SHIFT 0x2
+#define AVF_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE 0x0
+#define AVF_AQ_LLDP_BRIDGE_TYPE_NON_TPMR 0x1
+#define AVF_AQ_LLDP_TX_SHIFT 0x4
+#define AVF_AQ_LLDP_TX_MASK (0x03 << AVF_AQ_LLDP_TX_SHIFT)
+/* TX pause flags use AVF_AQ_LINK_TX_* above */
+ __le16 local_len;
+ __le16 remote_len;
+ u8 reserved2[2];
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_lldp_get_mib);
+
+/* Configure LLDP MIB Change Event (direct 0x0A01)
+ * also used for the event (with type in the command field)
+ */
+struct avf_aqc_lldp_update_mib {
+ u8 command;
+#define AVF_AQ_LLDP_MIB_UPDATE_ENABLE 0x0
+#define AVF_AQ_LLDP_MIB_UPDATE_DISABLE 0x1
+ u8 reserved[7];
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_lldp_update_mib);
+
+/* Add LLDP TLV (indirect 0x0A02)
+ * Delete LLDP TLV (indirect 0x0A04)
+ */
+struct avf_aqc_lldp_add_tlv {
+ u8 type; /* only nearest bridge and non-TPMR from 0x0A00 */
+ u8 reserved1[1];
+ __le16 len;
+ u8 reserved2[4];
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_lldp_add_tlv);
+
+/* Update LLDP TLV (indirect 0x0A03) */
+struct avf_aqc_lldp_update_tlv {
+ u8 type; /* only nearest bridge and non-TPMR from 0x0A00 */
+ u8 reserved;
+ __le16 old_len;
+ __le16 new_offset;
+ __le16 new_len;
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_lldp_update_tlv);
+
+/* Stop LLDP (direct 0x0A05) */
+struct avf_aqc_lldp_stop {
+ u8 command;
+#define AVF_AQ_LLDP_AGENT_STOP 0x0
+#define AVF_AQ_LLDP_AGENT_SHUTDOWN 0x1
+ u8 reserved[15];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_lldp_stop);
+
+/* Start LLDP (direct 0x0A06) */
+
+struct avf_aqc_lldp_start {
+ u8 command;
+#define AVF_AQ_LLDP_AGENT_START 0x1
+ u8 reserved[15];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_lldp_start);
+
+/* Set DCB (direct 0x0303) */
+struct avf_aqc_set_dcb_parameters {
+ u8 command;
+#define AVF_AQ_DCB_SET_AGENT 0x1
+#define AVF_DCB_VALID 0x1
+ u8 valid_flags;
+ u8 reserved[14];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_set_dcb_parameters);
+
+/* Get CEE DCBX Oper Config (0x0A07)
+ * uses the generic descriptor struct
+ * returns below as indirect response
+ */
+
+#define AVF_AQC_CEE_APP_FCOE_SHIFT 0x0
+#define AVF_AQC_CEE_APP_FCOE_MASK (0x7 << AVF_AQC_CEE_APP_FCOE_SHIFT)
+#define AVF_AQC_CEE_APP_ISCSI_SHIFT 0x3
+#define AVF_AQC_CEE_APP_ISCSI_MASK (0x7 << AVF_AQC_CEE_APP_ISCSI_SHIFT)
+#define AVF_AQC_CEE_APP_FIP_SHIFT 0x8
+#define AVF_AQC_CEE_APP_FIP_MASK (0x7 << AVF_AQC_CEE_APP_FIP_SHIFT)
+
+#define AVF_AQC_CEE_PG_STATUS_SHIFT 0x0
+#define AVF_AQC_CEE_PG_STATUS_MASK (0x7 << AVF_AQC_CEE_PG_STATUS_SHIFT)
+#define AVF_AQC_CEE_PFC_STATUS_SHIFT 0x3
+#define AVF_AQC_CEE_PFC_STATUS_MASK (0x7 << AVF_AQC_CEE_PFC_STATUS_SHIFT)
+#define AVF_AQC_CEE_APP_STATUS_SHIFT 0x8
+#define AVF_AQC_CEE_APP_STATUS_MASK (0x7 << AVF_AQC_CEE_APP_STATUS_SHIFT)
+#define AVF_AQC_CEE_FCOE_STATUS_SHIFT 0x8
+#define AVF_AQC_CEE_FCOE_STATUS_MASK (0x7 << AVF_AQC_CEE_FCOE_STATUS_SHIFT)
+#define AVF_AQC_CEE_ISCSI_STATUS_SHIFT 0xB
+#define AVF_AQC_CEE_ISCSI_STATUS_MASK (0x7 << AVF_AQC_CEE_ISCSI_STATUS_SHIFT)
+#define AVF_AQC_CEE_FIP_STATUS_SHIFT 0x10
+#define AVF_AQC_CEE_FIP_STATUS_MASK (0x7 << AVF_AQC_CEE_FIP_STATUS_SHIFT)
+
+/* struct avf_aqc_get_cee_dcb_cfg_v1_resp was originally defined with
+ * word boundary layout issues, which the Linux compilers silently deal
+ * with by adding padding, making the actual struct larger than designed.
+ * However, the FW compiler for the NIC is less lenient and complains
+ * about the struct. Hence, the struct defined here has an extra byte in
+ * fields reserved3 and reserved4 to directly acknowledge that padding,
+ * and the new length is used in the length check macro.
+ */
+struct avf_aqc_get_cee_dcb_cfg_v1_resp {
+ u8 reserved1;
+ u8 oper_num_tc;
+ u8 oper_prio_tc[4];
+ u8 reserved2;
+ u8 oper_tc_bw[8];
+ u8 oper_pfc_en;
+ u8 reserved3[2];
+ __le16 oper_app_prio;
+ u8 reserved4[2];
+ __le16 tlv_status;
+};
+
+AVF_CHECK_STRUCT_LEN(0x18, avf_aqc_get_cee_dcb_cfg_v1_resp);
+
+struct avf_aqc_get_cee_dcb_cfg_resp {
+ u8 oper_num_tc;
+ u8 oper_prio_tc[4];
+ u8 oper_tc_bw[8];
+ u8 oper_pfc_en;
+ __le16 oper_app_prio;
+ __le32 tlv_status;
+ u8 reserved[12];
+};
+
+AVF_CHECK_STRUCT_LEN(0x20, avf_aqc_get_cee_dcb_cfg_resp);
+
+/* Set Local LLDP MIB (indirect 0x0A08)
+ * Used to replace the local MIB of a given LLDP agent. e.g. DCBx
+ */
+struct avf_aqc_lldp_set_local_mib {
+#define SET_LOCAL_MIB_AC_TYPE_DCBX_SHIFT 0
+#define SET_LOCAL_MIB_AC_TYPE_DCBX_MASK (1 << \
+ SET_LOCAL_MIB_AC_TYPE_DCBX_SHIFT)
+#define SET_LOCAL_MIB_AC_TYPE_LOCAL_MIB 0x0
+#define SET_LOCAL_MIB_AC_TYPE_NON_WILLING_APPS_SHIFT (1)
+#define SET_LOCAL_MIB_AC_TYPE_NON_WILLING_APPS_MASK (1 << \
+ SET_LOCAL_MIB_AC_TYPE_NON_WILLING_APPS_SHIFT)
+#define SET_LOCAL_MIB_AC_TYPE_NON_WILLING_APPS 0x1
+ u8 type;
+ u8 reserved0;
+ __le16 length;
+ u8 reserved1[4];
+ __le32 address_high;
+ __le32 address_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_lldp_set_local_mib);
+
+struct avf_aqc_lldp_set_local_mib_resp {
+#define SET_LOCAL_MIB_RESP_EVENT_TRIGGERED_MASK 0x01
+ u8 status;
+ u8 reserved[15];
+};
+
+AVF_CHECK_STRUCT_LEN(0x10, avf_aqc_lldp_set_local_mib_resp);
+
+/* Stop/Start LLDP Agent (direct 0x0A09)
+ * Used for stopping/starting specific LLDP agent. e.g. DCBx
+ */
+struct avf_aqc_lldp_stop_start_specific_agent {
+#define AVF_AQC_START_SPECIFIC_AGENT_SHIFT 0
+#define AVF_AQC_START_SPECIFIC_AGENT_MASK \
+ (1 << AVF_AQC_START_SPECIFIC_AGENT_SHIFT)
+ u8 command;
+ u8 reserved[15];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_lldp_stop_start_specific_agent);
+
+/* Add Udp Tunnel command and completion (direct 0x0B00) */
+struct avf_aqc_add_udp_tunnel {
+ __le16 udp_port;
+ u8 reserved0[3];
+ u8 protocol_type;
+#define AVF_AQC_TUNNEL_TYPE_VXLAN 0x00
+#define AVF_AQC_TUNNEL_TYPE_NGE 0x01
+#define AVF_AQC_TUNNEL_TYPE_TEREDO 0x10
+#define AVF_AQC_TUNNEL_TYPE_VXLAN_GPE 0x11
+ u8 reserved1[10];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_add_udp_tunnel);
+
+struct avf_aqc_add_udp_tunnel_completion {
+ __le16 udp_port;
+ u8 filter_entry_index;
+ u8 multiple_pfs;
+#define AVF_AQC_SINGLE_PF 0x0
+#define AVF_AQC_MULTIPLE_PFS 0x1
+ u8 total_filters;
+ u8 reserved[11];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_add_udp_tunnel_completion);
+
+/* remove UDP Tunnel command (0x0B01) */
+struct avf_aqc_remove_udp_tunnel {
+ u8 reserved[2];
+ u8 index; /* 0 to 15 */
+ u8 reserved2[13];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_remove_udp_tunnel);
+
+struct avf_aqc_del_udp_tunnel_completion {
+ __le16 udp_port;
+ u8 index; /* 0 to 15 */
+ u8 multiple_pfs;
+ u8 total_filters_used;
+ u8 reserved1[11];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_del_udp_tunnel_completion);
+
+struct avf_aqc_get_set_rss_key {
+#define AVF_AQC_SET_RSS_KEY_VSI_VALID (0x1 << 15)
+#define AVF_AQC_SET_RSS_KEY_VSI_ID_SHIFT 0
+#define AVF_AQC_SET_RSS_KEY_VSI_ID_MASK (0x3FF << \
+ AVF_AQC_SET_RSS_KEY_VSI_ID_SHIFT)
+ __le16 vsi_id;
+ u8 reserved[6];
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_get_set_rss_key);
+
+struct avf_aqc_get_set_rss_key_data {
+ u8 standard_rss_key[0x28];
+ u8 extended_hash_key[0xc];
+};
+
+AVF_CHECK_STRUCT_LEN(0x34, avf_aqc_get_set_rss_key_data);
+
+struct avf_aqc_get_set_rss_lut {
+#define AVF_AQC_SET_RSS_LUT_VSI_VALID (0x1 << 15)
+#define AVF_AQC_SET_RSS_LUT_VSI_ID_SHIFT 0
+#define AVF_AQC_SET_RSS_LUT_VSI_ID_MASK (0x3FF << \
+ AVF_AQC_SET_RSS_LUT_VSI_ID_SHIFT)
+ __le16 vsi_id;
+#define AVF_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT 0
+#define AVF_AQC_SET_RSS_LUT_TABLE_TYPE_MASK (0x1 << \
+ AVF_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT)
+
+#define AVF_AQC_SET_RSS_LUT_TABLE_TYPE_VSI 0
+#define AVF_AQC_SET_RSS_LUT_TABLE_TYPE_PF 1
+ __le16 flags;
+ u8 reserved[4];
+ __le32 addr_high;
+ __le32 addr_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_get_set_rss_lut);
+
+/* tunnel key structure 0x0B10 */
+
+struct avf_aqc_tunnel_key_structure {
+ u8 key1_off;
+ u8 key2_off;
+ u8 key1_len; /* 0 to 15 */
+ u8 key2_len; /* 0 to 15 */
+ u8 flags;
+#define AVF_AQC_TUNNEL_KEY_STRUCT_OVERRIDE 0x01
+/* response flags */
+#define AVF_AQC_TUNNEL_KEY_STRUCT_SUCCESS 0x01
+#define AVF_AQC_TUNNEL_KEY_STRUCT_MODIFIED 0x02
+#define AVF_AQC_TUNNEL_KEY_STRUCT_OVERRIDDEN 0x03
+ u8 network_key_index;
+#define AVF_AQC_NETWORK_KEY_INDEX_VXLAN 0x0
+#define AVF_AQC_NETWORK_KEY_INDEX_NGE 0x1
+#define AVF_AQC_NETWORK_KEY_INDEX_FLEX_MAC_IN_UDP 0x2
+#define AVF_AQC_NETWORK_KEY_INDEX_GRE 0x3
+ u8 reserved[10];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_tunnel_key_structure);
+
+/* OEM mode commands (direct 0xFE0x) */
+struct avf_aqc_oem_param_change {
+ __le32 param_type;
+#define AVF_AQ_OEM_PARAM_TYPE_PF_CTL 0
+#define AVF_AQ_OEM_PARAM_TYPE_BW_CTL 1
+#define AVF_AQ_OEM_PARAM_MAC 2
+ __le32 param_value1;
+ __le16 param_value2;
+ u8 reserved[6];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_oem_param_change);
+
+struct avf_aqc_oem_state_change {
+ __le32 state;
+#define AVF_AQ_OEM_STATE_LINK_DOWN 0x0
+#define AVF_AQ_OEM_STATE_LINK_UP 0x1
+ u8 reserved[12];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_oem_state_change);
+
+/* Initialize OCSD (0xFE02, direct) */
+struct avf_aqc_opc_oem_ocsd_initialize {
+ u8 type_status;
+ u8 reserved1[3];
+ __le32 ocsd_memory_block_addr_high;
+ __le32 ocsd_memory_block_addr_low;
+ __le32 requested_update_interval;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_opc_oem_ocsd_initialize);
+
+/* Initialize OCBB (0xFE03, direct) */
+struct avf_aqc_opc_oem_ocbb_initialize {
+ u8 type_status;
+ u8 reserved1[3];
+ __le32 ocbb_memory_block_addr_high;
+ __le32 ocbb_memory_block_addr_low;
+ u8 reserved2[4];
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_opc_oem_ocbb_initialize);
+
+/* debug commands */
+
+/* get device id (0xFF00) uses the generic structure */
+
+/* set test more (0xFF01, internal) */
+
+struct avf_acq_set_test_mode {
+ u8 mode;
+#define AVF_AQ_TEST_PARTIAL 0
+#define AVF_AQ_TEST_FULL 1
+#define AVF_AQ_TEST_NVM 2
+ u8 reserved[3];
+ u8 command;
+#define AVF_AQ_TEST_OPEN 0
+#define AVF_AQ_TEST_CLOSE 1
+#define AVF_AQ_TEST_INC 2
+ u8 reserved2[3];
+ __le32 address_high;
+ __le32 address_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_acq_set_test_mode);
+
+/* Debug Read Register command (0xFF03)
+ * Debug Write Register command (0xFF04)
+ */
+struct avf_aqc_debug_reg_read_write {
+ __le32 reserved;
+ __le32 address;
+ __le32 value_high;
+ __le32 value_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_debug_reg_read_write);
+
+/* Scatter/gather Reg Read (indirect 0xFF05)
+ * Scatter/gather Reg Write (indirect 0xFF06)
+ */
+
+/* avf_aq_desc is used for the command */
+struct avf_aqc_debug_reg_sg_element_data {
+ __le32 address;
+ __le32 value;
+};
+
+/* Debug Modify register (direct 0xFF07) */
+struct avf_aqc_debug_modify_reg {
+ __le32 address;
+ __le32 value;
+ __le32 clear_mask;
+ __le32 set_mask;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_debug_modify_reg);
+
+/* dump internal data (0xFF08, indirect) */
+
+#define AVF_AQ_CLUSTER_ID_AUX 0
+#define AVF_AQ_CLUSTER_ID_SWITCH_FLU 1
+#define AVF_AQ_CLUSTER_ID_TXSCHED 2
+#define AVF_AQ_CLUSTER_ID_HMC 3
+#define AVF_AQ_CLUSTER_ID_MAC0 4
+#define AVF_AQ_CLUSTER_ID_MAC1 5
+#define AVF_AQ_CLUSTER_ID_MAC2 6
+#define AVF_AQ_CLUSTER_ID_MAC3 7
+#define AVF_AQ_CLUSTER_ID_DCB 8
+#define AVF_AQ_CLUSTER_ID_EMP_MEM 9
+#define AVF_AQ_CLUSTER_ID_PKT_BUF 10
+#define AVF_AQ_CLUSTER_ID_ALTRAM 11
+
+struct avf_aqc_debug_dump_internals {
+ u8 cluster_id;
+ u8 table_id;
+ __le16 data_size;
+ __le32 idx;
+ __le32 address_high;
+ __le32 address_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_debug_dump_internals);
+
+struct avf_aqc_debug_modify_internals {
+ u8 cluster_id;
+ u8 cluster_specific_params[7];
+ __le32 address_high;
+ __le32 address_low;
+};
+
+AVF_CHECK_CMD_LENGTH(avf_aqc_debug_modify_internals);
+
+#endif /* _AVF_ADMINQ_CMD_H_ */
diff --git a/drivers/net/iavf/base/iavf_alloc.h b/drivers/net/iavf/base/iavf_alloc.h
new file mode 100644
index 0000000..21e29bd
--- /dev/null
+++ b/drivers/net/iavf/base/iavf_alloc.h
@@ -0,0 +1,65 @@
+/*******************************************************************************
+
+Copyright (c) 2013 - 2015, Intel Corporation
+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.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+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.
+
+***************************************************************************/
+
+#ifndef _AVF_ALLOC_H_
+#define _AVF_ALLOC_H_
+
+struct avf_hw;
+
+/* Memory allocation types */
+enum avf_memory_type {
+ avf_mem_arq_buf = 0, /* ARQ indirect command buffer */
+ avf_mem_asq_buf = 1,
+ avf_mem_atq_buf = 2, /* ATQ indirect command buffer */
+ avf_mem_arq_ring = 3, /* ARQ descriptor ring */
+ avf_mem_atq_ring = 4, /* ATQ descriptor ring */
+ avf_mem_pd = 5, /* Page Descriptor */
+ avf_mem_bp = 6, /* Backing Page - 4KB */
+ avf_mem_bp_jumbo = 7, /* Backing Page - > 4KB */
+ avf_mem_reserved
+};
+
+/* prototype for functions used for dynamic memory allocation */
+enum avf_status_code avf_allocate_dma_mem(struct avf_hw *hw,
+ struct avf_dma_mem *mem,
+ enum avf_memory_type type,
+ u64 size, u32 alignment);
+enum avf_status_code avf_free_dma_mem(struct avf_hw *hw,
+ struct avf_dma_mem *mem);
+enum avf_status_code avf_allocate_virt_mem(struct avf_hw *hw,
+ struct avf_virt_mem *mem,
+ u32 size);
+enum avf_status_code avf_free_virt_mem(struct avf_hw *hw,
+ struct avf_virt_mem *mem);
+
+#endif /* _AVF_ALLOC_H_ */
diff --git a/drivers/net/iavf/base/iavf_common.c b/drivers/net/iavf/base/iavf_common.c
new file mode 100644
index 0000000..5b7f091
--- /dev/null
+++ b/drivers/net/iavf/base/iavf_common.c
@@ -0,0 +1,1845 @@
+/*******************************************************************************
+
+Copyright (c) 2013 - 2015, Intel Corporation
+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.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+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.
+
+***************************************************************************/
+
+#include "iavf_type.h"
+#include "iavf_adminq.h"
+#include "iavf_prototype.h"
+#include "virtchnl.h"
+
+
+/**
+ * avf_set_mac_type - Sets MAC type
+ * @hw: pointer to the HW structure
+ *
+ * This function sets the mac type of the adapter based on the
+ * vendor ID and device ID stored in the hw structure.
+ **/
+enum avf_status_code avf_set_mac_type(struct avf_hw *hw)
+{
+ enum avf_status_code status = AVF_SUCCESS;
+
+ DEBUGFUNC("avf_set_mac_type\n");
+
+ if (hw->vendor_id == AVF_INTEL_VENDOR_ID) {
+ switch (hw->device_id) {
+ /* TODO: remove undefined device ID now, need to think how to
+ * remove them in share code
+ */
+ case AVF_DEV_ID_ADAPTIVE_VF:
+ hw->mac.type = AVF_MAC_VF;
+ break;
+ default:
+ hw->mac.type = AVF_MAC_GENERIC;
+ break;
+ }
+ } else {
+ status = AVF_ERR_DEVICE_NOT_SUPPORTED;
+ }
+
+ DEBUGOUT2("avf_set_mac_type found mac: %d, returns: %d\n",
+ hw->mac.type, status);
+ return status;
+}
+
+/**
+ * avf_aq_str - convert AQ err code to a string
+ * @hw: pointer to the HW structure
+ * @aq_err: the AQ error code to convert
+ **/
+const char *avf_aq_str(struct avf_hw *hw, enum avf_admin_queue_err aq_err)
+{
+ switch (aq_err) {
+ case AVF_AQ_RC_OK:
+ return "OK";
+ case AVF_AQ_RC_EPERM:
+ return "AVF_AQ_RC_EPERM";
+ case AVF_AQ_RC_ENOENT:
+ return "AVF_AQ_RC_ENOENT";
+ case AVF_AQ_RC_ESRCH:
+ return "AVF_AQ_RC_ESRCH";
+ case AVF_AQ_RC_EINTR:
+ return "AVF_AQ_RC_EINTR";
+ case AVF_AQ_RC_EIO:
+ return "AVF_AQ_RC_EIO";
+ case AVF_AQ_RC_ENXIO:
+ return "AVF_AQ_RC_ENXIO";
+ case AVF_AQ_RC_E2BIG:
+ return "AVF_AQ_RC_E2BIG";
+ case AVF_AQ_RC_EAGAIN:
+ return "AVF_AQ_RC_EAGAIN";
+ case AVF_AQ_RC_ENOMEM:
+ return "AVF_AQ_RC_ENOMEM";
+ case AVF_AQ_RC_EACCES:
+ return "AVF_AQ_RC_EACCES";
+ case AVF_AQ_RC_EFAULT:
+ return "AVF_AQ_RC_EFAULT";
+ case AVF_AQ_RC_EBUSY:
+ return "AVF_AQ_RC_EBUSY";
+ case AVF_AQ_RC_EEXIST:
+ return "AVF_AQ_RC_EEXIST";
+ case AVF_AQ_RC_EINVAL:
+ return "AVF_AQ_RC_EINVAL";
+ case AVF_AQ_RC_ENOTTY:
+ return "AVF_AQ_RC_ENOTTY";
+ case AVF_AQ_RC_ENOSPC:
+ return "AVF_AQ_RC_ENOSPC";
+ case AVF_AQ_RC_ENOSYS:
+ return "AVF_AQ_RC_ENOSYS";
+ case AVF_AQ_RC_ERANGE:
+ return "AVF_AQ_RC_ERANGE";
+ case AVF_AQ_RC_EFLUSHED:
+ return "AVF_AQ_RC_EFLUSHED";
+ case AVF_AQ_RC_BAD_ADDR:
+ return "AVF_AQ_RC_BAD_ADDR";
+ case AVF_AQ_RC_EMODE:
+ return "AVF_AQ_RC_EMODE";
+ case AVF_AQ_RC_EFBIG:
+ return "AVF_AQ_RC_EFBIG";
+ }
+
+ snprintf(hw->err_str, sizeof(hw->err_str), "%d", aq_err);
+ return hw->err_str;
+}
+
+/**
+ * avf_stat_str - convert status err code to a string
+ * @hw: pointer to the HW structure
+ * @stat_err: the status error code to convert
+ **/
+const char *avf_stat_str(struct avf_hw *hw, enum avf_status_code stat_err)
+{
+ switch (stat_err) {
+ case AVF_SUCCESS:
+ return "OK";
+ case AVF_ERR_NVM:
+ return "AVF_ERR_NVM";
+ case AVF_ERR_NVM_CHECKSUM:
+ return "AVF_ERR_NVM_CHECKSUM";
+ case AVF_ERR_PHY:
+ return "AVF_ERR_PHY";
+ case AVF_ERR_CONFIG:
+ return "AVF_ERR_CONFIG";
+ case AVF_ERR_PARAM:
+ return "AVF_ERR_PARAM";
+ case AVF_ERR_MAC_TYPE:
+ return "AVF_ERR_MAC_TYPE";
+ case AVF_ERR_UNKNOWN_PHY:
+ return "AVF_ERR_UNKNOWN_PHY";
+ case AVF_ERR_LINK_SETUP:
+ return "AVF_ERR_LINK_SETUP";
+ case AVF_ERR_ADAPTER_STOPPED:
+ return "AVF_ERR_ADAPTER_STOPPED";
+ case AVF_ERR_INVALID_MAC_ADDR:
+ return "AVF_ERR_INVALID_MAC_ADDR";
+ case AVF_ERR_DEVICE_NOT_SUPPORTED:
+ return "AVF_ERR_DEVICE_NOT_SUPPORTED";
+ case AVF_ERR_MASTER_REQUESTS_PENDING:
+ return "AVF_ERR_MASTER_REQUESTS_PENDING";
+ case AVF_ERR_INVALID_LINK_SETTINGS:
+ return "AVF_ERR_INVALID_LINK_SETTINGS";
+ case AVF_ERR_AUTONEG_NOT_COMPLETE:
+ return "AVF_ERR_AUTONEG_NOT_COMPLETE";
+ case AVF_ERR_RESET_FAILED:
+ return "AVF_ERR_RESET_FAILED";
+ case AVF_ERR_SWFW_SYNC:
+ return "AVF_ERR_SWFW_SYNC";
+ case AVF_ERR_NO_AVAILABLE_VSI:
+ return "AVF_ERR_NO_AVAILABLE_VSI";
+ case AVF_ERR_NO_MEMORY:
+ return "AVF_ERR_NO_MEMORY";
+ case AVF_ERR_BAD_PTR:
+ return "AVF_ERR_BAD_PTR";
+ case AVF_ERR_RING_FULL:
+ return "AVF_ERR_RING_FULL";
+ case AVF_ERR_INVALID_PD_ID:
+ return "AVF_ERR_INVALID_PD_ID";
+ case AVF_ERR_INVALID_QP_ID:
+ return "AVF_ERR_INVALID_QP_ID";
+ case AVF_ERR_INVALID_CQ_ID:
+ return "AVF_ERR_INVALID_CQ_ID";
+ case AVF_ERR_INVALID_CEQ_ID:
+ return "AVF_ERR_INVALID_CEQ_ID";
+ case AVF_ERR_INVALID_AEQ_ID:
+ return "AVF_ERR_INVALID_AEQ_ID";
+ case AVF_ERR_INVALID_SIZE:
+ return "AVF_ERR_INVALID_SIZE";
+ case AVF_ERR_INVALID_ARP_INDEX:
+ return "AVF_ERR_INVALID_ARP_INDEX";
+ case AVF_ERR_INVALID_FPM_FUNC_ID:
+ return "AVF_ERR_INVALID_FPM_FUNC_ID";
+ case AVF_ERR_QP_INVALID_MSG_SIZE:
+ return "AVF_ERR_QP_INVALID_MSG_SIZE";
+ case AVF_ERR_QP_TOOMANY_WRS_POSTED:
+ return "AVF_ERR_QP_TOOMANY_WRS_POSTED";
+ case AVF_ERR_INVALID_FRAG_COUNT:
+ return "AVF_ERR_INVALID_FRAG_COUNT";
+ case AVF_ERR_QUEUE_EMPTY:
+ return "AVF_ERR_QUEUE_EMPTY";
+ case AVF_ERR_INVALID_ALIGNMENT:
+ return "AVF_ERR_INVALID_ALIGNMENT";
+ case AVF_ERR_FLUSHED_QUEUE:
+ return "AVF_ERR_FLUSHED_QUEUE";
+ case AVF_ERR_INVALID_PUSH_PAGE_INDEX:
+ return "AVF_ERR_INVALID_PUSH_PAGE_INDEX";
+ case AVF_ERR_INVALID_IMM_DATA_SIZE:
+ return "AVF_ERR_INVALID_IMM_DATA_SIZE";
+ case AVF_ERR_TIMEOUT:
+ return "AVF_ERR_TIMEOUT";
+ case AVF_ERR_OPCODE_MISMATCH:
+ return "AVF_ERR_OPCODE_MISMATCH";
+ case AVF_ERR_CQP_COMPL_ERROR:
+ return "AVF_ERR_CQP_COMPL_ERROR";
+ case AVF_ERR_INVALID_VF_ID:
+ return "AVF_ERR_INVALID_VF_ID";
+ case AVF_ERR_INVALID_HMCFN_ID:
+ return "AVF_ERR_INVALID_HMCFN_ID";
+ case AVF_ERR_BACKING_PAGE_ERROR:
+ return "AVF_ERR_BACKING_PAGE_ERROR";
+ case AVF_ERR_NO_PBLCHUNKS_AVAILABLE:
+ return "AVF_ERR_NO_PBLCHUNKS_AVAILABLE";
+ case AVF_ERR_INVALID_PBLE_INDEX:
+ return "AVF_ERR_INVALID_PBLE_INDEX";
+ case AVF_ERR_INVALID_SD_INDEX:
+ return "AVF_ERR_INVALID_SD_INDEX";
+ case AVF_ERR_INVALID_PAGE_DESC_INDEX:
+ return "AVF_ERR_INVALID_PAGE_DESC_INDEX";
+ case AVF_ERR_INVALID_SD_TYPE:
+ return "AVF_ERR_INVALID_SD_TYPE";
+ case AVF_ERR_MEMCPY_FAILED:
+ return "AVF_ERR_MEMCPY_FAILED";
+ case AVF_ERR_INVALID_HMC_OBJ_INDEX:
+ return "AVF_ERR_INVALID_HMC_OBJ_INDEX";
+ case AVF_ERR_INVALID_HMC_OBJ_COUNT:
+ return "AVF_ERR_INVALID_HMC_OBJ_COUNT";
+ case AVF_ERR_INVALID_SRQ_ARM_LIMIT:
+ return "AVF_ERR_INVALID_SRQ_ARM_LIMIT";
+ case AVF_ERR_SRQ_ENABLED:
+ return "AVF_ERR_SRQ_ENABLED";
+ case AVF_ERR_ADMIN_QUEUE_ERROR:
+ return "AVF_ERR_ADMIN_QUEUE_ERROR";
+ case AVF_ERR_ADMIN_QUEUE_TIMEOUT:
+ return "AVF_ERR_ADMIN_QUEUE_TIMEOUT";
+ case AVF_ERR_BUF_TOO_SHORT:
+ return "AVF_ERR_BUF_TOO_SHORT";
+ case AVF_ERR_ADMIN_QUEUE_FULL:
+ return "AVF_ERR_ADMIN_QUEUE_FULL";
+ case AVF_ERR_ADMIN_QUEUE_NO_WORK:
+ return "AVF_ERR_ADMIN_QUEUE_NO_WORK";
+ case AVF_ERR_BAD_IWARP_CQE:
+ return "AVF_ERR_BAD_IWARP_CQE";
+ case AVF_ERR_NVM_BLANK_MODE:
+ return "AVF_ERR_NVM_BLANK_MODE";
+ case AVF_ERR_NOT_IMPLEMENTED:
+ return "AVF_ERR_NOT_IMPLEMENTED";
+ case AVF_ERR_PE_DOORBELL_NOT_ENABLED:
+ return "AVF_ERR_PE_DOORBELL_NOT_ENABLED";
+ case AVF_ERR_DIAG_TEST_FAILED:
+ return "AVF_ERR_DIAG_TEST_FAILED";
+ case AVF_ERR_NOT_READY:
+ return "AVF_ERR_NOT_READY";
+ case AVF_NOT_SUPPORTED:
+ return "AVF_NOT_SUPPORTED";
+ case AVF_ERR_FIRMWARE_API_VERSION:
+ return "AVF_ERR_FIRMWARE_API_VERSION";
+ case AVF_ERR_ADMIN_QUEUE_CRITICAL_ERROR:
+ return "AVF_ERR_ADMIN_QUEUE_CRITICAL_ERROR";
+ }
+
+ snprintf(hw->err_str, sizeof(hw->err_str), "%d", stat_err);
+ return hw->err_str;
+}
+
+/**
+ * avf_debug_aq
+ * @hw: debug mask related to admin queue
+ * @mask: debug mask
+ * @desc: pointer to admin queue descriptor
+ * @buffer: pointer to command buffer
+ * @buf_len: max length of buffer
+ *
+ * Dumps debug log about adminq command with descriptor contents.
+ **/
+void avf_debug_aq(struct avf_hw *hw, enum avf_debug_mask mask, void *desc,
+ void *buffer, u16 buf_len)
+{
+ struct avf_aq_desc *aq_desc = (struct avf_aq_desc *)desc;
+ u8 *buf = (u8 *)buffer;
+ u16 len;
+ u16 i = 0;
+
+ if ((!(mask & hw->debug_mask)) || (desc == NULL))
+ return;
+
+ len = LE16_TO_CPU(aq_desc->datalen);
+
+ avf_debug(hw, mask,
+ "AQ CMD: opcode 0x%04X, flags 0x%04X, datalen 0x%04X, retval 0x%04X\n",
+ LE16_TO_CPU(aq_desc->opcode),
+ LE16_TO_CPU(aq_desc->flags),
+ LE16_TO_CPU(aq_desc->datalen),
+ LE16_TO_CPU(aq_desc->retval));
+ avf_debug(hw, mask, "\tcookie (h,l) 0x%08X 0x%08X\n",
+ LE32_TO_CPU(aq_desc->cookie_high),
+ LE32_TO_CPU(aq_desc->cookie_low));
+ avf_debug(hw, mask, "\tparam (0,1) 0x%08X 0x%08X\n",
+ LE32_TO_CPU(aq_desc->params.internal.param0),
+ LE32_TO_CPU(aq_desc->params.internal.param1));
+ avf_debug(hw, mask, "\taddr (h,l) 0x%08X 0x%08X\n",
+ LE32_TO_CPU(aq_desc->params.external.addr_high),
+ LE32_TO_CPU(aq_desc->params.external.addr_low));
+
+ if ((buffer != NULL) && (aq_desc->datalen != 0)) {
+ avf_debug(hw, mask, "AQ CMD Buffer:\n");
+ if (buf_len < len)
+ len = buf_len;
+ /* write the full 16-byte chunks */
+ for (i = 0; i < (len - 16); i += 16)
+ avf_debug(hw, mask,
+ "\t0x%04X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
+ i, buf[i], buf[i+1], buf[i+2], buf[i+3],
+ buf[i+4], buf[i+5], buf[i+6], buf[i+7],
+ buf[i+8], buf[i+9], buf[i+10], buf[i+11],
+ buf[i+12], buf[i+13], buf[i+14], buf[i+15]);
+ /* the most we could have left is 16 bytes, pad with zeros */
+ if (i < len) {
+ char d_buf[16];
+ int j, i_sav;
+
+ i_sav = i;
+ memset(d_buf, 0, sizeof(d_buf));
+ for (j = 0; i < len; j++, i++)
+ d_buf[j] = buf[i];
+ avf_debug(hw, mask,
+ "\t0x%04X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
+ i_sav, d_buf[0], d_buf[1], d_buf[2], d_buf[3],
+ d_buf[4], d_buf[5], d_buf[6], d_buf[7],
+ d_buf[8], d_buf[9], d_buf[10], d_buf[11],
+ d_buf[12], d_buf[13], d_buf[14], d_buf[15]);
+ }
+ }
+}
+
+/**
+ * avf_check_asq_alive
+ * @hw: pointer to the hw struct
+ *
+ * Returns true if Queue is enabled else false.
+ **/
+bool avf_check_asq_alive(struct avf_hw *hw)
+{
+ if (hw->aq.asq.len)
+#ifdef INTEGRATED_VF
+ if (avf_is_vf(hw))
+ return !!(rd32(hw, hw->aq.asq.len) &
+ AVF_ATQLEN1_ATQENABLE_MASK);
+#else
+ return !!(rd32(hw, hw->aq.asq.len) &
+ AVF_ATQLEN1_ATQENABLE_MASK);
+#endif /* INTEGRATED_VF */
+ return false;
+}
+
+/**
+ * avf_aq_queue_shutdown
+ * @hw: pointer to the hw struct
+ * @unloading: is the driver unloading itself
+ *
+ * Tell the Firmware that we're shutting down the AdminQ and whether
+ * or not the driver is unloading as well.
+ **/
+enum avf_status_code avf_aq_queue_shutdown(struct avf_hw *hw,
+ bool unloading)
+{
+ struct avf_aq_desc desc;
+ struct avf_aqc_queue_shutdown *cmd =
+ (struct avf_aqc_queue_shutdown *)&desc.params.raw;
+ enum avf_status_code status;
+
+ avf_fill_default_direct_cmd_desc(&desc,
+ avf_aqc_opc_queue_shutdown);
+
+ if (unloading)
+ cmd->driver_unloading = CPU_TO_LE32(AVF_AQ_DRIVER_UNLOADING);
+ status = avf_asq_send_command(hw, &desc, NULL, 0, NULL);
+
+ return status;
+}
+
+/**
+ * avf_aq_get_set_rss_lut
+ * @hw: pointer to the hardware structure
+ * @vsi_id: vsi fw index
+ * @pf_lut: for PF table set true, for VSI table set false
+ * @lut: pointer to the lut buffer provided by the caller
+ * @lut_size: size of the lut buffer
+ * @set: set true to set the table, false to get the table
+ *
+ * Internal function to get or set RSS look up table
+ **/
+STATIC enum avf_status_code avf_aq_get_set_rss_lut(struct avf_hw *hw,
+ u16 vsi_id, bool pf_lut,
+ u8 *lut, u16 lut_size,
+ bool set)
+{
+ enum avf_status_code status;
+ struct avf_aq_desc desc;
+ struct avf_aqc_get_set_rss_lut *cmd_resp =
+ (struct avf_aqc_get_set_rss_lut *)&desc.params.raw;
+
+ if (set)
+ avf_fill_default_direct_cmd_desc(&desc,
+ avf_aqc_opc_set_rss_lut);
+ else
+ avf_fill_default_direct_cmd_desc(&desc,
+ avf_aqc_opc_get_rss_lut);
+
+ /* Indirect command */
+ desc.flags |= CPU_TO_LE16((u16)AVF_AQ_FLAG_BUF);
+ desc.flags |= CPU_TO_LE16((u16)AVF_AQ_FLAG_RD);
+
+ cmd_resp->vsi_id =
+ CPU_TO_LE16((u16)((vsi_id <<
+ AVF_AQC_SET_RSS_LUT_VSI_ID_SHIFT) &
+ AVF_AQC_SET_RSS_LUT_VSI_ID_MASK));
+ cmd_resp->vsi_id |= CPU_TO_LE16((u16)AVF_AQC_SET_RSS_LUT_VSI_VALID);
+
+ if (pf_lut)
+ cmd_resp->flags |= CPU_TO_LE16((u16)
+ ((AVF_AQC_SET_RSS_LUT_TABLE_TYPE_PF <<
+ AVF_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT) &
+ AVF_AQC_SET_RSS_LUT_TABLE_TYPE_MASK));
+ else
+ cmd_resp->flags |= CPU_TO_LE16((u16)
+ ((AVF_AQC_SET_RSS_LUT_TABLE_TYPE_VSI <<
+ AVF_AQC_SET_RSS_LUT_TABLE_TYPE_SHIFT) &
+ AVF_AQC_SET_RSS_LUT_TABLE_TYPE_MASK));
+
+ status = avf_asq_send_command(hw, &desc, lut, lut_size, NULL);
+
+ return status;
+}
+
+/**
+ * avf_aq_get_rss_lut
+ * @hw: pointer to the hardware structure
+ * @vsi_id: vsi fw index
+ * @pf_lut: for PF table set true, for VSI table set false
+ * @lut: pointer to the lut buffer provided by the caller
+ * @lut_size: size of the lut buffer
+ *
+ * get the RSS lookup table, PF or VSI type
+ **/
+enum avf_status_code avf_aq_get_rss_lut(struct avf_hw *hw, u16 vsi_id,
+ bool pf_lut, u8 *lut, u16 lut_size)
+{
+ return avf_aq_get_set_rss_lut(hw, vsi_id, pf_lut, lut, lut_size,
+ false);
+}
+
+/**
+ * avf_aq_set_rss_lut
+ * @hw: pointer to the hardware structure
+ * @vsi_id: vsi fw index
+ * @pf_lut: for PF table set true, for VSI table set false
+ * @lut: pointer to the lut buffer provided by the caller
+ * @lut_size: size of the lut buffer
+ *
+ * set the RSS lookup table, PF or VSI type
+ **/
+enum avf_status_code avf_aq_set_rss_lut(struct avf_hw *hw, u16 vsi_id,
+ bool pf_lut, u8 *lut, u16 lut_size)
+{
+ return avf_aq_get_set_rss_lut(hw, vsi_id, pf_lut, lut, lut_size, true);
+}
+
+/**
+ * avf_aq_get_set_rss_key
+ * @hw: pointer to the hw struct
+ * @vsi_id: vsi fw index
+ * @key: pointer to key info struct
+ * @set: set true to set the key, false to get the key
+ *
+ * get the RSS key per VSI
+ **/
+STATIC enum avf_status_code avf_aq_get_set_rss_key(struct avf_hw *hw,
+ u16 vsi_id,
+ struct avf_aqc_get_set_rss_key_data *key,
+ bool set)
+{
+ enum avf_status_code status;
+ struct avf_aq_desc desc;
+ struct avf_aqc_get_set_rss_key *cmd_resp =
+ (struct avf_aqc_get_set_rss_key *)&desc.params.raw;
+ u16 key_size = sizeof(struct avf_aqc_get_set_rss_key_data);
+
+ if (set)
+ avf_fill_default_direct_cmd_desc(&desc,
+ avf_aqc_opc_set_rss_key);
+ else
+ avf_fill_default_direct_cmd_desc(&desc,
+ avf_aqc_opc_get_rss_key);
+
+ /* Indirect command */
+ desc.flags |= CPU_TO_LE16((u16)AVF_AQ_FLAG_BUF);
+ desc.flags |= CPU_TO_LE16((u16)AVF_AQ_FLAG_RD);
+
+ cmd_resp->vsi_id =
+ CPU_TO_LE16((u16)((vsi_id <<
+ AVF_AQC_SET_RSS_KEY_VSI_ID_SHIFT) &
+ AVF_AQC_SET_RSS_KEY_VSI_ID_MASK));
+ cmd_resp->vsi_id |= CPU_TO_LE16((u16)AVF_AQC_SET_RSS_KEY_VSI_VALID);
+
+ status = avf_asq_send_command(hw, &desc, key, key_size, NULL);
+
+ return status;
+}
+
+/**
+ * avf_aq_get_rss_key
+ * @hw: pointer to the hw struct
+ * @vsi_id: vsi fw index
+ * @key: pointer to key info struct
+ *
+ **/
+enum avf_status_code avf_aq_get_rss_key(struct avf_hw *hw,
+ u16 vsi_id,
+ struct avf_aqc_get_set_rss_key_data *key)
+{
+ return avf_aq_get_set_rss_key(hw, vsi_id, key, false);
+}
+
+/**
+ * avf_aq_set_rss_key
+ * @hw: pointer to the hw struct
+ * @vsi_id: vsi fw index
+ * @key: pointer to key info struct
+ *
+ * set the RSS key per VSI
+ **/
+enum avf_status_code avf_aq_set_rss_key(struct avf_hw *hw,
+ u16 vsi_id,
+ struct avf_aqc_get_set_rss_key_data *key)
+{
+ return avf_aq_get_set_rss_key(hw, vsi_id, key, true);
+}
+
+/* The avf_ptype_lookup table is used to convert from the 8-bit ptype in the
+ * hardware to a bit-field that can be used by SW to more easily determine the
+ * packet type.
+ *
+ * Macros are used to shorten the table lines and make this table human
+ * readable.
+ *
+ * We store the PTYPE in the top byte of the bit field - this is just so that
+ * we can check that the table doesn't have a row missing, as the index into
+ * the table should be the PTYPE.
+ *
+ * Typical work flow:
+ *
+ * IF NOT avf_ptype_lookup[ptype].known
+ * THEN
+ * Packet is unknown
+ * ELSE IF avf_ptype_lookup[ptype].outer_ip == AVF_RX_PTYPE_OUTER_IP
+ * Use the rest of the fields to look at the tunnels, inner protocols, etc
+ * ELSE
+ * Use the enum avf_rx_l2_ptype to decode the packet type
+ * ENDIF
+ */
+
+/* macro to make the table lines short */
+#define AVF_PTT(PTYPE, OUTER_IP, OUTER_IP_VER, OUTER_FRAG, T, TE, TEF, I, PL)\
+ { PTYPE, \
+ 1, \
+ AVF_RX_PTYPE_OUTER_##OUTER_IP, \
+ AVF_RX_PTYPE_OUTER_##OUTER_IP_VER, \
+ AVF_RX_PTYPE_##OUTER_FRAG, \
+ AVF_RX_PTYPE_TUNNEL_##T, \
+ AVF_RX_PTYPE_TUNNEL_END_##TE, \
+ AVF_RX_PTYPE_##TEF, \
+ AVF_RX_PTYPE_INNER_PROT_##I, \
+ AVF_RX_PTYPE_PAYLOAD_LAYER_##PL }
+
+#define AVF_PTT_UNUSED_ENTRY(PTYPE) \
+ { PTYPE, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+
+/* shorter macros makes the table fit but are terse */
+#define AVF_RX_PTYPE_NOF AVF_RX_PTYPE_NOT_FRAG
+#define AVF_RX_PTYPE_FRG AVF_RX_PTYPE_FRAG
+#define AVF_RX_PTYPE_INNER_PROT_TS AVF_RX_PTYPE_INNER_PROT_TIMESYNC
+
+/* Lookup table mapping the HW PTYPE to the bit field for decoding */
+struct avf_rx_ptype_decoded avf_ptype_lookup[] = {
+ /* L2 Packet types */
+ AVF_PTT_UNUSED_ENTRY(0),
+ AVF_PTT(1, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
+ AVF_PTT(2, L2, NONE, NOF, NONE, NONE, NOF, TS, PAY2),
+ AVF_PTT(3, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
+ AVF_PTT_UNUSED_ENTRY(4),
+ AVF_PTT_UNUSED_ENTRY(5),
+ AVF_PTT(6, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
+ AVF_PTT(7, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
+ AVF_PTT_UNUSED_ENTRY(8),
+ AVF_PTT_UNUSED_ENTRY(9),
+ AVF_PTT(10, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY2),
+ AVF_PTT(11, L2, NONE, NOF, NONE, NONE, NOF, NONE, NONE),
+ AVF_PTT(12, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
+ AVF_PTT(13, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
+ AVF_PTT(14, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
+ AVF_PTT(15, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
+ AVF_PTT(16, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
+ AVF_PTT(17, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
+ AVF_PTT(18, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
+ AVF_PTT(19, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
+ AVF_PTT(20, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
+ AVF_PTT(21, L2, NONE, NOF, NONE, NONE, NOF, NONE, PAY3),
+
+ /* Non Tunneled IPv4 */
+ AVF_PTT(22, IP, IPV4, FRG, NONE, NONE, NOF, NONE, PAY3),
+ AVF_PTT(23, IP, IPV4, NOF, NONE, NONE, NOF, NONE, PAY3),
+ AVF_PTT(24, IP, IPV4, NOF, NONE, NONE, NOF, UDP, PAY4),
+ AVF_PTT_UNUSED_ENTRY(25),
+ AVF_PTT(26, IP, IPV4, NOF, NONE, NONE, NOF, TCP, PAY4),
+ AVF_PTT(27, IP, IPV4, NOF, NONE, NONE, NOF, SCTP, PAY4),
+ AVF_PTT(28, IP, IPV4, NOF, NONE, NONE, NOF, ICMP, PAY4),
+
+ /* IPv4 --> IPv4 */
+ AVF_PTT(29, IP, IPV4, NOF, IP_IP, IPV4, FRG, NONE, PAY3),
+ AVF_PTT(30, IP, IPV4, NOF, IP_IP, IPV4, NOF, NONE, PAY3),
+ AVF_PTT(31, IP, IPV4, NOF, IP_IP, IPV4, NOF, UDP, PAY4),
+ AVF_PTT_UNUSED_ENTRY(32),
+ AVF_PTT(33, IP, IPV4, NOF, IP_IP, IPV4, NOF, TCP, PAY4),
+ AVF_PTT(34, IP, IPV4, NOF, IP_IP, IPV4, NOF, SCTP, PAY4),
+ AVF_PTT(35, IP, IPV4, NOF, IP_IP, IPV4, NOF, ICMP, PAY4),
+
+ /* IPv4 --> IPv6 */
+ AVF_PTT(36, IP, IPV4, NOF, IP_IP, IPV6, FRG, NONE, PAY3),
+ AVF_PTT(37, IP, IPV4, NOF, IP_IP, IPV6, NOF, NONE, PAY3),
+ AVF_PTT(38, IP, IPV4, NOF, IP_IP, IPV6, NOF, UDP, PAY4),
+ AVF_PTT_UNUSED_ENTRY(39),
+ AVF_PTT(40, IP, IPV4, NOF, IP_IP, IPV6, NOF, TCP, PAY4),
+ AVF_PTT(41, IP, IPV4, NOF, IP_IP, IPV6, NOF, SCTP, PAY4),
+ AVF_PTT(42, IP, IPV4, NOF, IP_IP, IPV6, NOF, ICMP, PAY4),
+
+ /* IPv4 --> GRE/NAT */
+ AVF_PTT(43, IP, IPV4, NOF, IP_GRENAT, NONE, NOF, NONE, PAY3),
+
+ /* IPv4 --> GRE/NAT --> IPv4 */
+ AVF_PTT(44, IP, IPV4, NOF, IP_GRENAT, IPV4, FRG, NONE, PAY3),
+ AVF_PTT(45, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, NONE, PAY3),
+ AVF_PTT(46, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, UDP, PAY4),
+ AVF_PTT_UNUSED_ENTRY(47),
+ AVF_PTT(48, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, TCP, PAY4),
+ AVF_PTT(49, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, SCTP, PAY4),
+ AVF_PTT(50, IP, IPV4, NOF, IP_GRENAT, IPV4, NOF, ICMP, PAY4),
+
+ /* IPv4 --> GRE/NAT --> IPv6 */
+ AVF_PTT(51, IP, IPV4, NOF, IP_GRENAT, IPV6, FRG, NONE, PAY3),
+ AVF_PTT(52, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, NONE, PAY3),
+ AVF_PTT(53, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, UDP, PAY4),
+ AVF_PTT_UNUSED_ENTRY(54),
+ AVF_PTT(55, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, TCP, PAY4),
+ AVF_PTT(56, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, SCTP, PAY4),
+ AVF_PTT(57, IP, IPV4, NOF, IP_GRENAT, IPV6, NOF, ICMP, PAY4),
+
+ /* IPv4 --> GRE/NAT --> MAC */
+ AVF_PTT(58, IP, IPV4, NOF, IP_GRENAT_MAC, NONE, NOF, NONE, PAY3),
+
+ /* IPv4 --> GRE/NAT --> MAC --> IPv4 */
+ AVF_PTT(59, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, FRG, NONE, PAY3),
+ AVF_PTT(60, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, NONE, PAY3),
+ AVF_PTT(61, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, UDP, PAY4),
+ AVF_PTT_UNUSED_ENTRY(62),
+ AVF_PTT(63, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, TCP, PAY4),
+ AVF_PTT(64, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, SCTP, PAY4),
+ AVF_PTT(65, IP, IPV4, NOF, IP_GRENAT_MAC, IPV4, NOF, ICMP, PAY4),
+
+ /* IPv4 --> GRE/NAT -> MAC --> IPv6 */
+ AVF_PTT(66, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, FRG, NONE, PAY3),
+ AVF_PTT(67, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, NONE, PAY3),
+ AVF_PTT(68, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, UDP, PAY4),
+ AVF_PTT_UNUSED_ENTRY(69),
+ AVF_PTT(70, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, TCP, PAY4),
+ AVF_PTT(71, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, SCTP, PAY4),
+ AVF_PTT(72, IP, IPV4, NOF, IP_GRENAT_MAC, IPV6, NOF, ICMP, PAY4),
+
+ /* IPv4 --> GRE/NAT --> MAC/VLAN */
+ AVF_PTT(73, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, NONE, NOF, NONE, PAY3),
+
+ /* IPv4 ---> GRE/NAT -> MAC/VLAN --> IPv4 */
+ AVF_PTT(74, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, FRG, NONE, PAY3),
+ AVF_PTT(75, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, NONE, PAY3),
+ AVF_PTT(76, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, UDP, PAY4),
+ AVF_PTT_UNUSED_ENTRY(77),
+ AVF_PTT(78, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, TCP, PAY4),
+ AVF_PTT(79, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, SCTP, PAY4),
+ AVF_PTT(80, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, ICMP, PAY4),
+
+ /* IPv4 -> GRE/NAT -> MAC/VLAN --> IPv6 */
+ AVF_PTT(81, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, FRG, NONE, PAY3),
+ AVF_PTT(82, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, NONE, PAY3),
+ AVF_PTT(83, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, UDP, PAY4),
+ AVF_PTT_UNUSED_ENTRY(84),
+ AVF_PTT(85, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, TCP, PAY4),
+ AVF_PTT(86, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, SCTP, PAY4),
+ AVF_PTT(87, IP, IPV4, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, ICMP, PAY4),
+
+ /* Non Tunneled IPv6 */
+ AVF_PTT(88, IP, IPV6, FRG, NONE, NONE, NOF, NONE, PAY3),
+ AVF_PTT(89, IP, IPV6, NOF, NONE, NONE, NOF, NONE, PAY3),
+ AVF_PTT(90, IP, IPV6, NOF, NONE, NONE, NOF, UDP, PAY4),
+ AVF_PTT_UNUSED_ENTRY(91),
+ AVF_PTT(92, IP, IPV6, NOF, NONE, NONE, NOF, TCP, PAY4),
+ AVF_PTT(93, IP, IPV6, NOF, NONE, NONE, NOF, SCTP, PAY4),
+ AVF_PTT(94, IP, IPV6, NOF, NONE, NONE, NOF, ICMP, PAY4),
+
+ /* IPv6 --> IPv4 */
+ AVF_PTT(95, IP, IPV6, NOF, IP_IP, IPV4, FRG, NONE, PAY3),
+ AVF_PTT(96, IP, IPV6, NOF, IP_IP, IPV4, NOF, NONE, PAY3),
+ AVF_PTT(97, IP, IPV6, NOF, IP_IP, IPV4, NOF, UDP, PAY4),
+ AVF_PTT_UNUSED_ENTRY(98),
+ AVF_PTT(99, IP, IPV6, NOF, IP_IP, IPV4, NOF, TCP, PAY4),
+ AVF_PTT(100, IP, IPV6, NOF, IP_IP, IPV4, NOF, SCTP, PAY4),
+ AVF_PTT(101, IP, IPV6, NOF, IP_IP, IPV4, NOF, ICMP, PAY4),
+
+ /* IPv6 --> IPv6 */
+ AVF_PTT(102, IP, IPV6, NOF, IP_IP, IPV6, FRG, NONE, PAY3),
+ AVF_PTT(103, IP, IPV6, NOF, IP_IP, IPV6, NOF, NONE, PAY3),
+ AVF_PTT(104, IP, IPV6, NOF, IP_IP, IPV6, NOF, UDP, PAY4),
+ AVF_PTT_UNUSED_ENTRY(105),
+ AVF_PTT(106, IP, IPV6, NOF, IP_IP, IPV6, NOF, TCP, PAY4),
+ AVF_PTT(107, IP, IPV6, NOF, IP_IP, IPV6, NOF, SCTP, PAY4),
+ AVF_PTT(108, IP, IPV6, NOF, IP_IP, IPV6, NOF, ICMP, PAY4),
+
+ /* IPv6 --> GRE/NAT */
+ AVF_PTT(109, IP, IPV6, NOF, IP_GRENAT, NONE, NOF, NONE, PAY3),
+
+ /* IPv6 --> GRE/NAT -> IPv4 */
+ AVF_PTT(110, IP, IPV6, NOF, IP_GRENAT, IPV4, FRG, NONE, PAY3),
+ AVF_PTT(111, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, NONE, PAY3),
+ AVF_PTT(112, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, UDP, PAY4),
+ AVF_PTT_UNUSED_ENTRY(113),
+ AVF_PTT(114, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, TCP, PAY4),
+ AVF_PTT(115, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, SCTP, PAY4),
+ AVF_PTT(116, IP, IPV6, NOF, IP_GRENAT, IPV4, NOF, ICMP, PAY4),
+
+ /* IPv6 --> GRE/NAT -> IPv6 */
+ AVF_PTT(117, IP, IPV6, NOF, IP_GRENAT, IPV6, FRG, NONE, PAY3),
+ AVF_PTT(118, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, NONE, PAY3),
+ AVF_PTT(119, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, UDP, PAY4),
+ AVF_PTT_UNUSED_ENTRY(120),
+ AVF_PTT(121, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, TCP, PAY4),
+ AVF_PTT(122, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, SCTP, PAY4),
+ AVF_PTT(123, IP, IPV6, NOF, IP_GRENAT, IPV6, NOF, ICMP, PAY4),
+
+ /* IPv6 --> GRE/NAT -> MAC */
+ AVF_PTT(124, IP, IPV6, NOF, IP_GRENAT_MAC, NONE, NOF, NONE, PAY3),
+
+ /* IPv6 --> GRE/NAT -> MAC -> IPv4 */
+ AVF_PTT(125, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, FRG, NONE, PAY3),
+ AVF_PTT(126, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, NONE, PAY3),
+ AVF_PTT(127, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, UDP, PAY4),
+ AVF_PTT_UNUSED_ENTRY(128),
+ AVF_PTT(129, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, TCP, PAY4),
+ AVF_PTT(130, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, SCTP, PAY4),
+ AVF_PTT(131, IP, IPV6, NOF, IP_GRENAT_MAC, IPV4, NOF, ICMP, PAY4),
+
+ /* IPv6 --> GRE/NAT -> MAC -> IPv6 */
+ AVF_PTT(132, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, FRG, NONE, PAY3),
+ AVF_PTT(133, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, NONE, PAY3),
+ AVF_PTT(134, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, UDP, PAY4),
+ AVF_PTT_UNUSED_ENTRY(135),
+ AVF_PTT(136, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, TCP, PAY4),
+ AVF_PTT(137, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, SCTP, PAY4),
+ AVF_PTT(138, IP, IPV6, NOF, IP_GRENAT_MAC, IPV6, NOF, ICMP, PAY4),
+
+ /* IPv6 --> GRE/NAT -> MAC/VLAN */
+ AVF_PTT(139, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, NONE, NOF, NONE, PAY3),
+
+ /* IPv6 --> GRE/NAT -> MAC/VLAN --> IPv4 */
+ AVF_PTT(140, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, FRG, NONE, PAY3),
+ AVF_PTT(141, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, NONE, PAY3),
+ AVF_PTT(142, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, UDP, PAY4),
+ AVF_PTT_UNUSED_ENTRY(143),
+ AVF_PTT(144, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, TCP, PAY4),
+ AVF_PTT(145, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, SCTP, PAY4),
+ AVF_PTT(146, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV4, NOF, ICMP, PAY4),
+
+ /* IPv6 --> GRE/NAT -> MAC/VLAN --> IPv6 */
+ AVF_PTT(147, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, FRG, NONE, PAY3),
+ AVF_PTT(148, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, NONE, PAY3),
+ AVF_PTT(149, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, UDP, PAY4),
+ AVF_PTT_UNUSED_ENTRY(150),
+ AVF_PTT(151, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, TCP, PAY4),
+ AVF_PTT(152, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, SCTP, PAY4),
+ AVF_PTT(153, IP, IPV6, NOF, IP_GRENAT_MAC_VLAN, IPV6, NOF, ICMP, PAY4),
+
+ /* unused entries */
+ AVF_PTT_UNUSED_ENTRY(154),
+ AVF_PTT_UNUSED_ENTRY(155),
+ AVF_PTT_UNUSED_ENTRY(156),
+ AVF_PTT_UNUSED_ENTRY(157),
+ AVF_PTT_UNUSED_ENTRY(158),
+ AVF_PTT_UNUSED_ENTRY(159),
+
+ AVF_PTT_UNUSED_ENTRY(160),
+ AVF_PTT_UNUSED_ENTRY(161),
+ AVF_PTT_UNUSED_ENTRY(162),
+ AVF_PTT_UNUSED_ENTRY(163),
+ AVF_PTT_UNUSED_ENTRY(164),
+ AVF_PTT_UNUSED_ENTRY(165),
+ AVF_PTT_UNUSED_ENTRY(166),
+ AVF_PTT_UNUSED_ENTRY(167),
+ AVF_PTT_UNUSED_ENTRY(168),
+ AVF_PTT_UNUSED_ENTRY(169),
+
+ AVF_PTT_UNUSED_ENTRY(170),
+ AVF_PTT_UNUSED_ENTRY(171),
+ AVF_PTT_UNUSED_ENTRY(172),
+ AVF_PTT_UNUSED_ENTRY(173),
+ AVF_PTT_UNUSED_ENTRY(174),
+ AVF_PTT_UNUSED_ENTRY(175),
+ AVF_PTT_UNUSED_ENTRY(176),
+ AVF_PTT_UNUSED_ENTRY(177),
+ AVF_PTT_UNUSED_ENTRY(178),
+ AVF_PTT_UNUSED_ENTRY(179),
+
+ AVF_PTT_UNUSED_ENTRY(180),
+ AVF_PTT_UNUSED_ENTRY(181),
+ AVF_PTT_UNUSED_ENTRY(182),
+ AVF_PTT_UNUSED_ENTRY(183),
+ AVF_PTT_UNUSED_ENTRY(184),
+ AVF_PTT_UNUSED_ENTRY(185),
+ AVF_PTT_UNUSED_ENTRY(186),
+ AVF_PTT_UNUSED_ENTRY(187),
+ AVF_PTT_UNUSED_ENTRY(188),
+ AVF_PTT_UNUSED_ENTRY(189),
+
+ AVF_PTT_UNUSED_ENTRY(190),
+ AVF_PTT_UNUSED_ENTRY(191),
+ AVF_PTT_UNUSED_ENTRY(192),
+ AVF_PTT_UNUSED_ENTRY(193),
+ AVF_PTT_UNUSED_ENTRY(194),
+ AVF_PTT_UNUSED_ENTRY(195),
+ AVF_PTT_UNUSED_ENTRY(196),
+ AVF_PTT_UNUSED_ENTRY(197),
+ AVF_PTT_UNUSED_ENTRY(198),
+ AVF_PTT_UNUSED_ENTRY(199),
+
+ AVF_PTT_UNUSED_ENTRY(200),
+ AVF_PTT_UNUSED_ENTRY(201),
+ AVF_PTT_UNUSED_ENTRY(202),
+ AVF_PTT_UNUSED_ENTRY(203),
+ AVF_PTT_UNUSED_ENTRY(204),
+ AVF_PTT_UNUSED_ENTRY(205),
+ AVF_PTT_UNUSED_ENTRY(206),
+ AVF_PTT_UNUSED_ENTRY(207),
+ AVF_PTT_UNUSED_ENTRY(208),
+ AVF_PTT_UNUSED_ENTRY(209),
+
+ AVF_PTT_UNUSED_ENTRY(210),
+ AVF_PTT_UNUSED_ENTRY(211),
+ AVF_PTT_UNUSED_ENTRY(212),
+ AVF_PTT_UNUSED_ENTRY(213),
+ AVF_PTT_UNUSED_ENTRY(214),
+ AVF_PTT_UNUSED_ENTRY(215),
+ AVF_PTT_UNUSED_ENTRY(216),
+ AVF_PTT_UNUSED_ENTRY(217),
+ AVF_PTT_UNUSED_ENTRY(218),
+ AVF_PTT_UNUSED_ENTRY(219),
+
+ AVF_PTT_UNUSED_ENTRY(220),
+ AVF_PTT_UNUSED_ENTRY(221),
+ AVF_PTT_UNUSED_ENTRY(222),
+ AVF_PTT_UNUSED_ENTRY(223),
+ AVF_PTT_UNUSED_ENTRY(224),
+ AVF_PTT_UNUSED_ENTRY(225),
+ AVF_PTT_UNUSED_ENTRY(226),
+ AVF_PTT_UNUSED_ENTRY(227),
+ AVF_PTT_UNUSED_ENTRY(228),
+ AVF_PTT_UNUSED_ENTRY(229),
+
+ AVF_PTT_UNUSED_ENTRY(230),
+ AVF_PTT_UNUSED_ENTRY(231),
+ AVF_PTT_UNUSED_ENTRY(232),
+ AVF_PTT_UNUSED_ENTRY(233),
+ AVF_PTT_UNUSED_ENTRY(234),
+ AVF_PTT_UNUSED_ENTRY(235),
+ AVF_PTT_UNUSED_ENTRY(236),
+ AVF_PTT_UNUSED_ENTRY(237),
+ AVF_PTT_UNUSED_ENTRY(238),
+ AVF_PTT_UNUSED_ENTRY(239),
+
+ AVF_PTT_UNUSED_ENTRY(240),
+ AVF_PTT_UNUSED_ENTRY(241),
+ AVF_PTT_UNUSED_ENTRY(242),
+ AVF_PTT_UNUSED_ENTRY(243),
+ AVF_PTT_UNUSED_ENTRY(244),
+ AVF_PTT_UNUSED_ENTRY(245),
+ AVF_PTT_UNUSED_ENTRY(246),
+ AVF_PTT_UNUSED_ENTRY(247),
+ AVF_PTT_UNUSED_ENTRY(248),
+ AVF_PTT_UNUSED_ENTRY(249),
+
+ AVF_PTT_UNUSED_ENTRY(250),
+ AVF_PTT_UNUSED_ENTRY(251),
+ AVF_PTT_UNUSED_ENTRY(252),
+ AVF_PTT_UNUSED_ENTRY(253),
+ AVF_PTT_UNUSED_ENTRY(254),
+ AVF_PTT_UNUSED_ENTRY(255)
+};
+
+
+/**
+ * avf_validate_mac_addr - Validate unicast MAC address
+ * @mac_addr: pointer to MAC address
+ *
+ * Tests a MAC address to ensure it is a valid Individual Address
+ **/
+enum avf_status_code avf_validate_mac_addr(u8 *mac_addr)
+{
+ enum avf_status_code status = AVF_SUCCESS;
+
+ DEBUGFUNC("avf_validate_mac_addr");
+
+ /* Broadcast addresses ARE multicast addresses
+ * Make sure it is not a multicast address
+ * Reject the zero address
+ */
+ if (AVF_IS_MULTICAST(mac_addr) ||
+ (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
+ mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0))
+ status = AVF_ERR_INVALID_MAC_ADDR;
+
+ return status;
+}
+
+/**
+ * avf_aq_rx_ctl_read_register - use FW to read from an Rx control register
+ * @hw: pointer to the hw struct
+ * @reg_addr: register address
+ * @reg_val: ptr to register value
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Use the firmware to read the Rx control register,
+ * especially useful if the Rx unit is under heavy pressure
+ **/
+enum avf_status_code avf_aq_rx_ctl_read_register(struct avf_hw *hw,
+ u32 reg_addr, u32 *reg_val,
+ struct avf_asq_cmd_details *cmd_details)
+{
+ struct avf_aq_desc desc;
+ struct avf_aqc_rx_ctl_reg_read_write *cmd_resp =
+ (struct avf_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
+ enum avf_status_code status;
+
+ if (reg_val == NULL)
+ return AVF_ERR_PARAM;
+
+ avf_fill_default_direct_cmd_desc(&desc, avf_aqc_opc_rx_ctl_reg_read);
+
+ cmd_resp->address = CPU_TO_LE32(reg_addr);
+
+ status = avf_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+ if (status == AVF_SUCCESS)
+ *reg_val = LE32_TO_CPU(cmd_resp->value);
+
+ return status;
+}
+
+/**
+ * avf_read_rx_ctl - read from an Rx control register
+ * @hw: pointer to the hw struct
+ * @reg_addr: register address
+ **/
+u32 avf_read_rx_ctl(struct avf_hw *hw, u32 reg_addr)
+{
+ enum avf_status_code status = AVF_SUCCESS;
+ bool use_register;
+ int retry = 5;
+ u32 val = 0;
+
+ use_register = (((hw->aq.api_maj_ver == 1) &&
+ (hw->aq.api_min_ver < 5)) ||
+ (hw->mac.type == AVF_MAC_X722));
+ if (!use_register) {
+do_retry:
+ status = avf_aq_rx_ctl_read_register(hw, reg_addr, &val, NULL);
+ if (hw->aq.asq_last_status == AVF_AQ_RC_EAGAIN && retry) {
+ avf_msec_delay(1);
+ retry--;
+ goto do_retry;
+ }
+ }
+
+ /* if the AQ access failed, try the old-fashioned way */
+ if (status || use_register)
+ val = rd32(hw, reg_addr);
+
+ return val;
+}
+
+/**
+ * avf_aq_rx_ctl_write_register
+ * @hw: pointer to the hw struct
+ * @reg_addr: register address
+ * @reg_val: register value
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Use the firmware to write to an Rx control register,
+ * especially useful if the Rx unit is under heavy pressure
+ **/
+enum avf_status_code avf_aq_rx_ctl_write_register(struct avf_hw *hw,
+ u32 reg_addr, u32 reg_val,
+ struct avf_asq_cmd_details *cmd_details)
+{
+ struct avf_aq_desc desc;
+ struct avf_aqc_rx_ctl_reg_read_write *cmd =
+ (struct avf_aqc_rx_ctl_reg_read_write *)&desc.params.raw;
+ enum avf_status_code status;
+
+ avf_fill_default_direct_cmd_desc(&desc, avf_aqc_opc_rx_ctl_reg_write);
+
+ cmd->address = CPU_TO_LE32(reg_addr);
+ cmd->value = CPU_TO_LE32(reg_val);
+
+ status = avf_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+ return status;
+}
+
+/**
+ * avf_write_rx_ctl - write to an Rx control register
+ * @hw: pointer to the hw struct
+ * @reg_addr: register address
+ * @reg_val: register value
+ **/
+void avf_write_rx_ctl(struct avf_hw *hw, u32 reg_addr, u32 reg_val)
+{
+ enum avf_status_code status = AVF_SUCCESS;
+ bool use_register;
+ int retry = 5;
+
+ use_register = (((hw->aq.api_maj_ver == 1) &&
+ (hw->aq.api_min_ver < 5)) ||
+ (hw->mac.type == AVF_MAC_X722));
+ if (!use_register) {
+do_retry:
+ status = avf_aq_rx_ctl_write_register(hw, reg_addr,
+ reg_val, NULL);
+ if (hw->aq.asq_last_status == AVF_AQ_RC_EAGAIN && retry) {
+ avf_msec_delay(1);
+ retry--;
+ goto do_retry;
+ }
+ }
+
+ /* if the AQ access failed, try the old-fashioned way */
+ if (status || use_register)
+ wr32(hw, reg_addr, reg_val);
+}
+
+/**
+ * avf_aq_set_phy_register
+ * @hw: pointer to the hw struct
+ * @phy_select: select which phy should be accessed
+ * @dev_addr: PHY device address
+ * @reg_addr: PHY register address
+ * @reg_val: new register value
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Write the external PHY register.
+ **/
+enum avf_status_code avf_aq_set_phy_register(struct avf_hw *hw,
+ u8 phy_select, u8 dev_addr,
+ u32 reg_addr, u32 reg_val,
+ struct avf_asq_cmd_details *cmd_details)
+{
+ struct avf_aq_desc desc;
+ struct avf_aqc_phy_register_access *cmd =
+ (struct avf_aqc_phy_register_access *)&desc.params.raw;
+ enum avf_status_code status;
+
+ avf_fill_default_direct_cmd_desc(&desc,
+ avf_aqc_opc_set_phy_register);
+
+ cmd->phy_interface = phy_select;
+ cmd->dev_addres = dev_addr;
+ cmd->reg_address = CPU_TO_LE32(reg_addr);
+ cmd->reg_value = CPU_TO_LE32(reg_val);
+
+ status = avf_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+ return status;
+}
+
+/**
+ * avf_aq_get_phy_register
+ * @hw: pointer to the hw struct
+ * @phy_select: select which phy should be accessed
+ * @dev_addr: PHY device address
+ * @reg_addr: PHY register address
+ * @reg_val: read register value
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Read the external PHY register.
+ **/
+enum avf_status_code avf_aq_get_phy_register(struct avf_hw *hw,
+ u8 phy_select, u8 dev_addr,
+ u32 reg_addr, u32 *reg_val,
+ struct avf_asq_cmd_details *cmd_details)
+{
+ struct avf_aq_desc desc;
+ struct avf_aqc_phy_register_access *cmd =
+ (struct avf_aqc_phy_register_access *)&desc.params.raw;
+ enum avf_status_code status;
+
+ avf_fill_default_direct_cmd_desc(&desc,
+ avf_aqc_opc_get_phy_register);
+
+ cmd->phy_interface = phy_select;
+ cmd->dev_addres = dev_addr;
+ cmd->reg_address = CPU_TO_LE32(reg_addr);
+
+ status = avf_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+ if (!status)
+ *reg_val = LE32_TO_CPU(cmd->reg_value);
+
+ return status;
+}
+
+
+/**
+ * avf_aq_send_msg_to_pf
+ * @hw: pointer to the hardware structure
+ * @v_opcode: opcodes for VF-PF communication
+ * @v_retval: return error code
+ * @msg: pointer to the msg buffer
+ * @msglen: msg length
+ * @cmd_details: pointer to command details
+ *
+ * Send message to PF driver using admin queue. By default, this message
+ * is sent asynchronously, i.e. avf_asq_send_command() does not wait for
+ * completion before returning.
+ **/
+enum avf_status_code avf_aq_send_msg_to_pf(struct avf_hw *hw,
+ enum virtchnl_ops v_opcode,
+ enum avf_status_code v_retval,
+ u8 *msg, u16 msglen,
+ struct avf_asq_cmd_details *cmd_details)
+{
+ struct avf_aq_desc desc;
+ struct avf_asq_cmd_details details;
+ enum avf_status_code status;
+
+ avf_fill_default_direct_cmd_desc(&desc, avf_aqc_opc_send_msg_to_pf);
+ desc.flags |= CPU_TO_LE16((u16)AVF_AQ_FLAG_SI);
+ desc.cookie_high = CPU_TO_LE32(v_opcode);
+ desc.cookie_low = CPU_TO_LE32(v_retval);
+ if (msglen) {
+ desc.flags |= CPU_TO_LE16((u16)(AVF_AQ_FLAG_BUF
+ | AVF_AQ_FLAG_RD));
+ if (msglen > AVF_AQ_LARGE_BUF)
+ desc.flags |= CPU_TO_LE16((u16)AVF_AQ_FLAG_LB);
+ desc.datalen = CPU_TO_LE16(msglen);
+ }
+ if (!cmd_details) {
+ avf_memset(&details, 0, sizeof(details), AVF_NONDMA_MEM);
+ details.async = true;
+ cmd_details = &details;
+ }
+ status = avf_asq_send_command(hw, (struct avf_aq_desc *)&desc, msg,
+ msglen, cmd_details);
+ return status;
+}
+
+/**
+ * avf_parse_hw_config
+ * @hw: pointer to the hardware structure
+ * @msg: pointer to the virtual channel VF resource structure
+ *
+ * Given a VF resource message from the PF, populate the hw struct
+ * with appropriate information.
+ **/
+void avf_parse_hw_config(struct avf_hw *hw,
+ struct virtchnl_vf_resource *msg)
+{
+ struct virtchnl_vsi_resource *vsi_res;
+ int i;
+
+ vsi_res = &msg->vsi_res[0];
+
+ hw->dev_caps.num_vsis = msg->num_vsis;
+ hw->dev_caps.num_rx_qp = msg->num_queue_pairs;
+ hw->dev_caps.num_tx_qp = msg->num_queue_pairs;
+ hw->dev_caps.num_msix_vectors_vf = msg->max_vectors;
+ hw->dev_caps.dcb = msg->vf_cap_flags &
+ VIRTCHNL_VF_OFFLOAD_L2;
+ hw->dev_caps.iwarp = (msg->vf_cap_flags &
+ VIRTCHNL_VF_OFFLOAD_IWARP) ? 1 : 0;
+ for (i = 0; i < msg->num_vsis; i++) {
+ if (vsi_res->vsi_type == VIRTCHNL_VSI_SRIOV) {
+ avf_memcpy(hw->mac.perm_addr,
+ vsi_res->default_mac_addr,
+ ETH_ALEN,
+ AVF_NONDMA_TO_NONDMA);
+ avf_memcpy(hw->mac.addr, vsi_res->default_mac_addr,
+ ETH_ALEN,
+ AVF_NONDMA_TO_NONDMA);
+ }
+ vsi_res++;
+ }
+}
+
+/**
+ * avf_reset
+ * @hw: pointer to the hardware structure
+ *
+ * Send a VF_RESET message to the PF. Does not wait for response from PF
+ * as none will be forthcoming. Immediately after calling this function,
+ * the admin queue should be shut down and (optionally) reinitialized.
+ **/
+enum avf_status_code avf_reset(struct avf_hw *hw)
+{
+ return avf_aq_send_msg_to_pf(hw, VIRTCHNL_OP_RESET_VF,
+ AVF_SUCCESS, NULL, 0, NULL);
+}
+
+/**
+ * avf_aq_set_arp_proxy_config
+ * @hw: pointer to the HW structure
+ * @proxy_config: pointer to proxy config command table struct
+ * @cmd_details: pointer to command details
+ *
+ * Set ARP offload parameters from pre-populated
+ * avf_aqc_arp_proxy_data struct
+ **/
+enum avf_status_code avf_aq_set_arp_proxy_config(struct avf_hw *hw,
+ struct avf_aqc_arp_proxy_data *proxy_config,
+ struct avf_asq_cmd_details *cmd_details)
+{
+ struct avf_aq_desc desc;
+ enum avf_status_code status;
+
+ if (!proxy_config)
+ return AVF_ERR_PARAM;
+
+ avf_fill_default_direct_cmd_desc(&desc, avf_aqc_opc_set_proxy_config);
+
+ desc.flags |= CPU_TO_LE16((u16)AVF_AQ_FLAG_BUF);
+ desc.flags |= CPU_TO_LE16((u16)AVF_AQ_FLAG_RD);
+ desc.params.external.addr_high =
+ CPU_TO_LE32(AVF_HI_DWORD((u64)proxy_config));
+ desc.params.external.addr_low =
+ CPU_TO_LE32(AVF_LO_DWORD((u64)proxy_config));
+ desc.datalen = CPU_TO_LE16(sizeof(struct avf_aqc_arp_proxy_data));
+
+ status = avf_asq_send_command(hw, &desc, proxy_config,
+ sizeof(struct avf_aqc_arp_proxy_data),
+ cmd_details);
+
+ return status;
+}
+
+/**
+ * avf_aq_opc_set_ns_proxy_table_entry
+ * @hw: pointer to the HW structure
+ * @ns_proxy_table_entry: pointer to NS table entry command struct
+ * @cmd_details: pointer to command details
+ *
+ * Set IPv6 Neighbor Solicitation (NS) protocol offload parameters
+ * from pre-populated avf_aqc_ns_proxy_data struct
+ **/
+enum avf_status_code avf_aq_set_ns_proxy_table_entry(struct avf_hw *hw,
+ struct avf_aqc_ns_proxy_data *ns_proxy_table_entry,
+ struct avf_asq_cmd_details *cmd_details)
+{
+ struct avf_aq_desc desc;
+ enum avf_status_code status;
+
+ if (!ns_proxy_table_entry)
+ return AVF_ERR_PARAM;
+
+ avf_fill_default_direct_cmd_desc(&desc,
+ avf_aqc_opc_set_ns_proxy_table_entry);
+
+ desc.flags |= CPU_TO_LE16((u16)AVF_AQ_FLAG_BUF);
+ desc.flags |= CPU_TO_LE16((u16)AVF_AQ_FLAG_RD);
+ desc.params.external.addr_high =
+ CPU_TO_LE32(AVF_HI_DWORD((u64)ns_proxy_table_entry));
+ desc.params.external.addr_low =
+ CPU_TO_LE32(AVF_LO_DWORD((u64)ns_proxy_table_entry));
+ desc.datalen = CPU_TO_LE16(sizeof(struct avf_aqc_ns_proxy_data));
+
+ status = avf_asq_send_command(hw, &desc, ns_proxy_table_entry,
+ sizeof(struct avf_aqc_ns_proxy_data),
+ cmd_details);
+
+ return status;
+}
+
+/**
+ * avf_aq_set_clear_wol_filter
+ * @hw: pointer to the hw struct
+ * @filter_index: index of filter to modify (0-7)
+ * @filter: buffer containing filter to be set
+ * @set_filter: true to set filter, false to clear filter
+ * @no_wol_tco: if true, pass through packets cannot cause wake-up
+ * if false, pass through packets may cause wake-up
+ * @filter_valid: true if filter action is valid
+ * @no_wol_tco_valid: true if no WoL in TCO traffic action valid
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Set or clear WoL filter for port attached to the PF
+ **/
+enum avf_status_code avf_aq_set_clear_wol_filter(struct avf_hw *hw,
+ u8 filter_index,
+ struct avf_aqc_set_wol_filter_data *filter,
+ bool set_filter, bool no_wol_tco,
+ bool filter_valid, bool no_wol_tco_valid,
+ struct avf_asq_cmd_details *cmd_details)
+{
+ struct avf_aq_desc desc;
+ struct avf_aqc_set_wol_filter *cmd =
+ (struct avf_aqc_set_wol_filter *)&desc.params.raw;
+ enum avf_status_code status;
+ u16 cmd_flags = 0;
+ u16 valid_flags = 0;
+ u16 buff_len = 0;
+
+ avf_fill_default_direct_cmd_desc(&desc, avf_aqc_opc_set_wol_filter);
+
+ if (filter_index >= AVF_AQC_MAX_NUM_WOL_FILTERS)
+ return AVF_ERR_PARAM;
+ cmd->filter_index = CPU_TO_LE16(filter_index);
+
+ if (set_filter) {
+ if (!filter)
+ return AVF_ERR_PARAM;
+
+ cmd_flags |= AVF_AQC_SET_WOL_FILTER;
+ cmd_flags |= AVF_AQC_SET_WOL_FILTER_WOL_PRESERVE_ON_PFR;
+ }
+
+ if (no_wol_tco)
+ cmd_flags |= AVF_AQC_SET_WOL_FILTER_NO_TCO_WOL;
+ cmd->cmd_flags = CPU_TO_LE16(cmd_flags);
+
+ if (filter_valid)
+ valid_flags |= AVF_AQC_SET_WOL_FILTER_ACTION_VALID;
+ if (no_wol_tco_valid)
+ valid_flags |= AVF_AQC_SET_WOL_FILTER_NO_TCO_ACTION_VALID;
+ cmd->valid_flags = CPU_TO_LE16(valid_flags);
+
+ buff_len = sizeof(*filter);
+ desc.datalen = CPU_TO_LE16(buff_len);
+
+ desc.flags |= CPU_TO_LE16((u16)AVF_AQ_FLAG_BUF);
+ desc.flags |= CPU_TO_LE16((u16)AVF_AQ_FLAG_RD);
+
+ cmd->address_high = CPU_TO_LE32(AVF_HI_DWORD((u64)filter));
+ cmd->address_low = CPU_TO_LE32(AVF_LO_DWORD((u64)filter));
+
+ status = avf_asq_send_command(hw, &desc, filter,
+ buff_len, cmd_details);
+
+ return status;
+}
+
+/**
+ * avf_aq_get_wake_event_reason
+ * @hw: pointer to the hw struct
+ * @wake_reason: return value, index of matching filter
+ * @cmd_details: pointer to command details structure or NULL
+ *
+ * Get information for the reason of a Wake Up event
+ **/
+enum avf_status_code avf_aq_get_wake_event_reason(struct avf_hw *hw,
+ u16 *wake_reason,
+ struct avf_asq_cmd_details *cmd_details)
+{
+ struct avf_aq_desc desc;
+ struct avf_aqc_get_wake_reason_completion *resp =
+ (struct avf_aqc_get_wake_reason_completion *)&desc.params.raw;
+ enum avf_status_code status;
+
+ avf_fill_default_direct_cmd_desc(&desc, avf_aqc_opc_get_wake_reason);
+
+ status = avf_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+ if (status == AVF_SUCCESS)
+ *wake_reason = LE16_TO_CPU(resp->wake_reason);
+
+ return status;
+}
+
+/**
+* avf_aq_clear_all_wol_filters
+* @hw: pointer to the hw struct
+* @cmd_details: pointer to command details structure or NULL
+*
+* Get information for the reason of a Wake Up event
+**/
+enum avf_status_code avf_aq_clear_all_wol_filters(struct avf_hw *hw,
+ struct avf_asq_cmd_details *cmd_details)
+{
+ struct avf_aq_desc desc;
+ enum avf_status_code status;
+
+ avf_fill_default_direct_cmd_desc(&desc,
+ avf_aqc_opc_clear_all_wol_filters);
+
+ status = avf_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+ return status;
+}
+
+/**
+ * avf_aq_write_ddp - Write dynamic device personalization (ddp)
+ * @hw: pointer to the hw struct
+ * @buff: command buffer (size in bytes = buff_size)
+ * @buff_size: buffer size in bytes
+ * @track_id: package tracking id
+ * @error_offset: returns error offset
+ * @error_info: returns error information
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum
+avf_status_code avf_aq_write_ddp(struct avf_hw *hw, void *buff,
+ u16 buff_size, u32 track_id,
+ u32 *error_offset, u32 *error_info,
+ struct avf_asq_cmd_details *cmd_details)
+{
+ struct avf_aq_desc desc;
+ struct avf_aqc_write_personalization_profile *cmd =
+ (struct avf_aqc_write_personalization_profile *)
+ &desc.params.raw;
+ struct avf_aqc_write_ddp_resp *resp;
+ enum avf_status_code status;
+
+ avf_fill_default_direct_cmd_desc(&desc,
+ avf_aqc_opc_write_personalization_profile);
+
+ desc.flags |= CPU_TO_LE16(AVF_AQ_FLAG_BUF | AVF_AQ_FLAG_RD);
+ if (buff_size > AVF_AQ_LARGE_BUF)
+ desc.flags |= CPU_TO_LE16((u16)AVF_AQ_FLAG_LB);
+
+ desc.datalen = CPU_TO_LE16(buff_size);
+
+ cmd->profile_track_id = CPU_TO_LE32(track_id);
+
+ status = avf_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
+ if (!status) {
+ resp = (struct avf_aqc_write_ddp_resp *)&desc.params.raw;
+ if (error_offset)
+ *error_offset = LE32_TO_CPU(resp->error_offset);
+ if (error_info)
+ *error_info = LE32_TO_CPU(resp->error_info);
+ }
+
+ return status;
+}
+
+/**
+ * avf_aq_get_ddp_list - Read dynamic device personalization (ddp)
+ * @hw: pointer to the hw struct
+ * @buff: command buffer (size in bytes = buff_size)
+ * @buff_size: buffer size in bytes
+ * @flags: AdminQ command flags
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+enum
+avf_status_code avf_aq_get_ddp_list(struct avf_hw *hw, void *buff,
+ u16 buff_size, u8 flags,
+ struct avf_asq_cmd_details *cmd_details)
+{
+ struct avf_aq_desc desc;
+ struct avf_aqc_get_applied_profiles *cmd =
+ (struct avf_aqc_get_applied_profiles *)&desc.params.raw;
+ enum avf_status_code status;
+
+ avf_fill_default_direct_cmd_desc(&desc,
+ avf_aqc_opc_get_personalization_profile_list);
+
+ desc.flags |= CPU_TO_LE16((u16)AVF_AQ_FLAG_BUF);
+ if (buff_size > AVF_AQ_LARGE_BUF)
+ desc.flags |= CPU_TO_LE16((u16)AVF_AQ_FLAG_LB);
+ desc.datalen = CPU_TO_LE16(buff_size);
+
+ cmd->flags = flags;
+
+ status = avf_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
+
+ return status;
+}
+
+/**
+ * avf_find_segment_in_package
+ * @segment_type: the segment type to search for (i.e., SEGMENT_TYPE_AVF)
+ * @pkg_hdr: pointer to the package header to be searched
+ *
+ * This function searches a package file for a particular segment type. On
+ * success it returns a pointer to the segment header, otherwise it will
+ * return NULL.
+ **/
+struct avf_generic_seg_header *
+avf_find_segment_in_package(u32 segment_type,
+ struct avf_package_header *pkg_hdr)
+{
+ struct avf_generic_seg_header *segment;
+ u32 i;
+
+ /* Search all package segments for the requested segment type */
+ for (i = 0; i < pkg_hdr->segment_count; i++) {
+ segment =
+ (struct avf_generic_seg_header *)((u8 *)pkg_hdr +
+ pkg_hdr->segment_offset[i]);
+
+ if (segment->type == segment_type)
+ return segment;
+ }
+
+ return NULL;
+}
+
+/* Get section table in profile */
+#define AVF_SECTION_TABLE(profile, sec_tbl) \
+ do { \
+ struct avf_profile_segment *p = (profile); \
+ u32 count; \
+ u32 *nvm; \
+ count = p->device_table_count; \
+ nvm = (u32 *)&p->device_table[count]; \
+ sec_tbl = (struct avf_section_table *)&nvm[nvm[0] + 1]; \
+ } while (0)
+
+/* Get section header in profile */
+#define AVF_SECTION_HEADER(profile, offset) \
+ (struct avf_profile_section_header *)((u8 *)(profile) + (offset))
+
+/**
+ * avf_find_section_in_profile
+ * @section_type: the section type to search for (i.e., SECTION_TYPE_NOTE)
+ * @profile: pointer to the avf segment header to be searched
+ *
+ * This function searches avf segment for a particular section type. On
+ * success it returns a pointer to the section header, otherwise it will
+ * return NULL.
+ **/
+struct avf_profile_section_header *
+avf_find_section_in_profile(u32 section_type,
+ struct avf_profile_segment *profile)
+{
+ struct avf_profile_section_header *sec;
+ struct avf_section_table *sec_tbl;
+ u32 sec_off;
+ u32 i;
+
+ if (profile->header.type != SEGMENT_TYPE_AVF)
+ return NULL;
+
+ AVF_SECTION_TABLE(profile, sec_tbl);
+
+ for (i = 0; i < sec_tbl->section_count; i++) {
+ sec_off = sec_tbl->section_offset[i];
+ sec = AVF_SECTION_HEADER(profile, sec_off);
+ if (sec->section.type == section_type)
+ return sec;
+ }
+
+ return NULL;
+}
+
+/**
+ * avf_ddp_exec_aq_section - Execute generic AQ for DDP
+ * @hw: pointer to the hw struct
+ * @aq: command buffer containing all data to execute AQ
+ **/
+STATIC enum
+avf_status_code avf_ddp_exec_aq_section(struct avf_hw *hw,
+ struct avf_profile_aq_section *aq)
+{
+ enum avf_status_code status;
+ struct avf_aq_desc desc;
+ u8 *msg = NULL;
+ u16 msglen;
+
+ avf_fill_default_direct_cmd_desc(&desc, aq->opcode);
+ desc.flags |= CPU_TO_LE16(aq->flags);
+ avf_memcpy(desc.params.raw, aq->param, sizeof(desc.params.raw),
+ AVF_NONDMA_TO_NONDMA);
+
+ msglen = aq->datalen;
+ if (msglen) {
+ desc.flags |= CPU_TO_LE16((u16)(AVF_AQ_FLAG_BUF |
+ AVF_AQ_FLAG_RD));
+ if (msglen > AVF_AQ_LARGE_BUF)
+ desc.flags |= CPU_TO_LE16((u16)AVF_AQ_FLAG_LB);
+ desc.datalen = CPU_TO_LE16(msglen);
+ msg = &aq->data[0];
+ }
+
+ status = avf_asq_send_command(hw, &desc, msg, msglen, NULL);
+
+ if (status != AVF_SUCCESS) {
+ avf_debug(hw, AVF_DEBUG_PACKAGE,
+ "unable to exec DDP AQ opcode %u, error %d\n",
+ aq->opcode, status);
+ return status;
+ }
+
+ /* copy returned desc to aq_buf */
+ avf_memcpy(aq->param, desc.params.raw, sizeof(desc.params.raw),
+ AVF_NONDMA_TO_NONDMA);
+
+ return AVF_SUCCESS;
+}
+
+/**
+ * avf_validate_profile
+ * @hw: pointer to the hardware structure
+ * @profile: pointer to the profile segment of the package to be validated
+ * @track_id: package tracking id
+ * @rollback: flag if the profile is for rollback.
+ *
+ * Validates supported devices and profile's sections.
+ */
+STATIC enum avf_status_code
+avf_validate_profile(struct avf_hw *hw, struct avf_profile_segment *profile,
+ u32 track_id, bool rollback)
+{
+ struct avf_profile_section_header *sec = NULL;
+ enum avf_status_code status = AVF_SUCCESS;
+ struct avf_section_table *sec_tbl;
+ u32 vendor_dev_id;
+ u32 dev_cnt;
+ u32 sec_off;
+ u32 i;
+
+ if (track_id == AVF_DDP_TRACKID_INVALID) {
+ avf_debug(hw, AVF_DEBUG_PACKAGE, "Invalid track_id\n");
+ return AVF_NOT_SUPPORTED;
+ }
+
+ dev_cnt = profile->device_table_count;
+ for (i = 0; i < dev_cnt; i++) {
+ vendor_dev_id = profile->device_table[i].vendor_dev_id;
+ if ((vendor_dev_id >> 16) == AVF_INTEL_VENDOR_ID &&
+ hw->device_id == (vendor_dev_id & 0xFFFF))
+ break;
+ }
+ if (dev_cnt && (i == dev_cnt)) {
+ avf_debug(hw, AVF_DEBUG_PACKAGE,
+ "Device doesn't support DDP\n");
+ return AVF_ERR_DEVICE_NOT_SUPPORTED;
+ }
+
+ AVF_SECTION_TABLE(profile, sec_tbl);
+
+ /* Validate sections types */
+ for (i = 0; i < sec_tbl->section_count; i++) {
+ sec_off = sec_tbl->section_offset[i];
+ sec = AVF_SECTION_HEADER(profile, sec_off);
+ if (rollback) {
+ if (sec->section.type == SECTION_TYPE_MMIO ||
+ sec->section.type == SECTION_TYPE_AQ ||
+ sec->section.type == SECTION_TYPE_RB_AQ) {
+ avf_debug(hw, AVF_DEBUG_PACKAGE,
+ "Not a roll-back package\n");
+ return AVF_NOT_SUPPORTED;
+ }
+ } else {
+ if (sec->section.type == SECTION_TYPE_RB_AQ ||
+ sec->section.type == SECTION_TYPE_RB_MMIO) {
+ avf_debug(hw, AVF_DEBUG_PACKAGE,
+ "Not an original package\n");
+ return AVF_NOT_SUPPORTED;
+ }
+ }
+ }
+
+ return status;
+}
+
+/**
+ * avf_write_profile
+ * @hw: pointer to the hardware structure
+ * @profile: pointer to the profile segment of the package to be downloaded
+ * @track_id: package tracking id
+ *
+ * Handles the download of a complete package.
+ */
+enum avf_status_code
+avf_write_profile(struct avf_hw *hw, struct avf_profile_segment *profile,
+ u32 track_id)
+{
+ enum avf_status_code status = AVF_SUCCESS;
+ struct avf_section_table *sec_tbl;
+ struct avf_profile_section_header *sec = NULL;
+ struct avf_profile_aq_section *ddp_aq;
+ u32 section_size = 0;
+ u32 offset = 0, info = 0;
+ u32 sec_off;
+ u32 i;
+
+ status = avf_validate_profile(hw, profile, track_id, false);
+ if (status)
+ return status;
+
+ AVF_SECTION_TABLE(profile, sec_tbl);
+
+ for (i = 0; i < sec_tbl->section_count; i++) {
+ sec_off = sec_tbl->section_offset[i];
+ sec = AVF_SECTION_HEADER(profile, sec_off);
+ /* Process generic admin command */
+ if (sec->section.type == SECTION_TYPE_AQ) {
+ ddp_aq = (struct avf_profile_aq_section *)&sec[1];
+ status = avf_ddp_exec_aq_section(hw, ddp_aq);
+ if (status) {
+ avf_debug(hw, AVF_DEBUG_PACKAGE,
+ "Failed to execute aq: section %d, opcode %u\n",
+ i, ddp_aq->opcode);
+ break;
+ }
+ sec->section.type = SECTION_TYPE_RB_AQ;
+ }
+
+ /* Skip any non-mmio sections */
+ if (sec->section.type != SECTION_TYPE_MMIO)
+ continue;
+
+ section_size = sec->section.size +
+ sizeof(struct avf_profile_section_header);
+
+ /* Write MMIO section */
+ status = avf_aq_write_ddp(hw, (void *)sec, (u16)section_size,
+ track_id, &offset, &info, NULL);
+ if (status) {
+ avf_debug(hw, AVF_DEBUG_PACKAGE,
+ "Failed to write profile: section %d, offset %d, info %d\n",
+ i, offset, info);
+ break;
+ }
+ }
+ return status;
+}
+
+/**
+ * avf_rollback_profile
+ * @hw: pointer to the hardware structure
+ * @profile: pointer to the profile segment of the package to be removed
+ * @track_id: package tracking id
+ *
+ * Rolls back previously loaded package.
+ */
+enum avf_status_code
+avf_rollback_profile(struct avf_hw *hw, struct avf_profile_segment *profile,
+ u32 track_id)
+{
+ struct avf_profile_section_header *sec = NULL;
+ enum avf_status_code status = AVF_SUCCESS;
+ struct avf_section_table *sec_tbl;
+ u32 offset = 0, info = 0;
+ u32 section_size = 0;
+ u32 sec_off;
+ int i;
+
+ status = avf_validate_profile(hw, profile, track_id, true);
+ if (status)
+ return status;
+
+ AVF_SECTION_TABLE(profile, sec_tbl);
+
+ /* For rollback write sections in reverse */
+ for (i = sec_tbl->section_count - 1; i >= 0; i--) {
+ sec_off = sec_tbl->section_offset[i];
+ sec = AVF_SECTION_HEADER(profile, sec_off);
+
+ /* Skip any non-rollback sections */
+ if (sec->section.type != SECTION_TYPE_RB_MMIO)
+ continue;
+
+ section_size = sec->section.size +
+ sizeof(struct avf_profile_section_header);
+
+ /* Write roll-back MMIO section */
+ status = avf_aq_write_ddp(hw, (void *)sec, (u16)section_size,
+ track_id, &offset, &info, NULL);
+ if (status) {
+ avf_debug(hw, AVF_DEBUG_PACKAGE,
+ "Failed to write profile: section %d, offset %d, info %d\n",
+ i, offset, info);
+ break;
+ }
+ }
+ return status;
+}
+
+/**
+ * avf_add_pinfo_to_list
+ * @hw: pointer to the hardware structure
+ * @profile: pointer to the profile segment of the package
+ * @profile_info_sec: buffer for information section
+ * @track_id: package tracking id
+ *
+ * Register a profile to the list of loaded profiles.
+ */
+enum avf_status_code
+avf_add_pinfo_to_list(struct avf_hw *hw,
+ struct avf_profile_segment *profile,
+ u8 *profile_info_sec, u32 track_id)
+{
+ enum avf_status_code status = AVF_SUCCESS;
+ struct avf_profile_section_header *sec = NULL;
+ struct avf_profile_info *pinfo;
+ u32 offset = 0, info = 0;
+
+ sec = (struct avf_profile_section_header *)profile_info_sec;
+ sec->tbl_size = 1;
+ sec->data_end = sizeof(struct avf_profile_section_header) +
+ sizeof(struct avf_profile_info);
+ sec->section.type = SECTION_TYPE_INFO;
+ sec->section.offset = sizeof(struct avf_profile_section_header);
+ sec->section.size = sizeof(struct avf_profile_info);
+ pinfo = (struct avf_profile_info *)(profile_info_sec +
+ sec->section.offset);
+ pinfo->track_id = track_id;
+ pinfo->version = profile->version;
+ pinfo->op = AVF_DDP_ADD_TRACKID;
+ avf_memcpy(pinfo->name, profile->name, AVF_DDP_NAME_SIZE,
+ AVF_NONDMA_TO_NONDMA);
+
+ status = avf_aq_write_ddp(hw, (void *)sec, sec->data_end,
+ track_id, &offset, &info, NULL);
+ return status;
+}
diff --git a/drivers/net/iavf/base/iavf_devids.h b/drivers/net/iavf/base/iavf_devids.h
new file mode 100644
index 0000000..7d9fed2
--- /dev/null
+++ b/drivers/net/iavf/base/iavf_devids.h
@@ -0,0 +1,43 @@
+/*******************************************************************************
+
+Copyright (c) 2017, Intel Corporation
+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.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+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.
+
+***************************************************************************/
+
+#ifndef _AVF_DEVIDS_H_
+#define _AVF_DEVIDS_H_
+
+/* Vendor ID */
+#define AVF_INTEL_VENDOR_ID 0x8086
+
+/* Device IDs */
+#define AVF_DEV_ID_ADAPTIVE_VF 0x1889
+
+#endif /* _AVF_DEVIDS_H_ */
diff --git a/drivers/net/iavf/base/iavf_hmc.h b/drivers/net/iavf/base/iavf_hmc.h
new file mode 100644
index 0000000..b9b7b5b
--- /dev/null
+++ b/drivers/net/iavf/base/iavf_hmc.h
@@ -0,0 +1,245 @@
+/*******************************************************************************
+
+Copyright (c) 2013 - 2015, Intel Corporation
+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.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+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.
+
+***************************************************************************/
+
+#ifndef _AVF_HMC_H_
+#define _AVF_HMC_H_
+
+#define AVF_HMC_MAX_BP_COUNT 512
+
+/* forward-declare the HW struct for the compiler */
+struct avf_hw;
+
+#define AVF_HMC_INFO_SIGNATURE 0x484D5347 /* HMSG */
+#define AVF_HMC_PD_CNT_IN_SD 512
+#define AVF_HMC_DIRECT_BP_SIZE 0x200000 /* 2M */
+#define AVF_HMC_PAGED_BP_SIZE 4096
+#define AVF_HMC_PD_BP_BUF_ALIGNMENT 4096
+#define AVF_FIRST_VF_FPM_ID 16
+
+struct avf_hmc_obj_info {
+ u64 base; /* base addr in FPM */
+ u32 max_cnt; /* max count available for this hmc func */
+ u32 cnt; /* count of objects driver actually wants to create */
+ u64 size; /* size in bytes of one object */
+};
+
+enum avf_sd_entry_type {
+ AVF_SD_TYPE_INVALID = 0,
+ AVF_SD_TYPE_PAGED = 1,
+ AVF_SD_TYPE_DIRECT = 2
+};
+
+struct avf_hmc_bp {
+ enum avf_sd_entry_type entry_type;
+ struct avf_dma_mem addr; /* populate to be used by hw */
+ u32 sd_pd_index;
+ u32 ref_cnt;
+};
+
+struct avf_hmc_pd_entry {
+ struct avf_hmc_bp bp;
+ u32 sd_index;
+ bool rsrc_pg;
+ bool valid;
+};
+
+struct avf_hmc_pd_table {
+ struct avf_dma_mem pd_page_addr; /* populate to be used by hw */
+ struct avf_hmc_pd_entry *pd_entry; /* [512] for sw book keeping */
+ struct avf_virt_mem pd_entry_virt_mem; /* virt mem for pd_entry */
+
+ u32 ref_cnt;
+ u32 sd_index;
+};
+
+struct avf_hmc_sd_entry {
+ enum avf_sd_entry_type entry_type;
+ bool valid;
+
+ union {
+ struct avf_hmc_pd_table pd_table;
+ struct avf_hmc_bp bp;
+ } u;
+};
+
+struct avf_hmc_sd_table {
+ struct avf_virt_mem addr; /* used to track sd_entry allocations */
+ u32 sd_cnt;
+ u32 ref_cnt;
+ struct avf_hmc_sd_entry *sd_entry; /* (sd_cnt*512) entries max */
+};
+
+struct avf_hmc_info {
+ u32 signature;
+ /* equals to pci func num for PF and dynamically allocated for VFs */
+ u8 hmc_fn_id;
+ u16 first_sd_index; /* index of the first available SD */
+
+ /* hmc objects */
+ struct avf_hmc_obj_info *hmc_obj;
+ struct avf_virt_mem hmc_obj_virt_mem;
+ struct avf_hmc_sd_table sd_table;
+};
+
+#define AVF_INC_SD_REFCNT(sd_table) ((sd_table)->ref_cnt++)
+#define AVF_INC_PD_REFCNT(pd_table) ((pd_table)->ref_cnt++)
+#define AVF_INC_BP_REFCNT(bp) ((bp)->ref_cnt++)
+
+#define AVF_DEC_SD_REFCNT(sd_table) ((sd_table)->ref_cnt--)
+#define AVF_DEC_PD_REFCNT(pd_table) ((pd_table)->ref_cnt--)
+#define AVF_DEC_BP_REFCNT(bp) ((bp)->ref_cnt--)
+
+/**
+ * AVF_SET_PF_SD_ENTRY - marks the sd entry as valid in the hardware
+ * @hw: pointer to our hw struct
+ * @pa: pointer to physical address
+ * @sd_index: segment descriptor index
+ * @type: if sd entry is direct or paged
+ **/
+#define AVF_SET_PF_SD_ENTRY(hw, pa, sd_index, type) \
+{ \
+ u32 val1, val2, val3; \
+ val1 = (u32)(AVF_HI_DWORD(pa)); \
+ val2 = (u32)(pa) | (AVF_HMC_MAX_BP_COUNT << \
+ AVF_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT) | \
+ ((((type) == AVF_SD_TYPE_PAGED) ? 0 : 1) << \
+ AVF_PFHMC_SDDATALOW_PMSDTYPE_SHIFT) | \
+ BIT(AVF_PFHMC_SDDATALOW_PMSDVALID_SHIFT); \
+ val3 = (sd_index) | BIT_ULL(AVF_PFHMC_SDCMD_PMSDWR_SHIFT); \
+ wr32((hw), AVF_PFHMC_SDDATAHIGH, val1); \
+ wr32((hw), AVF_PFHMC_SDDATALOW, val2); \
+ wr32((hw), AVF_PFHMC_SDCMD, val3); \
+}
+
+/**
+ * AVF_CLEAR_PF_SD_ENTRY - marks the sd entry as invalid in the hardware
+ * @hw: pointer to our hw struct
+ * @sd_index: segment descriptor index
+ * @type: if sd entry is direct or paged
+ **/
+#define AVF_CLEAR_PF_SD_ENTRY(hw, sd_index, type) \
+{ \
+ u32 val2, val3; \
+ val2 = (AVF_HMC_MAX_BP_COUNT << \
+ AVF_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT) | \
+ ((((type) == AVF_SD_TYPE_PAGED) ? 0 : 1) << \
+ AVF_PFHMC_SDDATALOW_PMSDTYPE_SHIFT); \
+ val3 = (sd_index) | BIT_ULL(AVF_PFHMC_SDCMD_PMSDWR_SHIFT); \
+ wr32((hw), AVF_PFHMC_SDDATAHIGH, 0); \
+ wr32((hw), AVF_PFHMC_SDDATALOW, val2); \
+ wr32((hw), AVF_PFHMC_SDCMD, val3); \
+}
+
+/**
+ * AVF_INVALIDATE_PF_HMC_PD - Invalidates the pd cache in the hardware
+ * @hw: pointer to our hw struct
+ * @sd_idx: segment descriptor index
+ * @pd_idx: page descriptor index
+ **/
+#define AVF_INVALIDATE_PF_HMC_PD(hw, sd_idx, pd_idx) \
+ wr32((hw), AVF_PFHMC_PDINV, \
+ (((sd_idx) << AVF_PFHMC_PDINV_PMSDIDX_SHIFT) | \
+ ((pd_idx) << AVF_PFHMC_PDINV_PMPDIDX_SHIFT)))
+
+/**
+ * AVF_FIND_SD_INDEX_LIMIT - finds segment descriptor index limit
+ * @hmc_info: pointer to the HMC configuration information structure
+ * @type: type of HMC resources we're searching
+ * @index: starting index for the object
+ * @cnt: number of objects we're trying to create
+ * @sd_idx: pointer to return index of the segment descriptor in question
+ * @sd_limit: pointer to return the maximum number of segment descriptors
+ *
+ * This function calculates the segment descriptor index and index limit
+ * for the resource defined by avf_hmc_rsrc_type.
+ **/
+#define AVF_FIND_SD_INDEX_LIMIT(hmc_info, type, index, cnt, sd_idx, sd_limit)\
+{ \
+ u64 fpm_addr, fpm_limit; \
+ fpm_addr = (hmc_info)->hmc_obj[(type)].base + \
+ (hmc_info)->hmc_obj[(type)].size * (index); \
+ fpm_limit = fpm_addr + (hmc_info)->hmc_obj[(type)].size * (cnt);\
+ *(sd_idx) = (u32)(fpm_addr / AVF_HMC_DIRECT_BP_SIZE); \
+ *(sd_limit) = (u32)((fpm_limit - 1) / AVF_HMC_DIRECT_BP_SIZE); \
+ /* add one more to the limit to correct our range */ \
+ *(sd_limit) += 1; \
+}
+
+/**
+ * AVF_FIND_PD_INDEX_LIMIT - finds page descriptor index limit
+ * @hmc_info: pointer to the HMC configuration information struct
+ * @type: HMC resource type we're examining
+ * @idx: starting index for the object
+ * @cnt: number of objects we're trying to create
+ * @pd_index: pointer to return page descriptor index
+ * @pd_limit: pointer to return page descriptor index limit
+ *
+ * Calculates the page descriptor index and index limit for the resource
+ * defined by avf_hmc_rsrc_type.
+ **/
+#define AVF_FIND_PD_INDEX_LIMIT(hmc_info, type, idx, cnt, pd_index, pd_limit)\
+{ \
+ u64 fpm_adr, fpm_limit; \
+ fpm_adr = (hmc_info)->hmc_obj[(type)].base + \
+ (hmc_info)->hmc_obj[(type)].size * (idx); \
+ fpm_limit = fpm_adr + (hmc_info)->hmc_obj[(type)].size * (cnt); \
+ *(pd_index) = (u32)(fpm_adr / AVF_HMC_PAGED_BP_SIZE); \
+ *(pd_limit) = (u32)((fpm_limit - 1) / AVF_HMC_PAGED_BP_SIZE); \
+ /* add one more to the limit to correct our range */ \
+ *(pd_limit) += 1; \
+}
+enum avf_status_code avf_add_sd_table_entry(struct avf_hw *hw,
+ struct avf_hmc_info *hmc_info,
+ u32 sd_index,
+ enum avf_sd_entry_type type,
+ u64 direct_mode_sz);
+
+enum avf_status_code avf_add_pd_table_entry(struct avf_hw *hw,
+ struct avf_hmc_info *hmc_info,
+ u32 pd_index,
+ struct avf_dma_mem *rsrc_pg);
+enum avf_status_code avf_remove_pd_bp(struct avf_hw *hw,
+ struct avf_hmc_info *hmc_info,
+ u32 idx);
+enum avf_status_code avf_prep_remove_sd_bp(struct avf_hmc_info *hmc_info,
+ u32 idx);
+enum avf_status_code avf_remove_sd_bp_new(struct avf_hw *hw,
+ struct avf_hmc_info *hmc_info,
+ u32 idx, bool is_pf);
+enum avf_status_code avf_prep_remove_pd_page(struct avf_hmc_info *hmc_info,
+ u32 idx);
+enum avf_status_code avf_remove_pd_page_new(struct avf_hw *hw,
+ struct avf_hmc_info *hmc_info,
+ u32 idx, bool is_pf);
+
+#endif /* _AVF_HMC_H_ */
diff --git a/drivers/net/iavf/base/iavf_lan_hmc.h b/drivers/net/iavf/base/iavf_lan_hmc.h
new file mode 100644
index 0000000..48805d8
--- /dev/null
+++ b/drivers/net/iavf/base/iavf_lan_hmc.h
@@ -0,0 +1,200 @@
+/*******************************************************************************
+
+Copyright (c) 2013 - 2015, Intel Corporation
+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.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+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.
+
+***************************************************************************/
+
+#ifndef _AVF_LAN_HMC_H_
+#define _AVF_LAN_HMC_H_
+
+/* forward-declare the HW struct for the compiler */
+struct avf_hw;
+
+/* HMC element context information */
+
+/* Rx queue context data
+ *
+ * The sizes of the variables may be larger than needed due to crossing byte
+ * boundaries. If we do not have the width of the variable set to the correct
+ * size then we could end up shifting bits off the top of the variable when the
+ * variable is at the top of a byte and crosses over into the next byte.
+ */
+struct avf_hmc_obj_rxq {
+ u16 head;
+ u16 cpuid; /* bigger than needed, see above for reason */
+ u64 base;
+ u16 qlen;
+#define AVF_RXQ_CTX_DBUFF_SHIFT 7
+ u16 dbuff; /* bigger than needed, see above for reason */
+#define AVF_RXQ_CTX_HBUFF_SHIFT 6
+ u16 hbuff; /* bigger than needed, see above for reason */
+ u8 dtype;
+ u8 dsize;
+ u8 crcstrip;
+ u8 fc_ena;
+ u8 l2tsel;
+ u8 hsplit_0;
+ u8 hsplit_1;
+ u8 showiv;
+ u32 rxmax; /* bigger than needed, see above for reason */
+ u8 tphrdesc_ena;
+ u8 tphwdesc_ena;
+ u8 tphdata_ena;
+ u8 tphhead_ena;
+ u16 lrxqthresh; /* bigger than needed, see above for reason */
+ u8 prefena; /* NOTE: normally must be set to 1 at init */
+};
+
+/* Tx queue context data
+*
+* The sizes of the variables may be larger than needed due to crossing byte
+* boundaries. If we do not have the width of the variable set to the correct
+* size then we could end up shifting bits off the top of the variable when the
+* variable is at the top of a byte and crosses over into the next byte.
+*/
+struct avf_hmc_obj_txq {
+ u16 head;
+ u8 new_context;
+ u64 base;
+ u8 fc_ena;
+ u8 timesync_ena;
+ u8 fd_ena;
+ u8 alt_vlan_ena;
+ u16 thead_wb;
+ u8 cpuid;
+ u8 head_wb_ena;
+ u16 qlen;
+ u8 tphrdesc_ena;
+ u8 tphrpacket_ena;
+ u8 tphwdesc_ena;
+ u64 head_wb_addr;
+ u32 crc;
+ u16 rdylist;
+ u8 rdylist_act;
+};
+
+/* for hsplit_0 field of Rx HMC context */
+enum avf_hmc_obj_rx_hsplit_0 {
+ AVF_HMC_OBJ_RX_HSPLIT_0_NO_SPLIT = 0,
+ AVF_HMC_OBJ_RX_HSPLIT_0_SPLIT_L2 = 1,
+ AVF_HMC_OBJ_RX_HSPLIT_0_SPLIT_IP = 2,
+ AVF_HMC_OBJ_RX_HSPLIT_0_SPLIT_TCP_UDP = 4,
+ AVF_HMC_OBJ_RX_HSPLIT_0_SPLIT_SCTP = 8,
+};
+
+/* fcoe_cntx and fcoe_filt are for debugging purpose only */
+struct avf_hmc_obj_fcoe_cntx {
+ u32 rsv[32];
+};
+
+struct avf_hmc_obj_fcoe_filt {
+ u32 rsv[8];
+};
+
+/* Context sizes for LAN objects */
+enum avf_hmc_lan_object_size {
+ AVF_HMC_LAN_OBJ_SZ_8 = 0x3,
+ AVF_HMC_LAN_OBJ_SZ_16 = 0x4,
+ AVF_HMC_LAN_OBJ_SZ_32 = 0x5,
+ AVF_HMC_LAN_OBJ_SZ_64 = 0x6,
+ AVF_HMC_LAN_OBJ_SZ_128 = 0x7,
+ AVF_HMC_LAN_OBJ_SZ_256 = 0x8,
+ AVF_HMC_LAN_OBJ_SZ_512 = 0x9,
+};
+
+#define AVF_HMC_L2OBJ_BASE_ALIGNMENT 512
+#define AVF_HMC_OBJ_SIZE_TXQ 128
+#define AVF_HMC_OBJ_SIZE_RXQ 32
+#define AVF_HMC_OBJ_SIZE_FCOE_CNTX 64
+#define AVF_HMC_OBJ_SIZE_FCOE_FILT 64
+
+enum avf_hmc_lan_rsrc_type {
+ AVF_HMC_LAN_FULL = 0,
+ AVF_HMC_LAN_TX = 1,
+ AVF_HMC_LAN_RX = 2,
+ AVF_HMC_FCOE_CTX = 3,
+ AVF_HMC_FCOE_FILT = 4,
+ AVF_HMC_LAN_MAX = 5
+};
+
+enum avf_hmc_model {
+ AVF_HMC_MODEL_DIRECT_PREFERRED = 0,
+ AVF_HMC_MODEL_DIRECT_ONLY = 1,
+ AVF_HMC_MODEL_PAGED_ONLY = 2,
+ AVF_HMC_MODEL_UNKNOWN,
+};
+
+struct avf_hmc_lan_create_obj_info {
+ struct avf_hmc_info *hmc_info;
+ u32 rsrc_type;
+ u32 start_idx;
+ u32 count;
+ enum avf_sd_entry_type entry_type;
+ u64 direct_mode_sz;
+};
+
+struct avf_hmc_lan_delete_obj_info {
+ struct avf_hmc_info *hmc_info;
+ u32 rsrc_type;
+ u32 start_idx;
+ u32 count;
+};
+
+enum avf_status_code avf_init_lan_hmc(struct avf_hw *hw, u32 txq_num,
+ u32 rxq_num, u32 fcoe_cntx_num,
+ u32 fcoe_filt_num);
+enum avf_status_code avf_configure_lan_hmc(struct avf_hw *hw,
+ enum avf_hmc_model model);
+enum avf_status_code avf_shutdown_lan_hmc(struct avf_hw *hw);
+
+u64 avf_calculate_l2fpm_size(u32 txq_num, u32 rxq_num,
+ u32 fcoe_cntx_num, u32 fcoe_filt_num);
+enum avf_status_code avf_get_lan_tx_queue_context(struct avf_hw *hw,
+ u16 queue,
+ struct avf_hmc_obj_txq *s);
+enum avf_status_code avf_clear_lan_tx_queue_context(struct avf_hw *hw,
+ u16 queue);
+enum avf_status_code avf_set_lan_tx_queue_context(struct avf_hw *hw,
+ u16 queue,
+ struct avf_hmc_obj_txq *s);
+enum avf_status_code avf_get_lan_rx_queue_context(struct avf_hw *hw,
+ u16 queue,
+ struct avf_hmc_obj_rxq *s);
+enum avf_status_code avf_clear_lan_rx_queue_context(struct avf_hw *hw,
+ u16 queue);
+enum avf_status_code avf_set_lan_rx_queue_context(struct avf_hw *hw,
+ u16 queue,
+ struct avf_hmc_obj_rxq *s);
+enum avf_status_code avf_create_lan_hmc_object(struct avf_hw *hw,
+ struct avf_hmc_lan_create_obj_info *info);
+enum avf_status_code avf_delete_lan_hmc_object(struct avf_hw *hw,
+ struct avf_hmc_lan_delete_obj_info *info);
+
+#endif /* _AVF_LAN_HMC_H_ */
diff --git a/drivers/net/iavf/base/iavf_osdep.h b/drivers/net/iavf/base/iavf_osdep.h
new file mode 100644
index 0000000..1f12266
--- /dev/null
+++ b/drivers/net/iavf/base/iavf_osdep.h
@@ -0,0 +1,187 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017 Intel Corporation
+ */
+
+#ifndef _AVF_OSDEP_H_
+#define _AVF_OSDEP_H_
+
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <rte_common.h>
+#include <rte_memcpy.h>
+#include <rte_memzone.h>
+#include <rte_malloc.h>
+#include <rte_byteorder.h>
+#include <rte_cycles.h>
+#include <rte_spinlock.h>
+#include <rte_log.h>
+#include <rte_io.h>
+
+#include "../iavf_log.h"
+
+#define INLINE inline
+#define STATIC static
+
+typedef uint8_t u8;
+typedef int8_t s8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef int32_t s32;
+typedef uint64_t u64;
+
+#define __iomem
+#define hw_dbg(hw, S, A...) do {} while (0)
+#define upper_32_bits(n) ((u32)(((n) >> 16) >> 16))
+#define lower_32_bits(n) ((u32)(n))
+
+#ifndef ETH_ADDR_LEN
+#define ETH_ADDR_LEN 6
+#endif
+
+#ifndef __le16
+#define __le16 uint16_t
+#endif
+#ifndef __le32
+#define __le32 uint32_t
+#endif
+#ifndef __le64
+#define __le64 uint64_t
+#endif
+#ifndef __be16
+#define __be16 uint16_t
+#endif
+#ifndef __be32
+#define __be32 uint32_t
+#endif
+#ifndef __be64
+#define __be64 uint64_t
+#endif
+
+#define FALSE 0
+#define TRUE 1
+#define false 0
+#define true 1
+
+#define min(a,b) RTE_MIN(a,b)
+#define max(a,b) RTE_MAX(a,b)
+
+#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
+#define ASSERT(x) if(!(x)) rte_panic("AVF: x")
+
+#define DEBUGOUT(S) PMD_DRV_LOG_RAW(DEBUG, S)
+#define DEBUGOUT2(S, A...) PMD_DRV_LOG_RAW(DEBUG, S, ##A)
+#define DEBUGFUNC(F) DEBUGOUT(F "\n")
+
+#define CPU_TO_LE16(o) rte_cpu_to_le_16(o)
+#define CPU_TO_LE32(s) rte_cpu_to_le_32(s)
+#define CPU_TO_LE64(h) rte_cpu_to_le_64(h)
+#define LE16_TO_CPU(a) rte_le_to_cpu_16(a)
+#define LE32_TO_CPU(c) rte_le_to_cpu_32(c)
+#define LE64_TO_CPU(k) rte_le_to_cpu_64(k)
+
+#define cpu_to_le16(o) rte_cpu_to_le_16(o)
+#define cpu_to_le32(s) rte_cpu_to_le_32(s)
+#define cpu_to_le64(h) rte_cpu_to_le_64(h)
+#define le16_to_cpu(a) rte_le_to_cpu_16(a)
+#define le32_to_cpu(c) rte_le_to_cpu_32(c)
+#define le64_to_cpu(k) rte_le_to_cpu_64(k)
+
+#define avf_memset(a, b, c, d) memset((a), (b), (c))
+#define avf_memcpy(a, b, c, d) rte_memcpy((a), (b), (c))
+
+#define avf_usec_delay(x) rte_delay_us_sleep(x)
+#define avf_msec_delay(x) avf_usec_delay(1000 * (x))
+
+#define AVF_PCI_REG(reg) rte_read32(reg)
+#define AVF_PCI_REG_ADDR(a, reg) \
+ ((volatile uint32_t *)((char *)(a)->hw_addr + (reg)))
+
+#define AVF_PCI_REG_WRITE(reg, value) \
+ rte_write32((rte_cpu_to_le_32(value)), reg)
+#define AVF_PCI_REG_WRITE_RELAXED(reg, value) \
+ rte_write32_relaxed((rte_cpu_to_le_32(value)), reg)
+static inline
+uint32_t avf_read_addr(volatile void *addr)
+{
+ return rte_le_to_cpu_32(AVF_PCI_REG(addr));
+}
+
+#define AVF_READ_REG(hw, reg) \
+ avf_read_addr(AVF_PCI_REG_ADDR((hw), (reg)))
+#define AVF_WRITE_REG(hw, reg, value) \
+ AVF_PCI_REG_WRITE(AVF_PCI_REG_ADDR((hw), (reg)), (value))
+#define AVF_WRITE_FLUSH(a) \
+ AVF_READ_REG(a, AVFGEN_RSTAT)
+
+#define rd32(a, reg) avf_read_addr(AVF_PCI_REG_ADDR((a), (reg)))
+#define wr32(a, reg, value) \
+ AVF_PCI_REG_WRITE(AVF_PCI_REG_ADDR((a), (reg)), (value))
+
+#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
+
+#define avf_debug(h, m, s, ...) \
+do { \
+ if (((m) & (h)->debug_mask)) \
+ PMD_DRV_LOG_RAW(DEBUG, "avf %02x.%x " s, \
+ (h)->bus.device, (h)->bus.func, \
+ ##__VA_ARGS__); \
+} while (0)
+
+/* memory allocation tracking */
+struct avf_dma_mem {
+ void *va;
+ u64 pa;
+ u32 size;
+ const void *zone;
+} __attribute__((packed));
+
+struct avf_virt_mem {
+ void *va;
+ u32 size;
+} __attribute__((packed));
+
+/* SW spinlock */
+struct avf_spinlock {
+ rte_spinlock_t spinlock;
+};
+
+#define avf_allocate_dma_mem(h, m, unused, s, a) \
+ avf_allocate_dma_mem_d(h, m, s, a)
+#define avf_free_dma_mem(h, m) avf_free_dma_mem_d(h, m)
+
+#define avf_allocate_virt_mem(h, m, s) avf_allocate_virt_mem_d(h, m, s)
+#define avf_free_virt_mem(h, m) avf_free_virt_mem_d(h, m)
+
+static inline void
+avf_init_spinlock_d(struct avf_spinlock *sp)
+{
+ rte_spinlock_init(&sp->spinlock);
+}
+
+static inline void
+avf_acquire_spinlock_d(struct avf_spinlock *sp)
+{
+ rte_spinlock_lock(&sp->spinlock);
+}
+
+static inline void
+avf_release_spinlock_d(struct avf_spinlock *sp)
+{
+ rte_spinlock_unlock(&sp->spinlock);
+}
+
+static inline void
+avf_destroy_spinlock_d(__rte_unused struct avf_spinlock *sp)
+{
+}
+
+#define avf_init_spinlock(_sp) avf_init_spinlock_d(_sp)
+#define avf_acquire_spinlock(_sp) avf_acquire_spinlock_d(_sp)
+#define avf_release_spinlock(_sp) avf_release_spinlock_d(_sp)
+#define avf_destroy_spinlock(_sp) avf_destroy_spinlock_d(_sp)
+
+#endif /* _AVF_OSDEP_H_ */
diff --git a/drivers/net/iavf/base/iavf_prototype.h b/drivers/net/iavf/base/iavf_prototype.h
new file mode 100644
index 0000000..8230d5c
--- /dev/null
+++ b/drivers/net/iavf/base/iavf_prototype.h
@@ -0,0 +1,206 @@
+/*******************************************************************************
+
+Copyright (c) 2013 - 2015, Intel Corporation
+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.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+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.
+
+***************************************************************************/
+
+#ifndef _AVF_PROTOTYPE_H_
+#define _AVF_PROTOTYPE_H_
+
+#include "iavf_type.h"
+#include "iavf_alloc.h"
+#include "virtchnl.h"
+
+/* Prototypes for shared code functions that are not in
+ * the standard function pointer structures. These are
+ * mostly because they are needed even before the init
+ * has happened and will assist in the early SW and FW
+ * setup.
+ */
+
+/* adminq functions */
+enum avf_status_code avf_init_adminq(struct avf_hw *hw);
+enum avf_status_code avf_shutdown_adminq(struct avf_hw *hw);
+enum avf_status_code avf_init_asq(struct avf_hw *hw);
+enum avf_status_code avf_init_arq(struct avf_hw *hw);
+enum avf_status_code avf_alloc_adminq_asq_ring(struct avf_hw *hw);
+enum avf_status_code avf_alloc_adminq_arq_ring(struct avf_hw *hw);
+enum avf_status_code avf_shutdown_asq(struct avf_hw *hw);
+enum avf_status_code avf_shutdown_arq(struct avf_hw *hw);
+u16 avf_clean_asq(struct avf_hw *hw);
+void avf_free_adminq_asq(struct avf_hw *hw);
+void avf_free_adminq_arq(struct avf_hw *hw);
+enum avf_status_code avf_validate_mac_addr(u8 *mac_addr);
+void avf_adminq_init_ring_data(struct avf_hw *hw);
+enum avf_status_code avf_clean_arq_element(struct avf_hw *hw,
+ struct avf_arq_event_info *e,
+ u16 *events_pending);
+enum avf_status_code avf_asq_send_command(struct avf_hw *hw,
+ struct avf_aq_desc *desc,
+ void *buff, /* can be NULL */
+ u16 buff_size,
+ struct avf_asq_cmd_details *cmd_details);
+bool avf_asq_done(struct avf_hw *hw);
+
+/* debug function for adminq */
+void avf_debug_aq(struct avf_hw *hw, enum avf_debug_mask mask,
+ void *desc, void *buffer, u16 buf_len);
+
+void avf_idle_aq(struct avf_hw *hw);
+bool avf_check_asq_alive(struct avf_hw *hw);
+enum avf_status_code avf_aq_queue_shutdown(struct avf_hw *hw, bool unloading);
+
+enum avf_status_code avf_aq_get_rss_lut(struct avf_hw *hw, u16 seid,
+ bool pf_lut, u8 *lut, u16 lut_size);
+enum avf_status_code avf_aq_set_rss_lut(struct avf_hw *hw, u16 seid,
+ bool pf_lut, u8 *lut, u16 lut_size);
+enum avf_status_code avf_aq_get_rss_key(struct avf_hw *hw,
+ u16 seid,
+ struct avf_aqc_get_set_rss_key_data *key);
+enum avf_status_code avf_aq_set_rss_key(struct avf_hw *hw,
+ u16 seid,
+ struct avf_aqc_get_set_rss_key_data *key);
+const char *avf_aq_str(struct avf_hw *hw, enum avf_admin_queue_err aq_err);
+const char *avf_stat_str(struct avf_hw *hw, enum avf_status_code stat_err);
+
+
+enum avf_status_code avf_set_mac_type(struct avf_hw *hw);
+
+extern struct avf_rx_ptype_decoded avf_ptype_lookup[];
+
+STATIC INLINE struct avf_rx_ptype_decoded decode_rx_desc_ptype(u8 ptype)
+{
+ return avf_ptype_lookup[ptype];
+}
+
+/* prototype for functions used for SW spinlocks */
+void avf_init_spinlock(struct avf_spinlock *sp);
+void avf_acquire_spinlock(struct avf_spinlock *sp);
+void avf_release_spinlock(struct avf_spinlock *sp);
+void avf_destroy_spinlock(struct avf_spinlock *sp);
+
+/* avf_common for VF drivers*/
+void avf_parse_hw_config(struct avf_hw *hw,
+ struct virtchnl_vf_resource *msg);
+enum avf_status_code avf_reset(struct avf_hw *hw);
+enum avf_status_code avf_aq_send_msg_to_pf(struct avf_hw *hw,
+ enum virtchnl_ops v_opcode,
+ enum avf_status_code v_retval,
+ u8 *msg, u16 msglen,
+ struct avf_asq_cmd_details *cmd_details);
+enum avf_status_code avf_set_filter_control(struct avf_hw *hw,
+ struct avf_filter_control_settings *settings);
+enum avf_status_code avf_aq_add_rem_control_packet_filter(struct avf_hw *hw,
+ u8 *mac_addr, u16 ethtype, u16 flags,
+ u16 vsi_seid, u16 queue, bool is_add,
+ struct avf_control_filter_stats *stats,
+ struct avf_asq_cmd_details *cmd_details);
+enum avf_status_code avf_aq_debug_dump(struct avf_hw *hw, u8 cluster_id,
+ u8 table_id, u32 start_index, u16 buff_size,
+ void *buff, u16 *ret_buff_size,
+ u8 *ret_next_table, u32 *ret_next_index,
+ struct avf_asq_cmd_details *cmd_details);
+void avf_add_filter_to_drop_tx_flow_control_frames(struct avf_hw *hw,
+ u16 vsi_seid);
+enum avf_status_code avf_aq_rx_ctl_read_register(struct avf_hw *hw,
+ u32 reg_addr, u32 *reg_val,
+ struct avf_asq_cmd_details *cmd_details);
+u32 avf_read_rx_ctl(struct avf_hw *hw, u32 reg_addr);
+enum avf_status_code avf_aq_rx_ctl_write_register(struct avf_hw *hw,
+ u32 reg_addr, u32 reg_val,
+ struct avf_asq_cmd_details *cmd_details);
+void avf_write_rx_ctl(struct avf_hw *hw, u32 reg_addr, u32 reg_val);
+enum avf_status_code avf_aq_set_phy_register(struct avf_hw *hw,
+ u8 phy_select, u8 dev_addr,
+ u32 reg_addr, u32 reg_val,
+ struct avf_asq_cmd_details *cmd_details);
+enum avf_status_code avf_aq_get_phy_register(struct avf_hw *hw,
+ u8 phy_select, u8 dev_addr,
+ u32 reg_addr, u32 *reg_val,
+ struct avf_asq_cmd_details *cmd_details);
+
+enum avf_status_code avf_aq_set_arp_proxy_config(struct avf_hw *hw,
+ struct avf_aqc_arp_proxy_data *proxy_config,
+ struct avf_asq_cmd_details *cmd_details);
+enum avf_status_code avf_aq_set_ns_proxy_table_entry(struct avf_hw *hw,
+ struct avf_aqc_ns_proxy_data *ns_proxy_table_entry,
+ struct avf_asq_cmd_details *cmd_details);
+enum avf_status_code avf_aq_set_clear_wol_filter(struct avf_hw *hw,
+ u8 filter_index,
+ struct avf_aqc_set_wol_filter_data *filter,
+ bool set_filter, bool no_wol_tco,
+ bool filter_valid, bool no_wol_tco_valid,
+ struct avf_asq_cmd_details *cmd_details);
+enum avf_status_code avf_aq_get_wake_event_reason(struct avf_hw *hw,
+ u16 *wake_reason,
+ struct avf_asq_cmd_details *cmd_details);
+enum avf_status_code avf_aq_clear_all_wol_filters(struct avf_hw *hw,
+ struct avf_asq_cmd_details *cmd_details);
+enum avf_status_code avf_read_phy_register_clause22(struct avf_hw *hw,
+ u16 reg, u8 phy_addr, u16 *value);
+enum avf_status_code avf_write_phy_register_clause22(struct avf_hw *hw,
+ u16 reg, u8 phy_addr, u16 value);
+enum avf_status_code avf_read_phy_register_clause45(struct avf_hw *hw,
+ u8 page, u16 reg, u8 phy_addr, u16 *value);
+enum avf_status_code avf_write_phy_register_clause45(struct avf_hw *hw,
+ u8 page, u16 reg, u8 phy_addr, u16 value);
+enum avf_status_code avf_read_phy_register(struct avf_hw *hw,
+ u8 page, u16 reg, u8 phy_addr, u16 *value);
+enum avf_status_code avf_write_phy_register(struct avf_hw *hw,
+ u8 page, u16 reg, u8 phy_addr, u16 value);
+u8 avf_get_phy_address(struct avf_hw *hw, u8 dev_num);
+enum avf_status_code avf_blink_phy_link_led(struct avf_hw *hw,
+ u32 time, u32 interval);
+enum avf_status_code avf_aq_write_ddp(struct avf_hw *hw, void *buff,
+ u16 buff_size, u32 track_id,
+ u32 *error_offset, u32 *error_info,
+ struct avf_asq_cmd_details *
+ cmd_details);
+enum avf_status_code avf_aq_get_ddp_list(struct avf_hw *hw, void *buff,
+ u16 buff_size, u8 flags,
+ struct avf_asq_cmd_details *
+ cmd_details);
+struct avf_generic_seg_header *
+avf_find_segment_in_package(u32 segment_type,
+ struct avf_package_header *pkg_header);
+struct avf_profile_section_header *
+avf_find_section_in_profile(u32 section_type,
+ struct avf_profile_segment *profile);
+enum avf_status_code
+avf_write_profile(struct avf_hw *hw, struct avf_profile_segment *avf_seg,
+ u32 track_id);
+enum avf_status_code
+avf_rollback_profile(struct avf_hw *hw, struct avf_profile_segment *avf_seg,
+ u32 track_id);
+enum avf_status_code
+avf_add_pinfo_to_list(struct avf_hw *hw,
+ struct avf_profile_segment *profile,
+ u8 *profile_info_sec, u32 track_id);
+#endif /* _AVF_PROTOTYPE_H_ */
diff --git a/drivers/net/iavf/base/iavf_register.h b/drivers/net/iavf/base/iavf_register.h
new file mode 100644
index 0000000..adb9895
--- /dev/null
+++ b/drivers/net/iavf/base/iavf_register.h
@@ -0,0 +1,346 @@
+/*******************************************************************************
+
+Copyright (c) 2013 - 2015, Intel Corporation
+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.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+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.
+
+***************************************************************************/
+
+#ifndef _AVF_REGISTER_H_
+#define _AVF_REGISTER_H_
+
+
+#define AVFMSIX_PBA1(_i) (0x00002000 + ((_i) * 4)) /* _i=0...19 */ /* Reset: VFLR */
+#define AVFMSIX_PBA1_MAX_INDEX 19
+#define AVFMSIX_PBA1_PENBIT_SHIFT 0
+#define AVFMSIX_PBA1_PENBIT_MASK AVF_MASK(0xFFFFFFFF, AVFMSIX_PBA1_PENBIT_SHIFT)
+#define AVFMSIX_TADD1(_i) (0x00002100 + ((_i) * 16)) /* _i=0...639 */ /* Reset: VFLR */
+#define AVFMSIX_TADD1_MAX_INDEX 639
+#define AVFMSIX_TADD1_MSIXTADD10_SHIFT 0
+#define AVFMSIX_TADD1_MSIXTADD10_MASK AVF_MASK(0x3, AVFMSIX_TADD1_MSIXTADD10_SHIFT)
+#define AVFMSIX_TADD1_MSIXTADD_SHIFT 2
+#define AVFMSIX_TADD1_MSIXTADD_MASK AVF_MASK(0x3FFFFFFF, AVFMSIX_TADD1_MSIXTADD_SHIFT)
+#define AVFMSIX_TMSG1(_i) (0x00002108 + ((_i) * 16)) /* _i=0...639 */ /* Reset: VFLR */
+#define AVFMSIX_TMSG1_MAX_INDEX 639
+#define AVFMSIX_TMSG1_MSIXTMSG_SHIFT 0
+#define AVFMSIX_TMSG1_MSIXTMSG_MASK AVF_MASK(0xFFFFFFFF, AVFMSIX_TMSG1_MSIXTMSG_SHIFT)
+#define AVFMSIX_TUADD1(_i) (0x00002104 + ((_i) * 16)) /* _i=0...639 */ /* Reset: VFLR */
+#define AVFMSIX_TUADD1_MAX_INDEX 639
+#define AVFMSIX_TUADD1_MSIXTUADD_SHIFT 0
+#define AVFMSIX_TUADD1_MSIXTUADD_MASK AVF_MASK(0xFFFFFFFF, AVFMSIX_TUADD1_MSIXTUADD_SHIFT)
+#define AVFMSIX_TVCTRL1(_i) (0x0000210C + ((_i) * 16)) /* _i=0...639 */ /* Reset: VFLR */
+#define AVFMSIX_TVCTRL1_MAX_INDEX 639
+#define AVFMSIX_TVCTRL1_MASK_SHIFT 0
+#define AVFMSIX_TVCTRL1_MASK_MASK AVF_MASK(0x1, AVFMSIX_TVCTRL1_MASK_SHIFT)
+#define AVF_ARQBAH1 0x00006000 /* Reset: EMPR */
+#define AVF_ARQBAH1_ARQBAH_SHIFT 0
+#define AVF_ARQBAH1_ARQBAH_MASK AVF_MASK(0xFFFFFFFF, AVF_ARQBAH1_ARQBAH_SHIFT)
+#define AVF_ARQBAL1 0x00006C00 /* Reset: EMPR */
+#define AVF_ARQBAL1_ARQBAL_SHIFT 0
+#define AVF_ARQBAL1_ARQBAL_MASK AVF_MASK(0xFFFFFFFF, AVF_ARQBAL1_ARQBAL_SHIFT)
+#define AVF_ARQH1 0x00007400 /* Reset: EMPR */
+#define AVF_ARQH1_ARQH_SHIFT 0
+#define AVF_ARQH1_ARQH_MASK AVF_MASK(0x3FF, AVF_ARQH1_ARQH_SHIFT)
+#define AVF_ARQLEN1 0x00008000 /* Reset: EMPR */
+#define AVF_ARQLEN1_ARQLEN_SHIFT 0
+#define AVF_ARQLEN1_ARQLEN_MASK AVF_MASK(0x3FF, AVF_ARQLEN1_ARQLEN_SHIFT)
+#define AVF_ARQLEN1_ARQVFE_SHIFT 28
+#define AVF_ARQLEN1_ARQVFE_MASK AVF_MASK(0x1, AVF_ARQLEN1_ARQVFE_SHIFT)
+#define AVF_ARQLEN1_ARQOVFL_SHIFT 29
+#define AVF_ARQLEN1_ARQOVFL_MASK AVF_MASK(0x1, AVF_ARQLEN1_ARQOVFL_SHIFT)
+#define AVF_ARQLEN1_ARQCRIT_SHIFT 30
+#define AVF_ARQLEN1_ARQCRIT_MASK AVF_MASK(0x1, AVF_ARQLEN1_ARQCRIT_SHIFT)
+#define AVF_ARQLEN1_ARQENABLE_SHIFT 31
+#define AVF_ARQLEN1_ARQENABLE_MASK AVF_MASK(0x1U, AVF_ARQLEN1_ARQENABLE_SHIFT)
+#define AVF_ARQT1 0x00007000 /* Reset: EMPR */
+#define AVF_ARQT1_ARQT_SHIFT 0
+#define AVF_ARQT1_ARQT_MASK AVF_MASK(0x3FF, AVF_ARQT1_ARQT_SHIFT)
+#define AVF_ATQBAH1 0x00007800 /* Reset: EMPR */
+#define AVF_ATQBAH1_ATQBAH_SHIFT 0
+#define AVF_ATQBAH1_ATQBAH_MASK AVF_MASK(0xFFFFFFFF, AVF_ATQBAH1_ATQBAH_SHIFT)
+#define AVF_ATQBAL1 0x00007C00 /* Reset: EMPR */
+#define AVF_ATQBAL1_ATQBAL_SHIFT 0
+#define AVF_ATQBAL1_ATQBAL_MASK AVF_MASK(0xFFFFFFFF, AVF_ATQBAL1_ATQBAL_SHIFT)
+#define AVF_ATQH1 0x00006400 /* Reset: EMPR */
+#define AVF_ATQH1_ATQH_SHIFT 0
+#define AVF_ATQH1_ATQH_MASK AVF_MASK(0x3FF, AVF_ATQH1_ATQH_SHIFT)
+#define AVF_ATQLEN1 0x00006800 /* Reset: EMPR */
+#define AVF_ATQLEN1_ATQLEN_SHIFT 0
+#define AVF_ATQLEN1_ATQLEN_MASK AVF_MASK(0x3FF, AVF_ATQLEN1_ATQLEN_SHIFT)
+#define AVF_ATQLEN1_ATQVFE_SHIFT 28
+#define AVF_ATQLEN1_ATQVFE_MASK AVF_MASK(0x1, AVF_ATQLEN1_ATQVFE_SHIFT)
+#define AVF_ATQLEN1_ATQOVFL_SHIFT 29
+#define AVF_ATQLEN1_ATQOVFL_MASK AVF_MASK(0x1, AVF_ATQLEN1_ATQOVFL_SHIFT)
+#define AVF_ATQLEN1_ATQCRIT_SHIFT 30
+#define AVF_ATQLEN1_ATQCRIT_MASK AVF_MASK(0x1, AVF_ATQLEN1_ATQCRIT_SHIFT)
+#define AVF_ATQLEN1_ATQENABLE_SHIFT 31
+#define AVF_ATQLEN1_ATQENABLE_MASK AVF_MASK(0x1U, AVF_ATQLEN1_ATQENABLE_SHIFT)
+#define AVF_ATQT1 0x00008400 /* Reset: EMPR */
+#define AVF_ATQT1_ATQT_SHIFT 0
+#define AVF_ATQT1_ATQT_MASK AVF_MASK(0x3FF, AVF_ATQT1_ATQT_SHIFT)
+#define AVFGEN_RSTAT 0x00008800 /* Reset: VFR */
+#define AVFGEN_RSTAT_VFR_STATE_SHIFT 0
+#define AVFGEN_RSTAT_VFR_STATE_MASK AVF_MASK(0x3, AVFGEN_RSTAT_VFR_STATE_SHIFT)
+#define AVFINT_DYN_CTL01 0x00005C00 /* Reset: VFR */
+#define AVFINT_DYN_CTL01_INTENA_SHIFT 0
+#define AVFINT_DYN_CTL01_INTENA_MASK AVF_MASK(0x1, AVFINT_DYN_CTL01_INTENA_SHIFT)
+#define AVFINT_DYN_CTL01_CLEARPBA_SHIFT 1
+#define AVFINT_DYN_CTL01_CLEARPBA_MASK AVF_MASK(0x1, AVFINT_DYN_CTL01_CLEARPBA_SHIFT)
+#define AVFINT_DYN_CTL01_SWINT_TRIG_SHIFT 2
+#define AVFINT_DYN_CTL01_SWINT_TRIG_MASK AVF_MASK(0x1, AVFINT_DYN_CTL01_SWINT_TRIG_SHIFT)
+#define AVFINT_DYN_CTL01_ITR_INDX_SHIFT 3
+#define AVFINT_DYN_CTL01_ITR_INDX_MASK AVF_MASK(0x3, AVFINT_DYN_CTL01_ITR_INDX_SHIFT)
+#define AVFINT_DYN_CTL01_INTERVAL_SHIFT 5
+#define AVFINT_DYN_CTL01_INTERVAL_MASK AVF_MASK(0xFFF, AVFINT_DYN_CTL01_INTERVAL_SHIFT)
+#define AVFINT_DYN_CTL01_SW_ITR_INDX_ENA_SHIFT 24
+#define AVFINT_DYN_CTL01_SW_ITR_INDX_ENA_MASK AVF_MASK(0x1, AVFINT_DYN_CTL01_SW_ITR_INDX_ENA_SHIFT)
+#define AVFINT_DYN_CTL01_SW_ITR_INDX_SHIFT 25
+#define AVFINT_DYN_CTL01_SW_ITR_INDX_MASK AVF_MASK(0x3, AVFINT_DYN_CTL01_SW_ITR_INDX_SHIFT)
+#define AVFINT_DYN_CTL01_INTENA_MSK_SHIFT 31
+#define AVFINT_DYN_CTL01_INTENA_MSK_MASK AVF_MASK(0x1, AVFINT_DYN_CTL01_INTENA_MSK_SHIFT)
+#define AVFINT_DYN_CTLN1(_INTVF) (0x00003800 + ((_INTVF) * 4)) /* _i=0...15 */ /* Reset: VFR */
+#define AVFINT_DYN_CTLN1_MAX_INDEX 15
+#define AVFINT_DYN_CTLN1_INTENA_SHIFT 0
+#define AVFINT_DYN_CTLN1_INTENA_MASK AVF_MASK(0x1, AVFINT_DYN_CTLN1_INTENA_SHIFT)
+#define AVFINT_DYN_CTLN1_CLEARPBA_SHIFT 1
+#define AVFINT_DYN_CTLN1_CLEARPBA_MASK AVF_MASK(0x1, AVFINT_DYN_CTLN1_CLEARPBA_SHIFT)
+#define AVFINT_DYN_CTLN1_SWINT_TRIG_SHIFT 2
+#define AVFINT_DYN_CTLN1_SWINT_TRIG_MASK AVF_MASK(0x1, AVFINT_DYN_CTLN1_SWINT_TRIG_SHIFT)
+#define AVFINT_DYN_CTLN1_ITR_INDX_SHIFT 3
+#define AVFINT_DYN_CTLN1_ITR_INDX_MASK AVF_MASK(0x3, AVFINT_DYN_CTLN1_ITR_INDX_SHIFT)
+#define AVFINT_DYN_CTLN1_INTERVAL_SHIFT 5
+#define AVFINT_DYN_CTLN1_INTERVAL_MASK AVF_MASK(0xFFF, AVFINT_DYN_CTLN1_INTERVAL_SHIFT)
+#define AVFINT_DYN_CTLN1_SW_ITR_INDX_ENA_SHIFT 24
+#define AVFINT_DYN_CTLN1_SW_ITR_INDX_ENA_MASK AVF_MASK(0x1, AVFINT_DYN_CTLN1_SW_ITR_INDX_ENA_SHIFT)
+#define AVFINT_DYN_CTLN1_SW_ITR_INDX_SHIFT 25
+#define AVFINT_DYN_CTLN1_SW_ITR_INDX_MASK AVF_MASK(0x3, AVFINT_DYN_CTLN1_SW_ITR_INDX_SHIFT)
+#define AVFINT_DYN_CTLN1_INTENA_MSK_SHIFT 31
+#define AVFINT_DYN_CTLN1_INTENA_MSK_MASK AVF_MASK(0x1, AVFINT_DYN_CTLN1_INTENA_MSK_SHIFT)
+#define AVFINT_ICR0_ENA1 0x00005000 /* Reset: CORER */
+#define AVFINT_ICR0_ENA1_LINK_STAT_CHANGE_SHIFT 25
+#define AVFINT_ICR0_ENA1_LINK_STAT_CHANGE_MASK AVF_MASK(0x1, AVFINT_ICR0_ENA1_LINK_STAT_CHANGE_SHIFT)
+#define AVFINT_ICR0_ENA1_ADMINQ_SHIFT 30
+#define AVFINT_ICR0_ENA1_ADMINQ_MASK AVF_MASK(0x1, AVFINT_ICR0_ENA1_ADMINQ_SHIFT)
+#define AVFINT_ICR0_ENA1_RSVD_SHIFT 31
+#define AVFINT_ICR0_ENA1_RSVD_MASK AVF_MASK(0x1, AVFINT_ICR0_ENA1_RSVD_SHIFT)
+#define AVFINT_ICR01 0x00004800 /* Reset: CORER */
+#define AVFINT_ICR01_INTEVENT_SHIFT 0
+#define AVFINT_ICR01_INTEVENT_MASK AVF_MASK(0x1, AVFINT_ICR01_INTEVENT_SHIFT)
+#define AVFINT_ICR01_QUEUE_0_SHIFT 1
+#define AVFINT_ICR01_QUEUE_0_MASK AVF_MASK(0x1, AVFINT_ICR01_QUEUE_0_SHIFT)
+#define AVFINT_ICR01_QUEUE_1_SHIFT 2
+#define AVFINT_ICR01_QUEUE_1_MASK AVF_MASK(0x1, AVFINT_ICR01_QUEUE_1_SHIFT)
+#define AVFINT_ICR01_QUEUE_2_SHIFT 3
+#define AVFINT_ICR01_QUEUE_2_MASK AVF_MASK(0x1, AVFINT_ICR01_QUEUE_2_SHIFT)
+#define AVFINT_ICR01_QUEUE_3_SHIFT 4
+#define AVFINT_ICR01_QUEUE_3_MASK AVF_MASK(0x1, AVFINT_ICR01_QUEUE_3_SHIFT)
+#define AVFINT_ICR01_LINK_STAT_CHANGE_SHIFT 25
+#define AVFINT_ICR01_LINK_STAT_CHANGE_MASK AVF_MASK(0x1, AVFINT_ICR01_LINK_STAT_CHANGE_SHIFT)
+#define AVFINT_ICR01_ADMINQ_SHIFT 30
+#define AVFINT_ICR01_ADMINQ_MASK AVF_MASK(0x1, AVFINT_ICR01_ADMINQ_SHIFT)
+#define AVFINT_ICR01_SWINT_SHIFT 31
+#define AVFINT_ICR01_SWINT_MASK AVF_MASK(0x1, AVFINT_ICR01_SWINT_SHIFT)
+#define AVFINT_ITR01(_i) (0x00004C00 + ((_i) * 4)) /* _i=0...2 */ /* Reset: VFR */
+#define AVFINT_ITR01_MAX_INDEX 2
+#define AVFINT_ITR01_INTERVAL_SHIFT 0
+#define AVFINT_ITR01_INTERVAL_MASK AVF_MASK(0xFFF, AVFINT_ITR01_INTERVAL_SHIFT)
+#define AVFINT_ITRN1(_i, _INTVF) (0x00002800 + ((_i) * 64 + (_INTVF) * 4)) /* _i=0...2, _INTVF=0...15 */ /* Reset: VFR */
+#define AVFINT_ITRN1_MAX_INDEX 2
+#define AVFINT_ITRN1_INTERVAL_SHIFT 0
+#define AVFINT_ITRN1_INTERVAL_MASK AVF_MASK(0xFFF, AVFINT_ITRN1_INTERVAL_SHIFT)
+#define AVFINT_STAT_CTL01 0x00005400 /* Reset: CORER */
+#define AVFINT_STAT_CTL01_OTHER_ITR_INDX_SHIFT 2
+#define AVFINT_STAT_CTL01_OTHER_ITR_INDX_MASK AVF_MASK(0x3, AVFINT_STAT_CTL01_OTHER_ITR_INDX_SHIFT)
+#define AVF_QRX_TAIL1(_Q) (0x00002000 + ((_Q) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define AVF_QRX_TAIL1_MAX_INDEX 15
+#define AVF_QRX_TAIL1_TAIL_SHIFT 0
+#define AVF_QRX_TAIL1_TAIL_MASK AVF_MASK(0x1FFF, AVF_QRX_TAIL1_TAIL_SHIFT)
+#define AVF_QTX_TAIL1(_Q) (0x00000000 + ((_Q) * 4)) /* _i=0...15 */ /* Reset: PFR */
+#define AVF_QTX_TAIL1_MAX_INDEX 15
+#define AVF_QTX_TAIL1_TAIL_SHIFT 0
+#define AVF_QTX_TAIL1_TAIL_MASK AVF_MASK(0x1FFF, AVF_QTX_TAIL1_TAIL_SHIFT)
+#define AVFMSIX_PBA 0x00002000 /* Reset: VFLR */
+#define AVFMSIX_PBA_PENBIT_SHIFT 0
+#define AVFMSIX_PBA_PENBIT_MASK AVF_MASK(0xFFFFFFFF, AVFMSIX_PBA_PENBIT_SHIFT)
+#define AVFMSIX_TADD(_i) (0x00000000 + ((_i) * 16)) /* _i=0...16 */ /* Reset: VFLR */
+#define AVFMSIX_TADD_MAX_INDEX 16
+#define AVFMSIX_TADD_MSIXTADD10_SHIFT 0
+#define AVFMSIX_TADD_MSIXTADD10_MASK AVF_MASK(0x3, AVFMSIX_TADD_MSIXTADD10_SHIFT)
+#define AVFMSIX_TADD_MSIXTADD_SHIFT 2
+#define AVFMSIX_TADD_MSIXTADD_MASK AVF_MASK(0x3FFFFFFF, AVFMSIX_TADD_MSIXTADD_SHIFT)
+#define AVFMSIX_TMSG(_i) (0x00000008 + ((_i) * 16)) /* _i=0...16 */ /* Reset: VFLR */
+#define AVFMSIX_TMSG_MAX_INDEX 16
+#define AVFMSIX_TMSG_MSIXTMSG_SHIFT 0
+#define AVFMSIX_TMSG_MSIXTMSG_MASK AVF_MASK(0xFFFFFFFF, AVFMSIX_TMSG_MSIXTMSG_SHIFT)
+#define AVFMSIX_TUADD(_i) (0x00000004 + ((_i) * 16)) /* _i=0...16 */ /* Reset: VFLR */
+#define AVFMSIX_TUADD_MAX_INDEX 16
+#define AVFMSIX_TUADD_MSIXTUADD_SHIFT 0
+#define AVFMSIX_TUADD_MSIXTUADD_MASK AVF_MASK(0xFFFFFFFF, AVFMSIX_TUADD_MSIXTUADD_SHIFT)
+#define AVFMSIX_TVCTRL(_i) (0x0000000C + ((_i) * 16)) /* _i=0...16 */ /* Reset: VFLR */
+#define AVFMSIX_TVCTRL_MAX_INDEX 16
+#define AVFMSIX_TVCTRL_MASK_SHIFT 0
+#define AVFMSIX_TVCTRL_MASK_MASK AVF_MASK(0x1, AVFMSIX_TVCTRL_MASK_SHIFT)
+#define AVFCM_PE_ERRDATA 0x0000DC00 /* Reset: VFR */
+#define AVFCM_PE_ERRDATA_ERROR_CODE_SHIFT 0
+#define AVFCM_PE_ERRDATA_ERROR_CODE_MASK AVF_MASK(0xF, AVFCM_PE_ERRDATA_ERROR_CODE_SHIFT)
+#define AVFCM_PE_ERRDATA_Q_TYPE_SHIFT 4
+#define AVFCM_PE_ERRDATA_Q_TYPE_MASK AVF_MASK(0x7, AVFCM_PE_ERRDATA_Q_TYPE_SHIFT)
+#define AVFCM_PE_ERRDATA_Q_NUM_SHIFT 8
+#define AVFCM_PE_ERRDATA_Q_NUM_MASK AVF_MASK(0x3FFFF, AVFCM_PE_ERRDATA_Q_NUM_SHIFT)
+#define AVFCM_PE_ERRINFO 0x0000D800 /* Reset: VFR */
+#define AVFCM_PE_ERRINFO_ERROR_VALID_SHIFT 0
+#define AVFCM_PE_ERRINFO_ERROR_VALID_MASK AVF_MASK(0x1, AVFCM_PE_ERRINFO_ERROR_VALID_SHIFT)
+#define AVFCM_PE_ERRINFO_ERROR_INST_SHIFT 4
+#define AVFCM_PE_ERRINFO_ERROR_INST_MASK AVF_MASK(0x7, AVFCM_PE_ERRINFO_ERROR_INST_SHIFT)
+#define AVFCM_PE_ERRINFO_DBL_ERROR_CNT_SHIFT 8
+#define AVFCM_PE_ERRINFO_DBL_ERROR_CNT_MASK AVF_MASK(0xFF, AVFCM_PE_ERRINFO_DBL_ERROR_CNT_SHIFT)
+#define AVFCM_PE_ERRINFO_RLU_ERROR_CNT_SHIFT 16
+#define AVFCM_PE_ERRINFO_RLU_ERROR_CNT_MASK AVF_MASK(0xFF, AVFCM_PE_ERRINFO_RLU_ERROR_CNT_SHIFT)
+#define AVFCM_PE_ERRINFO_RLS_ERROR_CNT_SHIFT 24
+#define AVFCM_PE_ERRINFO_RLS_ERROR_CNT_MASK AVF_MASK(0xFF, AVFCM_PE_ERRINFO_RLS_ERROR_CNT_SHIFT)
+#define AVFQF_HENA(_i) (0x0000C400 + ((_i) * 4)) /* _i=0...1 */ /* Reset: CORER */
+#define AVFQF_HENA_MAX_INDEX 1
+#define AVFQF_HENA_PTYPE_ENA_SHIFT 0
+#define AVFQF_HENA_PTYPE_ENA_MASK AVF_MASK(0xFFFFFFFF, AVFQF_HENA_PTYPE_ENA_SHIFT)
+#define AVFQF_HKEY(_i) (0x0000CC00 + ((_i) * 4)) /* _i=0...12 */ /* Reset: CORER */
+#define AVFQF_HKEY_MAX_INDEX 12
+#define AVFQF_HKEY_KEY_0_SHIFT 0
+#define AVFQF_HKEY_KEY_0_MASK AVF_MASK(0xFF, AVFQF_HKEY_KEY_0_SHIFT)
+#define AVFQF_HKEY_KEY_1_SHIFT 8
+#define AVFQF_HKEY_KEY_1_MASK AVF_MASK(0xFF, AVFQF_HKEY_KEY_1_SHIFT)
+#define AVFQF_HKEY_KEY_2_SHIFT 16
+#define AVFQF_HKEY_KEY_2_MASK AVF_MASK(0xFF, AVFQF_HKEY_KEY_2_SHIFT)
+#define AVFQF_HKEY_KEY_3_SHIFT 24
+#define AVFQF_HKEY_KEY_3_MASK AVF_MASK(0xFF, AVFQF_HKEY_KEY_3_SHIFT)
+#define AVFQF_HLUT(_i) (0x0000D000 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */
+#define AVFQF_HLUT_MAX_INDEX 15
+#define AVFQF_HLUT_LUT0_SHIFT 0
+#define AVFQF_HLUT_LUT0_MASK AVF_MASK(0xF, AVFQF_HLUT_LUT0_SHIFT)
+#define AVFQF_HLUT_LUT1_SHIFT 8
+#define AVFQF_HLUT_LUT1_MASK AVF_MASK(0xF, AVFQF_HLUT_LUT1_SHIFT)
+#define AVFQF_HLUT_LUT2_SHIFT 16
+#define AVFQF_HLUT_LUT2_MASK AVF_MASK(0xF, AVFQF_HLUT_LUT2_SHIFT)
+#define AVFQF_HLUT_LUT3_SHIFT 24
+#define AVFQF_HLUT_LUT3_MASK AVF_MASK(0xF, AVFQF_HLUT_LUT3_SHIFT)
+#define AVFQF_HREGION(_i) (0x0000D400 + ((_i) * 4)) /* _i=0...7 */ /* Reset: CORER */
+#define AVFQF_HREGION_MAX_INDEX 7
+#define AVFQF_HREGION_OVERRIDE_ENA_0_SHIFT 0
+#define AVFQF_HREGION_OVERRIDE_ENA_0_MASK AVF_MASK(0x1, AVFQF_HREGION_OVERRIDE_ENA_0_SHIFT)
+#define AVFQF_HREGION_REGION_0_SHIFT 1
+#define AVFQF_HREGION_REGION_0_MASK AVF_MASK(0x7, AVFQF_HREGION_REGION_0_SHIFT)
+#define AVFQF_HREGION_OVERRIDE_ENA_1_SHIFT 4
+#define AVFQF_HREGION_OVERRIDE_ENA_1_MASK AVF_MASK(0x1, AVFQF_HREGION_OVERRIDE_ENA_1_SHIFT)
+#define AVFQF_HREGION_REGION_1_SHIFT 5
+#define AVFQF_HREGION_REGION_1_MASK AVF_MASK(0x7, AVFQF_HREGION_REGION_1_SHIFT)
+#define AVFQF_HREGION_OVERRIDE_ENA_2_SHIFT 8
+#define AVFQF_HREGION_OVERRIDE_ENA_2_MASK AVF_MASK(0x1, AVFQF_HREGION_OVERRIDE_ENA_2_SHIFT)
+#define AVFQF_HREGION_REGION_2_SHIFT 9
+#define AVFQF_HREGION_REGION_2_MASK AVF_MASK(0x7, AVFQF_HREGION_REGION_2_SHIFT)
+#define AVFQF_HREGION_OVERRIDE_ENA_3_SHIFT 12
+#define AVFQF_HREGION_OVERRIDE_ENA_3_MASK AVF_MASK(0x1, AVFQF_HREGION_OVERRIDE_ENA_3_SHIFT)
+#define AVFQF_HREGION_REGION_3_SHIFT 13
+#define AVFQF_HREGION_REGION_3_MASK AVF_MASK(0x7, AVFQF_HREGION_REGION_3_SHIFT)
+#define AVFQF_HREGION_OVERRIDE_ENA_4_SHIFT 16
+#define AVFQF_HREGION_OVERRIDE_ENA_4_MASK AVF_MASK(0x1, AVFQF_HREGION_OVERRIDE_ENA_4_SHIFT)
+#define AVFQF_HREGION_REGION_4_SHIFT 17
+#define AVFQF_HREGION_REGION_4_MASK AVF_MASK(0x7, AVFQF_HREGION_REGION_4_SHIFT)
+#define AVFQF_HREGION_OVERRIDE_ENA_5_SHIFT 20
+#define AVFQF_HREGION_OVERRIDE_ENA_5_MASK AVF_MASK(0x1, AVFQF_HREGION_OVERRIDE_ENA_5_SHIFT)
+#define AVFQF_HREGION_REGION_5_SHIFT 21
+#define AVFQF_HREGION_REGION_5_MASK AVF_MASK(0x7, AVFQF_HREGION_REGION_5_SHIFT)
+#define AVFQF_HREGION_OVERRIDE_ENA_6_SHIFT 24
+#define AVFQF_HREGION_OVERRIDE_ENA_6_MASK AVF_MASK(0x1, AVFQF_HREGION_OVERRIDE_ENA_6_SHIFT)
+#define AVFQF_HREGION_REGION_6_SHIFT 25
+#define AVFQF_HREGION_REGION_6_MASK AVF_MASK(0x7, AVFQF_HREGION_REGION_6_SHIFT)
+#define AVFQF_HREGION_OVERRIDE_ENA_7_SHIFT 28
+#define AVFQF_HREGION_OVERRIDE_ENA_7_MASK AVF_MASK(0x1, AVFQF_HREGION_OVERRIDE_ENA_7_SHIFT)
+#define AVFQF_HREGION_REGION_7_SHIFT 29
+#define AVFQF_HREGION_REGION_7_MASK AVF_MASK(0x7, AVFQF_HREGION_REGION_7_SHIFT)
+
+#define AVFINT_DYN_CTL01_WB_ON_ITR_SHIFT 30
+#define AVFINT_DYN_CTL01_WB_ON_ITR_MASK AVF_MASK(0x1, AVFINT_DYN_CTL01_WB_ON_ITR_SHIFT)
+#define AVFINT_DYN_CTLN1_WB_ON_ITR_SHIFT 30
+#define AVFINT_DYN_CTLN1_WB_ON_ITR_MASK AVF_MASK(0x1, AVFINT_DYN_CTLN1_WB_ON_ITR_SHIFT)
+#define AVFPE_AEQALLOC1 0x0000A400 /* Reset: VFR */
+#define AVFPE_AEQALLOC1_AECOUNT_SHIFT 0
+#define AVFPE_AEQALLOC1_AECOUNT_MASK AVF_MASK(0xFFFFFFFF, AVFPE_AEQALLOC1_AECOUNT_SHIFT)
+#define AVFPE_CCQPHIGH1 0x00009800 /* Reset: VFR */
+#define AVFPE_CCQPHIGH1_PECCQPHIGH_SHIFT 0
+#define AVFPE_CCQPHIGH1_PECCQPHIGH_MASK AVF_MASK(0xFFFFFFFF, AVFPE_CCQPHIGH1_PECCQPHIGH_SHIFT)
+#define AVFPE_CCQPLOW1 0x0000AC00 /* Reset: VFR */
+#define AVFPE_CCQPLOW1_PECCQPLOW_SHIFT 0
+#define AVFPE_CCQPLOW1_PECCQPLOW_MASK AVF_MASK(0xFFFFFFFF, AVFPE_CCQPLOW1_PECCQPLOW_SHIFT)
+#define AVFPE_CCQPSTATUS1 0x0000B800 /* Reset: VFR */
+#define AVFPE_CCQPSTATUS1_CCQP_DONE_SHIFT 0
+#define AVFPE_CCQPSTATUS1_CCQP_DONE_MASK AVF_MASK(0x1, AVFPE_CCQPSTATUS1_CCQP_DONE_SHIFT)
+#define AVFPE_CCQPSTATUS1_HMC_PROFILE_SHIFT 4
+#define AVFPE_CCQPSTATUS1_HMC_PROFILE_MASK AVF_MASK(0x7, AVFPE_CCQPSTATUS1_HMC_PROFILE_SHIFT)
+#define AVFPE_CCQPSTATUS1_RDMA_EN_VFS_SHIFT 16
+#define AVFPE_CCQPSTATUS1_RDMA_EN_VFS_MASK AVF_MASK(0x3F, AVFPE_CCQPSTATUS1_RDMA_EN_VFS_SHIFT)
+#define AVFPE_CCQPSTATUS1_CCQP_ERR_SHIFT 31
+#define AVFPE_CCQPSTATUS1_CCQP_ERR_MASK AVF_MASK(0x1, AVFPE_CCQPSTATUS1_CCQP_ERR_SHIFT)
+#define AVFPE_CQACK1 0x0000B000 /* Reset: VFR */
+#define AVFPE_CQACK1_PECQID_SHIFT 0
+#define AVFPE_CQACK1_PECQID_MASK AVF_MASK(0x1FFFF, AVFPE_CQACK1_PECQID_SHIFT)
+#define AVFPE_CQARM1 0x0000B400 /* Reset: VFR */
+#define AVFPE_CQARM1_PECQID_SHIFT 0
+#define AVFPE_CQARM1_PECQID_MASK AVF_MASK(0x1FFFF, AVFPE_CQARM1_PECQID_SHIFT)
+#define AVFPE_CQPDB1 0x0000BC00 /* Reset: VFR */
+#define AVFPE_CQPDB1_WQHEAD_SHIFT 0
+#define AVFPE_CQPDB1_WQHEAD_MASK AVF_MASK(0x7FF, AVFPE_CQPDB1_WQHEAD_SHIFT)
+#define AVFPE_CQPERRCODES1 0x00009C00 /* Reset: VFR */
+#define AVFPE_CQPERRCODES1_CQP_MINOR_CODE_SHIFT 0
+#define AVFPE_CQPERRCODES1_CQP_MINOR_CODE_MASK AVF_MASK(0xFFFF, AVFPE_CQPERRCODES1_CQP_MINOR_CODE_SHIFT)
+#define AVFPE_CQPERRCODES1_CQP_MAJOR_CODE_SHIFT 16
+#define AVFPE_CQPERRCODES1_CQP_MAJOR_CODE_MASK AVF_MASK(0xFFFF, AVFPE_CQPERRCODES1_CQP_MAJOR_CODE_SHIFT)
+#define AVFPE_CQPTAIL1 0x0000A000 /* Reset: VFR */
+#define AVFPE_CQPTAIL1_WQTAIL_SHIFT 0
+#define AVFPE_CQPTAIL1_WQTAIL_MASK AVF_MASK(0x7FF, AVFPE_CQPTAIL1_WQTAIL_SHIFT)
+#define AVFPE_CQPTAIL1_CQP_OP_ERR_SHIFT 31
+#define AVFPE_CQPTAIL1_CQP_OP_ERR_MASK AVF_MASK(0x1, AVFPE_CQPTAIL1_CQP_OP_ERR_SHIFT)
+#define AVFPE_IPCONFIG01 0x00008C00 /* Reset: VFR */
+#define AVFPE_IPCONFIG01_PEIPID_SHIFT 0
+#define AVFPE_IPCONFIG01_PEIPID_MASK AVF_MASK(0xFFFF, AVFPE_IPCONFIG01_PEIPID_SHIFT)
+#define AVFPE_IPCONFIG01_USEENTIREIDRANGE_SHIFT 16
+#define AVFPE_IPCONFIG01_USEENTIREIDRANGE_MASK AVF_MASK(0x1, AVFPE_IPCONFIG01_USEENTIREIDRANGE_SHIFT)
+#define AVFPE_MRTEIDXMASK1 0x00009000 /* Reset: VFR */
+#define AVFPE_MRTEIDXMASK1_MRTEIDXMASKBITS_SHIFT 0
+#define AVFPE_MRTEIDXMASK1_MRTEIDXMASKBITS_MASK AVF_MASK(0x1F, AVFPE_MRTEIDXMASK1_MRTEIDXMASKBITS_SHIFT)
+#define AVFPE_RCVUNEXPECTEDERROR1 0x00009400 /* Reset: VFR */
+#define AVFPE_RCVUNEXPECTEDERROR1_TCP_RX_UNEXP_ERR_SHIFT 0
+#define AVFPE_RCVUNEXPECTEDERROR1_TCP_RX_UNEXP_ERR_MASK AVF_MASK(0xFFFFFF, AVFPE_RCVUNEXPECTEDERROR1_TCP_RX_UNEXP_ERR_SHIFT)
+#define AVFPE_TCPNOWTIMER1 0x0000A800 /* Reset: VFR */
+#define AVFPE_TCPNOWTIMER1_TCP_NOW_SHIFT 0
+#define AVFPE_TCPNOWTIMER1_TCP_NOW_MASK AVF_MASK(0xFFFFFFFF, AVFPE_TCPNOWTIMER1_TCP_NOW_SHIFT)
+#define AVFPE_WQEALLOC1 0x0000C000 /* Reset: VFR */
+#define AVFPE_WQEALLOC1_PEQPID_SHIFT 0
+#define AVFPE_WQEALLOC1_PEQPID_MASK AVF_MASK(0x3FFFF, AVFPE_WQEALLOC1_PEQPID_SHIFT)
+#define AVFPE_WQEALLOC1_WQE_DESC_INDEX_SHIFT 20
+#define AVFPE_WQEALLOC1_WQE_DESC_INDEX_MASK AVF_MASK(0xFFF, AVFPE_WQEALLOC1_WQE_DESC_INDEX_SHIFT)
+
+#endif /* _AVF_REGISTER_H_ */
diff --git a/drivers/net/iavf/base/iavf_status.h b/drivers/net/iavf/base/iavf_status.h
new file mode 100644
index 0000000..e8a673b
--- /dev/null
+++ b/drivers/net/iavf/base/iavf_status.h
@@ -0,0 +1,108 @@
+/*******************************************************************************
+
+Copyright (c) 2013 - 2015, Intel Corporation
+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.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+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.
+
+***************************************************************************/
+
+#ifndef _AVF_STATUS_H_
+#define _AVF_STATUS_H_
+
+/* Error Codes */
+enum avf_status_code {
+ AVF_SUCCESS = 0,
+ AVF_ERR_NVM = -1,
+ AVF_ERR_NVM_CHECKSUM = -2,
+ AVF_ERR_PHY = -3,
+ AVF_ERR_CONFIG = -4,
+ AVF_ERR_PARAM = -5,
+ AVF_ERR_MAC_TYPE = -6,
+ AVF_ERR_UNKNOWN_PHY = -7,
+ AVF_ERR_LINK_SETUP = -8,
+ AVF_ERR_ADAPTER_STOPPED = -9,
+ AVF_ERR_INVALID_MAC_ADDR = -10,
+ AVF_ERR_DEVICE_NOT_SUPPORTED = -11,
+ AVF_ERR_MASTER_REQUESTS_PENDING = -12,
+ AVF_ERR_INVALID_LINK_SETTINGS = -13,
+ AVF_ERR_AUTONEG_NOT_COMPLETE = -14,
+ AVF_ERR_RESET_FAILED = -15,
+ AVF_ERR_SWFW_SYNC = -16,
+ AVF_ERR_NO_AVAILABLE_VSI = -17,
+ AVF_ERR_NO_MEMORY = -18,
+ AVF_ERR_BAD_PTR = -19,
+ AVF_ERR_RING_FULL = -20,
+ AVF_ERR_INVALID_PD_ID = -21,
+ AVF_ERR_INVALID_QP_ID = -22,
+ AVF_ERR_INVALID_CQ_ID = -23,
+ AVF_ERR_INVALID_CEQ_ID = -24,
+ AVF_ERR_INVALID_AEQ_ID = -25,
+ AVF_ERR_INVALID_SIZE = -26,
+ AVF_ERR_INVALID_ARP_INDEX = -27,
+ AVF_ERR_INVALID_FPM_FUNC_ID = -28,
+ AVF_ERR_QP_INVALID_MSG_SIZE = -29,
+ AVF_ERR_QP_TOOMANY_WRS_POSTED = -30,
+ AVF_ERR_INVALID_FRAG_COUNT = -31,
+ AVF_ERR_QUEUE_EMPTY = -32,
+ AVF_ERR_INVALID_ALIGNMENT = -33,
+ AVF_ERR_FLUSHED_QUEUE = -34,
+ AVF_ERR_INVALID_PUSH_PAGE_INDEX = -35,
+ AVF_ERR_INVALID_IMM_DATA_SIZE = -36,
+ AVF_ERR_TIMEOUT = -37,
+ AVF_ERR_OPCODE_MISMATCH = -38,
+ AVF_ERR_CQP_COMPL_ERROR = -39,
+ AVF_ERR_INVALID_VF_ID = -40,
+ AVF_ERR_INVALID_HMCFN_ID = -41,
+ AVF_ERR_BACKING_PAGE_ERROR = -42,
+ AVF_ERR_NO_PBLCHUNKS_AVAILABLE = -43,
+ AVF_ERR_INVALID_PBLE_INDEX = -44,
+ AVF_ERR_INVALID_SD_INDEX = -45,
+ AVF_ERR_INVALID_PAGE_DESC_INDEX = -46,
+ AVF_ERR_INVALID_SD_TYPE = -47,
+ AVF_ERR_MEMCPY_FAILED = -48,
+ AVF_ERR_INVALID_HMC_OBJ_INDEX = -49,
+ AVF_ERR_INVALID_HMC_OBJ_COUNT = -50,
+ AVF_ERR_INVALID_SRQ_ARM_LIMIT = -51,
+ AVF_ERR_SRQ_ENABLED = -52,
+ AVF_ERR_ADMIN_QUEUE_ERROR = -53,
+ AVF_ERR_ADMIN_QUEUE_TIMEOUT = -54,
+ AVF_ERR_BUF_TOO_SHORT = -55,
+ AVF_ERR_ADMIN_QUEUE_FULL = -56,
+ AVF_ERR_ADMIN_QUEUE_NO_WORK = -57,
+ AVF_ERR_BAD_IWARP_CQE = -58,
+ AVF_ERR_NVM_BLANK_MODE = -59,
+ AVF_ERR_NOT_IMPLEMENTED = -60,
+ AVF_ERR_PE_DOORBELL_NOT_ENABLED = -61,
+ AVF_ERR_DIAG_TEST_FAILED = -62,
+ AVF_ERR_NOT_READY = -63,
+ AVF_NOT_SUPPORTED = -64,
+ AVF_ERR_FIRMWARE_API_VERSION = -65,
+ AVF_ERR_ADMIN_QUEUE_CRITICAL_ERROR = -66,
+};
+
+#endif /* _AVF_STATUS_H_ */
diff --git a/drivers/net/iavf/base/iavf_type.h b/drivers/net/iavf/base/iavf_type.h
new file mode 100644
index 0000000..7c59073
--- /dev/null
+++ b/drivers/net/iavf/base/iavf_type.h
@@ -0,0 +1,2024 @@
+/*******************************************************************************
+
+Copyright (c) 2013 - 2015, Intel Corporation
+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.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+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.
+
+***************************************************************************/
+
+#ifndef _AVF_TYPE_H_
+#define _AVF_TYPE_H_
+
+#include "iavf_status.h"
+#include "iavf_osdep.h"
+#include "iavf_register.h"
+#include "iavf_adminq.h"
+#include "iavf_hmc.h"
+#include "iavf_lan_hmc.h"
+#include "iavf_devids.h"
+
+#define UNREFERENCED_XPARAMETER
+#define UNREFERENCED_1PARAMETER(_p) (_p);
+#define UNREFERENCED_2PARAMETER(_p, _q) (_p); (_q);
+#define UNREFERENCED_3PARAMETER(_p, _q, _r) (_p); (_q); (_r);
+#define UNREFERENCED_4PARAMETER(_p, _q, _r, _s) (_p); (_q); (_r); (_s);
+#define UNREFERENCED_5PARAMETER(_p, _q, _r, _s, _t) (_p); (_q); (_r); (_s); (_t);
+
+#ifndef LINUX_MACROS
+#ifndef BIT
+#define BIT(a) (1UL << (a))
+#endif /* BIT */
+#ifndef BIT_ULL
+#define BIT_ULL(a) (1ULL << (a))
+#endif /* BIT_ULL */
+#endif /* LINUX_MACROS */
+
+#ifndef AVF_MASK
+/* AVF_MASK is a macro used on 32 bit registers */
+#define AVF_MASK(mask, shift) (mask << shift)
+#endif
+
+#define AVF_MAX_PF 16
+#define AVF_MAX_PF_VSI 64
+#define AVF_MAX_PF_QP 128
+#define AVF_MAX_VSI_QP 16
+#define AVF_MAX_VF_VSI 3
+#define AVF_MAX_CHAINED_RX_BUFFERS 5
+#define AVF_MAX_PF_UDP_OFFLOAD_PORTS 16
+
+/* something less than 1 minute */
+#define AVF_HEARTBEAT_TIMEOUT (HZ * 50)
+
+/* Max default timeout in ms, */
+#define AVF_MAX_NVM_TIMEOUT 18000
+
+/* Max timeout in ms for the phy to respond */
+#define AVF_MAX_PHY_TIMEOUT 500
+
+/* Check whether address is multicast. */
+#define AVF_IS_MULTICAST(address) (bool)(((u8 *)(address))[0] & ((u8)0x01))
+
+/* Check whether an address is broadcast. */
+#define AVF_IS_BROADCAST(address) \
+ ((((u8 *)(address))[0] == ((u8)0xff)) && \
+ (((u8 *)(address))[1] == ((u8)0xff)))
+
+/* Switch from ms to the 1usec global time (this is the GTIME resolution) */
+#define AVF_MS_TO_GTIME(time) ((time) * 1000)
+
+/* forward declaration */
+struct avf_hw;
+typedef void (*AVF_ADMINQ_CALLBACK)(struct avf_hw *, struct avf_aq_desc *);
+
+#ifndef ETH_ALEN
+#define ETH_ALEN 6
+#endif
+/* Data type manipulation macros. */
+#define AVF_HI_DWORD(x) ((u32)((((x) >> 16) >> 16) & 0xFFFFFFFF))
+#define AVF_LO_DWORD(x) ((u32)((x) & 0xFFFFFFFF))
+
+#define AVF_HI_WORD(x) ((u16)(((x) >> 16) & 0xFFFF))
+#define AVF_LO_WORD(x) ((u16)((x) & 0xFFFF))
+
+#define AVF_HI_BYTE(x) ((u8)(((x) >> 8) & 0xFF))
+#define AVF_LO_BYTE(x) ((u8)((x) & 0xFF))
+
+/* Number of Transmit Descriptors must be a multiple of 8. */
+#define AVF_REQ_TX_DESCRIPTOR_MULTIPLE 8
+/* Number of Receive Descriptors must be a multiple of 32 if
+ * the number of descriptors is greater than 32.
+ */
+#define AVF_REQ_RX_DESCRIPTOR_MULTIPLE 32
+
+#define AVF_DESC_UNUSED(R) \
+ ((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \
+ (R)->next_to_clean - (R)->next_to_use - 1)
+
+/* bitfields for Tx queue mapping in QTX_CTL */
+#define AVF_QTX_CTL_VF_QUEUE 0x0
+#define AVF_QTX_CTL_VM_QUEUE 0x1
+#define AVF_QTX_CTL_PF_QUEUE 0x2
+
+/* debug masks - set these bits in hw->debug_mask to control output */
+enum avf_debug_mask {
+ AVF_DEBUG_INIT = 0x00000001,
+ AVF_DEBUG_RELEASE = 0x00000002,
+
+ AVF_DEBUG_LINK = 0x00000010,
+ AVF_DEBUG_PHY = 0x00000020,
+ AVF_DEBUG_HMC = 0x00000040,
+ AVF_DEBUG_NVM = 0x00000080,
+ AVF_DEBUG_LAN = 0x00000100,
+ AVF_DEBUG_FLOW = 0x00000200,
+ AVF_DEBUG_DCB = 0x00000400,
+ AVF_DEBUG_DIAG = 0x00000800,
+ AVF_DEBUG_FD = 0x00001000,
+ AVF_DEBUG_PACKAGE = 0x00002000,
+
+ AVF_DEBUG_AQ_MESSAGE = 0x01000000,
+ AVF_DEBUG_AQ_DESCRIPTOR = 0x02000000,
+ AVF_DEBUG_AQ_DESC_BUFFER = 0x04000000,
+ AVF_DEBUG_AQ_COMMAND = 0x06000000,
+ AVF_DEBUG_AQ = 0x0F000000,
+
+ AVF_DEBUG_USER = 0xF0000000,
+
+ AVF_DEBUG_ALL = 0xFFFFFFFF
+};
+
+/* PCI Bus Info */
+#define AVF_PCI_LINK_STATUS 0xB2
+#define AVF_PCI_LINK_WIDTH 0x3F0
+#define AVF_PCI_LINK_WIDTH_1 0x10
+#define AVF_PCI_LINK_WIDTH_2 0x20
+#define AVF_PCI_LINK_WIDTH_4 0x40
+#define AVF_PCI_LINK_WIDTH_8 0x80
+#define AVF_PCI_LINK_SPEED 0xF
+#define AVF_PCI_LINK_SPEED_2500 0x1
+#define AVF_PCI_LINK_SPEED_5000 0x2
+#define AVF_PCI_LINK_SPEED_8000 0x3
+
+#define AVF_MDIO_CLAUSE22_STCODE_MASK AVF_MASK(1, \
+ AVF_GLGEN_MSCA_STCODE_SHIFT)
+#define AVF_MDIO_CLAUSE22_OPCODE_WRITE_MASK AVF_MASK(1, \
+ AVF_GLGEN_MSCA_OPCODE_SHIFT)
+#define AVF_MDIO_CLAUSE22_OPCODE_READ_MASK AVF_MASK(2, \
+ AVF_GLGEN_MSCA_OPCODE_SHIFT)
+
+#define AVF_MDIO_CLAUSE45_STCODE_MASK AVF_MASK(0, \
+ AVF_GLGEN_MSCA_STCODE_SHIFT)
+#define AVF_MDIO_CLAUSE45_OPCODE_ADDRESS_MASK AVF_MASK(0, \
+ AVF_GLGEN_MSCA_OPCODE_SHIFT)
+#define AVF_MDIO_CLAUSE45_OPCODE_WRITE_MASK AVF_MASK(1, \
+ AVF_GLGEN_MSCA_OPCODE_SHIFT)
+#define AVF_MDIO_CLAUSE45_OPCODE_READ_INC_ADDR_MASK AVF_MASK(2, \
+ AVF_GLGEN_MSCA_OPCODE_SHIFT)
+#define AVF_MDIO_CLAUSE45_OPCODE_READ_MASK AVF_MASK(3, \
+ AVF_GLGEN_MSCA_OPCODE_SHIFT)
+
+#define AVF_PHY_COM_REG_PAGE 0x1E
+#define AVF_PHY_LED_LINK_MODE_MASK 0xF0
+#define AVF_PHY_LED_MANUAL_ON 0x100
+#define AVF_PHY_LED_PROV_REG_1 0xC430
+#define AVF_PHY_LED_MODE_MASK 0xFFFF
+#define AVF_PHY_LED_MODE_ORIG 0x80000000
+
+/* Memory types */
+enum avf_memset_type {
+ AVF_NONDMA_MEM = 0,
+ AVF_DMA_MEM
+};
+
+/* Memcpy types */
+enum avf_memcpy_type {
+ AVF_NONDMA_TO_NONDMA = 0,
+ AVF_NONDMA_TO_DMA,
+ AVF_DMA_TO_DMA,
+ AVF_DMA_TO_NONDMA
+};
+
+/* These are structs for managing the hardware information and the operations.
+ * The structures of function pointers are filled out at init time when we
+ * know for sure exactly which hardware we're working with. This gives us the
+ * flexibility of using the same main driver code but adapting to slightly
+ * different hardware needs as new parts are developed. For this architecture,
+ * the Firmware and AdminQ are intended to insulate the driver from most of the
+ * future changes, but these structures will also do part of the job.
+ */
+enum avf_mac_type {
+ AVF_MAC_UNKNOWN = 0,
+ AVF_MAC_XL710,
+ AVF_MAC_VF,
+ AVF_MAC_X722,
+ AVF_MAC_X722_VF,
+ AVF_MAC_GENERIC,
+};
+
+enum avf_media_type {
+ AVF_MEDIA_TYPE_UNKNOWN = 0,
+ AVF_MEDIA_TYPE_FIBER,
+ AVF_MEDIA_TYPE_BASET,
+ AVF_MEDIA_TYPE_BACKPLANE,
+ AVF_MEDIA_TYPE_CX4,
+ AVF_MEDIA_TYPE_DA,
+ AVF_MEDIA_TYPE_VIRTUAL
+};
+
+enum avf_fc_mode {
+ AVF_FC_NONE = 0,
+ AVF_FC_RX_PAUSE,
+ AVF_FC_TX_PAUSE,
+ AVF_FC_FULL,
+ AVF_FC_PFC,
+ AVF_FC_DEFAULT
+};
+
+enum avf_set_fc_aq_failures {
+ AVF_SET_FC_AQ_FAIL_NONE = 0,
+ AVF_SET_FC_AQ_FAIL_GET = 1,
+ AVF_SET_FC_AQ_FAIL_SET = 2,
+ AVF_SET_FC_AQ_FAIL_UPDATE = 4,
+ AVF_SET_FC_AQ_FAIL_SET_UPDATE = 6
+};
+
+enum avf_vsi_type {
+ AVF_VSI_MAIN = 0,
+ AVF_VSI_VMDQ1 = 1,
+ AVF_VSI_VMDQ2 = 2,
+ AVF_VSI_CTRL = 3,
+ AVF_VSI_FCOE = 4,
+ AVF_VSI_MIRROR = 5,
+ AVF_VSI_SRIOV = 6,
+ AVF_VSI_FDIR = 7,
+ AVF_VSI_TYPE_UNKNOWN
+};
+
+enum avf_queue_type {
+ AVF_QUEUE_TYPE_RX = 0,
+ AVF_QUEUE_TYPE_TX,
+ AVF_QUEUE_TYPE_PE_CEQ,
+ AVF_QUEUE_TYPE_UNKNOWN
+};
+
+struct avf_link_status {
+ enum avf_aq_phy_type phy_type;
+ enum avf_aq_link_speed link_speed;
+ u8 link_info;
+ u8 an_info;
+ u8 req_fec_info;
+ u8 fec_info;
+ u8 ext_info;
+ u8 loopback;
+ /* is Link Status Event notification to SW enabled */
+ bool lse_enable;
+ u16 max_frame_size;
+ bool crc_enable;
+ u8 pacing;
+ u8 requested_speeds;
+ u8 module_type[3];
+ /* 1st byte: module identifier */
+#define AVF_MODULE_TYPE_SFP 0x03
+#define AVF_MODULE_TYPE_QSFP 0x0D
+ /* 2nd byte: ethernet compliance codes for 10/40G */
+#define AVF_MODULE_TYPE_40G_ACTIVE 0x01
+#define AVF_MODULE_TYPE_40G_LR4 0x02
+#define AVF_MODULE_TYPE_40G_SR4 0x04
+#define AVF_MODULE_TYPE_40G_CR4 0x08
+#define AVF_MODULE_TYPE_10G_BASE_SR 0x10
+#define AVF_MODULE_TYPE_10G_BASE_LR 0x20
+#define AVF_MODULE_TYPE_10G_BASE_LRM 0x40
+#define AVF_MODULE_TYPE_10G_BASE_ER 0x80
+ /* 3rd byte: ethernet compliance codes for 1G */
+#define AVF_MODULE_TYPE_1000BASE_SX 0x01
+#define AVF_MODULE_TYPE_1000BASE_LX 0x02
+#define AVF_MODULE_TYPE_1000BASE_CX 0x04
+#define AVF_MODULE_TYPE_1000BASE_T 0x08
+};
+
+struct avf_phy_info {
+ struct avf_link_status link_info;
+ struct avf_link_status link_info_old;
+ bool get_link_info;
+ enum avf_media_type media_type;
+ /* all the phy types the NVM is capable of */
+ u64 phy_types;
+};
+
+#define AVF_CAP_PHY_TYPE_SGMII BIT_ULL(AVF_PHY_TYPE_SGMII)
+#define AVF_CAP_PHY_TYPE_1000BASE_KX BIT_ULL(AVF_PHY_TYPE_1000BASE_KX)
+#define AVF_CAP_PHY_TYPE_10GBASE_KX4 BIT_ULL(AVF_PHY_TYPE_10GBASE_KX4)
+#define AVF_CAP_PHY_TYPE_10GBASE_KR BIT_ULL(AVF_PHY_TYPE_10GBASE_KR)
+#define AVF_CAP_PHY_TYPE_40GBASE_KR4 BIT_ULL(AVF_PHY_TYPE_40GBASE_KR4)
+#define AVF_CAP_PHY_TYPE_XAUI BIT_ULL(AVF_PHY_TYPE_XAUI)
+#define AVF_CAP_PHY_TYPE_XFI BIT_ULL(AVF_PHY_TYPE_XFI)
+#define AVF_CAP_PHY_TYPE_SFI BIT_ULL(AVF_PHY_TYPE_SFI)
+#define AVF_CAP_PHY_TYPE_XLAUI BIT_ULL(AVF_PHY_TYPE_XLAUI)
+#define AVF_CAP_PHY_TYPE_XLPPI BIT_ULL(AVF_PHY_TYPE_XLPPI)
+#define AVF_CAP_PHY_TYPE_40GBASE_CR4_CU BIT_ULL(AVF_PHY_TYPE_40GBASE_CR4_CU)
+#define AVF_CAP_PHY_TYPE_10GBASE_CR1_CU BIT_ULL(AVF_PHY_TYPE_10GBASE_CR1_CU)
+#define AVF_CAP_PHY_TYPE_10GBASE_AOC BIT_ULL(AVF_PHY_TYPE_10GBASE_AOC)
+#define AVF_CAP_PHY_TYPE_40GBASE_AOC BIT_ULL(AVF_PHY_TYPE_40GBASE_AOC)
+#define AVF_CAP_PHY_TYPE_100BASE_TX BIT_ULL(AVF_PHY_TYPE_100BASE_TX)
+#define AVF_CAP_PHY_TYPE_1000BASE_T BIT_ULL(AVF_PHY_TYPE_1000BASE_T)
+#define AVF_CAP_PHY_TYPE_10GBASE_T BIT_ULL(AVF_PHY_TYPE_10GBASE_T)
+#define AVF_CAP_PHY_TYPE_10GBASE_SR BIT_ULL(AVF_PHY_TYPE_10GBASE_SR)
+#define AVF_CAP_PHY_TYPE_10GBASE_LR BIT_ULL(AVF_PHY_TYPE_10GBASE_LR)
+#define AVF_CAP_PHY_TYPE_10GBASE_SFPP_CU BIT_ULL(AVF_PHY_TYPE_10GBASE_SFPP_CU)
+#define AVF_CAP_PHY_TYPE_10GBASE_CR1 BIT_ULL(AVF_PHY_TYPE_10GBASE_CR1)
+#define AVF_CAP_PHY_TYPE_40GBASE_CR4 BIT_ULL(AVF_PHY_TYPE_40GBASE_CR4)
+#define AVF_CAP_PHY_TYPE_40GBASE_SR4 BIT_ULL(AVF_PHY_TYPE_40GBASE_SR4)
+#define AVF_CAP_PHY_TYPE_40GBASE_LR4 BIT_ULL(AVF_PHY_TYPE_40GBASE_LR4)
+#define AVF_CAP_PHY_TYPE_1000BASE_SX BIT_ULL(AVF_PHY_TYPE_1000BASE_SX)
+#define AVF_CAP_PHY_TYPE_1000BASE_LX BIT_ULL(AVF_PHY_TYPE_1000BASE_LX)
+#define AVF_CAP_PHY_TYPE_1000BASE_T_OPTICAL \
+ BIT_ULL(AVF_PHY_TYPE_1000BASE_T_OPTICAL)
+#define AVF_CAP_PHY_TYPE_20GBASE_KR2 BIT_ULL(AVF_PHY_TYPE_20GBASE_KR2)
+/*
+ * Defining the macro AVF_TYPE_OFFSET to implement a bit shift for some
+ * PHY types. There is an unused bit (31) in the AVF_CAP_PHY_TYPE_* bit
+ * fields but no corresponding gap in the avf_aq_phy_type enumeration. So,
+ * a shift is needed to adjust for this with values larger than 31. The
+ * only affected values are AVF_PHY_TYPE_25GBASE_*.
+ */
+#define AVF_PHY_TYPE_OFFSET 1
+#define AVF_CAP_PHY_TYPE_25GBASE_KR BIT_ULL(AVF_PHY_TYPE_25GBASE_KR + \
+ AVF_PHY_TYPE_OFFSET)
+#define AVF_CAP_PHY_TYPE_25GBASE_CR BIT_ULL(AVF_PHY_TYPE_25GBASE_CR + \
+ AVF_PHY_TYPE_OFFSET)
+#define AVF_CAP_PHY_TYPE_25GBASE_SR BIT_ULL(AVF_PHY_TYPE_25GBASE_SR + \
+ AVF_PHY_TYPE_OFFSET)
+#define AVF_CAP_PHY_TYPE_25GBASE_LR BIT_ULL(AVF_PHY_TYPE_25GBASE_LR + \
+ AVF_PHY_TYPE_OFFSET)
+#define AVF_CAP_PHY_TYPE_25GBASE_AOC BIT_ULL(AVF_PHY_TYPE_25GBASE_AOC + \
+ AVF_PHY_TYPE_OFFSET)
+#define AVF_CAP_PHY_TYPE_25GBASE_ACC BIT_ULL(AVF_PHY_TYPE_25GBASE_ACC + \
+ AVF_PHY_TYPE_OFFSET)
+#define AVF_HW_CAP_MAX_GPIO 30
+#define AVF_HW_CAP_MDIO_PORT_MODE_MDIO 0
+#define AVF_HW_CAP_MDIO_PORT_MODE_I2C 1
+
+enum avf_acpi_programming_method {
+ AVF_ACPI_PROGRAMMING_METHOD_HW_FVL = 0,
+ AVF_ACPI_PROGRAMMING_METHOD_AQC_FPK = 1
+};
+
+#define AVF_WOL_SUPPORT_MASK 0x1
+#define AVF_ACPI_PROGRAMMING_METHOD_MASK 0x2
+#define AVF_PROXY_SUPPORT_MASK 0x4
+
+/* Capabilities of a PF or a VF or the whole device */
+struct avf_hw_capabilities {
+ u32 switch_mode;
+#define AVF_NVM_IMAGE_TYPE_EVB 0x0
+#define AVF_NVM_IMAGE_TYPE_CLOUD 0x2
+#define AVF_NVM_IMAGE_TYPE_UDP_CLOUD 0x3
+
+ u32 management_mode;
+ u32 mng_protocols_over_mctp;
+#define AVF_MNG_PROTOCOL_PLDM 0x2
+#define AVF_MNG_PROTOCOL_OEM_COMMANDS 0x4
+#define AVF_MNG_PROTOCOL_NCSI 0x8
+ u32 npar_enable;
+ u32 os2bmc;
+ u32 valid_functions;
+ bool sr_iov_1_1;
+ bool vmdq;
+ bool evb_802_1_qbg; /* Edge Virtual Bridging */
+ bool evb_802_1_qbh; /* Bridge Port Extension */
+ bool dcb;
+ bool fcoe;
+ bool iscsi; /* Indicates iSCSI enabled */
+ bool flex10_enable;
+ bool flex10_capable;
+ u32 flex10_mode;
+#define AVF_FLEX10_MODE_UNKNOWN 0x0
+#define AVF_FLEX10_MODE_DCC 0x1
+#define AVF_FLEX10_MODE_DCI 0x2
+
+ u32 flex10_status;
+#define AVF_FLEX10_STATUS_DCC_ERROR 0x1
+#define AVF_FLEX10_STATUS_VC_MODE 0x2
+
+ bool sec_rev_disabled;
+ bool update_disabled;
+#define AVF_NVM_MGMT_SEC_REV_DISABLED 0x1
+#define AVF_NVM_MGMT_UPDATE_DISABLED 0x2
+
+ bool mgmt_cem;
+ bool ieee_1588;
+ bool iwarp;
+ bool fd;
+ u32 fd_filters_guaranteed;
+ u32 fd_filters_best_effort;
+ bool rss;
+ u32 rss_table_size;
+ u32 rss_table_entry_width;
+ bool led[AVF_HW_CAP_MAX_GPIO];
+ bool sdp[AVF_HW_CAP_MAX_GPIO];
+ u32 nvm_image_type;
+ u32 num_flow_director_filters;
+ u32 num_vfs;
+ u32 vf_base_id;
+ u32 num_vsis;
+ u32 num_rx_qp;
+ u32 num_tx_qp;
+ u32 base_queue;
+ u32 num_msix_vectors;
+ u32 num_msix_vectors_vf;
+ u32 led_pin_num;
+ u32 sdp_pin_num;
+ u32 mdio_port_num;
+ u32 mdio_port_mode;
+ u8 rx_buf_chain_len;
+ u32 enabled_tcmap;
+ u32 maxtc;
+ u64 wr_csr_prot;
+ bool apm_wol_support;
+ enum avf_acpi_programming_method acpi_prog_method;
+ bool proxy_support;
+};
+
+struct avf_mac_info {
+ enum avf_mac_type type;
+ u8 addr[ETH_ALEN];
+ u8 perm_addr[ETH_ALEN];
+ u8 san_addr[ETH_ALEN];
+ u8 port_addr[ETH_ALEN];
+ u16 max_fcoeq;
+};
+
+enum avf_aq_resources_ids {
+ AVF_NVM_RESOURCE_ID = 1
+};
+
+enum avf_aq_resource_access_type {
+ AVF_RESOURCE_READ = 1,
+ AVF_RESOURCE_WRITE
+};
+
+struct avf_nvm_info {
+ u64 hw_semaphore_timeout; /* usec global time (GTIME resolution) */
+ u32 timeout; /* [ms] */
+ u16 sr_size; /* Shadow RAM size in words */
+ bool blank_nvm_mode; /* is NVM empty (no FW present)*/
+ u16 version; /* NVM package version */
+ u32 eetrack; /* NVM data version */
+ u32 oem_ver; /* OEM version info */
+};
+
+/* definitions used in NVM update support */
+
+enum avf_nvmupd_cmd {
+ AVF_NVMUPD_INVALID,
+ AVF_NVMUPD_READ_CON,
+ AVF_NVMUPD_READ_SNT,
+ AVF_NVMUPD_READ_LCB,
+ AVF_NVMUPD_READ_SA,
+ AVF_NVMUPD_WRITE_ERA,
+ AVF_NVMUPD_WRITE_CON,
+ AVF_NVMUPD_WRITE_SNT,
+ AVF_NVMUPD_WRITE_LCB,
+ AVF_NVMUPD_WRITE_SA,
+ AVF_NVMUPD_CSUM_CON,
+ AVF_NVMUPD_CSUM_SA,
+ AVF_NVMUPD_CSUM_LCB,
+ AVF_NVMUPD_STATUS,
+ AVF_NVMUPD_EXEC_AQ,
+ AVF_NVMUPD_GET_AQ_RESULT,
+ AVF_NVMUPD_GET_AQ_EVENT,
+};
+
+enum avf_nvmupd_state {
+ AVF_NVMUPD_STATE_INIT,
+ AVF_NVMUPD_STATE_READING,
+ AVF_NVMUPD_STATE_WRITING,
+ AVF_NVMUPD_STATE_INIT_WAIT,
+ AVF_NVMUPD_STATE_WRITE_WAIT,
+ AVF_NVMUPD_STATE_ERROR
+};
+
+/* nvm_access definition and its masks/shifts need to be accessible to
+ * application, core driver, and shared code. Where is the right file?
+ */
+#define AVF_NVM_READ 0xB
+#define AVF_NVM_WRITE 0xC
+
+#define AVF_NVM_MOD_PNT_MASK 0xFF
+
+#define AVF_NVM_TRANS_SHIFT 8
+#define AVF_NVM_TRANS_MASK (0xf << AVF_NVM_TRANS_SHIFT)
+#define AVF_NVM_PRESERVATION_FLAGS_SHIFT 12
+#define AVF_NVM_PRESERVATION_FLAGS_MASK \
+ (0x3 << AVF_NVM_PRESERVATION_FLAGS_SHIFT)
+#define AVF_NVM_PRESERVATION_FLAGS_SELECTED 0x01
+#define AVF_NVM_PRESERVATION_FLAGS_ALL 0x02
+#define AVF_NVM_CON 0x0
+#define AVF_NVM_SNT 0x1
+#define AVF_NVM_LCB 0x2
+#define AVF_NVM_SA (AVF_NVM_SNT | AVF_NVM_LCB)
+#define AVF_NVM_ERA 0x4
+#define AVF_NVM_CSUM 0x8
+#define AVF_NVM_AQE 0xe
+#define AVF_NVM_EXEC 0xf
+
+#define AVF_NVM_ADAPT_SHIFT 16
+#define AVF_NVM_ADAPT_MASK (0xffffULL << AVF_NVM_ADAPT_SHIFT)
+
+#define AVF_NVMUPD_MAX_DATA 4096
+#define AVF_NVMUPD_IFACE_TIMEOUT 2 /* seconds */
+
+struct avf_nvm_access {
+ u32 command;
+ u32 config;
+ u32 offset; /* in bytes */
+ u32 data_size; /* in bytes */
+ u8 data[1];
+};
+
+/* (Q)SFP module access definitions */
+#define AVF_I2C_EEPROM_DEV_ADDR 0xA0
+#define AVF_I2C_EEPROM_DEV_ADDR2 0xA2
+#define AVF_MODULE_TYPE_ADDR 0x00
+#define AVF_MODULE_REVISION_ADDR 0x01
+#define AVF_MODULE_SFF_8472_COMP 0x5E
+#define AVF_MODULE_SFF_8472_SWAP 0x5C
+#define AVF_MODULE_SFF_ADDR_MODE 0x04
+#define AVF_MODULE_SFF_DIAG_CAPAB 0x40
+#define AVF_MODULE_TYPE_QSFP_PLUS 0x0D
+#define AVF_MODULE_TYPE_QSFP28 0x11
+#define AVF_MODULE_QSFP_MAX_LEN 640
+
+/* PCI bus types */
+enum avf_bus_type {
+ avf_bus_type_unknown = 0,
+ avf_bus_type_pci,
+ avf_bus_type_pcix,
+ avf_bus_type_pci_express,
+ avf_bus_type_reserved
+};
+
+/* PCI bus speeds */
+enum avf_bus_speed {
+ avf_bus_speed_unknown = 0,
+ avf_bus_speed_33 = 33,
+ avf_bus_speed_66 = 66,
+ avf_bus_speed_100 = 100,
+ avf_bus_speed_120 = 120,
+ avf_bus_speed_133 = 133,
+ avf_bus_speed_2500 = 2500,
+ avf_bus_speed_5000 = 5000,
+ avf_bus_speed_8000 = 8000,
+ avf_bus_speed_reserved
+};
+
+/* PCI bus widths */
+enum avf_bus_width {
+ avf_bus_width_unknown = 0,
+ avf_bus_width_pcie_x1 = 1,
+ avf_bus_width_pcie_x2 = 2,
+ avf_bus_width_pcie_x4 = 4,
+ avf_bus_width_pcie_x8 = 8,
+ avf_bus_width_32 = 32,
+ avf_bus_width_64 = 64,
+ avf_bus_width_reserved
+};
+
+/* Bus parameters */
+struct avf_bus_info {
+ enum avf_bus_speed speed;
+ enum avf_bus_width width;
+ enum avf_bus_type type;
+
+ u16 func;
+ u16 device;
+ u16 lan_id;
+ u16 bus_id;
+};
+
+/* Flow control (FC) parameters */
+struct avf_fc_info {
+ enum avf_fc_mode current_mode; /* FC mode in effect */
+ enum avf_fc_mode requested_mode; /* FC mode requested by caller */
+};
+
+#define AVF_MAX_TRAFFIC_CLASS 8
+#define AVF_MAX_USER_PRIORITY 8
+#define AVF_DCBX_MAX_APPS 32
+#define AVF_LLDPDU_SIZE 1500
+#define AVF_TLV_STATUS_OPER 0x1
+#define AVF_TLV_STATUS_SYNC 0x2
+#define AVF_TLV_STATUS_ERR 0x4
+#define AVF_CEE_OPER_MAX_APPS 3
+#define AVF_APP_PROTOID_FCOE 0x8906
+#define AVF_APP_PROTOID_ISCSI 0x0cbc
+#define AVF_APP_PROTOID_FIP 0x8914
+#define AVF_APP_SEL_ETHTYPE 0x1
+#define AVF_APP_SEL_TCPIP 0x2
+#define AVF_CEE_APP_SEL_ETHTYPE 0x0
+#define AVF_CEE_APP_SEL_TCPIP 0x1
+
+/* CEE or IEEE 802.1Qaz ETS Configuration data */
+struct avf_dcb_ets_config {
+ u8 willing;
+ u8 cbs;
+ u8 maxtcs;
+ u8 prioritytable[AVF_MAX_TRAFFIC_CLASS];
+ u8 tcbwtable[AVF_MAX_TRAFFIC_CLASS];
+ u8 tsatable[AVF_MAX_TRAFFIC_CLASS];
+};
+
+/* CEE or IEEE 802.1Qaz PFC Configuration data */
+struct avf_dcb_pfc_config {
+ u8 willing;
+ u8 mbc;
+ u8 pfccap;
+ u8 pfcenable;
+};
+
+/* CEE or IEEE 802.1Qaz Application Priority data */
+struct avf_dcb_app_priority_table {
+ u8 priority;
+ u8 selector;
+ u16 protocolid;
+};
+
+struct avf_dcbx_config {
+ u8 dcbx_mode;
+#define AVF_DCBX_MODE_CEE 0x1
+#define AVF_DCBX_MODE_IEEE 0x2
+ u8 app_mode;
+#define AVF_DCBX_APPS_NON_WILLING 0x1
+ u32 numapps;
+ u32 tlv_status; /* CEE mode TLV status */
+ struct avf_dcb_ets_config etscfg;
+ struct avf_dcb_ets_config etsrec;
+ struct avf_dcb_pfc_config pfc;
+ struct avf_dcb_app_priority_table app[AVF_DCBX_MAX_APPS];
+};
+
+/* Port hardware description */
+struct avf_hw {
+ u8 *hw_addr;
+ void *back;
+
+ /* subsystem structs */
+ struct avf_phy_info phy;
+ struct avf_mac_info mac;
+ struct avf_bus_info bus;
+ struct avf_nvm_info nvm;
+ struct avf_fc_info fc;
+
+ /* pci info */
+ u16 device_id;
+ u16 vendor_id;
+ u16 subsystem_device_id;
+ u16 subsystem_vendor_id;
+ u8 revision_id;
+ u8 port;
+ bool adapter_stopped;
+
+ /* capabilities for entire device and PCI func */
+ struct avf_hw_capabilities dev_caps;
+ struct avf_hw_capabilities func_caps;
+
+ /* Flow Director shared filter space */
+ u16 fdir_shared_filter_count;
+
+ /* device profile info */
+ u8 pf_id;
+ u16 main_vsi_seid;
+
+ /* for multi-function MACs */
+ u16 partition_id;
+ u16 num_partitions;
+ u16 num_ports;
+
+ /* Closest numa node to the device */
+ u16 numa_node;
+
+ /* Admin Queue info */
+ struct avf_adminq_info aq;
+
+ /* state of nvm update process */
+ enum avf_nvmupd_state nvmupd_state;
+ struct avf_aq_desc nvm_wb_desc;
+ struct avf_aq_desc nvm_aq_event_desc;
+ struct avf_virt_mem nvm_buff;
+ bool nvm_release_on_done;
+ u16 nvm_wait_opcode;
+
+ /* HMC info */
+ struct avf_hmc_info hmc; /* HMC info struct */
+
+ /* LLDP/DCBX Status */
+ u16 dcbx_status;
+
+ /* DCBX info */
+ struct avf_dcbx_config local_dcbx_config; /* Oper/Local Cfg */
+ struct avf_dcbx_config remote_dcbx_config; /* Peer Cfg */
+ struct avf_dcbx_config desired_dcbx_config; /* CEE Desired Cfg */
+
+ /* WoL and proxy support */
+ u16 num_wol_proxy_filters;
+ u16 wol_proxy_vsi_seid;
+
+#define AVF_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE BIT_ULL(0)
+#define AVF_HW_FLAG_802_1AD_CAPABLE BIT_ULL(1)
+#define AVF_HW_FLAG_AQ_PHY_ACCESS_CAPABLE BIT_ULL(2)
+#define AVF_HW_FLAG_NVM_READ_REQUIRES_LOCK BIT_ULL(3)
+ u64 flags;
+
+ /* Used in set switch config AQ command */
+ u16 switch_tag;
+ u16 first_tag;
+ u16 second_tag;
+
+ /* debug mask */
+ u32 debug_mask;
+ char err_str[16];
+};
+
+STATIC INLINE bool avf_is_vf(struct avf_hw *hw)
+{
+ return (hw->mac.type == AVF_MAC_VF ||
+ hw->mac.type == AVF_MAC_X722_VF);
+}
+
+struct avf_driver_version {
+ u8 major_version;
+ u8 minor_version;
+ u8 build_version;
+ u8 subbuild_version;
+ u8 driver_string[32];
+};
+
+/* RX Descriptors */
+union avf_16byte_rx_desc {
+ struct {
+ __le64 pkt_addr; /* Packet buffer address */
+ __le64 hdr_addr; /* Header buffer address */
+ } read;
+ struct {
+ struct {
+ struct {
+ union {
+ __le16 mirroring_status;
+ __le16 fcoe_ctx_id;
+ } mirr_fcoe;
+ __le16 l2tag1;
+ } lo_dword;
+ union {
+ __le32 rss; /* RSS Hash */
+ __le32 fd_id; /* Flow director filter id */
+ __le32 fcoe_param; /* FCoE DDP Context id */
+ } hi_dword;
+ } qword0;
+ struct {
+ /* ext status/error/pktype/length */
+ __le64 status_error_len;
+ } qword1;
+ } wb; /* writeback */
+};
+
+union avf_32byte_rx_desc {
+ struct {
+ __le64 pkt_addr; /* Packet buffer address */
+ __le64 hdr_addr; /* Header buffer address */
+ /* bit 0 of hdr_buffer_addr is DD bit */
+ __le64 rsvd1;
+ __le64 rsvd2;
+ } read;
+ struct {
+ struct {
+ struct {
+ union {
+ __le16 mirroring_status;
+ __le16 fcoe_ctx_id;
+ } mirr_fcoe;
+ __le16 l2tag1;
+ } lo_dword;
+ union {
+ __le32 rss; /* RSS Hash */
+ __le32 fcoe_param; /* FCoE DDP Context id */
+ /* Flow director filter id in case of
+ * Programming status desc WB
+ */
+ __le32 fd_id;
+ } hi_dword;
+ } qword0;
+ struct {
+ /* status/error/pktype/length */
+ __le64 status_error_len;
+ } qword1;
+ struct {
+ __le16 ext_status; /* extended status */
+ __le16 rsvd;
+ __le16 l2tag2_1;
+ __le16 l2tag2_2;
+ } qword2;
+ struct {
+ union {
+ __le32 flex_bytes_lo;
+ __le32 pe_status;
+ } lo_dword;
+ union {
+ __le32 flex_bytes_hi;
+ __le32 fd_id;
+ } hi_dword;
+ } qword3;
+ } wb; /* writeback */
+};
+
+#define AVF_RXD_QW0_MIRROR_STATUS_SHIFT 8
+#define AVF_RXD_QW0_MIRROR_STATUS_MASK (0x3FUL << \
+ AVF_RXD_QW0_MIRROR_STATUS_SHIFT)
+#define AVF_RXD_QW0_FCOEINDX_SHIFT 0
+#define AVF_RXD_QW0_FCOEINDX_MASK (0xFFFUL << \
+ AVF_RXD_QW0_FCOEINDX_SHIFT)
+
+enum avf_rx_desc_status_bits {
+ /* Note: These are predefined bit offsets */
+ AVF_RX_DESC_STATUS_DD_SHIFT = 0,
+ AVF_RX_DESC_STATUS_EOF_SHIFT = 1,
+ AVF_RX_DESC_STATUS_L2TAG1P_SHIFT = 2,
+ AVF_RX_DESC_STATUS_L3L4P_SHIFT = 3,
+ AVF_RX_DESC_STATUS_CRCP_SHIFT = 4,
+ AVF_RX_DESC_STATUS_TSYNINDX_SHIFT = 5, /* 2 BITS */
+ AVF_RX_DESC_STATUS_TSYNVALID_SHIFT = 7,
+ AVF_RX_DESC_STATUS_EXT_UDP_0_SHIFT = 8,
+
+ AVF_RX_DESC_STATUS_UMBCAST_SHIFT = 9, /* 2 BITS */
+ AVF_RX_DESC_STATUS_FLM_SHIFT = 11,
+ AVF_RX_DESC_STATUS_FLTSTAT_SHIFT = 12, /* 2 BITS */
+ AVF_RX_DESC_STATUS_LPBK_SHIFT = 14,
+ AVF_RX_DESC_STATUS_IPV6EXADD_SHIFT = 15,
+ AVF_RX_DESC_STATUS_RESERVED2_SHIFT = 16, /* 2 BITS */
+ AVF_RX_DESC_STATUS_INT_UDP_0_SHIFT = 18,
+ AVF_RX_DESC_STATUS_LAST /* this entry must be last!!! */
+};
+
+#define AVF_RXD_QW1_STATUS_SHIFT 0
+#define AVF_RXD_QW1_STATUS_MASK ((BIT(AVF_RX_DESC_STATUS_LAST) - 1) << \
+ AVF_RXD_QW1_STATUS_SHIFT)
+
+#define AVF_RXD_QW1_STATUS_TSYNINDX_SHIFT AVF_RX_DESC_STATUS_TSYNINDX_SHIFT
+#define AVF_RXD_QW1_STATUS_TSYNINDX_MASK (0x3UL << \
+ AVF_RXD_QW1_STATUS_TSYNINDX_SHIFT)
+
+#define AVF_RXD_QW1_STATUS_TSYNVALID_SHIFT AVF_RX_DESC_STATUS_TSYNVALID_SHIFT
+#define AVF_RXD_QW1_STATUS_TSYNVALID_MASK BIT_ULL(AVF_RXD_QW1_STATUS_TSYNVALID_SHIFT)
+
+#define AVF_RXD_QW1_STATUS_UMBCAST_SHIFT AVF_RX_DESC_STATUS_UMBCAST
+#define AVF_RXD_QW1_STATUS_UMBCAST_MASK (0x3UL << \
+ AVF_RXD_QW1_STATUS_UMBCAST_SHIFT)
+
+enum avf_rx_desc_fltstat_values {
+ AVF_RX_DESC_FLTSTAT_NO_DATA = 0,
+ AVF_RX_DESC_FLTSTAT_RSV_FD_ID = 1, /* 16byte desc? FD_ID : RSV */
+ AVF_RX_DESC_FLTSTAT_RSV = 2,
+ AVF_RX_DESC_FLTSTAT_RSS_HASH = 3,
+};
+
+#define AVF_RXD_PACKET_TYPE_UNICAST 0
+#define AVF_RXD_PACKET_TYPE_MULTICAST 1
+#define AVF_RXD_PACKET_TYPE_BROADCAST 2
+#define AVF_RXD_PACKET_TYPE_MIRRORED 3
+
+#define AVF_RXD_QW1_ERROR_SHIFT 19
+#define AVF_RXD_QW1_ERROR_MASK (0xFFUL << AVF_RXD_QW1_ERROR_SHIFT)
+
+enum avf_rx_desc_error_bits {
+ /* Note: These are predefined bit offsets */
+ AVF_RX_DESC_ERROR_RXE_SHIFT = 0,
+ AVF_RX_DESC_ERROR_RECIPE_SHIFT = 1,
+ AVF_RX_DESC_ERROR_HBO_SHIFT = 2,
+ AVF_RX_DESC_ERROR_L3L4E_SHIFT = 3, /* 3 BITS */
+ AVF_RX_DESC_ERROR_IPE_SHIFT = 3,
+ AVF_RX_DESC_ERROR_L4E_SHIFT = 4,
+ AVF_RX_DESC_ERROR_EIPE_SHIFT = 5,
+ AVF_RX_DESC_ERROR_OVERSIZE_SHIFT = 6,
+ AVF_RX_DESC_ERROR_PPRS_SHIFT = 7
+};
+
+enum avf_rx_desc_error_l3l4e_fcoe_masks {
+ AVF_RX_DESC_ERROR_L3L4E_NONE = 0,
+ AVF_RX_DESC_ERROR_L3L4E_PROT = 1,
+ AVF_RX_DESC_ERROR_L3L4E_FC = 2,
+ AVF_RX_DESC_ERROR_L3L4E_DMAC_ERR = 3,
+ AVF_RX_DESC_ERROR_L3L4E_DMAC_WARN = 4
+};
+
+#define AVF_RXD_QW1_PTYPE_SHIFT 30
+#define AVF_RXD_QW1_PTYPE_MASK (0xFFULL << AVF_RXD_QW1_PTYPE_SHIFT)
+
+/* Packet type non-ip values */
+enum avf_rx_l2_ptype {
+ AVF_RX_PTYPE_L2_RESERVED = 0,
+ AVF_RX_PTYPE_L2_MAC_PAY2 = 1,
+ AVF_RX_PTYPE_L2_TIMESYNC_PAY2 = 2,
+ AVF_RX_PTYPE_L2_FIP_PAY2 = 3,
+ AVF_RX_PTYPE_L2_OUI_PAY2 = 4,
+ AVF_RX_PTYPE_L2_MACCNTRL_PAY2 = 5,
+ AVF_RX_PTYPE_L2_LLDP_PAY2 = 6,
+ AVF_RX_PTYPE_L2_ECP_PAY2 = 7,
+ AVF_RX_PTYPE_L2_EVB_PAY2 = 8,
+ AVF_RX_PTYPE_L2_QCN_PAY2 = 9,
+ AVF_RX_PTYPE_L2_EAPOL_PAY2 = 10,
+ AVF_RX_PTYPE_L2_ARP = 11,
+ AVF_RX_PTYPE_L2_FCOE_PAY3 = 12,
+ AVF_RX_PTYPE_L2_FCOE_FCDATA_PAY3 = 13,
+ AVF_RX_PTYPE_L2_FCOE_FCRDY_PAY3 = 14,
+ AVF_RX_PTYPE_L2_FCOE_FCRSP_PAY3 = 15,
+ AVF_RX_PTYPE_L2_FCOE_FCOTHER_PA = 16,
+ AVF_RX_PTYPE_L2_FCOE_VFT_PAY3 = 17,
+ AVF_RX_PTYPE_L2_FCOE_VFT_FCDATA = 18,
+ AVF_RX_PTYPE_L2_FCOE_VFT_FCRDY = 19,
+ AVF_RX_PTYPE_L2_FCOE_VFT_FCRSP = 20,
+ AVF_RX_PTYPE_L2_FCOE_VFT_FCOTHER = 21,
+ AVF_RX_PTYPE_GRENAT4_MAC_PAY3 = 58,
+ AVF_RX_PTYPE_GRENAT4_MACVLAN_IPV6_ICMP_PAY4 = 87,
+ AVF_RX_PTYPE_GRENAT6_MAC_PAY3 = 124,
+ AVF_RX_PTYPE_GRENAT6_MACVLAN_IPV6_ICMP_PAY4 = 153
+};
+
+struct avf_rx_ptype_decoded {
+ u32 ptype:8;
+ u32 known:1;
+ u32 outer_ip:1;
+ u32 outer_ip_ver:1;
+ u32 outer_frag:1;
+ u32 tunnel_type:3;
+ u32 tunnel_end_prot:2;
+ u32 tunnel_end_frag:1;
+ u32 inner_prot:4;
+ u32 payload_layer:3;
+};
+
+enum avf_rx_ptype_outer_ip {
+ AVF_RX_PTYPE_OUTER_L2 = 0,
+ AVF_RX_PTYPE_OUTER_IP = 1
+};
+
+enum avf_rx_ptype_outer_ip_ver {
+ AVF_RX_PTYPE_OUTER_NONE = 0,
+ AVF_RX_PTYPE_OUTER_IPV4 = 0,
+ AVF_RX_PTYPE_OUTER_IPV6 = 1
+};
+
+enum avf_rx_ptype_outer_fragmented {
+ AVF_RX_PTYPE_NOT_FRAG = 0,
+ AVF_RX_PTYPE_FRAG = 1
+};
+
+enum avf_rx_ptype_tunnel_type {
+ AVF_RX_PTYPE_TUNNEL_NONE = 0,
+ AVF_RX_PTYPE_TUNNEL_IP_IP = 1,
+ AVF_RX_PTYPE_TUNNEL_IP_GRENAT = 2,
+ AVF_RX_PTYPE_TUNNEL_IP_GRENAT_MAC = 3,
+ AVF_RX_PTYPE_TUNNEL_IP_GRENAT_MAC_VLAN = 4,
+};
+
+enum avf_rx_ptype_tunnel_end_prot {
+ AVF_RX_PTYPE_TUNNEL_END_NONE = 0,
+ AVF_RX_PTYPE_TUNNEL_END_IPV4 = 1,
+ AVF_RX_PTYPE_TUNNEL_END_IPV6 = 2,
+};
+
+enum avf_rx_ptype_inner_prot {
+ AVF_RX_PTYPE_INNER_PROT_NONE = 0,
+ AVF_RX_PTYPE_INNER_PROT_UDP = 1,
+ AVF_RX_PTYPE_INNER_PROT_TCP = 2,
+ AVF_RX_PTYPE_INNER_PROT_SCTP = 3,
+ AVF_RX_PTYPE_INNER_PROT_ICMP = 4,
+ AVF_RX_PTYPE_INNER_PROT_TIMESYNC = 5
+};
+
+enum avf_rx_ptype_payload_layer {
+ AVF_RX_PTYPE_PAYLOAD_LAYER_NONE = 0,
+ AVF_RX_PTYPE_PAYLOAD_LAYER_PAY2 = 1,
+ AVF_RX_PTYPE_PAYLOAD_LAYER_PAY3 = 2,
+ AVF_RX_PTYPE_PAYLOAD_LAYER_PAY4 = 3,
+};
+
+#define AVF_RX_PTYPE_BIT_MASK 0x0FFFFFFF
+#define AVF_RX_PTYPE_SHIFT 56
+
+#define AVF_RXD_QW1_LENGTH_PBUF_SHIFT 38
+#define AVF_RXD_QW1_LENGTH_PBUF_MASK (0x3FFFULL << \
+ AVF_RXD_QW1_LENGTH_PBUF_SHIFT)
+
+#define AVF_RXD_QW1_LENGTH_HBUF_SHIFT 52
+#define AVF_RXD_QW1_LENGTH_HBUF_MASK (0x7FFULL << \
+ AVF_RXD_QW1_LENGTH_HBUF_SHIFT)
+
+#define AVF_RXD_QW1_LENGTH_SPH_SHIFT 63
+#define AVF_RXD_QW1_LENGTH_SPH_MASK BIT_ULL(AVF_RXD_QW1_LENGTH_SPH_SHIFT)
+
+#define AVF_RXD_QW1_NEXTP_SHIFT 38
+#define AVF_RXD_QW1_NEXTP_MASK (0x1FFFULL << AVF_RXD_QW1_NEXTP_SHIFT)
+
+#define AVF_RXD_QW2_EXT_STATUS_SHIFT 0
+#define AVF_RXD_QW2_EXT_STATUS_MASK (0xFFFFFUL << \
+ AVF_RXD_QW2_EXT_STATUS_SHIFT)
+
+enum avf_rx_desc_ext_status_bits {
+ /* Note: These are predefined bit offsets */
+ AVF_RX_DESC_EXT_STATUS_L2TAG2P_SHIFT = 0,
+ AVF_RX_DESC_EXT_STATUS_L2TAG3P_SHIFT = 1,
+ AVF_RX_DESC_EXT_STATUS_FLEXBL_SHIFT = 2, /* 2 BITS */
+ AVF_RX_DESC_EXT_STATUS_FLEXBH_SHIFT = 4, /* 2 BITS */
+ AVF_RX_DESC_EXT_STATUS_FDLONGB_SHIFT = 9,
+ AVF_RX_DESC_EXT_STATUS_FCOELONGB_SHIFT = 10,
+ AVF_RX_DESC_EXT_STATUS_PELONGB_SHIFT = 11,
+};
+
+#define AVF_RXD_QW2_L2TAG2_SHIFT 0
+#define AVF_RXD_QW2_L2TAG2_MASK (0xFFFFUL << AVF_RXD_QW2_L2TAG2_SHIFT)
+
+#define AVF_RXD_QW2_L2TAG3_SHIFT 16
+#define AVF_RXD_QW2_L2TAG3_MASK (0xFFFFUL << AVF_RXD_QW2_L2TAG3_SHIFT)
+
+enum avf_rx_desc_pe_status_bits {
+ /* Note: These are predefined bit offsets */
+ AVF_RX_DESC_PE_STATUS_QPID_SHIFT = 0, /* 18 BITS */
+ AVF_RX_DESC_PE_STATUS_L4PORT_SHIFT = 0, /* 16 BITS */
+ AVF_RX_DESC_PE_STATUS_IPINDEX_SHIFT = 16, /* 8 BITS */
+ AVF_RX_DESC_PE_STATUS_QPIDHIT_SHIFT = 24,
+ AVF_RX_DESC_PE_STATUS_APBVTHIT_SHIFT = 25,
+ AVF_RX_DESC_PE_STATUS_PORTV_SHIFT = 26,
+ AVF_RX_DESC_PE_STATUS_URG_SHIFT = 27,
+ AVF_RX_DESC_PE_STATUS_IPFRAG_SHIFT = 28,
+ AVF_RX_DESC_PE_STATUS_IPOPT_SHIFT = 29
+};
+
+#define AVF_RX_PROG_STATUS_DESC_LENGTH_SHIFT 38
+#define AVF_RX_PROG_STATUS_DESC_LENGTH 0x2000000
+
+#define AVF_RX_PROG_STATUS_DESC_QW1_PROGID_SHIFT 2
+#define AVF_RX_PROG_STATUS_DESC_QW1_PROGID_MASK (0x7UL << \
+ AVF_RX_PROG_STATUS_DESC_QW1_PROGID_SHIFT)
+
+#define AVF_RX_PROG_STATUS_DESC_QW1_STATUS_SHIFT 0
+#define AVF_RX_PROG_STATUS_DESC_QW1_STATUS_MASK (0x7FFFUL << \
+ AVF_RX_PROG_STATUS_DESC_QW1_STATUS_SHIFT)
+
+#define AVF_RX_PROG_STATUS_DESC_QW1_ERROR_SHIFT 19
+#define AVF_RX_PROG_STATUS_DESC_QW1_ERROR_MASK (0x3FUL << \
+ AVF_RX_PROG_STATUS_DESC_QW1_ERROR_SHIFT)
+
+enum avf_rx_prog_status_desc_status_bits {
+ /* Note: These are predefined bit offsets */
+ AVF_RX_PROG_STATUS_DESC_DD_SHIFT = 0,
+ AVF_RX_PROG_STATUS_DESC_PROG_ID_SHIFT = 2 /* 3 BITS */
+};
+
+enum avf_rx_prog_status_desc_prog_id_masks {
+ AVF_RX_PROG_STATUS_DESC_FD_FILTER_STATUS = 1,
+ AVF_RX_PROG_STATUS_DESC_FCOE_CTXT_PROG_STATUS = 2,
+ AVF_RX_PROG_STATUS_DESC_FCOE_CTXT_INVL_STATUS = 4,
+};
+
+enum avf_rx_prog_status_desc_error_bits {
+ /* Note: These are predefined bit offsets */
+ AVF_RX_PROG_STATUS_DESC_FD_TBL_FULL_SHIFT = 0,
+ AVF_RX_PROG_STATUS_DESC_NO_FD_ENTRY_SHIFT = 1,
+ AVF_RX_PROG_STATUS_DESC_FCOE_TBL_FULL_SHIFT = 2,
+ AVF_RX_PROG_STATUS_DESC_FCOE_CONFLICT_SHIFT = 3
+};
+
+#define AVF_TWO_BIT_MASK 0x3
+#define AVF_THREE_BIT_MASK 0x7
+#define AVF_FOUR_BIT_MASK 0xF
+#define AVF_EIGHTEEN_BIT_MASK 0x3FFFF
+
+/* TX Descriptor */
+struct avf_tx_desc {
+ __le64 buffer_addr; /* Address of descriptor's data buf */
+ __le64 cmd_type_offset_bsz;
+};
+
+#define AVF_TXD_QW1_DTYPE_SHIFT 0
+#define AVF_TXD_QW1_DTYPE_MASK (0xFUL << AVF_TXD_QW1_DTYPE_SHIFT)
+
+enum avf_tx_desc_dtype_value {
+ AVF_TX_DESC_DTYPE_DATA = 0x0,
+ AVF_TX_DESC_DTYPE_NOP = 0x1, /* same as Context desc */
+ AVF_TX_DESC_DTYPE_CONTEXT = 0x1,
+ AVF_TX_DESC_DTYPE_FCOE_CTX = 0x2,
+ AVF_TX_DESC_DTYPE_FILTER_PROG = 0x8,
+ AVF_TX_DESC_DTYPE_DDP_CTX = 0x9,
+ AVF_TX_DESC_DTYPE_FLEX_DATA = 0xB,
+ AVF_TX_DESC_DTYPE_FLEX_CTX_1 = 0xC,
+ AVF_TX_DESC_DTYPE_FLEX_CTX_2 = 0xD,
+ AVF_TX_DESC_DTYPE_DESC_DONE = 0xF
+};
+
+#define AVF_TXD_QW1_CMD_SHIFT 4
+#define AVF_TXD_QW1_CMD_MASK (0x3FFUL << AVF_TXD_QW1_CMD_SHIFT)
+
+enum avf_tx_desc_cmd_bits {
+ AVF_TX_DESC_CMD_EOP = 0x0001,
+ AVF_TX_DESC_CMD_RS = 0x0002,
+ AVF_TX_DESC_CMD_ICRC = 0x0004,
+ AVF_TX_DESC_CMD_IL2TAG1 = 0x0008,
+ AVF_TX_DESC_CMD_DUMMY = 0x0010,
+ AVF_TX_DESC_CMD_IIPT_NONIP = 0x0000, /* 2 BITS */
+ AVF_TX_DESC_CMD_IIPT_IPV6 = 0x0020, /* 2 BITS */
+ AVF_TX_DESC_CMD_IIPT_IPV4 = 0x0040, /* 2 BITS */
+ AVF_TX_DESC_CMD_IIPT_IPV4_CSUM = 0x0060, /* 2 BITS */
+ AVF_TX_DESC_CMD_FCOET = 0x0080,
+ AVF_TX_DESC_CMD_L4T_EOFT_UNK = 0x0000, /* 2 BITS */
+ AVF_TX_DESC_CMD_L4T_EOFT_TCP = 0x0100, /* 2 BITS */
+ AVF_TX_DESC_CMD_L4T_EOFT_SCTP = 0x0200, /* 2 BITS */
+ AVF_TX_DESC_CMD_L4T_EOFT_UDP = 0x0300, /* 2 BITS */
+ AVF_TX_DESC_CMD_L4T_EOFT_EOF_N = 0x0000, /* 2 BITS */
+ AVF_TX_DESC_CMD_L4T_EOFT_EOF_T = 0x0100, /* 2 BITS */
+ AVF_TX_DESC_CMD_L4T_EOFT_EOF_NI = 0x0200, /* 2 BITS */
+ AVF_TX_DESC_CMD_L4T_EOFT_EOF_A = 0x0300, /* 2 BITS */
+};
+
+#define AVF_TXD_QW1_OFFSET_SHIFT 16
+#define AVF_TXD_QW1_OFFSET_MASK (0x3FFFFULL << \
+ AVF_TXD_QW1_OFFSET_SHIFT)
+
+enum avf_tx_desc_length_fields {
+ /* Note: These are predefined bit offsets */
+ AVF_TX_DESC_LENGTH_MACLEN_SHIFT = 0, /* 7 BITS */
+ AVF_TX_DESC_LENGTH_IPLEN_SHIFT = 7, /* 7 BITS */
+ AVF_TX_DESC_LENGTH_L4_FC_LEN_SHIFT = 14 /* 4 BITS */
+};
+
+#define AVF_TXD_QW1_MACLEN_MASK (0x7FUL << AVF_TX_DESC_LENGTH_MACLEN_SHIFT)
+#define AVF_TXD_QW1_IPLEN_MASK (0x7FUL << AVF_TX_DESC_LENGTH_IPLEN_SHIFT)
+#define AVF_TXD_QW1_L4LEN_MASK (0xFUL << AVF_TX_DESC_LENGTH_L4_FC_LEN_SHIFT)
+#define AVF_TXD_QW1_FCLEN_MASK (0xFUL << AVF_TX_DESC_LENGTH_L4_FC_LEN_SHIFT)
+
+#define AVF_TXD_QW1_TX_BUF_SZ_SHIFT 34
+#define AVF_TXD_QW1_TX_BUF_SZ_MASK (0x3FFFULL << \
+ AVF_TXD_QW1_TX_BUF_SZ_SHIFT)
+
+#define AVF_TXD_QW1_L2TAG1_SHIFT 48
+#define AVF_TXD_QW1_L2TAG1_MASK (0xFFFFULL << AVF_TXD_QW1_L2TAG1_SHIFT)
+
+/* Context descriptors */
+struct avf_tx_context_desc {
+ __le32 tunneling_params;
+ __le16 l2tag2;
+ __le16 rsvd;
+ __le64 type_cmd_tso_mss;
+};
+
+#define AVF_TXD_CTX_QW1_DTYPE_SHIFT 0
+#define AVF_TXD_CTX_QW1_DTYPE_MASK (0xFUL << AVF_TXD_CTX_QW1_DTYPE_SHIFT)
+
+#define AVF_TXD_CTX_QW1_CMD_SHIFT 4
+#define AVF_TXD_CTX_QW1_CMD_MASK (0xFFFFUL << AVF_TXD_CTX_QW1_CMD_SHIFT)
+
+enum avf_tx_ctx_desc_cmd_bits {
+ AVF_TX_CTX_DESC_TSO = 0x01,
+ AVF_TX_CTX_DESC_TSYN = 0x02,
+ AVF_TX_CTX_DESC_IL2TAG2 = 0x04,
+ AVF_TX_CTX_DESC_IL2TAG2_IL2H = 0x08,
+ AVF_TX_CTX_DESC_SWTCH_NOTAG = 0x00,
+ AVF_TX_CTX_DESC_SWTCH_UPLINK = 0x10,
+ AVF_TX_CTX_DESC_SWTCH_LOCAL = 0x20,
+ AVF_TX_CTX_DESC_SWTCH_VSI = 0x30,
+ AVF_TX_CTX_DESC_SWPE = 0x40
+};
+
+#define AVF_TXD_CTX_QW1_TSO_LEN_SHIFT 30
+#define AVF_TXD_CTX_QW1_TSO_LEN_MASK (0x3FFFFULL << \
+ AVF_TXD_CTX_QW1_TSO_LEN_SHIFT)
+
+#define AVF_TXD_CTX_QW1_MSS_SHIFT 50
+#define AVF_TXD_CTX_QW1_MSS_MASK (0x3FFFULL << \
+ AVF_TXD_CTX_QW1_MSS_SHIFT)
+
+#define AVF_TXD_CTX_QW1_VSI_SHIFT 50
+#define AVF_TXD_CTX_QW1_VSI_MASK (0x1FFULL << AVF_TXD_CTX_QW1_VSI_SHIFT)
+
+#define AVF_TXD_CTX_QW0_EXT_IP_SHIFT 0
+#define AVF_TXD_CTX_QW0_EXT_IP_MASK (0x3ULL << \
+ AVF_TXD_CTX_QW0_EXT_IP_SHIFT)
+
+enum avf_tx_ctx_desc_eipt_offload {
+ AVF_TX_CTX_EXT_IP_NONE = 0x0,
+ AVF_TX_CTX_EXT_IP_IPV6 = 0x1,
+ AVF_TX_CTX_EXT_IP_IPV4_NO_CSUM = 0x2,
+ AVF_TX_CTX_EXT_IP_IPV4 = 0x3
+};
+
+#define AVF_TXD_CTX_QW0_EXT_IPLEN_SHIFT 2
+#define AVF_TXD_CTX_QW0_EXT_IPLEN_MASK (0x3FULL << \
+ AVF_TXD_CTX_QW0_EXT_IPLEN_SHIFT)
+
+#define AVF_TXD_CTX_QW0_NATT_SHIFT 9
+#define AVF_TXD_CTX_QW0_NATT_MASK (0x3ULL << AVF_TXD_CTX_QW0_NATT_SHIFT)
+
+#define AVF_TXD_CTX_UDP_TUNNELING BIT_ULL(AVF_TXD_CTX_QW0_NATT_SHIFT)
+#define AVF_TXD_CTX_GRE_TUNNELING (0x2ULL << AVF_TXD_CTX_QW0_NATT_SHIFT)
+
+#define AVF_TXD_CTX_QW0_EIP_NOINC_SHIFT 11
+#define AVF_TXD_CTX_QW0_EIP_NOINC_MASK BIT_ULL(AVF_TXD_CTX_QW0_EIP_NOINC_SHIFT)
+
+#define AVF_TXD_CTX_EIP_NOINC_IPID_CONST AVF_TXD_CTX_QW0_EIP_NOINC_MASK
+
+#define AVF_TXD_CTX_QW0_NATLEN_SHIFT 12
+#define AVF_TXD_CTX_QW0_NATLEN_MASK (0X7FULL << \
+ AVF_TXD_CTX_QW0_NATLEN_SHIFT)
+
+#define AVF_TXD_CTX_QW0_DECTTL_SHIFT 19
+#define AVF_TXD_CTX_QW0_DECTTL_MASK (0xFULL << \
+ AVF_TXD_CTX_QW0_DECTTL_SHIFT)
+
+#define AVF_TXD_CTX_QW0_L4T_CS_SHIFT 23
+#define AVF_TXD_CTX_QW0_L4T_CS_MASK BIT_ULL(AVF_TXD_CTX_QW0_L4T_CS_SHIFT)
+struct avf_nop_desc {
+ __le64 rsvd;
+ __le64 dtype_cmd;
+};
+
+#define AVF_TXD_NOP_QW1_DTYPE_SHIFT 0
+#define AVF_TXD_NOP_QW1_DTYPE_MASK (0xFUL << AVF_TXD_NOP_QW1_DTYPE_SHIFT)
+
+#define AVF_TXD_NOP_QW1_CMD_SHIFT 4
+#define AVF_TXD_NOP_QW1_CMD_MASK (0x7FUL << AVF_TXD_NOP_QW1_CMD_SHIFT)
+
+enum avf_tx_nop_desc_cmd_bits {
+ /* Note: These are predefined bit offsets */
+ AVF_TX_NOP_DESC_EOP_SHIFT = 0,
+ AVF_TX_NOP_DESC_RS_SHIFT = 1,
+ AVF_TX_NOP_DESC_RSV_SHIFT = 2 /* 5 bits */
+};
+
+struct avf_filter_program_desc {
+ __le32 qindex_flex_ptype_vsi;
+ __le32 rsvd;
+ __le32 dtype_cmd_cntindex;
+ __le32 fd_id;
+};
+#define AVF_TXD_FLTR_QW0_QINDEX_SHIFT 0
+#define AVF_TXD_FLTR_QW0_QINDEX_MASK (0x7FFUL << \
+ AVF_TXD_FLTR_QW0_QINDEX_SHIFT)
+#define AVF_TXD_FLTR_QW0_FLEXOFF_SHIFT 11
+#define AVF_TXD_FLTR_QW0_FLEXOFF_MASK (0x7UL << \
+ AVF_TXD_FLTR_QW0_FLEXOFF_SHIFT)
+#define AVF_TXD_FLTR_QW0_PCTYPE_SHIFT 17
+#define AVF_TXD_FLTR_QW0_PCTYPE_MASK (0x3FUL << \
+ AVF_TXD_FLTR_QW0_PCTYPE_SHIFT)
+
+/* Packet Classifier Types for filters */
+enum avf_filter_pctype {
+ /* Note: Values 0-28 are reserved for future use.
+ * Value 29, 30, 32 are not supported on XL710 and X710.
+ */
+ AVF_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP = 29,
+ AVF_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP = 30,
+ AVF_FILTER_PCTYPE_NONF_IPV4_UDP = 31,
+ AVF_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK = 32,
+ AVF_FILTER_PCTYPE_NONF_IPV4_TCP = 33,
+ AVF_FILTER_PCTYPE_NONF_IPV4_SCTP = 34,
+ AVF_FILTER_PCTYPE_NONF_IPV4_OTHER = 35,
+ AVF_FILTER_PCTYPE_FRAG_IPV4 = 36,
+ /* Note: Values 37-38 are reserved for future use.
+ * Value 39, 40, 42 are not supported on XL710 and X710.
+ */
+ AVF_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP = 39,
+ AVF_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP = 40,
+ AVF_FILTER_PCTYPE_NONF_IPV6_UDP = 41,
+ AVF_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK = 42,
+ AVF_FILTER_PCTYPE_NONF_IPV6_TCP = 43,
+ AVF_FILTER_PCTYPE_NONF_IPV6_SCTP = 44,
+ AVF_FILTER_PCTYPE_NONF_IPV6_OTHER = 45,
+ AVF_FILTER_PCTYPE_FRAG_IPV6 = 46,
+ /* Note: Value 47 is reserved for future use */
+ AVF_FILTER_PCTYPE_FCOE_OX = 48,
+ AVF_FILTER_PCTYPE_FCOE_RX = 49,
+ AVF_FILTER_PCTYPE_FCOE_OTHER = 50,
+ /* Note: Values 51-62 are reserved for future use */
+ AVF_FILTER_PCTYPE_L2_PAYLOAD = 63,
+};
+
+enum avf_filter_program_desc_dest {
+ AVF_FILTER_PROGRAM_DESC_DEST_DROP_PACKET = 0x0,
+ AVF_FILTER_PROGRAM_DESC_DEST_DIRECT_PACKET_QINDEX = 0x1,
+ AVF_FILTER_PROGRAM_DESC_DEST_DIRECT_PACKET_OTHER = 0x2,
+};
+
+enum avf_filter_program_desc_fd_status {
+ AVF_FILTER_PROGRAM_DESC_FD_STATUS_NONE = 0x0,
+ AVF_FILTER_PROGRAM_DESC_FD_STATUS_FD_ID = 0x1,
+ AVF_FILTER_PROGRAM_DESC_FD_STATUS_FD_ID_4FLEX_BYTES = 0x2,
+ AVF_FILTER_PROGRAM_DESC_FD_STATUS_8FLEX_BYTES = 0x3,
+};
+
+#define AVF_TXD_FLTR_QW0_DEST_VSI_SHIFT 23
+#define AVF_TXD_FLTR_QW0_DEST_VSI_MASK (0x1FFUL << \
+ AVF_TXD_FLTR_QW0_DEST_VSI_SHIFT)
+
+#define AVF_TXD_FLTR_QW1_DTYPE_SHIFT 0
+#define AVF_TXD_FLTR_QW1_DTYPE_MASK (0xFUL << AVF_TXD_FLTR_QW1_DTYPE_SHIFT)
+
+#define AVF_TXD_FLTR_QW1_CMD_SHIFT 4
+#define AVF_TXD_FLTR_QW1_CMD_MASK (0xFFFFULL << \
+ AVF_TXD_FLTR_QW1_CMD_SHIFT)
+
+#define AVF_TXD_FLTR_QW1_PCMD_SHIFT (0x0ULL + AVF_TXD_FLTR_QW1_CMD_SHIFT)
+#define AVF_TXD_FLTR_QW1_PCMD_MASK (0x7ULL << AVF_TXD_FLTR_QW1_PCMD_SHIFT)
+
+enum avf_filter_program_desc_pcmd {
+ AVF_FILTER_PROGRAM_DESC_PCMD_ADD_UPDATE = 0x1,
+ AVF_FILTER_PROGRAM_DESC_PCMD_REMOVE = 0x2,
+};
+
+#define AVF_TXD_FLTR_QW1_DEST_SHIFT (0x3ULL + AVF_TXD_FLTR_QW1_CMD_SHIFT)
+#define AVF_TXD_FLTR_QW1_DEST_MASK (0x3ULL << AVF_TXD_FLTR_QW1_DEST_SHIFT)
+
+#define AVF_TXD_FLTR_QW1_CNT_ENA_SHIFT (0x7ULL + AVF_TXD_FLTR_QW1_CMD_SHIFT)
+#define AVF_TXD_FLTR_QW1_CNT_ENA_MASK BIT_ULL(AVF_TXD_FLTR_QW1_CNT_ENA_SHIFT)
+
+#define AVF_TXD_FLTR_QW1_FD_STATUS_SHIFT (0x9ULL + \
+ AVF_TXD_FLTR_QW1_CMD_SHIFT)
+#define AVF_TXD_FLTR_QW1_FD_STATUS_MASK (0x3ULL << \
+ AVF_TXD_FLTR_QW1_FD_STATUS_SHIFT)
+
+#define AVF_TXD_FLTR_QW1_ATR_SHIFT (0xEULL + \
+ AVF_TXD_FLTR_QW1_CMD_SHIFT)
+#define AVF_TXD_FLTR_QW1_ATR_MASK BIT_ULL(AVF_TXD_FLTR_QW1_ATR_SHIFT)
+
+#define AVF_TXD_FLTR_QW1_CNTINDEX_SHIFT 20
+#define AVF_TXD_FLTR_QW1_CNTINDEX_MASK (0x1FFUL << \
+ AVF_TXD_FLTR_QW1_CNTINDEX_SHIFT)
+
+enum avf_filter_type {
+ AVF_FLOW_DIRECTOR_FLTR = 0,
+ AVF_PE_QUAD_HASH_FLTR = 1,
+ AVF_ETHERTYPE_FLTR,
+ AVF_FCOE_CTX_FLTR,
+ AVF_MAC_VLAN_FLTR,
+ AVF_HASH_FLTR
+};
+
+struct avf_vsi_context {
+ u16 seid;
+ u16 uplink_seid;
+ u16 vsi_number;
+ u16 vsis_allocated;
+ u16 vsis_unallocated;
+ u16 flags;
+ u8 pf_num;
+ u8 vf_num;
+ u8 connection_type;
+ struct avf_aqc_vsi_properties_data info;
+};
+
+struct avf_veb_context {
+ u16 seid;
+ u16 uplink_seid;
+ u16 veb_number;
+ u16 vebs_allocated;
+ u16 vebs_unallocated;
+ u16 flags;
+ struct avf_aqc_get_veb_parameters_completion info;
+};
+
+/* Statistics collected by each port, VSI, VEB, and S-channel */
+struct avf_eth_stats {
+ u64 rx_bytes; /* gorc */
+ u64 rx_unicast; /* uprc */
+ u64 rx_multicast; /* mprc */
+ u64 rx_broadcast; /* bprc */
+ u64 rx_discards; /* rdpc */
+ u64 rx_unknown_protocol; /* rupp */
+ u64 tx_bytes; /* gotc */
+ u64 tx_unicast; /* uptc */
+ u64 tx_multicast; /* mptc */
+ u64 tx_broadcast; /* bptc */
+ u64 tx_discards; /* tdpc */
+ u64 tx_errors; /* tepc */
+};
+
+/* Statistics collected per VEB per TC */
+struct avf_veb_tc_stats {
+ u64 tc_rx_packets[AVF_MAX_TRAFFIC_CLASS];
+ u64 tc_rx_bytes[AVF_MAX_TRAFFIC_CLASS];
+ u64 tc_tx_packets[AVF_MAX_TRAFFIC_CLASS];
+ u64 tc_tx_bytes[AVF_MAX_TRAFFIC_CLASS];
+};
+
+/* Statistics collected per function for FCoE */
+struct avf_fcoe_stats {
+ u64 rx_fcoe_packets; /* fcoeprc */
+ u64 rx_fcoe_dwords; /* focedwrc */
+ u64 rx_fcoe_dropped; /* fcoerpdc */
+ u64 tx_fcoe_packets; /* fcoeptc */
+ u64 tx_fcoe_dwords; /* focedwtc */
+ u64 fcoe_bad_fccrc; /* fcoecrc */
+ u64 fcoe_last_error; /* fcoelast */
+ u64 fcoe_ddp_count; /* fcoeddpc */
+};
+
+/* offset to per function FCoE statistics block */
+#define AVF_FCOE_VF_STAT_OFFSET 0
+#define AVF_FCOE_PF_STAT_OFFSET 128
+#define AVF_FCOE_STAT_MAX (AVF_FCOE_PF_STAT_OFFSET + AVF_MAX_PF)
+
+/* Statistics collected by the MAC */
+struct avf_hw_port_stats {
+ /* eth stats collected by the port */
+ struct avf_eth_stats eth;
+
+ /* additional port specific stats */
+ u64 tx_dropped_link_down; /* tdold */
+ u64 crc_errors; /* crcerrs */
+ u64 illegal_bytes; /* illerrc */
+ u64 error_bytes; /* errbc */
+ u64 mac_local_faults; /* mlfc */
+ u64 mac_remote_faults; /* mrfc */
+ u64 rx_length_errors; /* rlec */
+ u64 link_xon_rx; /* lxonrxc */
+ u64 link_xoff_rx; /* lxoffrxc */
+ u64 priority_xon_rx[8]; /* pxonrxc[8] */
+ u64 priority_xoff_rx[8]; /* pxoffrxc[8] */
+ u64 link_xon_tx; /* lxontxc */
+ u64 link_xoff_tx; /* lxofftxc */
+ u64 priority_xon_tx[8]; /* pxontxc[8] */
+ u64 priority_xoff_tx[8]; /* pxofftxc[8] */
+ u64 priority_xon_2_xoff[8]; /* pxon2offc[8] */
+ u64 rx_size_64; /* prc64 */
+ u64 rx_size_127; /* prc127 */
+ u64 rx_size_255; /* prc255 */
+ u64 rx_size_511; /* prc511 */
+ u64 rx_size_1023; /* prc1023 */
+ u64 rx_size_1522; /* prc1522 */
+ u64 rx_size_big; /* prc9522 */
+ u64 rx_undersize; /* ruc */
+ u64 rx_fragments; /* rfc */
+ u64 rx_oversize; /* roc */
+ u64 rx_jabber; /* rjc */
+ u64 tx_size_64; /* ptc64 */
+ u64 tx_size_127; /* ptc127 */
+ u64 tx_size_255; /* ptc255 */
+ u64 tx_size_511; /* ptc511 */
+ u64 tx_size_1023; /* ptc1023 */
+ u64 tx_size_1522; /* ptc1522 */
+ u64 tx_size_big; /* ptc9522 */
+ u64 mac_short_packet_dropped; /* mspdc */
+ u64 checksum_error; /* xec */
+ /* flow director stats */
+ u64 fd_atr_match;
+ u64 fd_sb_match;
+ u64 fd_atr_tunnel_match;
+ u32 fd_atr_status;
+ u32 fd_sb_status;
+ /* EEE LPI */
+ u32 tx_lpi_status;
+ u32 rx_lpi_status;
+ u64 tx_lpi_count; /* etlpic */
+ u64 rx_lpi_count; /* erlpic */
+};
+
+/* Checksum and Shadow RAM pointers */
+#define AVF_SR_NVM_CONTROL_WORD 0x00
+#define AVF_SR_PCIE_ANALOG_CONFIG_PTR 0x03
+#define AVF_SR_PHY_ANALOG_CONFIG_PTR 0x04
+#define AVF_SR_OPTION_ROM_PTR 0x05
+#define AVF_SR_RO_PCIR_REGS_AUTO_LOAD_PTR 0x06
+#define AVF_SR_AUTO_GENERATED_POINTERS_PTR 0x07
+#define AVF_SR_PCIR_REGS_AUTO_LOAD_PTR 0x08
+#define AVF_SR_EMP_GLOBAL_MODULE_PTR 0x09
+#define AVF_SR_RO_PCIE_LCB_PTR 0x0A
+#define AVF_SR_EMP_IMAGE_PTR 0x0B
+#define AVF_SR_PE_IMAGE_PTR 0x0C
+#define AVF_SR_CSR_PROTECTED_LIST_PTR 0x0D
+#define AVF_SR_MNG_CONFIG_PTR 0x0E
+#define AVF_EMP_MODULE_PTR 0x0F
+#define AVF_SR_EMP_MODULE_PTR 0x48
+#define AVF_SR_PBA_FLAGS 0x15
+#define AVF_SR_PBA_BLOCK_PTR 0x16
+#define AVF_SR_BOOT_CONFIG_PTR 0x17
+#define AVF_NVM_OEM_VER_OFF 0x83
+#define AVF_SR_NVM_DEV_STARTER_VERSION 0x18
+#define AVF_SR_NVM_WAKE_ON_LAN 0x19
+#define AVF_SR_ALTERNATE_SAN_MAC_ADDRESS_PTR 0x27
+#define AVF_SR_PERMANENT_SAN_MAC_ADDRESS_PTR 0x28
+#define AVF_SR_NVM_MAP_VERSION 0x29
+#define AVF_SR_NVM_IMAGE_VERSION 0x2A
+#define AVF_SR_NVM_STRUCTURE_VERSION 0x2B
+#define AVF_SR_NVM_EETRACK_LO 0x2D
+#define AVF_SR_NVM_EETRACK_HI 0x2E
+#define AVF_SR_VPD_PTR 0x2F
+#define AVF_SR_PXE_SETUP_PTR 0x30
+#define AVF_SR_PXE_CONFIG_CUST_OPTIONS_PTR 0x31
+#define AVF_SR_NVM_ORIGINAL_EETRACK_LO 0x34
+#define AVF_SR_NVM_ORIGINAL_EETRACK_HI 0x35
+#define AVF_SR_SW_ETHERNET_MAC_ADDRESS_PTR 0x37
+#define AVF_SR_POR_REGS_AUTO_LOAD_PTR 0x38
+#define AVF_SR_EMPR_REGS_AUTO_LOAD_PTR 0x3A
+#define AVF_SR_GLOBR_REGS_AUTO_LOAD_PTR 0x3B
+#define AVF_SR_CORER_REGS_AUTO_LOAD_PTR 0x3C
+#define AVF_SR_PHY_ACTIVITY_LIST_PTR 0x3D
+#define AVF_SR_PCIE_ALT_AUTO_LOAD_PTR 0x3E
+#define AVF_SR_SW_CHECKSUM_WORD 0x3F
+#define AVF_SR_1ST_FREE_PROVISION_AREA_PTR 0x40
+#define AVF_SR_4TH_FREE_PROVISION_AREA_PTR 0x42
+#define AVF_SR_3RD_FREE_PROVISION_AREA_PTR 0x44
+#define AVF_SR_2ND_FREE_PROVISION_AREA_PTR 0x46
+#define AVF_SR_EMP_SR_SETTINGS_PTR 0x48
+#define AVF_SR_FEATURE_CONFIGURATION_PTR 0x49
+#define AVF_SR_CONFIGURATION_METADATA_PTR 0x4D
+#define AVF_SR_IMMEDIATE_VALUES_PTR 0x4E
+
+/* Auxiliary field, mask and shift definition for Shadow RAM and NVM Flash */
+#define AVF_SR_VPD_MODULE_MAX_SIZE 1024
+#define AVF_SR_PCIE_ALT_MODULE_MAX_SIZE 1024
+#define AVF_SR_CONTROL_WORD_1_SHIFT 0x06
+#define AVF_SR_CONTROL_WORD_1_MASK (0x03 << AVF_SR_CONTROL_WORD_1_SHIFT)
+#define AVF_SR_CONTROL_WORD_1_NVM_BANK_VALID BIT(5)
+#define AVF_SR_NVM_MAP_STRUCTURE_TYPE BIT(12)
+#define AVF_PTR_TYPE BIT(15)
+
+/* Shadow RAM related */
+#define AVF_SR_SECTOR_SIZE_IN_WORDS 0x800
+#define AVF_SR_BUF_ALIGNMENT 4096
+#define AVF_SR_WORDS_IN_1KB 512
+/* Checksum should be calculated such that after adding all the words,
+ * including the checksum word itself, the sum should be 0xBABA.
+ */
+#define AVF_SR_SW_CHECKSUM_BASE 0xBABA
+
+#define AVF_SRRD_SRCTL_ATTEMPTS 100000
+
+/* FCoE Tx context descriptor - Use the avf_tx_context_desc struct */
+
+enum i40E_fcoe_tx_ctx_desc_cmd_bits {
+ AVF_FCOE_TX_CTX_DESC_OPCODE_SINGLE_SEND = 0x00, /* 4 BITS */
+ AVF_FCOE_TX_CTX_DESC_OPCODE_TSO_FC_CLASS2 = 0x01, /* 4 BITS */
+ AVF_FCOE_TX_CTX_DESC_OPCODE_TSO_FC_CLASS3 = 0x05, /* 4 BITS */
+ AVF_FCOE_TX_CTX_DESC_OPCODE_ETSO_FC_CLASS2 = 0x02, /* 4 BITS */
+ AVF_FCOE_TX_CTX_DESC_OPCODE_ETSO_FC_CLASS3 = 0x06, /* 4 BITS */
+ AVF_FCOE_TX_CTX_DESC_OPCODE_DWO_FC_CLASS2 = 0x03, /* 4 BITS */
+ AVF_FCOE_TX_CTX_DESC_OPCODE_DWO_FC_CLASS3 = 0x07, /* 4 BITS */
+ AVF_FCOE_TX_CTX_DESC_OPCODE_DDP_CTX_INVL = 0x08, /* 4 BITS */
+ AVF_FCOE_TX_CTX_DESC_OPCODE_DWO_CTX_INVL = 0x09, /* 4 BITS */
+ AVF_FCOE_TX_CTX_DESC_RELOFF = 0x10,
+ AVF_FCOE_TX_CTX_DESC_CLRSEQ = 0x20,
+ AVF_FCOE_TX_CTX_DESC_DIFENA = 0x40,
+ AVF_FCOE_TX_CTX_DESC_IL2TAG2 = 0x80
+};
+
+/* FCoE DIF/DIX Context descriptor */
+struct avf_fcoe_difdix_context_desc {
+ __le64 flags_buff0_buff1_ref;
+ __le64 difapp_msk_bias;
+};
+
+#define AVF_FCOE_DIFDIX_CTX_QW0_FLAGS_SHIFT 0
+#define AVF_FCOE_DIFDIX_CTX_QW0_FLAGS_MASK (0xFFFULL << \
+ AVF_FCOE_DIFDIX_CTX_QW0_FLAGS_SHIFT)
+
+enum avf_fcoe_difdix_ctx_desc_flags_bits {
+ /* 2 BITS */
+ AVF_FCOE_DIFDIX_CTX_DESC_RSVD = 0x0000,
+ /* 1 BIT */
+ AVF_FCOE_DIFDIX_CTX_DESC_APPTYPE_TAGCHK = 0x0000,
+ /* 1 BIT */
+ AVF_FCOE_DIFDIX_CTX_DESC_APPTYPE_TAGNOTCHK = 0x0004,
+ /* 2 BITS */
+ AVF_FCOE_DIFDIX_CTX_DESC_GTYPE_OPAQUE = 0x0000,
+ /* 2 BITS */
+ AVF_FCOE_DIFDIX_CTX_DESC_GTYPE_CHKINTEGRITY = 0x0008,
+ /* 2 BITS */
+ AVF_FCOE_DIFDIX_CTX_DESC_GTYPE_CHKINTEGRITY_APPTAG = 0x0010,
+ /* 2 BITS */
+ AVF_FCOE_DIFDIX_CTX_DESC_GTYPE_CHKINTEGRITY_APPREFTAG = 0x0018,
+ /* 2 BITS */
+ AVF_FCOE_DIFDIX_CTX_DESC_REFTYPE_CNST = 0x0000,
+ /* 2 BITS */
+ AVF_FCOE_DIFDIX_CTX_DESC_REFTYPE_INC1BLK = 0x0020,
+ /* 2 BITS */
+ AVF_FCOE_DIFDIX_CTX_DESC_REFTYPE_APPTAG = 0x0040,
+ /* 2 BITS */
+ AVF_FCOE_DIFDIX_CTX_DESC_REFTYPE_RSVD = 0x0060,
+ /* 1 BIT */
+ AVF_FCOE_DIFDIX_CTX_DESC_DIXMODE_XSUM = 0x0000,
+ /* 1 BIT */
+ AVF_FCOE_DIFDIX_CTX_DESC_DIXMODE_CRC = 0x0080,
+ /* 2 BITS */
+ AVF_FCOE_DIFDIX_CTX_DESC_DIFHOST_UNTAG = 0x0000,
+ /* 2 BITS */
+ AVF_FCOE_DIFDIX_CTX_DESC_DIFHOST_BUF = 0x0100,
+ /* 2 BITS */
+ AVF_FCOE_DIFDIX_CTX_DESC_DIFHOST_RSVD = 0x0200,
+ /* 2 BITS */
+ AVF_FCOE_DIFDIX_CTX_DESC_DIFHOST_EMBDTAGS = 0x0300,
+ /* 1 BIT */
+ AVF_FCOE_DIFDIX_CTX_DESC_DIFLAN_UNTAG = 0x0000,
+ /* 1 BIT */
+ AVF_FCOE_DIFDIX_CTX_DESC_DIFLAN_TAG = 0x0400,
+ /* 1 BIT */
+ AVF_FCOE_DIFDIX_CTX_DESC_DIFBLK_512B = 0x0000,
+ /* 1 BIT */
+ AVF_FCOE_DIFDIX_CTX_DESC_DIFBLK_4K = 0x0800
+};
+
+#define AVF_FCOE_DIFDIX_CTX_QW0_BUFF0_SHIFT 12
+#define AVF_FCOE_DIFDIX_CTX_QW0_BUFF0_MASK (0x3FFULL << \
+ AVF_FCOE_DIFDIX_CTX_QW0_BUFF0_SHIFT)
+
+#define AVF_FCOE_DIFDIX_CTX_QW0_BUFF1_SHIFT 22
+#define AVF_FCOE_DIFDIX_CTX_QW0_BUFF1_MASK (0x3FFULL << \
+ AVF_FCOE_DIFDIX_CTX_QW0_BUFF1_SHIFT)
+
+#define AVF_FCOE_DIFDIX_CTX_QW0_REF_SHIFT 32
+#define AVF_FCOE_DIFDIX_CTX_QW0_REF_MASK (0xFFFFFFFFULL << \
+ AVF_FCOE_DIFDIX_CTX_QW0_REF_SHIFT)
+
+#define AVF_FCOE_DIFDIX_CTX_QW1_APP_SHIFT 0
+#define AVF_FCOE_DIFDIX_CTX_QW1_APP_MASK (0xFFFFULL << \
+ AVF_FCOE_DIFDIX_CTX_QW1_APP_SHIFT)
+
+#define AVF_FCOE_DIFDIX_CTX_QW1_APP_MSK_SHIFT 16
+#define AVF_FCOE_DIFDIX_CTX_QW1_APP_MSK_MASK (0xFFFFULL << \
+ AVF_FCOE_DIFDIX_CTX_QW1_APP_MSK_SHIFT)
+
+#define AVF_FCOE_DIFDIX_CTX_QW1_REF_BIAS_SHIFT 32
+#define AVF_FCOE_DIFDIX_CTX_QW0_REF_BIAS_MASK (0xFFFFFFFFULL << \
+ AVF_FCOE_DIFDIX_CTX_QW1_REF_BIAS_SHIFT)
+
+/* FCoE DIF/DIX Buffers descriptor */
+struct avf_fcoe_difdix_buffers_desc {
+ __le64 buff_addr0;
+ __le64 buff_addr1;
+};
+
+/* FCoE DDP Context descriptor */
+struct avf_fcoe_ddp_context_desc {
+ __le64 rsvd;
+ __le64 type_cmd_foff_lsize;
+};
+
+#define AVF_FCOE_DDP_CTX_QW1_DTYPE_SHIFT 0
+#define AVF_FCOE_DDP_CTX_QW1_DTYPE_MASK (0xFULL << \
+ AVF_FCOE_DDP_CTX_QW1_DTYPE_SHIFT)
+
+#define AVF_FCOE_DDP_CTX_QW1_CMD_SHIFT 4
+#define AVF_FCOE_DDP_CTX_QW1_CMD_MASK (0xFULL << \
+ AVF_FCOE_DDP_CTX_QW1_CMD_SHIFT)
+
+enum avf_fcoe_ddp_ctx_desc_cmd_bits {
+ AVF_FCOE_DDP_CTX_DESC_BSIZE_512B = 0x00, /* 2 BITS */
+ AVF_FCOE_DDP_CTX_DESC_BSIZE_4K = 0x01, /* 2 BITS */
+ AVF_FCOE_DDP_CTX_DESC_BSIZE_8K = 0x02, /* 2 BITS */
+ AVF_FCOE_DDP_CTX_DESC_BSIZE_16K = 0x03, /* 2 BITS */
+ AVF_FCOE_DDP_CTX_DESC_DIFENA = 0x04, /* 1 BIT */
+ AVF_FCOE_DDP_CTX_DESC_LASTSEQH = 0x08, /* 1 BIT */
+};
+
+#define AVF_FCOE_DDP_CTX_QW1_FOFF_SHIFT 16
+#define AVF_FCOE_DDP_CTX_QW1_FOFF_MASK (0x3FFFULL << \
+ AVF_FCOE_DDP_CTX_QW1_FOFF_SHIFT)
+
+#define AVF_FCOE_DDP_CTX_QW1_LSIZE_SHIFT 32
+#define AVF_FCOE_DDP_CTX_QW1_LSIZE_MASK (0x3FFFULL << \
+ AVF_FCOE_DDP_CTX_QW1_LSIZE_SHIFT)
+
+/* FCoE DDP/DWO Queue Context descriptor */
+struct avf_fcoe_queue_context_desc {
+ __le64 dmaindx_fbase; /* 0:11 DMAINDX, 12:63 FBASE */
+ __le64 flen_tph; /* 0:12 FLEN, 13:15 TPH */
+};
+
+#define AVF_FCOE_QUEUE_CTX_QW0_DMAINDX_SHIFT 0
+#define AVF_FCOE_QUEUE_CTX_QW0_DMAINDX_MASK (0xFFFULL << \
+ AVF_FCOE_QUEUE_CTX_QW0_DMAINDX_SHIFT)
+
+#define AVF_FCOE_QUEUE_CTX_QW0_FBASE_SHIFT 12
+#define AVF_FCOE_QUEUE_CTX_QW0_FBASE_MASK (0xFFFFFFFFFFFFFULL << \
+ AVF_FCOE_QUEUE_CTX_QW0_FBASE_SHIFT)
+
+#define AVF_FCOE_QUEUE_CTX_QW1_FLEN_SHIFT 0
+#define AVF_FCOE_QUEUE_CTX_QW1_FLEN_MASK (0x1FFFULL << \
+ AVF_FCOE_QUEUE_CTX_QW1_FLEN_SHIFT)
+
+#define AVF_FCOE_QUEUE_CTX_QW1_TPH_SHIFT 13
+#define AVF_FCOE_QUEUE_CTX_QW1_TPH_MASK (0x7ULL << \
+ AVF_FCOE_QUEUE_CTX_QW1_FLEN_SHIFT)
+
+enum avf_fcoe_queue_ctx_desc_tph_bits {
+ AVF_FCOE_QUEUE_CTX_DESC_TPHRDESC = 0x1,
+ AVF_FCOE_QUEUE_CTX_DESC_TPHDATA = 0x2
+};
+
+#define AVF_FCOE_QUEUE_CTX_QW1_RECIPE_SHIFT 30
+#define AVF_FCOE_QUEUE_CTX_QW1_RECIPE_MASK (0x3ULL << \
+ AVF_FCOE_QUEUE_CTX_QW1_RECIPE_SHIFT)
+
+/* FCoE DDP/DWO Filter Context descriptor */
+struct avf_fcoe_filter_context_desc {
+ __le32 param;
+ __le16 seqn;
+
+ /* 48:51(0:3) RSVD, 52:63(4:15) DMAINDX */
+ __le16 rsvd_dmaindx;
+
+ /* 0:7 FLAGS, 8:52 RSVD, 53:63 LANQ */
+ __le64 flags_rsvd_lanq;
+};
+
+#define AVF_FCOE_FILTER_CTX_QW0_DMAINDX_SHIFT 4
+#define AVF_FCOE_FILTER_CTX_QW0_DMAINDX_MASK (0xFFF << \
+ AVF_FCOE_FILTER_CTX_QW0_DMAINDX_SHIFT)
+
+enum avf_fcoe_filter_ctx_desc_flags_bits {
+ AVF_FCOE_FILTER_CTX_DESC_CTYP_DDP = 0x00,
+ AVF_FCOE_FILTER_CTX_DESC_CTYP_DWO = 0x01,
+ AVF_FCOE_FILTER_CTX_DESC_ENODE_INIT = 0x00,
+ AVF_FCOE_FILTER_CTX_DESC_ENODE_RSP = 0x02,
+ AVF_FCOE_FILTER_CTX_DESC_FC_CLASS2 = 0x00,
+ AVF_FCOE_FILTER_CTX_DESC_FC_CLASS3 = 0x04
+};
+
+#define AVF_FCOE_FILTER_CTX_QW1_FLAGS_SHIFT 0
+#define AVF_FCOE_FILTER_CTX_QW1_FLAGS_MASK (0xFFULL << \
+ AVF_FCOE_FILTER_CTX_QW1_FLAGS_SHIFT)
+
+#define AVF_FCOE_FILTER_CTX_QW1_PCTYPE_SHIFT 8
+#define AVF_FCOE_FILTER_CTX_QW1_PCTYPE_MASK (0x3FULL << \
+ AVF_FCOE_FILTER_CTX_QW1_PCTYPE_SHIFT)
+
+#define AVF_FCOE_FILTER_CTX_QW1_LANQINDX_SHIFT 53
+#define AVF_FCOE_FILTER_CTX_QW1_LANQINDX_MASK (0x7FFULL << \
+ AVF_FCOE_FILTER_CTX_QW1_LANQINDX_SHIFT)
+
+enum avf_switch_element_types {
+ AVF_SWITCH_ELEMENT_TYPE_MAC = 1,
+ AVF_SWITCH_ELEMENT_TYPE_PF = 2,
+ AVF_SWITCH_ELEMENT_TYPE_VF = 3,
+ AVF_SWITCH_ELEMENT_TYPE_EMP = 4,
+ AVF_SWITCH_ELEMENT_TYPE_BMC = 6,
+ AVF_SWITCH_ELEMENT_TYPE_PE = 16,
+ AVF_SWITCH_ELEMENT_TYPE_VEB = 17,
+ AVF_SWITCH_ELEMENT_TYPE_PA = 18,
+ AVF_SWITCH_ELEMENT_TYPE_VSI = 19,
+};
+
+/* Supported EtherType filters */
+enum avf_ether_type_index {
+ AVF_ETHER_TYPE_1588 = 0,
+ AVF_ETHER_TYPE_FIP = 1,
+ AVF_ETHER_TYPE_OUI_EXTENDED = 2,
+ AVF_ETHER_TYPE_MAC_CONTROL = 3,
+ AVF_ETHER_TYPE_LLDP = 4,
+ AVF_ETHER_TYPE_EVB_PROTOCOL1 = 5,
+ AVF_ETHER_TYPE_EVB_PROTOCOL2 = 6,
+ AVF_ETHER_TYPE_QCN_CNM = 7,
+ AVF_ETHER_TYPE_8021X = 8,
+ AVF_ETHER_TYPE_ARP = 9,
+ AVF_ETHER_TYPE_RSV1 = 10,
+ AVF_ETHER_TYPE_RSV2 = 11,
+};
+
+/* Filter context base size is 1K */
+#define AVF_HASH_FILTER_BASE_SIZE 1024
+/* Supported Hash filter values */
+enum avf_hash_filter_size {
+ AVF_HASH_FILTER_SIZE_1K = 0,
+ AVF_HASH_FILTER_SIZE_2K = 1,
+ AVF_HASH_FILTER_SIZE_4K = 2,
+ AVF_HASH_FILTER_SIZE_8K = 3,
+ AVF_HASH_FILTER_SIZE_16K = 4,
+ AVF_HASH_FILTER_SIZE_32K = 5,
+ AVF_HASH_FILTER_SIZE_64K = 6,
+ AVF_HASH_FILTER_SIZE_128K = 7,
+ AVF_HASH_FILTER_SIZE_256K = 8,
+ AVF_HASH_FILTER_SIZE_512K = 9,
+ AVF_HASH_FILTER_SIZE_1M = 10,
+};
+
+/* DMA context base size is 0.5K */
+#define AVF_DMA_CNTX_BASE_SIZE 512
+/* Supported DMA context values */
+enum avf_dma_cntx_size {
+ AVF_DMA_CNTX_SIZE_512 = 0,
+ AVF_DMA_CNTX_SIZE_1K = 1,
+ AVF_DMA_CNTX_SIZE_2K = 2,
+ AVF_DMA_CNTX_SIZE_4K = 3,
+ AVF_DMA_CNTX_SIZE_8K = 4,
+ AVF_DMA_CNTX_SIZE_16K = 5,
+ AVF_DMA_CNTX_SIZE_32K = 6,
+ AVF_DMA_CNTX_SIZE_64K = 7,
+ AVF_DMA_CNTX_SIZE_128K = 8,
+ AVF_DMA_CNTX_SIZE_256K = 9,
+};
+
+/* Supported Hash look up table (LUT) sizes */
+enum avf_hash_lut_size {
+ AVF_HASH_LUT_SIZE_128 = 0,
+ AVF_HASH_LUT_SIZE_512 = 1,
+};
+
+/* Structure to hold a per PF filter control settings */
+struct avf_filter_control_settings {
+ /* number of PE Quad Hash filter buckets */
+ enum avf_hash_filter_size pe_filt_num;
+ /* number of PE Quad Hash contexts */
+ enum avf_dma_cntx_size pe_cntx_num;
+ /* number of FCoE filter buckets */
+ enum avf_hash_filter_size fcoe_filt_num;
+ /* number of FCoE DDP contexts */
+ enum avf_dma_cntx_size fcoe_cntx_num;
+ /* size of the Hash LUT */
+ enum avf_hash_lut_size hash_lut_size;
+ /* enable FDIR filters for PF and its VFs */
+ bool enable_fdir;
+ /* enable Ethertype filters for PF and its VFs */
+ bool enable_ethtype;
+ /* enable MAC/VLAN filters for PF and its VFs */
+ bool enable_macvlan;
+};
+
+/* Structure to hold device level control filter counts */
+struct avf_control_filter_stats {
+ u16 mac_etype_used; /* Used perfect match MAC/EtherType filters */
+ u16 etype_used; /* Used perfect EtherType filters */
+ u16 mac_etype_free; /* Un-used perfect match MAC/EtherType filters */
+ u16 etype_free; /* Un-used perfect EtherType filters */
+};
+
+enum avf_reset_type {
+ AVF_RESET_POR = 0,
+ AVF_RESET_CORER = 1,
+ AVF_RESET_GLOBR = 2,
+ AVF_RESET_EMPR = 3,
+};
+
+/* IEEE 802.1AB LLDP Agent Variables from NVM */
+#define AVF_NVM_LLDP_CFG_PTR 0x06
+#define AVF_SR_LLDP_CFG_PTR 0x31
+struct avf_lldp_variables {
+ u16 length;
+ u16 adminstatus;
+ u16 msgfasttx;
+ u16 msgtxinterval;
+ u16 txparams;
+ u16 timers;
+ u16 crc8;
+};
+
+/* Offsets into Alternate Ram */
+#define AVF_ALT_STRUCT_FIRST_PF_OFFSET 0 /* in dwords */
+#define AVF_ALT_STRUCT_DWORDS_PER_PF 64 /* in dwords */
+#define AVF_ALT_STRUCT_OUTER_VLAN_TAG_OFFSET 0xD /* in dwords */
+#define AVF_ALT_STRUCT_USER_PRIORITY_OFFSET 0xC /* in dwords */
+#define AVF_ALT_STRUCT_MIN_BW_OFFSET 0xE /* in dwords */
+#define AVF_ALT_STRUCT_MAX_BW_OFFSET 0xF /* in dwords */
+
+/* Alternate Ram Bandwidth Masks */
+#define AVF_ALT_BW_VALUE_MASK 0xFF
+#define AVF_ALT_BW_RELATIVE_MASK 0x40000000
+#define AVF_ALT_BW_VALID_MASK 0x80000000
+
+/* RSS Hash Table Size */
+#define AVF_PFQF_CTL_0_HASHLUTSIZE_512 0x00010000
+
+/* INPUT SET MASK for RSS, flow director, and flexible payload */
+#define AVF_L3_SRC_SHIFT 47
+#define AVF_L3_SRC_MASK (0x3ULL << AVF_L3_SRC_SHIFT)
+#define AVF_L3_V6_SRC_SHIFT 43
+#define AVF_L3_V6_SRC_MASK (0xFFULL << AVF_L3_V6_SRC_SHIFT)
+#define AVF_L3_DST_SHIFT 35
+#define AVF_L3_DST_MASK (0x3ULL << AVF_L3_DST_SHIFT)
+#define AVF_L3_V6_DST_SHIFT 35
+#define AVF_L3_V6_DST_MASK (0xFFULL << AVF_L3_V6_DST_SHIFT)
+#define AVF_L4_SRC_SHIFT 34
+#define AVF_L4_SRC_MASK (0x1ULL << AVF_L4_SRC_SHIFT)
+#define AVF_L4_DST_SHIFT 33
+#define AVF_L4_DST_MASK (0x1ULL << AVF_L4_DST_SHIFT)
+#define AVF_VERIFY_TAG_SHIFT 31
+#define AVF_VERIFY_TAG_MASK (0x3ULL << AVF_VERIFY_TAG_SHIFT)
+
+#define AVF_FLEX_50_SHIFT 13
+#define AVF_FLEX_50_MASK (0x1ULL << AVF_FLEX_50_SHIFT)
+#define AVF_FLEX_51_SHIFT 12
+#define AVF_FLEX_51_MASK (0x1ULL << AVF_FLEX_51_SHIFT)
+#define AVF_FLEX_52_SHIFT 11
+#define AVF_FLEX_52_MASK (0x1ULL << AVF_FLEX_52_SHIFT)
+#define AVF_FLEX_53_SHIFT 10
+#define AVF_FLEX_53_MASK (0x1ULL << AVF_FLEX_53_SHIFT)
+#define AVF_FLEX_54_SHIFT 9
+#define AVF_FLEX_54_MASK (0x1ULL << AVF_FLEX_54_SHIFT)
+#define AVF_FLEX_55_SHIFT 8
+#define AVF_FLEX_55_MASK (0x1ULL << AVF_FLEX_55_SHIFT)
+#define AVF_FLEX_56_SHIFT 7
+#define AVF_FLEX_56_MASK (0x1ULL << AVF_FLEX_56_SHIFT)
+#define AVF_FLEX_57_SHIFT 6
+#define AVF_FLEX_57_MASK (0x1ULL << AVF_FLEX_57_SHIFT)
+
+/* Version format for Dynamic Device Personalization(DDP) */
+struct avf_ddp_version {
+ u8 major;
+ u8 minor;
+ u8 update;
+ u8 draft;
+};
+
+#define AVF_DDP_NAME_SIZE 32
+
+/* Package header */
+struct avf_package_header {
+ struct avf_ddp_version version;
+ u32 segment_count;
+ u32 segment_offset[1];
+};
+
+/* Generic segment header */
+struct avf_generic_seg_header {
+#define SEGMENT_TYPE_METADATA 0x00000001
+#define SEGMENT_TYPE_NOTES 0x00000002
+#define SEGMENT_TYPE_AVF 0x00000011
+#define SEGMENT_TYPE_X722 0x00000012
+ u32 type;
+ struct avf_ddp_version version;
+ u32 size;
+ char name[AVF_DDP_NAME_SIZE];
+};
+
+struct avf_metadata_segment {
+ struct avf_generic_seg_header header;
+ struct avf_ddp_version version;
+#define AVF_DDP_TRACKID_RDONLY 0
+#define AVF_DDP_TRACKID_INVALID 0xFFFFFFFF
+ u32 track_id;
+ char name[AVF_DDP_NAME_SIZE];
+};
+
+struct avf_device_id_entry {
+ u32 vendor_dev_id;
+ u32 sub_vendor_dev_id;
+};
+
+struct avf_profile_segment {
+ struct avf_generic_seg_header header;
+ struct avf_ddp_version version;
+ char name[AVF_DDP_NAME_SIZE];
+ u32 device_table_count;
+ struct avf_device_id_entry device_table[1];
+};
+
+struct avf_section_table {
+ u32 section_count;
+ u32 section_offset[1];
+};
+
+struct avf_profile_section_header {
+ u16 tbl_size;
+ u16 data_end;
+ struct {
+#define SECTION_TYPE_INFO 0x00000010
+#define SECTION_TYPE_MMIO 0x00000800
+#define SECTION_TYPE_RB_MMIO 0x00001800
+#define SECTION_TYPE_AQ 0x00000801
+#define SECTION_TYPE_RB_AQ 0x00001801
+#define SECTION_TYPE_NOTE 0x80000000
+#define SECTION_TYPE_NAME 0x80000001
+#define SECTION_TYPE_PROTO 0x80000002
+#define SECTION_TYPE_PCTYPE 0x80000003
+#define SECTION_TYPE_PTYPE 0x80000004
+ u32 type;
+ u32 offset;
+ u32 size;
+ } section;
+};
+
+struct avf_profile_tlv_section_record {
+ u8 rtype;
+ u8 type;
+ u16 len;
+ u8 data[12];
+};
+
+/* Generic AQ section in proflie */
+struct avf_profile_aq_section {
+ u16 opcode;
+ u16 flags;
+ u8 param[16];
+ u16 datalen;
+ u8 data[1];
+};
+
+struct avf_profile_info {
+ u32 track_id;
+ struct avf_ddp_version version;
+ u8 op;
+#define AVF_DDP_ADD_TRACKID 0x01
+#define AVF_DDP_REMOVE_TRACKID 0x02
+ u8 reserved[7];
+ u8 name[AVF_DDP_NAME_SIZE];
+};
+#endif /* _AVF_TYPE_H_ */
diff --git a/drivers/net/iavf/base/meson.build b/drivers/net/iavf/base/meson.build
new file mode 100644
index 0000000..bcb24b7
--- /dev/null
+++ b/drivers/net/iavf/base/meson.build
@@ -0,0 +1,23 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2018 Luca Boccassi <bluca@debian.org>
+
+sources = [
+ 'iavf_adminq.c',
+ 'iavf_common.c',
+]
+
+error_cflags = ['-Wno-pointer-to-int-cast']
+c_args = cflags
+if allow_experimental_apis
+ c_args += '-DALLOW_EXPERIMENTAL_API'
+endif
+foreach flag: error_cflags
+ if cc.has_argument(flag)
+ c_args += flag
+ endif
+endforeach
+
+base_lib = static_library('iavf_base', sources,
+ dependencies: static_rte_eal,
+ c_args: c_args)
+base_objs = base_lib.extract_all_objects()
diff --git a/drivers/net/iavf/base/virtchnl.h b/drivers/net/iavf/base/virtchnl.h
new file mode 100644
index 0000000..167518f
--- /dev/null
+++ b/drivers/net/iavf/base/virtchnl.h
@@ -0,0 +1,787 @@
+/*******************************************************************************
+
+Copyright (c) 2013 - 2015, Intel Corporation
+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.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+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.
+
+***************************************************************************/
+
+#ifndef _VIRTCHNL_H_
+#define _VIRTCHNL_H_
+
+/* Description:
+ * This header file describes the VF-PF communication protocol used
+ * by the drivers for all devices starting from our 40G product line
+ *
+ * Admin queue buffer usage:
+ * desc->opcode is always aqc_opc_send_msg_to_pf
+ * flags, retval, datalen, and data addr are all used normally.
+ * The Firmware copies the cookie fields when sending messages between the
+ * PF and VF, but uses all other fields internally. Due to this limitation,
+ * we must send all messages as "indirect", i.e. using an external buffer.
+ *
+ * All the VSI indexes are relative to the VF. Each VF can have maximum of
+ * three VSIs. All the queue indexes are relative to the VSI. Each VF can
+ * have a maximum of sixteen queues for all of its VSIs.
+ *
+ * The PF is required to return a status code in v_retval for all messages
+ * except RESET_VF, which does not require any response. The return value
+ * is of status_code type, defined in the shared type.h.
+ *
+ * In general, VF driver initialization should roughly follow the order of
+ * these opcodes. The VF driver must first validate the API version of the
+ * PF driver, then request a reset, then get resources, then configure
+ * queues and interrupts. After these operations are complete, the VF
+ * driver may start its queues, optionally add MAC and VLAN filters, and
+ * process traffic.
+ */
+
+/* START GENERIC DEFINES
+ * Need to ensure the following enums and defines hold the same meaning and
+ * value in current and future projects
+ */
+
+/* Error Codes */
+enum virtchnl_status_code {
+ VIRTCHNL_STATUS_SUCCESS = 0,
+ VIRTCHNL_ERR_PARAM = -5,
+ VIRTCHNL_STATUS_ERR_OPCODE_MISMATCH = -38,
+ VIRTCHNL_STATUS_ERR_CQP_COMPL_ERROR = -39,
+ VIRTCHNL_STATUS_ERR_INVALID_VF_ID = -40,
+ VIRTCHNL_STATUS_NOT_SUPPORTED = -64,
+};
+
+#define VIRTCHNL_LINK_SPEED_100MB_SHIFT 0x1
+#define VIRTCHNL_LINK_SPEED_1000MB_SHIFT 0x2
+#define VIRTCHNL_LINK_SPEED_10GB_SHIFT 0x3
+#define VIRTCHNL_LINK_SPEED_40GB_SHIFT 0x4
+#define VIRTCHNL_LINK_SPEED_20GB_SHIFT 0x5
+#define VIRTCHNL_LINK_SPEED_25GB_SHIFT 0x6
+
+enum virtchnl_link_speed {
+ VIRTCHNL_LINK_SPEED_UNKNOWN = 0,
+ VIRTCHNL_LINK_SPEED_100MB = BIT(VIRTCHNL_LINK_SPEED_100MB_SHIFT),
+ VIRTCHNL_LINK_SPEED_1GB = BIT(VIRTCHNL_LINK_SPEED_1000MB_SHIFT),
+ VIRTCHNL_LINK_SPEED_10GB = BIT(VIRTCHNL_LINK_SPEED_10GB_SHIFT),
+ VIRTCHNL_LINK_SPEED_40GB = BIT(VIRTCHNL_LINK_SPEED_40GB_SHIFT),
+ VIRTCHNL_LINK_SPEED_20GB = BIT(VIRTCHNL_LINK_SPEED_20GB_SHIFT),
+ VIRTCHNL_LINK_SPEED_25GB = BIT(VIRTCHNL_LINK_SPEED_25GB_SHIFT),
+};
+
+/* for hsplit_0 field of Rx HMC context */
+/* deprecated with AVF 1.0 */
+enum virtchnl_rx_hsplit {
+ VIRTCHNL_RX_HSPLIT_NO_SPLIT = 0,
+ VIRTCHNL_RX_HSPLIT_SPLIT_L2 = 1,
+ VIRTCHNL_RX_HSPLIT_SPLIT_IP = 2,
+ VIRTCHNL_RX_HSPLIT_SPLIT_TCP_UDP = 4,
+ VIRTCHNL_RX_HSPLIT_SPLIT_SCTP = 8,
+};
+
+#define VIRTCHNL_ETH_LENGTH_OF_ADDRESS 6
+/* END GENERIC DEFINES */
+
+/* Opcodes for VF-PF communication. These are placed in the v_opcode field
+ * of the virtchnl_msg structure.
+ */
+enum virtchnl_ops {
+/* The PF sends status change events to VFs using
+ * the VIRTCHNL_OP_EVENT opcode.
+ * VFs send requests to the PF using the other ops.
+ * Use of "advanced opcode" features must be negotiated as part of capabilities
+ * exchange and are not considered part of base mode feature set.
+ */
+ VIRTCHNL_OP_UNKNOWN = 0,
+ VIRTCHNL_OP_VERSION = 1, /* must ALWAYS be 1 */
+ VIRTCHNL_OP_RESET_VF = 2,
+ VIRTCHNL_OP_GET_VF_RESOURCES = 3,
+ VIRTCHNL_OP_CONFIG_TX_QUEUE = 4,
+ VIRTCHNL_OP_CONFIG_RX_QUEUE = 5,
+ VIRTCHNL_OP_CONFIG_VSI_QUEUES = 6,
+ VIRTCHNL_OP_CONFIG_IRQ_MAP = 7,
+ VIRTCHNL_OP_ENABLE_QUEUES = 8,
+ VIRTCHNL_OP_DISABLE_QUEUES = 9,
+ VIRTCHNL_OP_ADD_ETH_ADDR = 10,
+ VIRTCHNL_OP_DEL_ETH_ADDR = 11,
+ VIRTCHNL_OP_ADD_VLAN = 12,
+ VIRTCHNL_OP_DEL_VLAN = 13,
+ VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE = 14,
+ VIRTCHNL_OP_GET_STATS = 15,
+ VIRTCHNL_OP_RSVD = 16,
+ VIRTCHNL_OP_EVENT = 17, /* must ALWAYS be 17 */
+#ifdef VIRTCHNL_SOL_VF_SUPPORT
+ VIRTCHNL_OP_GET_ADDNL_SOL_CONFIG = 19,
+#endif
+#ifdef VIRTCHNL_IWARP
+ VIRTCHNL_OP_IWARP = 20, /* advanced opcode */
+ VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP = 21, /* advanced opcode */
+ VIRTCHNL_OP_RELEASE_IWARP_IRQ_MAP = 22, /* advanced opcode */
+#endif
+ VIRTCHNL_OP_CONFIG_RSS_KEY = 23,
+ VIRTCHNL_OP_CONFIG_RSS_LUT = 24,
+ VIRTCHNL_OP_GET_RSS_HENA_CAPS = 25,
+ VIRTCHNL_OP_SET_RSS_HENA = 26,
+ VIRTCHNL_OP_ENABLE_VLAN_STRIPPING = 27,
+ VIRTCHNL_OP_DISABLE_VLAN_STRIPPING = 28,
+ VIRTCHNL_OP_REQUEST_QUEUES = 29,
+
+};
+
+/* This macro is used to generate a compilation error if a structure
+ * is not exactly the correct length. It gives a divide by zero error if the
+ * structure is not of the correct size, otherwise it creates an enum that is
+ * never used.
+ */
+#define VIRTCHNL_CHECK_STRUCT_LEN(n, X) enum virtchnl_static_assert_enum_##X \
+ {virtchnl_static_assert_##X = (n) / ((sizeof(struct X) == (n)) ? 1 : 0)}
+
+/* Virtual channel message descriptor. This overlays the admin queue
+ * descriptor. All other data is passed in external buffers.
+ */
+
+struct virtchnl_msg {
+ u8 pad[8]; /* AQ flags/opcode/len/retval fields */
+ enum virtchnl_ops v_opcode; /* avoid confusion with desc->opcode */
+ enum virtchnl_status_code v_retval; /* ditto for desc->retval */
+ u32 vfid; /* used by PF when sending to VF */
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(20, virtchnl_msg);
+
+/* Message descriptions and data structures.*/
+
+/* VIRTCHNL_OP_VERSION
+ * VF posts its version number to the PF. PF responds with its version number
+ * in the same format, along with a return code.
+ * Reply from PF has its major/minor versions also in param0 and param1.
+ * If there is a major version mismatch, then the VF cannot operate.
+ * If there is a minor version mismatch, then the VF can operate but should
+ * add a warning to the system log.
+ *
+ * This enum element MUST always be specified as == 1, regardless of other
+ * changes in the API. The PF must always respond to this message without
+ * error regardless of version mismatch.
+ */
+#define VIRTCHNL_VERSION_MAJOR 1
+#define VIRTCHNL_VERSION_MINOR 1
+#define VIRTCHNL_VERSION_MINOR_NO_VF_CAPS 0
+
+struct virtchnl_version_info {
+ u32 major;
+ u32 minor;
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_version_info);
+
+#define VF_IS_V10(_v) (((_v)->major == 1) && ((_v)->minor == 0))
+#define VF_IS_V11(_ver) (((_ver)->major == 1) && ((_ver)->minor == 1))
+
+/* VIRTCHNL_OP_RESET_VF
+ * VF sends this request to PF with no parameters
+ * PF does NOT respond! VF driver must delay then poll VFGEN_RSTAT register
+ * until reset completion is indicated. The admin queue must be reinitialized
+ * after this operation.
+ *
+ * When reset is complete, PF must ensure that all queues in all VSIs associated
+ * with the VF are stopped, all queue configurations in the HMC are set to 0,
+ * and all MAC and VLAN filters (except the default MAC address) on all VSIs
+ * are cleared.
+ */
+
+/* VSI types that use VIRTCHNL interface for VF-PF communication. VSI_SRIOV
+ * vsi_type should always be 6 for backward compatibility. Add other fields
+ * as needed.
+ */
+enum virtchnl_vsi_type {
+ VIRTCHNL_VSI_TYPE_INVALID = 0,
+ VIRTCHNL_VSI_SRIOV = 6,
+};
+
+/* VIRTCHNL_OP_GET_VF_RESOURCES
+ * Version 1.0 VF sends this request to PF with no parameters
+ * Version 1.1 VF sends this request to PF with u32 bitmap of its capabilities
+ * PF responds with an indirect message containing
+ * virtchnl_vf_resource and one or more
+ * virtchnl_vsi_resource structures.
+ */
+
+struct virtchnl_vsi_resource {
+ u16 vsi_id;
+ u16 num_queue_pairs;
+ enum virtchnl_vsi_type vsi_type;
+ u16 qset_handle;
+ u8 default_mac_addr[VIRTCHNL_ETH_LENGTH_OF_ADDRESS];
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_vsi_resource);
+
+/* VF capability flags
+ * VIRTCHNL_VF_OFFLOAD_L2 flag is inclusive of base mode L2 offloads including
+ * TX/RX Checksum offloading and TSO for non-tunnelled packets.
+ */
+#define VIRTCHNL_VF_OFFLOAD_L2 0x00000001
+#define VIRTCHNL_VF_OFFLOAD_IWARP 0x00000002
+#define VIRTCHNL_VF_OFFLOAD_RSVD 0x00000004
+#define VIRTCHNL_VF_OFFLOAD_RSS_AQ 0x00000008
+#define VIRTCHNL_VF_OFFLOAD_RSS_REG 0x00000010
+#define VIRTCHNL_VF_OFFLOAD_WB_ON_ITR 0x00000020
+#define VIRTCHNL_VF_OFFLOAD_REQ_QUEUES 0x00000040
+#define VIRTCHNL_VF_OFFLOAD_VLAN 0x00010000
+#define VIRTCHNL_VF_OFFLOAD_RX_POLLING 0x00020000
+#define VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2 0x00040000
+#define VIRTCHNL_VF_OFFLOAD_RSS_PF 0X00080000
+#define VIRTCHNL_VF_OFFLOAD_ENCAP 0X00100000
+#define VIRTCHNL_VF_OFFLOAD_ENCAP_CSUM 0X00200000
+#define VIRTCHNL_VF_OFFLOAD_RX_ENCAP_CSUM 0X00400000
+
+#define VF_BASE_MODE_OFFLOADS (VIRTCHNL_VF_OFFLOAD_L2 | \
+ VIRTCHNL_VF_OFFLOAD_VLAN | \
+ VIRTCHNL_VF_OFFLOAD_RSS_PF)
+
+struct virtchnl_vf_resource {
+ u16 num_vsis;
+ u16 num_queue_pairs;
+ u16 max_vectors;
+ u16 max_mtu;
+
+ u32 vf_cap_flags;
+ u32 rss_key_size;
+ u32 rss_lut_size;
+
+ struct virtchnl_vsi_resource vsi_res[1];
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(36, virtchnl_vf_resource);
+
+/* VIRTCHNL_OP_CONFIG_TX_QUEUE
+ * VF sends this message to set up parameters for one TX queue.
+ * External data buffer contains one instance of virtchnl_txq_info.
+ * PF configures requested queue and returns a status code.
+ */
+
+/* Tx queue config info */
+struct virtchnl_txq_info {
+ u16 vsi_id;
+ u16 queue_id;
+ u16 ring_len; /* number of descriptors, multiple of 8 */
+ u16 headwb_enabled; /* deprecated with AVF 1.0 */
+ u64 dma_ring_addr;
+ u64 dma_headwb_addr; /* deprecated with AVF 1.0 */
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_txq_info);
+
+/* VIRTCHNL_OP_CONFIG_RX_QUEUE
+ * VF sends this message to set up parameters for one RX queue.
+ * External data buffer contains one instance of virtchnl_rxq_info.
+ * PF configures requested queue and returns a status code.
+ */
+
+/* Rx queue config info */
+struct virtchnl_rxq_info {
+ u16 vsi_id;
+ u16 queue_id;
+ u32 ring_len; /* number of descriptors, multiple of 32 */
+ u16 hdr_size;
+ u16 splithdr_enabled; /* deprecated with AVF 1.0 */
+ u32 databuffer_size;
+ u32 max_pkt_size;
+ u32 pad1;
+ u64 dma_ring_addr;
+ enum virtchnl_rx_hsplit rx_split_pos; /* deprecated with AVF 1.0 */
+ u32 pad2;
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(40, virtchnl_rxq_info);
+
+/* VIRTCHNL_OP_CONFIG_VSI_QUEUES
+ * VF sends this message to set parameters for all active TX and RX queues
+ * associated with the specified VSI.
+ * PF configures queues and returns status.
+ * If the number of queues specified is greater than the number of queues
+ * associated with the VSI, an error is returned and no queues are configured.
+ */
+struct virtchnl_queue_pair_info {
+ /* NOTE: vsi_id and queue_id should be identical for both queues. */
+ struct virtchnl_txq_info txq;
+ struct virtchnl_rxq_info rxq;
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(64, virtchnl_queue_pair_info);
+
+struct virtchnl_vsi_queue_config_info {
+ u16 vsi_id;
+ u16 num_queue_pairs;
+ u32 pad;
+ struct virtchnl_queue_pair_info qpair[1];
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(72, virtchnl_vsi_queue_config_info);
+
+/* VIRTCHNL_OP_REQUEST_QUEUES
+ * VF sends this message to request the PF to allocate additional queues to
+ * this VF. Each VF gets a guaranteed number of queues on init but asking for
+ * additional queues must be negotiated. This is a best effort request as it
+ * is possible the PF does not have enough queues left to support the request.
+ * If the PF cannot support the number requested it will respond with the
+ * maximum number it is able to support. If the request is successful, PF will
+ * then reset the VF to institute required changes.
+ */
+
+/* VF resource request */
+struct virtchnl_vf_res_request {
+ u16 num_queue_pairs;
+};
+
+/* VIRTCHNL_OP_CONFIG_IRQ_MAP
+ * VF uses this message to map vectors to queues.
+ * The rxq_map and txq_map fields are bitmaps used to indicate which queues
+ * are to be associated with the specified vector.
+ * The "other" causes are always mapped to vector 0.
+ * PF configures interrupt mapping and returns status.
+ */
+struct virtchnl_vector_map {
+ u16 vsi_id;
+ u16 vector_id;
+ u16 rxq_map;
+ u16 txq_map;
+ u16 rxitr_idx;
+ u16 txitr_idx;
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_vector_map);
+
+struct virtchnl_irq_map_info {
+ u16 num_vectors;
+ struct virtchnl_vector_map vecmap[1];
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(14, virtchnl_irq_map_info);
+
+/* VIRTCHNL_OP_ENABLE_QUEUES
+ * VIRTCHNL_OP_DISABLE_QUEUES
+ * VF sends these message to enable or disable TX/RX queue pairs.
+ * The queues fields are bitmaps indicating which queues to act upon.
+ * (Currently, we only support 16 queues per VF, but we make the field
+ * u32 to allow for expansion.)
+ * PF performs requested action and returns status.
+ */
+struct virtchnl_queue_select {
+ u16 vsi_id;
+ u16 pad;
+ u32 rx_queues;
+ u32 tx_queues;
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_queue_select);
+
+/* VIRTCHNL_OP_ADD_ETH_ADDR
+ * VF sends this message in order to add one or more unicast or multicast
+ * address filters for the specified VSI.
+ * PF adds the filters and returns status.
+ */
+
+/* VIRTCHNL_OP_DEL_ETH_ADDR
+ * VF sends this message in order to remove one or more unicast or multicast
+ * filters for the specified VSI.
+ * PF removes the filters and returns status.
+ */
+
+struct virtchnl_ether_addr {
+ u8 addr[VIRTCHNL_ETH_LENGTH_OF_ADDRESS];
+ u8 pad[2];
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_ether_addr);
+
+struct virtchnl_ether_addr_list {
+ u16 vsi_id;
+ u16 num_elements;
+ struct virtchnl_ether_addr list[1];
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_ether_addr_list);
+
+#ifdef VIRTCHNL_SOL_VF_SUPPORT
+/* VIRTCHNL_OP_GET_ADDNL_SOL_CONFIG
+ * VF sends this message to get the default MTU and list of additional ethernet
+ * addresses it is allowed to use.
+ * PF responds with an indirect message containing
+ * virtchnl_addnl_solaris_config with zero or more
+ * virtchnl_ether_addr structures.
+ *
+ * It is expected that this operation will only ever be needed for Solaris VFs
+ * running under a Solaris PF.
+ */
+struct virtchnl_addnl_solaris_config {
+ u16 default_mtu;
+ struct virtchnl_ether_addr_list al;
+};
+
+#endif
+/* VIRTCHNL_OP_ADD_VLAN
+ * VF sends this message to add one or more VLAN tag filters for receives.
+ * PF adds the filters and returns status.
+ * If a port VLAN is configured by the PF, this operation will return an
+ * error to the VF.
+ */
+
+/* VIRTCHNL_OP_DEL_VLAN
+ * VF sends this message to remove one or more VLAN tag filters for receives.
+ * PF removes the filters and returns status.
+ * If a port VLAN is configured by the PF, this operation will return an
+ * error to the VF.
+ */
+
+struct virtchnl_vlan_filter_list {
+ u16 vsi_id;
+ u16 num_elements;
+ u16 vlan_id[1];
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_vlan_filter_list);
+
+/* VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE
+ * VF sends VSI id and flags.
+ * PF returns status code in retval.
+ * Note: we assume that broadcast accept mode is always enabled.
+ */
+struct virtchnl_promisc_info {
+ u16 vsi_id;
+ u16 flags;
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(4, virtchnl_promisc_info);
+
+#define FLAG_VF_UNICAST_PROMISC 0x00000001
+#define FLAG_VF_MULTICAST_PROMISC 0x00000002
+
+/* VIRTCHNL_OP_GET_STATS
+ * VF sends this message to request stats for the selected VSI. VF uses
+ * the virtchnl_queue_select struct to specify the VSI. The queue_id
+ * field is ignored by the PF.
+ *
+ * PF replies with struct virtchnl_eth_stats in an external buffer.
+ */
+
+struct virtchnl_eth_stats {
+ u64 rx_bytes; /* received bytes */
+ u64 rx_unicast; /* received unicast pkts */
+ u64 rx_multicast; /* received multicast pkts */
+ u64 rx_broadcast; /* received broadcast pkts */
+ u64 rx_discards;
+ u64 rx_unknown_protocol;
+ u64 tx_bytes; /* transmitted bytes*/
+ u64 tx_unicast; /* transmitted unicast pkts */
+ u64 tx_multicast; /* transmitted multicast pkts */
+ u64 tx_broadcast; /* transmitted broadcast pkts */
+ u64 tx_discards;
+ u64 tx_errors;
+};
+
+/* VIRTCHNL_OP_CONFIG_RSS_KEY
+ * VIRTCHNL_OP_CONFIG_RSS_LUT
+ * VF sends these messages to configure RSS. Only supported if both PF
+ * and VF drivers set the VIRTCHNL_VF_OFFLOAD_RSS_PF bit during
+ * configuration negotiation. If this is the case, then the RSS fields in
+ * the VF resource struct are valid.
+ * Both the key and LUT are initialized to 0 by the PF, meaning that
+ * RSS is effectively disabled until set up by the VF.
+ */
+struct virtchnl_rss_key {
+ u16 vsi_id;
+ u16 key_len;
+ u8 key[1]; /* RSS hash key, packed bytes */
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_rss_key);
+
+struct virtchnl_rss_lut {
+ u16 vsi_id;
+ u16 lut_entries;
+ u8 lut[1]; /* RSS lookup table */
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(6, virtchnl_rss_lut);
+
+/* VIRTCHNL_OP_GET_RSS_HENA_CAPS
+ * VIRTCHNL_OP_SET_RSS_HENA
+ * VF sends these messages to get and set the hash filter enable bits for RSS.
+ * By default, the PF sets these to all possible traffic types that the
+ * hardware supports. The VF can query this value if it wants to change the
+ * traffic types that are hashed by the hardware.
+ */
+struct virtchnl_rss_hena {
+ u64 hena;
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(8, virtchnl_rss_hena);
+
+/* VIRTCHNL_OP_EVENT
+ * PF sends this message to inform the VF driver of events that may affect it.
+ * No direct response is expected from the VF, though it may generate other
+ * messages in response to this one.
+ */
+enum virtchnl_event_codes {
+ VIRTCHNL_EVENT_UNKNOWN = 0,
+ VIRTCHNL_EVENT_LINK_CHANGE,
+ VIRTCHNL_EVENT_RESET_IMPENDING,
+ VIRTCHNL_EVENT_PF_DRIVER_CLOSE,
+};
+
+#define PF_EVENT_SEVERITY_INFO 0
+#define PF_EVENT_SEVERITY_ATTENTION 1
+#define PF_EVENT_SEVERITY_ACTION_REQUIRED 2
+#define PF_EVENT_SEVERITY_CERTAIN_DOOM 255
+
+struct virtchnl_pf_event {
+ enum virtchnl_event_codes event;
+ union {
+ struct {
+ enum virtchnl_link_speed link_speed;
+ bool link_status;
+ } link_event;
+ } event_data;
+
+ int severity;
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_pf_event);
+
+#ifdef VIRTCHNL_IWARP
+
+/* VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP
+ * VF uses this message to request PF to map IWARP vectors to IWARP queues.
+ * The request for this originates from the VF IWARP driver through
+ * a client interface between VF LAN and VF IWARP driver.
+ * A vector could have an AEQ and CEQ attached to it although
+ * there is a single AEQ per VF IWARP instance in which case
+ * most vectors will have an INVALID_IDX for aeq and valid idx for ceq.
+ * There will never be a case where there will be multiple CEQs attached
+ * to a single vector.
+ * PF configures interrupt mapping and returns status.
+ */
+
+/* HW does not define a type value for AEQ; only for RX/TX and CEQ.
+ * In order for us to keep the interface simple, SW will define a
+ * unique type value for AEQ.
+ */
+#define QUEUE_TYPE_PE_AEQ 0x80
+#define QUEUE_INVALID_IDX 0xFFFF
+
+struct virtchnl_iwarp_qv_info {
+ u32 v_idx; /* msix_vector */
+ u16 ceq_idx;
+ u16 aeq_idx;
+ u8 itr_idx;
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(12, virtchnl_iwarp_qv_info);
+
+struct virtchnl_iwarp_qvlist_info {
+ u32 num_vectors;
+ struct virtchnl_iwarp_qv_info qv_info[1];
+};
+
+VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_iwarp_qvlist_info);
+
+#endif
+
+/* VF reset states - these are written into the RSTAT register:
+ * VFGEN_RSTAT on the VF
+ * When the PF initiates a reset, it writes 0
+ * When the reset is complete, it writes 1
+ * When the PF detects that the VF has recovered, it writes 2
+ * VF checks this register periodically to determine if a reset has occurred,
+ * then polls it to know when the reset is complete.
+ * If either the PF or VF reads the register while the hardware
+ * is in a reset state, it will return DEADBEEF, which, when masked
+ * will result in 3.
+ */
+enum virtchnl_vfr_states {
+ VIRTCHNL_VFR_INPROGRESS = 0,
+ VIRTCHNL_VFR_COMPLETED,
+ VIRTCHNL_VFR_VFACTIVE,
+};
+
+/**
+ * virtchnl_vc_validate_vf_msg
+ * @ver: Virtchnl version info
+ * @v_opcode: Opcode for the message
+ * @msg: pointer to the msg buffer
+ * @msglen: msg length
+ *
+ * validate msg format against struct for each opcode
+ */
+static inline int
+virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode,
+ u8 *msg, u16 msglen)
+{
+ bool err_msg_format = false;
+ int valid_len = 0;
+
+ /* Validate message length. */
+ switch (v_opcode) {
+ case VIRTCHNL_OP_VERSION:
+ valid_len = sizeof(struct virtchnl_version_info);
+ break;
+ case VIRTCHNL_OP_RESET_VF:
+ break;
+ case VIRTCHNL_OP_GET_VF_RESOURCES:
+ if (VF_IS_V11(ver))
+ valid_len = sizeof(u32);
+ break;
+ case VIRTCHNL_OP_CONFIG_TX_QUEUE:
+ valid_len = sizeof(struct virtchnl_txq_info);
+ break;
+ case VIRTCHNL_OP_CONFIG_RX_QUEUE:
+ valid_len = sizeof(struct virtchnl_rxq_info);
+ break;
+ case VIRTCHNL_OP_CONFIG_VSI_QUEUES:
+ valid_len = sizeof(struct virtchnl_vsi_queue_config_info);
+ if (msglen >= valid_len) {
+ struct virtchnl_vsi_queue_config_info *vqc =
+ (struct virtchnl_vsi_queue_config_info *)msg;
+ valid_len += (vqc->num_queue_pairs *
+ sizeof(struct
+ virtchnl_queue_pair_info));
+ if (vqc->num_queue_pairs == 0)
+ err_msg_format = true;
+ }
+ break;
+ case VIRTCHNL_OP_CONFIG_IRQ_MAP:
+ valid_len = sizeof(struct virtchnl_irq_map_info);
+ if (msglen >= valid_len) {
+ struct virtchnl_irq_map_info *vimi =
+ (struct virtchnl_irq_map_info *)msg;
+ valid_len += (vimi->num_vectors *
+ sizeof(struct virtchnl_vector_map));
+ if (vimi->num_vectors == 0)
+ err_msg_format = true;
+ }
+ break;
+ case VIRTCHNL_OP_ENABLE_QUEUES:
+ case VIRTCHNL_OP_DISABLE_QUEUES:
+ valid_len = sizeof(struct virtchnl_queue_select);
+ break;
+ case VIRTCHNL_OP_ADD_ETH_ADDR:
+ case VIRTCHNL_OP_DEL_ETH_ADDR:
+ valid_len = sizeof(struct virtchnl_ether_addr_list);
+ if (msglen >= valid_len) {
+ struct virtchnl_ether_addr_list *veal =
+ (struct virtchnl_ether_addr_list *)msg;
+ valid_len += veal->num_elements *
+ sizeof(struct virtchnl_ether_addr);
+ if (veal->num_elements == 0)
+ err_msg_format = true;
+ }
+ break;
+ case VIRTCHNL_OP_ADD_VLAN:
+ case VIRTCHNL_OP_DEL_VLAN:
+ valid_len = sizeof(struct virtchnl_vlan_filter_list);
+ if (msglen >= valid_len) {
+ struct virtchnl_vlan_filter_list *vfl =
+ (struct virtchnl_vlan_filter_list *)msg;
+ valid_len += vfl->num_elements * sizeof(u16);
+ if (vfl->num_elements == 0)
+ err_msg_format = true;
+ }
+ break;
+ case VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE:
+ valid_len = sizeof(struct virtchnl_promisc_info);
+ break;
+ case VIRTCHNL_OP_GET_STATS:
+ valid_len = sizeof(struct virtchnl_queue_select);
+ break;
+#ifdef VIRTCHNL_IWARP
+ case VIRTCHNL_OP_IWARP:
+ /* These messages are opaque to us and will be validated in
+ * the RDMA client code. We just need to check for nonzero
+ * length. The firmware will enforce max length restrictions.
+ */
+ if (msglen)
+ valid_len = msglen;
+ else
+ err_msg_format = true;
+ break;
+ case VIRTCHNL_OP_RELEASE_IWARP_IRQ_MAP:
+ break;
+ case VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP:
+ valid_len = sizeof(struct virtchnl_iwarp_qvlist_info);
+ if (msglen >= valid_len) {
+ struct virtchnl_iwarp_qvlist_info *qv =
+ (struct virtchnl_iwarp_qvlist_info *)msg;
+ if (qv->num_vectors == 0) {
+ err_msg_format = true;
+ break;
+ }
+ valid_len += ((qv->num_vectors - 1) *
+ sizeof(struct virtchnl_iwarp_qv_info));
+ }
+ break;
+#endif
+ case VIRTCHNL_OP_CONFIG_RSS_KEY:
+ valid_len = sizeof(struct virtchnl_rss_key);
+ if (msglen >= valid_len) {
+ struct virtchnl_rss_key *vrk =
+ (struct virtchnl_rss_key *)msg;
+ valid_len += vrk->key_len - 1;
+ }
+ break;
+ case VIRTCHNL_OP_CONFIG_RSS_LUT:
+ valid_len = sizeof(struct virtchnl_rss_lut);
+ if (msglen >= valid_len) {
+ struct virtchnl_rss_lut *vrl =
+ (struct virtchnl_rss_lut *)msg;
+ valid_len += vrl->lut_entries - 1;
+ }
+ break;
+ case VIRTCHNL_OP_GET_RSS_HENA_CAPS:
+ break;
+ case VIRTCHNL_OP_SET_RSS_HENA:
+ valid_len = sizeof(struct virtchnl_rss_hena);
+ break;
+ case VIRTCHNL_OP_ENABLE_VLAN_STRIPPING:
+ case VIRTCHNL_OP_DISABLE_VLAN_STRIPPING:
+ break;
+ case VIRTCHNL_OP_REQUEST_QUEUES:
+ valid_len = sizeof(struct virtchnl_vf_res_request);
+ break;
+ /* These are always errors coming from the VF. */
+ case VIRTCHNL_OP_EVENT:
+ case VIRTCHNL_OP_UNKNOWN:
+ default:
+ return VIRTCHNL_ERR_PARAM;
+ }
+ /* few more checks */
+ if (err_msg_format || valid_len != msglen)
+ return VIRTCHNL_STATUS_ERR_OPCODE_MISMATCH;
+
+ return 0;
+}
+#endif /* _VIRTCHNL_H_ */
diff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h
new file mode 100644
index 0000000..dcf8d1c
--- /dev/null
+++ b/drivers/net/iavf/iavf.h
@@ -0,0 +1,216 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017 Intel Corporation
+ */
+
+#ifndef _AVF_ETHDEV_H_
+#define _AVF_ETHDEV_H_
+
+#include <rte_kvargs.h>
+
+#define AVF_AQ_LEN 32
+#define AVF_AQ_BUF_SZ 4096
+#define AVF_RESET_WAIT_CNT 50
+#define AVF_BUF_SIZE_MIN 1024
+#define AVF_FRAME_SIZE_MAX 9728
+#define AVF_QUEUE_BASE_ADDR_UNIT 128
+
+#define AVF_MAX_NUM_QUEUES 16
+
+#define AVF_NUM_MACADDR_MAX 64
+
+#define AVF_DEFAULT_RX_PTHRESH 8
+#define AVF_DEFAULT_RX_HTHRESH 8
+#define AVF_DEFAULT_RX_WTHRESH 0
+
+#define AVF_DEFAULT_RX_FREE_THRESH 32
+
+#define AVF_DEFAULT_TX_PTHRESH 32
+#define AVF_DEFAULT_TX_HTHRESH 0
+#define AVF_DEFAULT_TX_WTHRESH 0
+
+#define AVF_DEFAULT_TX_FREE_THRESH 32
+#define AVF_DEFAULT_TX_RS_THRESH 32
+
+#define AVF_BASIC_OFFLOAD_CAPS ( \
+ VF_BASE_MODE_OFFLOADS | \
+ VIRTCHNL_VF_OFFLOAD_WB_ON_ITR | \
+ VIRTCHNL_VF_OFFLOAD_RX_POLLING)
+
+#define AVF_RSS_OFFLOAD_ALL ( \
+ ETH_RSS_FRAG_IPV4 | \
+ ETH_RSS_NONFRAG_IPV4_TCP | \
+ ETH_RSS_NONFRAG_IPV4_UDP | \
+ ETH_RSS_NONFRAG_IPV4_SCTP | \
+ ETH_RSS_NONFRAG_IPV4_OTHER)
+
+#define AVF_MISC_VEC_ID RTE_INTR_VEC_ZERO_OFFSET
+#define AVF_RX_VEC_START RTE_INTR_VEC_RXTX_OFFSET
+
+/* Default queue interrupt throttling time in microseconds */
+#define AVF_ITR_INDEX_DEFAULT 0
+#define AVF_QUEUE_ITR_INTERVAL_DEFAULT 32 /* 32 us */
+#define AVF_QUEUE_ITR_INTERVAL_MAX 8160 /* 8160 us */
+
+/* The overhead from MTU to max frame size.
+ * Considering QinQ packet, the VLAN tag needs to be counted twice.
+ */
+#define AVF_VLAN_TAG_SIZE 4
+#define AVF_ETH_OVERHEAD \
+ (ETHER_HDR_LEN + ETHER_CRC_LEN + AVF_VLAN_TAG_SIZE * 2)
+
+struct avf_adapter;
+struct avf_rx_queue;
+struct avf_tx_queue;
+
+/* Structure that defines a VSI, associated with a adapter. */
+struct avf_vsi {
+ struct avf_adapter *adapter; /* Backreference to associated adapter */
+ uint16_t vsi_id;
+ uint16_t nb_qps; /* Number of queue pairs VSI can occupy */
+ uint16_t nb_used_qps; /* Number of queue pairs VSI uses */
+ uint16_t max_macaddrs; /* Maximum number of MAC addresses */
+ uint16_t base_vector;
+ uint16_t msix_intr; /* The MSIX interrupt binds to VSI */
+};
+
+/* TODO: is that correct to assume the max number to be 16 ?*/
+#define AVF_MAX_MSIX_VECTORS 16
+
+/* Structure to store private data specific for VF instance. */
+struct avf_info {
+ uint16_t num_queue_pairs;
+ uint16_t max_pkt_len; /* Maximum packet length */
+ uint16_t mac_num; /* Number of MAC addresses */
+ bool promisc_unicast_enabled;
+ bool promisc_multicast_enabled;
+
+ struct virtchnl_version_info virtchnl_version;
+ struct virtchnl_vf_resource *vf_res; /* VF resource */
+ struct virtchnl_vsi_resource *vsi_res; /* LAN VSI */
+
+ volatile enum virtchnl_ops pend_cmd; /* pending command not finished */
+ uint32_t cmd_retval; /* return value of the cmd response from PF */
+ uint8_t *aq_resp; /* buffer to store the adminq response from PF */
+
+ /* Event from pf */
+ bool dev_closed;
+ bool link_up;
+ enum virtchnl_link_speed link_speed;
+
+ struct avf_vsi vsi;
+ bool vf_reset;
+ uint64_t flags;
+
+ uint8_t *rss_lut;
+ uint8_t *rss_key;
+ uint16_t nb_msix; /* number of MSI-X interrupts on Rx */
+ uint16_t msix_base; /* msix vector base from */
+ /* queue bitmask for each vector */
+ uint16_t rxq_map[AVF_MAX_MSIX_VECTORS];
+};
+
+#define AVF_MAX_PKT_TYPE 256
+
+/* Structure to store private data for each VF instance. */
+struct avf_adapter {
+ struct avf_hw hw;
+ struct rte_eth_dev *eth_dev;
+ struct avf_info vf;
+
+ bool rx_bulk_alloc_allowed;
+ /* For vector PMD */
+ bool rx_vec_allowed;
+ bool tx_vec_allowed;
+};
+
+/* AVF_DEV_PRIVATE_TO */
+#define AVF_DEV_PRIVATE_TO_ADAPTER(adapter) \
+ ((struct avf_adapter *)adapter)
+#define AVF_DEV_PRIVATE_TO_VF(adapter) \
+ (&((struct avf_adapter *)adapter)->vf)
+#define AVF_DEV_PRIVATE_TO_HW(adapter) \
+ (&((struct avf_adapter *)adapter)->hw)
+
+/* AVF_VSI_TO */
+#define AVF_VSI_TO_HW(vsi) \
+ (&(((struct avf_vsi *)vsi)->adapter->hw))
+#define AVF_VSI_TO_VF(vsi) \
+ (&(((struct avf_vsi *)vsi)->adapter->vf))
+#define AVF_VSI_TO_ETH_DEV(vsi) \
+ (((struct avf_vsi *)vsi)->adapter->eth_dev)
+
+static inline void
+avf_init_adminq_parameter(struct avf_hw *hw)
+{
+ hw->aq.num_arq_entries = AVF_AQ_LEN;
+ hw->aq.num_asq_entries = AVF_AQ_LEN;
+ hw->aq.arq_buf_size = AVF_AQ_BUF_SZ;
+ hw->aq.asq_buf_size = AVF_AQ_BUF_SZ;
+}
+
+static inline uint16_t
+avf_calc_itr_interval(int16_t interval)
+{
+ if (interval < 0 || interval > AVF_QUEUE_ITR_INTERVAL_MAX)
+ interval = AVF_QUEUE_ITR_INTERVAL_DEFAULT;
+
+ /* Convert to hardware count, as writing each 1 represents 2 us */
+ return interval / 2;
+}
+
+/* structure used for sending and checking response of virtchnl ops */
+struct avf_cmd_info {
+ enum virtchnl_ops ops;
+ uint8_t *in_args; /* buffer for sending */
+ uint32_t in_args_size; /* buffer size for sending */
+ uint8_t *out_buffer; /* buffer for response */
+ uint32_t out_size; /* buffer size for response */
+};
+
+/* clear current command. Only call in case execute
+ * _atomic_set_cmd successfully.
+ */
+static inline void
+_clear_cmd(struct avf_info *vf)
+{
+ rte_wmb();
+ vf->pend_cmd = VIRTCHNL_OP_UNKNOWN;
+ vf->cmd_retval = VIRTCHNL_STATUS_SUCCESS;
+}
+
+/* Check there is pending cmd in execution. If none, set new command. */
+static inline int
+_atomic_set_cmd(struct avf_info *vf, enum virtchnl_ops ops)
+{
+ int ret = rte_atomic32_cmpset(&vf->pend_cmd, VIRTCHNL_OP_UNKNOWN, ops);
+
+ if (!ret)
+ PMD_DRV_LOG(ERR, "There is incomplete cmd %d", vf->pend_cmd);
+
+ return !ret;
+}
+
+int avf_check_api_version(struct avf_adapter *adapter);
+int avf_get_vf_resource(struct avf_adapter *adapter);
+void avf_handle_virtchnl_msg(struct rte_eth_dev *dev);
+int avf_enable_vlan_strip(struct avf_adapter *adapter);
+int avf_disable_vlan_strip(struct avf_adapter *adapter);
+int avf_switch_queue(struct avf_adapter *adapter, uint16_t qid,
+ bool rx, bool on);
+int avf_enable_queues(struct avf_adapter *adapter);
+int avf_disable_queues(struct avf_adapter *adapter);
+int avf_configure_rss_lut(struct avf_adapter *adapter);
+int avf_configure_rss_key(struct avf_adapter *adapter);
+int avf_configure_queues(struct avf_adapter *adapter);
+int avf_config_irq_map(struct avf_adapter *adapter);
+void avf_add_del_all_mac_addr(struct avf_adapter *adapter, bool add);
+int avf_dev_link_update(struct rte_eth_dev *dev,
+ __rte_unused int wait_to_complete);
+int avf_query_stats(struct avf_adapter *adapter,
+ struct virtchnl_eth_stats **pstats);
+int avf_config_promisc(struct avf_adapter *adapter, bool enable_unicast,
+ bool enable_multicast);
+int avf_add_del_eth_addr(struct avf_adapter *adapter,
+ struct ether_addr *addr, bool add);
+int avf_add_del_vlan(struct avf_adapter *adapter, uint16_t vlanid, bool add);
+#endif /* _AVF_ETHDEV_H_ */
diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c
new file mode 100644
index 0000000..efc20e1
--- /dev/null
+++ b/drivers/net/iavf/iavf_ethdev.c
@@ -0,0 +1,1428 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017 Intel Corporation
+ */
+
+#include <sys/queue.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <inttypes.h>
+#include <rte_byteorder.h>
+#include <rte_common.h>
+
+#include <rte_interrupts.h>
+#include <rte_debug.h>
+#include <rte_pci.h>
+#include <rte_atomic.h>
+#include <rte_eal.h>
+#include <rte_ether.h>
+#include <rte_ethdev_driver.h>
+#include <rte_ethdev_pci.h>
+#include <rte_malloc.h>
+#include <rte_memzone.h>
+#include <rte_dev.h>
+
+#include "iavf_log.h"
+#include "base/iavf_prototype.h"
+#include "base/iavf_adminq_cmd.h"
+#include "base/iavf_type.h"
+
+#include "iavf.h"
+#include "iavf_rxtx.h"
+
+static int avf_dev_configure(struct rte_eth_dev *dev);
+static int avf_dev_start(struct rte_eth_dev *dev);
+static void avf_dev_stop(struct rte_eth_dev *dev);
+static void avf_dev_close(struct rte_eth_dev *dev);
+static void avf_dev_info_get(struct rte_eth_dev *dev,
+ struct rte_eth_dev_info *dev_info);
+static const uint32_t *avf_dev_supported_ptypes_get(struct rte_eth_dev *dev);
+static int avf_dev_stats_get(struct rte_eth_dev *dev,
+ struct rte_eth_stats *stats);
+static void avf_dev_promiscuous_enable(struct rte_eth_dev *dev);
+static void avf_dev_promiscuous_disable(struct rte_eth_dev *dev);
+static void avf_dev_allmulticast_enable(struct rte_eth_dev *dev);
+static void avf_dev_allmulticast_disable(struct rte_eth_dev *dev);
+static int avf_dev_add_mac_addr(struct rte_eth_dev *dev,
+ struct ether_addr *addr,
+ uint32_t index,
+ uint32_t pool);
+static void avf_dev_del_mac_addr(struct rte_eth_dev *dev, uint32_t index);
+static int avf_dev_vlan_filter_set(struct rte_eth_dev *dev,
+ uint16_t vlan_id, int on);
+static int avf_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
+static int avf_dev_rss_reta_update(struct rte_eth_dev *dev,
+ struct rte_eth_rss_reta_entry64 *reta_conf,
+ uint16_t reta_size);
+static int avf_dev_rss_reta_query(struct rte_eth_dev *dev,
+ struct rte_eth_rss_reta_entry64 *reta_conf,
+ uint16_t reta_size);
+static int avf_dev_rss_hash_update(struct rte_eth_dev *dev,
+ struct rte_eth_rss_conf *rss_conf);
+static int avf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
+ struct rte_eth_rss_conf *rss_conf);
+static int avf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
+static int avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
+ struct ether_addr *mac_addr);
+static int avf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev,
+ uint16_t queue_id);
+static int avf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev,
+ uint16_t queue_id);
+
+int avf_logtype_init;
+int avf_logtype_driver;
+
+static const struct rte_pci_id pci_id_avf_map[] = {
+ { RTE_PCI_DEVICE(AVF_INTEL_VENDOR_ID, AVF_DEV_ID_ADAPTIVE_VF) },
+ { .vendor_id = 0, /* sentinel */ },
+};
+
+static const struct eth_dev_ops avf_eth_dev_ops = {
+ .dev_configure = avf_dev_configure,
+ .dev_start = avf_dev_start,
+ .dev_stop = avf_dev_stop,
+ .dev_close = avf_dev_close,
+ .dev_infos_get = avf_dev_info_get,
+ .dev_supported_ptypes_get = avf_dev_supported_ptypes_get,
+ .link_update = avf_dev_link_update,
+ .stats_get = avf_dev_stats_get,
+ .promiscuous_enable = avf_dev_promiscuous_enable,
+ .promiscuous_disable = avf_dev_promiscuous_disable,
+ .allmulticast_enable = avf_dev_allmulticast_enable,
+ .allmulticast_disable = avf_dev_allmulticast_disable,
+ .mac_addr_add = avf_dev_add_mac_addr,
+ .mac_addr_remove = avf_dev_del_mac_addr,
+ .vlan_filter_set = avf_dev_vlan_filter_set,
+ .vlan_offload_set = avf_dev_vlan_offload_set,
+ .rx_queue_start = avf_dev_rx_queue_start,
+ .rx_queue_stop = avf_dev_rx_queue_stop,
+ .tx_queue_start = avf_dev_tx_queue_start,
+ .tx_queue_stop = avf_dev_tx_queue_stop,
+ .rx_queue_setup = avf_dev_rx_queue_setup,
+ .rx_queue_release = avf_dev_rx_queue_release,
+ .tx_queue_setup = avf_dev_tx_queue_setup,
+ .tx_queue_release = avf_dev_tx_queue_release,
+ .mac_addr_set = avf_dev_set_default_mac_addr,
+ .reta_update = avf_dev_rss_reta_update,
+ .reta_query = avf_dev_rss_reta_query,
+ .rss_hash_update = avf_dev_rss_hash_update,
+ .rss_hash_conf_get = avf_dev_rss_hash_conf_get,
+ .rxq_info_get = avf_dev_rxq_info_get,
+ .txq_info_get = avf_dev_txq_info_get,
+ .rx_queue_count = avf_dev_rxq_count,
+ .rx_descriptor_status = avf_dev_rx_desc_status,
+ .tx_descriptor_status = avf_dev_tx_desc_status,
+ .mtu_set = avf_dev_mtu_set,
+ .rx_queue_intr_enable = avf_dev_rx_queue_intr_enable,
+ .rx_queue_intr_disable = avf_dev_rx_queue_intr_disable,
+};
+
+static int
+avf_dev_configure(struct rte_eth_dev *dev)
+{
+ struct avf_adapter *ad =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(ad);
+ struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
+
+ ad->rx_bulk_alloc_allowed = true;
+#ifdef RTE_LIBRTE_AVF_INC_VECTOR
+ /* Initialize to TRUE. If any of Rx queues doesn't meet the
+ * vector Rx/Tx preconditions, it will be reset.
+ */
+ ad->rx_vec_allowed = true;
+ ad->tx_vec_allowed = true;
+#else
+ ad->rx_vec_allowed = false;
+ ad->tx_vec_allowed = false;
+#endif
+
+ /* Vlan stripping setting */
+ if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN) {
+ if (dev_conf->rxmode.offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
+ avf_enable_vlan_strip(ad);
+ else
+ avf_disable_vlan_strip(ad);
+ }
+ return 0;
+}
+
+static int
+avf_init_rss(struct avf_adapter *adapter)
+{
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ struct rte_eth_rss_conf *rss_conf;
+ uint8_t i, j, nb_q;
+ int ret;
+
+ rss_conf = &adapter->eth_dev->data->dev_conf.rx_adv_conf.rss_conf;
+ nb_q = RTE_MIN(adapter->eth_dev->data->nb_rx_queues,
+ AVF_MAX_NUM_QUEUES);
+
+ if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF)) {
+ PMD_DRV_LOG(DEBUG, "RSS is not supported");
+ return -ENOTSUP;
+ }
+ if (adapter->eth_dev->data->dev_conf.rxmode.mq_mode != ETH_MQ_RX_RSS) {
+ PMD_DRV_LOG(WARNING, "RSS is enabled by PF by default");
+ /* set all lut items to default queue */
+ for (i = 0; i < vf->vf_res->rss_lut_size; i++)
+ vf->rss_lut[i] = 0;
+ ret = avf_configure_rss_lut(adapter);
+ return ret;
+ }
+
+ /* In AVF, RSS enablement is set by PF driver. It is not supported
+ * to set based on rss_conf->rss_hf.
+ */
+
+ /* configure RSS key */
+ if (!rss_conf->rss_key) {
+ /* Calculate the default hash key */
+ for (i = 0; i <= vf->vf_res->rss_key_size; i++)
+ vf->rss_key[i] = (uint8_t)rte_rand();
+ } else
+ rte_memcpy(vf->rss_key, rss_conf->rss_key,
+ RTE_MIN(rss_conf->rss_key_len,
+ vf->vf_res->rss_key_size));
+
+ /* init RSS LUT table */
+ for (i = 0, j = 0; i < vf->vf_res->rss_lut_size; i++, j++) {
+ if (j >= nb_q)
+ j = 0;
+ vf->rss_lut[i] = j;
+ }
+ /* send virtchnnl ops to configure rss*/
+ ret = avf_configure_rss_lut(adapter);
+ if (ret)
+ return ret;
+ ret = avf_configure_rss_key(adapter);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int
+avf_init_rxq(struct rte_eth_dev *dev, struct avf_rx_queue *rxq)
+{
+ struct avf_hw *hw = AVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct rte_eth_dev_data *dev_data = dev->data;
+ uint16_t buf_size, max_pkt_len, len;
+
+ buf_size = rte_pktmbuf_data_room_size(rxq->mp) - RTE_PKTMBUF_HEADROOM;
+
+ /* Calculate the maximum packet length allowed */
+ len = rxq->rx_buf_len * AVF_MAX_CHAINED_RX_BUFFERS;
+ max_pkt_len = RTE_MIN(len, dev->data->dev_conf.rxmode.max_rx_pkt_len);
+
+ /* Check if the jumbo frame and maximum packet length are set
+ * correctly.
+ */
+ if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) {
+ if (max_pkt_len <= ETHER_MAX_LEN ||
+ max_pkt_len > AVF_FRAME_SIZE_MAX) {
+ PMD_DRV_LOG(ERR, "maximum packet length must be "
+ "larger than %u and smaller than %u, "
+ "as jumbo frame is enabled",
+ (uint32_t)ETHER_MAX_LEN,
+ (uint32_t)AVF_FRAME_SIZE_MAX);
+ return -EINVAL;
+ }
+ } else {
+ if (max_pkt_len < ETHER_MIN_LEN ||
+ max_pkt_len > ETHER_MAX_LEN) {
+ PMD_DRV_LOG(ERR, "maximum packet length must be "
+ "larger than %u and smaller than %u, "
+ "as jumbo frame is disabled",
+ (uint32_t)ETHER_MIN_LEN,
+ (uint32_t)ETHER_MAX_LEN);
+ return -EINVAL;
+ }
+ }
+
+ rxq->max_pkt_len = max_pkt_len;
+ if ((dev_data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_SCATTER) ||
+ (rxq->max_pkt_len + 2 * AVF_VLAN_TAG_SIZE) > buf_size) {
+ dev_data->scattered_rx = 1;
+ }
+ AVF_PCI_REG_WRITE(rxq->qrx_tail, rxq->nb_rx_desc - 1);
+ AVF_WRITE_FLUSH(hw);
+
+ return 0;
+}
+
+static int
+avf_init_queues(struct rte_eth_dev *dev)
+{
+ struct avf_rx_queue **rxq =
+ (struct avf_rx_queue **)dev->data->rx_queues;
+ int i, ret = AVF_SUCCESS;
+
+ for (i = 0; i < dev->data->nb_rx_queues; i++) {
+ if (!rxq[i] || !rxq[i]->q_set)
+ continue;
+ ret = avf_init_rxq(dev, rxq[i]);
+ if (ret != AVF_SUCCESS)
+ break;
+ }
+ /* set rx/tx function to vector/scatter/single-segment
+ * according to parameters
+ */
+ avf_set_rx_function(dev);
+ avf_set_tx_function(dev);
+
+ return ret;
+}
+
+static int avf_config_rx_queues_irqs(struct rte_eth_dev *dev,
+ struct rte_intr_handle *intr_handle)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ struct avf_hw *hw = AVF_DEV_PRIVATE_TO_HW(adapter);
+ uint16_t interval, i;
+ int vec;
+
+ if (rte_intr_cap_multiple(intr_handle) &&
+ dev->data->dev_conf.intr_conf.rxq) {
+ if (rte_intr_efd_enable(intr_handle, dev->data->nb_rx_queues))
+ return -1;
+ }
+
+ if (rte_intr_dp_is_en(intr_handle) && !intr_handle->intr_vec) {
+ intr_handle->intr_vec =
+ rte_zmalloc("intr_vec",
+ dev->data->nb_rx_queues * sizeof(int), 0);
+ if (!intr_handle->intr_vec) {
+ PMD_DRV_LOG(ERR, "Failed to allocate %d rx intr_vec",
+ dev->data->nb_rx_queues);
+ return -1;
+ }
+ }
+
+ if (!dev->data->dev_conf.intr_conf.rxq ||
+ !rte_intr_dp_is_en(intr_handle)) {
+ /* Rx interrupt disabled, Map interrupt only for writeback */
+ vf->nb_msix = 1;
+ if (vf->vf_res->vf_cap_flags &
+ VIRTCHNL_VF_OFFLOAD_WB_ON_ITR) {
+ /* If WB_ON_ITR supports, enable it */
+ vf->msix_base = AVF_RX_VEC_START;
+ AVF_WRITE_REG(hw, AVFINT_DYN_CTLN1(vf->msix_base - 1),
+ AVFINT_DYN_CTLN1_ITR_INDX_MASK |
+ AVFINT_DYN_CTLN1_WB_ON_ITR_MASK);
+ } else {
+ /* If no WB_ON_ITR offload flags, need to set
+ * interrupt for descriptor write back.
+ */
+ vf->msix_base = AVF_MISC_VEC_ID;
+
+ /* set ITR to max */
+ interval = avf_calc_itr_interval(
+ AVF_QUEUE_ITR_INTERVAL_MAX);
+ AVF_WRITE_REG(hw, AVFINT_DYN_CTL01,
+ AVFINT_DYN_CTL01_INTENA_MASK |
+ (AVF_ITR_INDEX_DEFAULT <<
+ AVFINT_DYN_CTL01_ITR_INDX_SHIFT) |
+ (interval <<
+ AVFINT_DYN_CTL01_INTERVAL_SHIFT));
+ }
+ AVF_WRITE_FLUSH(hw);
+ /* map all queues to the same interrupt */
+ for (i = 0; i < dev->data->nb_rx_queues; i++)
+ vf->rxq_map[vf->msix_base] |= 1 << i;
+ } else {
+ if (!rte_intr_allow_others(intr_handle)) {
+ vf->nb_msix = 1;
+ vf->msix_base = AVF_MISC_VEC_ID;
+ for (i = 0; i < dev->data->nb_rx_queues; i++) {
+ vf->rxq_map[vf->msix_base] |= 1 << i;
+ intr_handle->intr_vec[i] = AVF_MISC_VEC_ID;
+ }
+ PMD_DRV_LOG(DEBUG,
+ "vector %u are mapping to all Rx queues",
+ vf->msix_base);
+ } else {
+ /* If Rx interrupt is reuquired, and we can use
+ * multi interrupts, then the vec is from 1
+ */
+ vf->nb_msix = RTE_MIN(vf->vf_res->max_vectors,
+ intr_handle->nb_efd);
+ vf->msix_base = AVF_RX_VEC_START;
+ vec = AVF_RX_VEC_START;
+ for (i = 0; i < dev->data->nb_rx_queues; i++) {
+ vf->rxq_map[vec] |= 1 << i;
+ intr_handle->intr_vec[i] = vec++;
+ if (vec >= vf->nb_msix)
+ vec = AVF_RX_VEC_START;
+ }
+ PMD_DRV_LOG(DEBUG,
+ "%u vectors are mapping to %u Rx queues",
+ vf->nb_msix, dev->data->nb_rx_queues);
+ }
+ }
+
+ if (avf_config_irq_map(adapter)) {
+ PMD_DRV_LOG(ERR, "config interrupt mapping failed");
+ return -1;
+ }
+ return 0;
+}
+
+static int
+avf_start_queues(struct rte_eth_dev *dev)
+{
+ struct avf_rx_queue *rxq;
+ struct avf_tx_queue *txq;
+ int i;
+
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ if (txq->tx_deferred_start)
+ continue;
+ if (avf_dev_tx_queue_start(dev, i) != 0) {
+ PMD_DRV_LOG(ERR, "Fail to start queue %u", i);
+ return -1;
+ }
+ }
+
+ for (i = 0; i < dev->data->nb_rx_queues; i++) {
+ rxq = dev->data->rx_queues[i];
+ if (rxq->rx_deferred_start)
+ continue;
+ if (avf_dev_rx_queue_start(dev, i) != 0) {
+ PMD_DRV_LOG(ERR, "Fail to start queue %u", i);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+avf_dev_start(struct rte_eth_dev *dev)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+ struct avf_hw *hw = AVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct rte_intr_handle *intr_handle = dev->intr_handle;
+
+ PMD_INIT_FUNC_TRACE();
+
+ hw->adapter_stopped = 0;
+
+ vf->max_pkt_len = dev->data->dev_conf.rxmode.max_rx_pkt_len;
+ vf->num_queue_pairs = RTE_MAX(dev->data->nb_rx_queues,
+ dev->data->nb_tx_queues);
+
+ if (avf_init_queues(dev) != 0) {
+ PMD_DRV_LOG(ERR, "failed to do Queue init");
+ return -1;
+ }
+
+ if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF) {
+ if (avf_init_rss(adapter) != 0) {
+ PMD_DRV_LOG(ERR, "configure rss failed");
+ goto err_rss;
+ }
+ }
+
+ if (avf_configure_queues(adapter) != 0) {
+ PMD_DRV_LOG(ERR, "configure queues failed");
+ goto err_queue;
+ }
+
+ if (avf_config_rx_queues_irqs(dev, intr_handle) != 0) {
+ PMD_DRV_LOG(ERR, "configure irq failed");
+ goto err_queue;
+ }
+ /* re-enable intr again, because efd assign may change */
+ if (dev->data->dev_conf.intr_conf.rxq != 0) {
+ rte_intr_disable(intr_handle);
+ rte_intr_enable(intr_handle);
+ }
+
+ /* Set all mac addrs */
+ avf_add_del_all_mac_addr(adapter, TRUE);
+
+ if (avf_start_queues(dev) != 0) {
+ PMD_DRV_LOG(ERR, "enable queues failed");
+ goto err_mac;
+ }
+
+ return 0;
+
+err_mac:
+ avf_add_del_all_mac_addr(adapter, FALSE);
+err_queue:
+err_rss:
+ return -1;
+}
+
+static void
+avf_dev_stop(struct rte_eth_dev *dev)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_hw *hw = AVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct rte_intr_handle *intr_handle = dev->intr_handle;
+
+ PMD_INIT_FUNC_TRACE();
+
+ if (hw->adapter_stopped == 1)
+ return;
+
+ avf_stop_queues(dev);
+
+ /* Disable the interrupt for Rx */
+ rte_intr_efd_disable(intr_handle);
+ /* Rx interrupt vector mapping free */
+ if (intr_handle->intr_vec) {
+ rte_free(intr_handle->intr_vec);
+ intr_handle->intr_vec = NULL;
+ }
+
+ /* remove all mac addrs */
+ avf_add_del_all_mac_addr(adapter, FALSE);
+ hw->adapter_stopped = 1;
+}
+
+static void
+avf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
+{
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+
+ memset(dev_info, 0, sizeof(*dev_info));
+ dev_info->max_rx_queues = vf->vsi_res->num_queue_pairs;
+ dev_info->max_tx_queues = vf->vsi_res->num_queue_pairs;
+ dev_info->min_rx_bufsize = AVF_BUF_SIZE_MIN;
+ dev_info->max_rx_pktlen = AVF_FRAME_SIZE_MAX;
+ dev_info->hash_key_size = vf->vf_res->rss_key_size;
+ dev_info->reta_size = vf->vf_res->rss_lut_size;
+ dev_info->flow_type_rss_offloads = AVF_RSS_OFFLOAD_ALL;
+ dev_info->max_mac_addrs = AVF_NUM_MACADDR_MAX;
+ dev_info->rx_offload_capa =
+ DEV_RX_OFFLOAD_VLAN_STRIP |
+ DEV_RX_OFFLOAD_QINQ_STRIP |
+ DEV_RX_OFFLOAD_IPV4_CKSUM |
+ DEV_RX_OFFLOAD_UDP_CKSUM |
+ DEV_RX_OFFLOAD_TCP_CKSUM |
+ DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM |
+ DEV_RX_OFFLOAD_SCATTER |
+ DEV_RX_OFFLOAD_JUMBO_FRAME |
+ DEV_RX_OFFLOAD_VLAN_FILTER;
+ dev_info->tx_offload_capa =
+ DEV_TX_OFFLOAD_VLAN_INSERT |
+ DEV_TX_OFFLOAD_QINQ_INSERT |
+ DEV_TX_OFFLOAD_IPV4_CKSUM |
+ DEV_TX_OFFLOAD_UDP_CKSUM |
+ DEV_TX_OFFLOAD_TCP_CKSUM |
+ DEV_TX_OFFLOAD_SCTP_CKSUM |
+ DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM |
+ DEV_TX_OFFLOAD_TCP_TSO |
+ DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
+ DEV_TX_OFFLOAD_GRE_TNL_TSO |
+ DEV_TX_OFFLOAD_IPIP_TNL_TSO |
+ DEV_TX_OFFLOAD_GENEVE_TNL_TSO |
+ DEV_TX_OFFLOAD_MULTI_SEGS;
+
+ dev_info->default_rxconf = (struct rte_eth_rxconf) {
+ .rx_free_thresh = AVF_DEFAULT_RX_FREE_THRESH,
+ .rx_drop_en = 0,
+ .offloads = 0,
+ };
+
+ dev_info->default_txconf = (struct rte_eth_txconf) {
+ .tx_free_thresh = AVF_DEFAULT_TX_FREE_THRESH,
+ .tx_rs_thresh = AVF_DEFAULT_TX_RS_THRESH,
+ .offloads = 0,
+ };
+
+ dev_info->rx_desc_lim = (struct rte_eth_desc_lim) {
+ .nb_max = AVF_MAX_RING_DESC,
+ .nb_min = AVF_MIN_RING_DESC,
+ .nb_align = AVF_ALIGN_RING_DESC,
+ };
+
+ dev_info->tx_desc_lim = (struct rte_eth_desc_lim) {
+ .nb_max = AVF_MAX_RING_DESC,
+ .nb_min = AVF_MIN_RING_DESC,
+ .nb_align = AVF_ALIGN_RING_DESC,
+ };
+}
+
+static const uint32_t *
+avf_dev_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused)
+{
+ static const uint32_t ptypes[] = {
+ RTE_PTYPE_L2_ETHER,
+ RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
+ RTE_PTYPE_L4_FRAG,
+ RTE_PTYPE_L4_ICMP,
+ RTE_PTYPE_L4_NONFRAG,
+ RTE_PTYPE_L4_SCTP,
+ RTE_PTYPE_L4_TCP,
+ RTE_PTYPE_L4_UDP,
+ RTE_PTYPE_UNKNOWN
+ };
+ return ptypes;
+}
+
+int
+avf_dev_link_update(struct rte_eth_dev *dev,
+ __rte_unused int wait_to_complete)
+{
+ struct rte_eth_link new_link;
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+
+ /* Only read status info stored in VF, and the info is updated
+ * when receive LINK_CHANGE evnet from PF by Virtchnnl.
+ */
+ switch (vf->link_speed) {
+ case VIRTCHNL_LINK_SPEED_100MB:
+ new_link.link_speed = ETH_SPEED_NUM_100M;
+ break;
+ case VIRTCHNL_LINK_SPEED_1GB:
+ new_link.link_speed = ETH_SPEED_NUM_1G;
+ break;
+ case VIRTCHNL_LINK_SPEED_10GB:
+ new_link.link_speed = ETH_SPEED_NUM_10G;
+ break;
+ case VIRTCHNL_LINK_SPEED_20GB:
+ new_link.link_speed = ETH_SPEED_NUM_20G;
+ break;
+ case VIRTCHNL_LINK_SPEED_25GB:
+ new_link.link_speed = ETH_SPEED_NUM_25G;
+ break;
+ case VIRTCHNL_LINK_SPEED_40GB:
+ new_link.link_speed = ETH_SPEED_NUM_40G;
+ break;
+ default:
+ new_link.link_speed = ETH_SPEED_NUM_NONE;
+ break;
+ }
+
+ new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
+ new_link.link_status = vf->link_up ? ETH_LINK_UP :
+ ETH_LINK_DOWN;
+ new_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+ ETH_LINK_SPEED_FIXED);
+
+ if (rte_atomic64_cmpset((uint64_t *)&dev->data->dev_link,
+ *(uint64_t *)&dev->data->dev_link,
+ *(uint64_t *)&new_link) == 0)
+ return -1;
+
+ return 0;
+}
+
+static void
+avf_dev_promiscuous_enable(struct rte_eth_dev *dev)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ int ret;
+
+ if (vf->promisc_unicast_enabled)
+ return;
+
+ ret = avf_config_promisc(adapter, TRUE, vf->promisc_multicast_enabled);
+ if (!ret)
+ vf->promisc_unicast_enabled = TRUE;
+}
+
+static void
+avf_dev_promiscuous_disable(struct rte_eth_dev *dev)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ int ret;
+
+ if (!vf->promisc_unicast_enabled)
+ return;
+
+ ret = avf_config_promisc(adapter, FALSE, vf->promisc_multicast_enabled);
+ if (!ret)
+ vf->promisc_unicast_enabled = FALSE;
+}
+
+static void
+avf_dev_allmulticast_enable(struct rte_eth_dev *dev)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ int ret;
+
+ if (vf->promisc_multicast_enabled)
+ return;
+
+ ret = avf_config_promisc(adapter, vf->promisc_unicast_enabled, TRUE);
+ if (!ret)
+ vf->promisc_multicast_enabled = TRUE;
+}
+
+static void
+avf_dev_allmulticast_disable(struct rte_eth_dev *dev)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ int ret;
+
+ if (!vf->promisc_multicast_enabled)
+ return;
+
+ ret = avf_config_promisc(adapter, vf->promisc_unicast_enabled, FALSE);
+ if (!ret)
+ vf->promisc_multicast_enabled = FALSE;
+}
+
+static int
+avf_dev_add_mac_addr(struct rte_eth_dev *dev, struct ether_addr *addr,
+ __rte_unused uint32_t index,
+ __rte_unused uint32_t pool)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ int err;
+
+ if (is_zero_ether_addr(addr)) {
+ PMD_DRV_LOG(ERR, "Invalid Ethernet Address");
+ return -EINVAL;
+ }
+
+ err = avf_add_del_eth_addr(adapter, addr, TRUE);
+ if (err) {
+ PMD_DRV_LOG(ERR, "fail to add MAC address");
+ return -EIO;
+ }
+
+ vf->mac_num++;
+
+ return 0;
+}
+
+static void
+avf_dev_del_mac_addr(struct rte_eth_dev *dev, uint32_t index)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ struct ether_addr *addr;
+ int err;
+
+ addr = &dev->data->mac_addrs[index];
+
+ err = avf_add_del_eth_addr(adapter, addr, FALSE);
+ if (err)
+ PMD_DRV_LOG(ERR, "fail to delete MAC address");
+
+ vf->mac_num--;
+}
+
+static int
+avf_dev_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ int err;
+
+ if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN))
+ return -ENOTSUP;
+
+ err = avf_add_del_vlan(adapter, vlan_id, on);
+ if (err)
+ return -EIO;
+ return 0;
+}
+
+static int
+avf_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
+ int err;
+
+ if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN))
+ return -ENOTSUP;
+
+ /* Vlan stripping setting */
+ if (mask & ETH_VLAN_STRIP_MASK) {
+ /* Enable or disable VLAN stripping */
+ if (dev_conf->rxmode.offloads & DEV_RX_OFFLOAD_VLAN_STRIP)
+ err = avf_enable_vlan_strip(adapter);
+ else
+ err = avf_disable_vlan_strip(adapter);
+
+ if (err)
+ return -EIO;
+ }
+ return 0;
+}
+
+static int
+avf_dev_rss_reta_update(struct rte_eth_dev *dev,
+ struct rte_eth_rss_reta_entry64 *reta_conf,
+ uint16_t reta_size)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ uint8_t *lut;
+ uint16_t i, idx, shift;
+ int ret;
+
+ if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF))
+ return -ENOTSUP;
+
+ if (reta_size != vf->vf_res->rss_lut_size) {
+ PMD_DRV_LOG(ERR, "The size of hash lookup table configured "
+ "(%d) doesn't match the number of hardware can "
+ "support (%d)", reta_size, vf->vf_res->rss_lut_size);
+ return -EINVAL;
+ }
+
+ lut = rte_zmalloc("rss_lut", reta_size, 0);
+ if (!lut) {
+ PMD_DRV_LOG(ERR, "No memory can be allocated");
+ return -ENOMEM;
+ }
+ /* store the old lut table temporarily */
+ rte_memcpy(lut, vf->rss_lut, reta_size);
+
+ for (i = 0; i < reta_size; i++) {
+ idx = i / RTE_RETA_GROUP_SIZE;
+ shift = i % RTE_RETA_GROUP_SIZE;
+ if (reta_conf[idx].mask & (1ULL << shift))
+ lut[i] = reta_conf[idx].reta[shift];
+ }
+
+ rte_memcpy(vf->rss_lut, lut, reta_size);
+ /* send virtchnnl ops to configure rss*/
+ ret = avf_configure_rss_lut(adapter);
+ if (ret) /* revert back */
+ rte_memcpy(vf->rss_lut, lut, reta_size);
+ rte_free(lut);
+
+ return ret;
+}
+
+static int
+avf_dev_rss_reta_query(struct rte_eth_dev *dev,
+ struct rte_eth_rss_reta_entry64 *reta_conf,
+ uint16_t reta_size)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ uint16_t i, idx, shift;
+
+ if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF))
+ return -ENOTSUP;
+
+ if (reta_size != vf->vf_res->rss_lut_size) {
+ PMD_DRV_LOG(ERR, "The size of hash lookup table configured "
+ "(%d) doesn't match the number of hardware can "
+ "support (%d)", reta_size, vf->vf_res->rss_lut_size);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < reta_size; i++) {
+ idx = i / RTE_RETA_GROUP_SIZE;
+ shift = i % RTE_RETA_GROUP_SIZE;
+ if (reta_conf[idx].mask & (1ULL << shift))
+ reta_conf[idx].reta[shift] = vf->rss_lut[i];
+ }
+
+ return 0;
+}
+
+static int
+avf_dev_rss_hash_update(struct rte_eth_dev *dev,
+ struct rte_eth_rss_conf *rss_conf)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+
+ if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF))
+ return -ENOTSUP;
+
+ /* HENA setting, it is enabled by default, no change */
+ if (!rss_conf->rss_key || rss_conf->rss_key_len == 0) {
+ PMD_DRV_LOG(DEBUG, "No key to be configured");
+ return 0;
+ } else if (rss_conf->rss_key_len != vf->vf_res->rss_key_size) {
+ PMD_DRV_LOG(ERR, "The size of hash key configured "
+ "(%d) doesn't match the size of hardware can "
+ "support (%d)", rss_conf->rss_key_len,
+ vf->vf_res->rss_key_size);
+ return -EINVAL;
+ }
+
+ rte_memcpy(vf->rss_key, rss_conf->rss_key, rss_conf->rss_key_len);
+
+ return avf_configure_rss_key(adapter);
+}
+
+static int
+avf_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
+ struct rte_eth_rss_conf *rss_conf)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+
+ if (!(vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF))
+ return -ENOTSUP;
+
+ /* Just set it to default value now. */
+ rss_conf->rss_hf = AVF_RSS_OFFLOAD_ALL;
+
+ if (!rss_conf->rss_key)
+ return 0;
+
+ rss_conf->rss_key_len = vf->vf_res->rss_key_size;
+ rte_memcpy(rss_conf->rss_key, vf->rss_key, rss_conf->rss_key_len);
+
+ return 0;
+}
+
+static int
+avf_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
+{
+ uint32_t frame_size = mtu + AVF_ETH_OVERHEAD;
+ int ret = 0;
+
+ if (mtu < ETHER_MIN_MTU || frame_size > AVF_FRAME_SIZE_MAX)
+ return -EINVAL;
+
+ /* mtu setting is forbidden if port is start */
+ if (dev->data->dev_started) {
+ PMD_DRV_LOG(ERR, "port must be stopped before configuration");
+ return -EBUSY;
+ }
+
+ if (frame_size > ETHER_MAX_LEN)
+ dev->data->dev_conf.rxmode.offloads |=
+ DEV_RX_OFFLOAD_JUMBO_FRAME;
+ else
+ dev->data->dev_conf.rxmode.offloads &=
+ ~DEV_RX_OFFLOAD_JUMBO_FRAME;
+
+ dev->data->dev_conf.rxmode.max_rx_pkt_len = frame_size;
+
+ return ret;
+}
+
+static int
+avf_dev_set_default_mac_addr(struct rte_eth_dev *dev,
+ struct ether_addr *mac_addr)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_hw *hw = AVF_DEV_PRIVATE_TO_HW(adapter);
+ struct ether_addr *perm_addr, *old_addr;
+ int ret;
+
+ old_addr = (struct ether_addr *)hw->mac.addr;
+ perm_addr = (struct ether_addr *)hw->mac.perm_addr;
+
+ if (is_same_ether_addr(mac_addr, old_addr))
+ return 0;
+
+ /* If the MAC address is configured by host, skip the setting */
+ if (is_valid_assigned_ether_addr(perm_addr))
+ return -EPERM;
+
+ ret = avf_add_del_eth_addr(adapter, old_addr, FALSE);
+ if (ret)
+ PMD_DRV_LOG(ERR, "Fail to delete old MAC:"
+ " %02X:%02X:%02X:%02X:%02X:%02X",
+ old_addr->addr_bytes[0],
+ old_addr->addr_bytes[1],
+ old_addr->addr_bytes[2],
+ old_addr->addr_bytes[3],
+ old_addr->addr_bytes[4],
+ old_addr->addr_bytes[5]);
+
+ ret = avf_add_del_eth_addr(adapter, mac_addr, TRUE);
+ if (ret)
+ PMD_DRV_LOG(ERR, "Fail to add new MAC:"
+ " %02X:%02X:%02X:%02X:%02X:%02X",
+ mac_addr->addr_bytes[0],
+ mac_addr->addr_bytes[1],
+ mac_addr->addr_bytes[2],
+ mac_addr->addr_bytes[3],
+ mac_addr->addr_bytes[4],
+ mac_addr->addr_bytes[5]);
+
+ if (ret)
+ return -EIO;
+
+ ether_addr_copy(mac_addr, (struct ether_addr *)hw->mac.addr);
+ return 0;
+}
+
+static int
+avf_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct virtchnl_eth_stats *pstats = NULL;
+ int ret;
+
+ ret = avf_query_stats(adapter, &pstats);
+ if (ret == 0) {
+ stats->ipackets = pstats->rx_unicast + pstats->rx_multicast +
+ pstats->rx_broadcast;
+ stats->opackets = pstats->tx_broadcast + pstats->tx_multicast +
+ pstats->tx_unicast;
+ stats->imissed = pstats->rx_discards;
+ stats->oerrors = pstats->tx_errors + pstats->tx_discards;
+ stats->ibytes = pstats->rx_bytes;
+ stats->obytes = pstats->tx_bytes;
+ } else {
+ PMD_DRV_LOG(ERR, "Get statistics failed");
+ }
+ return -EIO;
+}
+
+static int
+avf_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+ struct avf_hw *hw = AVF_DEV_PRIVATE_TO_HW(adapter);
+ uint16_t msix_intr;
+
+ msix_intr = pci_dev->intr_handle.intr_vec[queue_id];
+ if (msix_intr == AVF_MISC_VEC_ID) {
+ PMD_DRV_LOG(INFO, "MISC is also enabled for control");
+ AVF_WRITE_REG(hw, AVFINT_DYN_CTL01,
+ AVFINT_DYN_CTL01_INTENA_MASK |
+ AVFINT_DYN_CTL01_ITR_INDX_MASK);
+ } else {
+ AVF_WRITE_REG(hw,
+ AVFINT_DYN_CTLN1(msix_intr - AVF_RX_VEC_START),
+ AVFINT_DYN_CTLN1_INTENA_MASK |
+ AVFINT_DYN_CTLN1_ITR_INDX_MASK);
+ }
+
+ AVF_WRITE_FLUSH(hw);
+
+ rte_intr_enable(&pci_dev->intr_handle);
+
+ return 0;
+}
+
+static int
+avf_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+ struct avf_hw *hw = AVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint16_t msix_intr;
+
+ msix_intr = pci_dev->intr_handle.intr_vec[queue_id];
+ if (msix_intr == AVF_MISC_VEC_ID) {
+ PMD_DRV_LOG(ERR, "MISC is used for control, cannot disable it");
+ return -EIO;
+ }
+
+ AVF_WRITE_REG(hw,
+ AVFINT_DYN_CTLN1(msix_intr - AVF_RX_VEC_START),
+ 0);
+
+ AVF_WRITE_FLUSH(hw);
+ return 0;
+}
+
+static int
+avf_check_vf_reset_done(struct avf_hw *hw)
+{
+ int i, reset;
+
+ for (i = 0; i < AVF_RESET_WAIT_CNT; i++) {
+ reset = AVF_READ_REG(hw, AVFGEN_RSTAT) &
+ AVFGEN_RSTAT_VFR_STATE_MASK;
+ reset = reset >> AVFGEN_RSTAT_VFR_STATE_SHIFT;
+ if (reset == VIRTCHNL_VFR_VFACTIVE ||
+ reset == VIRTCHNL_VFR_COMPLETED)
+ break;
+ rte_delay_ms(20);
+ }
+
+ if (i >= AVF_RESET_WAIT_CNT)
+ return -1;
+
+ return 0;
+}
+
+static int
+avf_init_vf(struct rte_eth_dev *dev)
+{
+ int err, bufsz;
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_hw *hw = AVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+
+ err = avf_set_mac_type(hw);
+ if (err) {
+ PMD_INIT_LOG(ERR, "set_mac_type failed: %d", err);
+ goto err;
+ }
+
+ err = avf_check_vf_reset_done(hw);
+ if (err) {
+ PMD_INIT_LOG(ERR, "VF is still resetting");
+ goto err;
+ }
+
+ avf_init_adminq_parameter(hw);
+ err = avf_init_adminq(hw);
+ if (err) {
+ PMD_INIT_LOG(ERR, "init_adminq failed: %d", err);
+ goto err;
+ }
+
+ vf->aq_resp = rte_zmalloc("vf_aq_resp", AVF_AQ_BUF_SZ, 0);
+ if (!vf->aq_resp) {
+ PMD_INIT_LOG(ERR, "unable to allocate vf_aq_resp memory");
+ goto err_aq;
+ }
+ if (avf_check_api_version(adapter) != 0) {
+ PMD_INIT_LOG(ERR, "check_api version failed");
+ goto err_api;
+ }
+
+ bufsz = sizeof(struct virtchnl_vf_resource) +
+ (AVF_MAX_VF_VSI * sizeof(struct virtchnl_vsi_resource));
+ vf->vf_res = rte_zmalloc("vf_res", bufsz, 0);
+ if (!vf->vf_res) {
+ PMD_INIT_LOG(ERR, "unable to allocate vf_res memory");
+ goto err_api;
+ }
+ if (avf_get_vf_resource(adapter) != 0) {
+ PMD_INIT_LOG(ERR, "avf_get_vf_config failed");
+ goto err_alloc;
+ }
+ /* Allocate memort for RSS info */
+ if (vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_RSS_PF) {
+ vf->rss_key = rte_zmalloc("rss_key",
+ vf->vf_res->rss_key_size, 0);
+ if (!vf->rss_key) {
+ PMD_INIT_LOG(ERR, "unable to allocate rss_key memory");
+ goto err_rss;
+ }
+ vf->rss_lut = rte_zmalloc("rss_lut",
+ vf->vf_res->rss_lut_size, 0);
+ if (!vf->rss_lut) {
+ PMD_INIT_LOG(ERR, "unable to allocate rss_lut memory");
+ goto err_rss;
+ }
+ }
+ return 0;
+err_rss:
+ rte_free(vf->rss_key);
+ rte_free(vf->rss_lut);
+err_alloc:
+ rte_free(vf->vf_res);
+ vf->vsi_res = NULL;
+err_api:
+ rte_free(vf->aq_resp);
+err_aq:
+ avf_shutdown_adminq(hw);
+err:
+ return -1;
+}
+
+/* Enable default admin queue interrupt setting */
+static inline void
+avf_enable_irq0(struct avf_hw *hw)
+{
+ /* Enable admin queue interrupt trigger */
+ AVF_WRITE_REG(hw, AVFINT_ICR0_ENA1, AVFINT_ICR0_ENA1_ADMINQ_MASK);
+
+ AVF_WRITE_REG(hw, AVFINT_DYN_CTL01, AVFINT_DYN_CTL01_INTENA_MASK |
+ AVFINT_DYN_CTL01_CLEARPBA_MASK | AVFINT_DYN_CTL01_ITR_INDX_MASK);
+
+ AVF_WRITE_FLUSH(hw);
+}
+
+static inline void
+avf_disable_irq0(struct avf_hw *hw)
+{
+ /* Disable all interrupt types */
+ AVF_WRITE_REG(hw, AVFINT_ICR0_ENA1, 0);
+ AVF_WRITE_REG(hw, AVFINT_DYN_CTL01,
+ AVFINT_DYN_CTL01_ITR_INDX_MASK);
+ AVF_WRITE_FLUSH(hw);
+}
+
+static void
+avf_dev_interrupt_handler(void *param)
+{
+ struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
+ struct avf_hw *hw = AVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ avf_disable_irq0(hw);
+
+ avf_handle_virtchnl_msg(dev);
+
+ avf_enable_irq0(hw);
+}
+
+static int
+avf_dev_init(struct rte_eth_dev *eth_dev)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(eth_dev->data->dev_private);
+ struct avf_hw *hw = AVF_DEV_PRIVATE_TO_HW(adapter);
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+
+ PMD_INIT_FUNC_TRACE();
+
+ /* assign ops func pointer */
+ eth_dev->dev_ops = &avf_eth_dev_ops;
+ eth_dev->rx_pkt_burst = &avf_recv_pkts;
+ eth_dev->tx_pkt_burst = &avf_xmit_pkts;
+ eth_dev->tx_pkt_prepare = &avf_prep_pkts;
+
+ /* For secondary processes, we don't initialise any further as primary
+ * has already done this work. Only check if we need a different RX
+ * and TX function.
+ */
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+ avf_set_rx_function(eth_dev);
+ avf_set_tx_function(eth_dev);
+ return 0;
+ }
+ rte_eth_copy_pci_info(eth_dev, pci_dev);
+
+ hw->vendor_id = pci_dev->id.vendor_id;
+ hw->device_id = pci_dev->id.device_id;
+ hw->subsystem_vendor_id = pci_dev->id.subsystem_vendor_id;
+ hw->subsystem_device_id = pci_dev->id.subsystem_device_id;
+ hw->bus.bus_id = pci_dev->addr.bus;
+ hw->bus.device = pci_dev->addr.devid;
+ hw->bus.func = pci_dev->addr.function;
+ hw->hw_addr = (void *)pci_dev->mem_resource[0].addr;
+ hw->back = AVF_DEV_PRIVATE_TO_ADAPTER(eth_dev->data->dev_private);
+ adapter->eth_dev = eth_dev;
+
+ if (avf_init_vf(eth_dev) != 0) {
+ PMD_INIT_LOG(ERR, "Init vf failed");
+ return -1;
+ }
+
+ /* copy mac addr */
+ eth_dev->data->mac_addrs = rte_zmalloc(
+ "avf_mac",
+ ETHER_ADDR_LEN * AVF_NUM_MACADDR_MAX,
+ 0);
+ if (!eth_dev->data->mac_addrs) {
+ PMD_INIT_LOG(ERR, "Failed to allocate %d bytes needed to"
+ " store MAC addresses",
+ ETHER_ADDR_LEN * AVF_NUM_MACADDR_MAX);
+ return -ENOMEM;
+ }
+ /* If the MAC address is not configured by host,
+ * generate a random one.
+ */
+ if (!is_valid_assigned_ether_addr((struct ether_addr *)hw->mac.addr))
+ eth_random_addr(hw->mac.addr);
+ ether_addr_copy((struct ether_addr *)hw->mac.addr,
+ &eth_dev->data->mac_addrs[0]);
+
+ /* register callback func to eal lib */
+ rte_intr_callback_register(&pci_dev->intr_handle,
+ avf_dev_interrupt_handler,
+ (void *)eth_dev);
+
+ /* enable uio intr after callback register */
+ rte_intr_enable(&pci_dev->intr_handle);
+
+ /* configure and enable device interrupt */
+ avf_enable_irq0(hw);
+
+ return 0;
+}
+
+static void
+avf_dev_close(struct rte_eth_dev *dev)
+{
+ struct avf_hw *hw = AVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+ struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
+
+ avf_dev_stop(dev);
+ avf_shutdown_adminq(hw);
+ /* disable uio intr before callback unregister */
+ rte_intr_disable(intr_handle);
+
+ /* unregister callback func from eal lib */
+ rte_intr_callback_unregister(intr_handle,
+ avf_dev_interrupt_handler, dev);
+ avf_disable_irq0(hw);
+}
+
+static int
+avf_dev_uninit(struct rte_eth_dev *dev)
+{
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+ struct avf_hw *hw = AVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+ return -EPERM;
+
+ dev->dev_ops = NULL;
+ dev->rx_pkt_burst = NULL;
+ dev->tx_pkt_burst = NULL;
+ if (hw->adapter_stopped == 0)
+ avf_dev_close(dev);
+
+ rte_free(vf->vf_res);
+ vf->vsi_res = NULL;
+ vf->vf_res = NULL;
+
+ rte_free(vf->aq_resp);
+ vf->aq_resp = NULL;
+
+ if (vf->rss_lut) {
+ rte_free(vf->rss_lut);
+ vf->rss_lut = NULL;
+ }
+ if (vf->rss_key) {
+ rte_free(vf->rss_key);
+ vf->rss_key = NULL;
+ }
+
+ return 0;
+}
+
+static int eth_avf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
+ struct rte_pci_device *pci_dev)
+{
+ return rte_eth_dev_pci_generic_probe(pci_dev,
+ sizeof(struct avf_adapter), avf_dev_init);
+}
+
+static int eth_avf_pci_remove(struct rte_pci_device *pci_dev)
+{
+ return rte_eth_dev_pci_generic_remove(pci_dev, avf_dev_uninit);
+}
+
+/* Adaptive virtual function driver struct */
+static struct rte_pci_driver rte_avf_pmd = {
+ .id_table = pci_id_avf_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
+ RTE_PCI_DRV_IOVA_AS_VA,
+ .probe = eth_avf_pci_probe,
+ .remove = eth_avf_pci_remove,
+};
+
+RTE_PMD_REGISTER_PCI(net_avf, rte_avf_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(net_avf, pci_id_avf_map);
+RTE_PMD_REGISTER_KMOD_DEP(net_avf, "* igb_uio | vfio-pci");
+RTE_INIT(avf_init_log)
+{
+ avf_logtype_init = rte_log_register("pmd.net.avf.init");
+ if (avf_logtype_init >= 0)
+ rte_log_set_level(avf_logtype_init, RTE_LOG_NOTICE);
+ avf_logtype_driver = rte_log_register("pmd.net.avf.driver");
+ if (avf_logtype_driver >= 0)
+ rte_log_set_level(avf_logtype_driver, RTE_LOG_NOTICE);
+}
+
+/* memory func for base code */
+enum avf_status_code
+avf_allocate_dma_mem_d(__rte_unused struct avf_hw *hw,
+ struct avf_dma_mem *mem,
+ u64 size,
+ u32 alignment)
+{
+ const struct rte_memzone *mz = NULL;
+ char z_name[RTE_MEMZONE_NAMESIZE];
+
+ if (!mem)
+ return AVF_ERR_PARAM;
+
+ snprintf(z_name, sizeof(z_name), "avf_dma_%"PRIu64, rte_rand());
+ mz = rte_memzone_reserve_bounded(z_name, size, SOCKET_ID_ANY,
+ RTE_MEMZONE_IOVA_CONTIG, alignment, RTE_PGSIZE_2M);
+ if (!mz)
+ return AVF_ERR_NO_MEMORY;
+
+ mem->size = size;
+ mem->va = mz->addr;
+ mem->pa = mz->phys_addr;
+ mem->zone = (const void *)mz;
+ PMD_DRV_LOG(DEBUG,
+ "memzone %s allocated with physical address: %"PRIu64,
+ mz->name, mem->pa);
+
+ return AVF_SUCCESS;
+}
+
+enum avf_status_code
+avf_free_dma_mem_d(__rte_unused struct avf_hw *hw,
+ struct avf_dma_mem *mem)
+{
+ if (!mem)
+ return AVF_ERR_PARAM;
+
+ PMD_DRV_LOG(DEBUG,
+ "memzone %s to be freed with physical address: %"PRIu64,
+ ((const struct rte_memzone *)mem->zone)->name, mem->pa);
+ rte_memzone_free((const struct rte_memzone *)mem->zone);
+ mem->zone = NULL;
+ mem->va = NULL;
+ mem->pa = (u64)0;
+
+ return AVF_SUCCESS;
+}
+
+enum avf_status_code
+avf_allocate_virt_mem_d(__rte_unused struct avf_hw *hw,
+ struct avf_virt_mem *mem,
+ u32 size)
+{
+ if (!mem)
+ return AVF_ERR_PARAM;
+
+ mem->size = size;
+ mem->va = rte_zmalloc("avf", size, 0);
+
+ if (mem->va)
+ return AVF_SUCCESS;
+ else
+ return AVF_ERR_NO_MEMORY;
+}
+
+enum avf_status_code
+avf_free_virt_mem_d(__rte_unused struct avf_hw *hw,
+ struct avf_virt_mem *mem)
+{
+ if (!mem)
+ return AVF_ERR_PARAM;
+
+ rte_free(mem->va);
+ mem->va = NULL;
+
+ return AVF_SUCCESS;
+}
diff --git a/drivers/net/iavf/iavf_log.h b/drivers/net/iavf/iavf_log.h
new file mode 100644
index 0000000..8d574d3
--- /dev/null
+++ b/drivers/net/iavf/iavf_log.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017 Intel Corporation
+ */
+
+#ifndef _AVF_LOG_H_
+#define _AVF_LOG_H_
+
+extern int avf_logtype_init;
+#define PMD_INIT_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, avf_logtype_init, "%s(): " fmt "\n", \
+ __func__, ## args)
+#define PMD_INIT_FUNC_TRACE() PMD_INIT_LOG(DEBUG, " >>")
+
+extern int avf_logtype_driver;
+#define PMD_DRV_LOG_RAW(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, avf_logtype_driver, "%s(): " fmt, \
+ __func__, ## args)
+
+#define PMD_DRV_LOG(level, fmt, args...) \
+ PMD_DRV_LOG_RAW(level, fmt "\n", ## args)
+#define PMD_DRV_FUNC_TRACE() PMD_DRV_LOG(DEBUG, " >>")
+
+#ifdef RTE_LIBRTE_AVF_DEBUG_RX
+#define PMD_RX_LOG(level, fmt, args...) \
+ RTE_LOG_DP(level, PMD, "%s(): " fmt "\n", __func__, ## args)
+#else
+#define PMD_RX_LOG(level, fmt, args...) do { } while (0)
+#endif
+
+#ifdef RTE_LIBRTE_AVF_DEBUG_TX
+#define PMD_TX_LOG(level, fmt, args...) \
+ RTE_LOG_DP(level, PMD, "%s(): " fmt "\n", __func__, ## args)
+#else
+#define PMD_TX_LOG(level, fmt, args...) do { } while (0)
+#endif
+
+#ifdef RTE_LIBRTE_AVF_DEBUG_TX_FREE
+#define PMD_TX_FREE_LOG(level, fmt, args...) \
+ RTE_LOG_DP(level, PMD, "%s(): " fmt "\n", __func__, ## args)
+#else
+#define PMD_TX_FREE_LOG(level, fmt, args...) do { } while (0)
+#endif
+
+#endif /* _AVF_LOG_H_ */
diff --git a/drivers/net/iavf/iavf_rxtx.c b/drivers/net/iavf/iavf_rxtx.c
new file mode 100644
index 0000000..988a68f
--- /dev/null
+++ b/drivers/net/iavf/iavf_rxtx.c
@@ -0,0 +1,1955 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017 Intel Corporation
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <sys/queue.h>
+
+#include <rte_string_fns.h>
+#include <rte_memzone.h>
+#include <rte_mbuf.h>
+#include <rte_malloc.h>
+#include <rte_ether.h>
+#include <rte_ethdev_driver.h>
+#include <rte_tcp.h>
+#include <rte_sctp.h>
+#include <rte_udp.h>
+#include <rte_ip.h>
+#include <rte_net.h>
+
+#include "iavf_log.h"
+#include "base/iavf_prototype.h"
+#include "base/iavf_type.h"
+#include "iavf.h"
+#include "iavf_rxtx.h"
+
+static inline int
+check_rx_thresh(uint16_t nb_desc, uint16_t thresh)
+{
+ /* The following constraints must be satisfied:
+ * thresh < rxq->nb_rx_desc
+ */
+ if (thresh >= nb_desc) {
+ PMD_INIT_LOG(ERR, "rx_free_thresh (%u) must be less than %u",
+ thresh, nb_desc);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static inline int
+check_tx_thresh(uint16_t nb_desc, uint16_t tx_rs_thresh,
+ uint16_t tx_free_thresh)
+{
+ /* TX descriptors will have their RS bit set after tx_rs_thresh
+ * descriptors have been used. The TX descriptor ring will be cleaned
+ * after tx_free_thresh descriptors are used or if the number of
+ * descriptors required to transmit a packet is greater than the
+ * number of free TX descriptors.
+ *
+ * The following constraints must be satisfied:
+ * - tx_rs_thresh must be less than the size of the ring minus 2.
+ * - tx_free_thresh must be less than the size of the ring minus 3.
+ * - tx_rs_thresh must be less than or equal to tx_free_thresh.
+ * - tx_rs_thresh must be a divisor of the ring size.
+ *
+ * One descriptor in the TX ring is used as a sentinel to avoid a H/W
+ * race condition, hence the maximum threshold constraints. When set
+ * to zero use default values.
+ */
+ if (tx_rs_thresh >= (nb_desc - 2)) {
+ PMD_INIT_LOG(ERR, "tx_rs_thresh (%u) must be less than the "
+ "number of TX descriptors (%u) minus 2",
+ tx_rs_thresh, nb_desc);
+ return -EINVAL;
+ }
+ if (tx_free_thresh >= (nb_desc - 3)) {
+ PMD_INIT_LOG(ERR, "tx_free_thresh (%u) must be less than the "
+ "number of TX descriptors (%u) minus 3.",
+ tx_free_thresh, nb_desc);
+ return -EINVAL;
+ }
+ if (tx_rs_thresh > tx_free_thresh) {
+ PMD_INIT_LOG(ERR, "tx_rs_thresh (%u) must be less than or "
+ "equal to tx_free_thresh (%u).",
+ tx_rs_thresh, tx_free_thresh);
+ return -EINVAL;
+ }
+ if ((nb_desc % tx_rs_thresh) != 0) {
+ PMD_INIT_LOG(ERR, "tx_rs_thresh (%u) must be a divisor of the "
+ "number of TX descriptors (%u).",
+ tx_rs_thresh, nb_desc);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+#ifdef RTE_LIBRTE_AVF_INC_VECTOR
+static inline bool
+check_rx_vec_allow(struct avf_rx_queue *rxq)
+{
+ if (rxq->rx_free_thresh >= AVF_VPMD_RX_MAX_BURST &&
+ rxq->nb_rx_desc % rxq->rx_free_thresh == 0) {
+ PMD_INIT_LOG(DEBUG, "Vector Rx can be enabled on this rxq.");
+ return TRUE;
+ }
+
+ PMD_INIT_LOG(DEBUG, "Vector Rx cannot be enabled on this rxq.");
+ return FALSE;
+}
+
+static inline bool
+check_tx_vec_allow(struct avf_tx_queue *txq)
+{
+ if (!(txq->offloads & AVF_NO_VECTOR_FLAGS) &&
+ txq->rs_thresh >= AVF_VPMD_TX_MAX_BURST &&
+ txq->rs_thresh <= AVF_VPMD_TX_MAX_FREE_BUF) {
+ PMD_INIT_LOG(DEBUG, "Vector tx can be enabled on this txq.");
+ return TRUE;
+ }
+ PMD_INIT_LOG(DEBUG, "Vector Tx cannot be enabled on this txq.");
+ return FALSE;
+}
+#endif
+
+static inline bool
+check_rx_bulk_allow(struct avf_rx_queue *rxq)
+{
+ int ret = TRUE;
+
+ if (!(rxq->rx_free_thresh >= AVF_RX_MAX_BURST)) {
+ PMD_INIT_LOG(DEBUG, "Rx Burst Bulk Alloc Preconditions: "
+ "rxq->rx_free_thresh=%d, "
+ "AVF_RX_MAX_BURST=%d",
+ rxq->rx_free_thresh, AVF_RX_MAX_BURST);
+ ret = FALSE;
+ } else if (rxq->nb_rx_desc % rxq->rx_free_thresh != 0) {
+ PMD_INIT_LOG(DEBUG, "Rx Burst Bulk Alloc Preconditions: "
+ "rxq->nb_rx_desc=%d, "
+ "rxq->rx_free_thresh=%d",
+ rxq->nb_rx_desc, rxq->rx_free_thresh);
+ ret = FALSE;
+ }
+ return ret;
+}
+
+static inline void
+reset_rx_queue(struct avf_rx_queue *rxq)
+{
+ uint16_t len, i;
+
+ if (!rxq)
+ return;
+
+ len = rxq->nb_rx_desc + AVF_RX_MAX_BURST;
+
+ for (i = 0; i < len * sizeof(union avf_rx_desc); i++)
+ ((volatile char *)rxq->rx_ring)[i] = 0;
+
+ memset(&rxq->fake_mbuf, 0x0, sizeof(rxq->fake_mbuf));
+
+ for (i = 0; i < AVF_RX_MAX_BURST; i++)
+ rxq->sw_ring[rxq->nb_rx_desc + i] = &rxq->fake_mbuf;
+
+ /* for rx bulk */
+ rxq->rx_nb_avail = 0;
+ rxq->rx_next_avail = 0;
+ rxq->rx_free_trigger = (uint16_t)(rxq->rx_free_thresh - 1);
+
+ rxq->rx_tail = 0;
+ rxq->nb_rx_hold = 0;
+ rxq->pkt_first_seg = NULL;
+ rxq->pkt_last_seg = NULL;
+}
+
+static inline void
+reset_tx_queue(struct avf_tx_queue *txq)
+{
+ struct avf_tx_entry *txe;
+ uint16_t i, prev, size;
+
+ if (!txq) {
+ PMD_DRV_LOG(DEBUG, "Pointer to txq is NULL");
+ return;
+ }
+
+ txe = txq->sw_ring;
+ size = sizeof(struct avf_tx_desc) * txq->nb_tx_desc;
+ for (i = 0; i < size; i++)
+ ((volatile char *)txq->tx_ring)[i] = 0;
+
+ prev = (uint16_t)(txq->nb_tx_desc - 1);
+ for (i = 0; i < txq->nb_tx_desc; i++) {
+ txq->tx_ring[i].cmd_type_offset_bsz =
+ rte_cpu_to_le_64(AVF_TX_DESC_DTYPE_DESC_DONE);
+ txe[i].mbuf = NULL;
+ txe[i].last_id = i;
+ txe[prev].next_id = i;
+ prev = i;
+ }
+
+ txq->tx_tail = 0;
+ txq->nb_used = 0;
+
+ txq->last_desc_cleaned = txq->nb_tx_desc - 1;
+ txq->nb_free = txq->nb_tx_desc - 1;
+
+ txq->next_dd = txq->rs_thresh - 1;
+ txq->next_rs = txq->rs_thresh - 1;
+}
+
+static int
+alloc_rxq_mbufs(struct avf_rx_queue *rxq)
+{
+ volatile union avf_rx_desc *rxd;
+ struct rte_mbuf *mbuf = NULL;
+ uint64_t dma_addr;
+ uint16_t i;
+
+ for (i = 0; i < rxq->nb_rx_desc; i++) {
+ mbuf = rte_mbuf_raw_alloc(rxq->mp);
+ if (unlikely(!mbuf)) {
+ PMD_DRV_LOG(ERR, "Failed to allocate mbuf for RX");
+ return -ENOMEM;
+ }
+
+ rte_mbuf_refcnt_set(mbuf, 1);
+ mbuf->next = NULL;
+ mbuf->data_off = RTE_PKTMBUF_HEADROOM;
+ mbuf->nb_segs = 1;
+ mbuf->port = rxq->port_id;
+
+ dma_addr =
+ rte_cpu_to_le_64(rte_mbuf_data_iova_default(mbuf));
+
+ rxd = &rxq->rx_ring[i];
+ rxd->read.pkt_addr = dma_addr;
+ rxd->read.hdr_addr = 0;
+#ifndef RTE_LIBRTE_AVF_16BYTE_RX_DESC
+ rxd->read.rsvd1 = 0;
+ rxd->read.rsvd2 = 0;
+#endif
+
+ rxq->sw_ring[i] = mbuf;
+ }
+
+ return 0;
+}
+
+static inline void
+release_rxq_mbufs(struct avf_rx_queue *rxq)
+{
+ uint16_t i;
+
+ if (!rxq->sw_ring)
+ return;
+
+ for (i = 0; i < rxq->nb_rx_desc; i++) {
+ if (rxq->sw_ring[i]) {
+ rte_pktmbuf_free_seg(rxq->sw_ring[i]);
+ rxq->sw_ring[i] = NULL;
+ }
+ }
+
+ /* for rx bulk */
+ if (rxq->rx_nb_avail == 0)
+ return;
+ for (i = 0; i < rxq->rx_nb_avail; i++) {
+ struct rte_mbuf *mbuf;
+
+ mbuf = rxq->rx_stage[rxq->rx_next_avail + i];
+ rte_pktmbuf_free_seg(mbuf);
+ }
+ rxq->rx_nb_avail = 0;
+}
+
+static inline void
+release_txq_mbufs(struct avf_tx_queue *txq)
+{
+ uint16_t i;
+
+ if (!txq || !txq->sw_ring) {
+ PMD_DRV_LOG(DEBUG, "Pointer to rxq or sw_ring is NULL");
+ return;
+ }
+
+ for (i = 0; i < txq->nb_tx_desc; i++) {
+ if (txq->sw_ring[i].mbuf) {
+ rte_pktmbuf_free_seg(txq->sw_ring[i].mbuf);
+ txq->sw_ring[i].mbuf = NULL;
+ }
+ }
+}
+
+static const struct avf_rxq_ops def_rxq_ops = {
+ .release_mbufs = release_rxq_mbufs,
+};
+
+static const struct avf_txq_ops def_txq_ops = {
+ .release_mbufs = release_txq_mbufs,
+};
+
+int
+avf_dev_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
+ uint16_t nb_desc, unsigned int socket_id,
+ const struct rte_eth_rxconf *rx_conf,
+ struct rte_mempool *mp)
+{
+ struct avf_hw *hw = AVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct avf_adapter *ad =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_rx_queue *rxq;
+ const struct rte_memzone *mz;
+ uint32_t ring_size;
+ uint16_t len;
+ uint16_t rx_free_thresh;
+
+ PMD_INIT_FUNC_TRACE();
+
+ if (nb_desc % AVF_ALIGN_RING_DESC != 0 ||
+ nb_desc > AVF_MAX_RING_DESC ||
+ nb_desc < AVF_MIN_RING_DESC) {
+ PMD_INIT_LOG(ERR, "Number (%u) of receive descriptors is "
+ "invalid", nb_desc);
+ return -EINVAL;
+ }
+
+ /* Check free threshold */
+ rx_free_thresh = (rx_conf->rx_free_thresh == 0) ?
+ AVF_DEFAULT_RX_FREE_THRESH :
+ rx_conf->rx_free_thresh;
+ if (check_rx_thresh(nb_desc, rx_free_thresh) != 0)
+ return -EINVAL;
+
+ /* Free memory if needed */
+ if (dev->data->rx_queues[queue_idx]) {
+ avf_dev_rx_queue_release(dev->data->rx_queues[queue_idx]);
+ dev->data->rx_queues[queue_idx] = NULL;
+ }
+
+ /* Allocate the rx queue data structure */
+ rxq = rte_zmalloc_socket("avf rxq",
+ sizeof(struct avf_rx_queue),
+ RTE_CACHE_LINE_SIZE,
+ socket_id);
+ if (!rxq) {
+ PMD_INIT_LOG(ERR, "Failed to allocate memory for "
+ "rx queue data structure");
+ return -ENOMEM;
+ }
+
+ rxq->mp = mp;
+ rxq->nb_rx_desc = nb_desc;
+ rxq->rx_free_thresh = rx_free_thresh;
+ rxq->queue_id = queue_idx;
+ rxq->port_id = dev->data->port_id;
+ rxq->crc_len = 0; /* crc stripping by default */
+ rxq->rx_deferred_start = rx_conf->rx_deferred_start;
+ rxq->rx_hdr_len = 0;
+
+ len = rte_pktmbuf_data_room_size(rxq->mp) - RTE_PKTMBUF_HEADROOM;
+ rxq->rx_buf_len = RTE_ALIGN(len, (1 << AVF_RXQ_CTX_DBUFF_SHIFT));
+
+ /* Allocate the software ring. */
+ len = nb_desc + AVF_RX_MAX_BURST;
+ rxq->sw_ring =
+ rte_zmalloc_socket("avf rx sw ring",
+ sizeof(struct rte_mbuf *) * len,
+ RTE_CACHE_LINE_SIZE,
+ socket_id);
+ if (!rxq->sw_ring) {
+ PMD_INIT_LOG(ERR, "Failed to allocate memory for SW ring");
+ rte_free(rxq);
+ return -ENOMEM;
+ }
+
+ /* Allocate the maximun number of RX ring hardware descriptor with
+ * a liitle more to support bulk allocate.
+ */
+ len = AVF_MAX_RING_DESC + AVF_RX_MAX_BURST;
+ ring_size = RTE_ALIGN(len * sizeof(union avf_rx_desc),
+ AVF_DMA_MEM_ALIGN);
+ mz = rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx,
+ ring_size, AVF_RING_BASE_ALIGN,
+ socket_id);
+ if (!mz) {
+ PMD_INIT_LOG(ERR, "Failed to reserve DMA memory for RX");
+ rte_free(rxq->sw_ring);
+ rte_free(rxq);
+ return -ENOMEM;
+ }
+ /* Zero all the descriptors in the ring. */
+ memset(mz->addr, 0, ring_size);
+ rxq->rx_ring_phys_addr = mz->iova;
+ rxq->rx_ring = (union avf_rx_desc *)mz->addr;
+
+ rxq->mz = mz;
+ reset_rx_queue(rxq);
+ rxq->q_set = TRUE;
+ dev->data->rx_queues[queue_idx] = rxq;
+ rxq->qrx_tail = hw->hw_addr + AVF_QRX_TAIL1(rxq->queue_id);
+ rxq->ops = &def_rxq_ops;
+
+ if (check_rx_bulk_allow(rxq) == TRUE) {
+ PMD_INIT_LOG(DEBUG, "Rx Burst Bulk Alloc Preconditions are "
+ "satisfied. Rx Burst Bulk Alloc function will be "
+ "used on port=%d, queue=%d.",
+ rxq->port_id, rxq->queue_id);
+ } else {
+ PMD_INIT_LOG(DEBUG, "Rx Burst Bulk Alloc Preconditions are "
+ "not satisfied, Scattered Rx is requested "
+ "on port=%d, queue=%d.",
+ rxq->port_id, rxq->queue_id);
+ ad->rx_bulk_alloc_allowed = false;
+ }
+
+#ifdef RTE_LIBRTE_AVF_INC_VECTOR
+ if (check_rx_vec_allow(rxq) == FALSE)
+ ad->rx_vec_allowed = false;
+#endif
+ return 0;
+}
+
+int
+avf_dev_tx_queue_setup(struct rte_eth_dev *dev,
+ uint16_t queue_idx,
+ uint16_t nb_desc,
+ unsigned int socket_id,
+ const struct rte_eth_txconf *tx_conf)
+{
+ struct avf_hw *hw = AVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct avf_tx_queue *txq;
+ const struct rte_memzone *mz;
+ uint32_t ring_size;
+ uint16_t tx_rs_thresh, tx_free_thresh;
+ uint64_t offloads;
+
+ PMD_INIT_FUNC_TRACE();
+
+ offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
+
+ if (nb_desc % AVF_ALIGN_RING_DESC != 0 ||
+ nb_desc > AVF_MAX_RING_DESC ||
+ nb_desc < AVF_MIN_RING_DESC) {
+ PMD_INIT_LOG(ERR, "Number (%u) of transmit descriptors is "
+ "invalid", nb_desc);
+ return -EINVAL;
+ }
+
+ tx_rs_thresh = (uint16_t)((tx_conf->tx_rs_thresh) ?
+ tx_conf->tx_rs_thresh : DEFAULT_TX_RS_THRESH);
+ tx_free_thresh = (uint16_t)((tx_conf->tx_free_thresh) ?
+ tx_conf->tx_free_thresh : DEFAULT_TX_FREE_THRESH);
+ check_tx_thresh(nb_desc, tx_rs_thresh, tx_rs_thresh);
+
+ /* Free memory if needed. */
+ if (dev->data->tx_queues[queue_idx]) {
+ avf_dev_tx_queue_release(dev->data->tx_queues[queue_idx]);
+ dev->data->tx_queues[queue_idx] = NULL;
+ }
+
+ /* Allocate the TX queue data structure. */
+ txq = rte_zmalloc_socket("avf txq",
+ sizeof(struct avf_tx_queue),
+ RTE_CACHE_LINE_SIZE,
+ socket_id);
+ if (!txq) {
+ PMD_INIT_LOG(ERR, "Failed to allocate memory for "
+ "tx queue structure");
+ return -ENOMEM;
+ }
+
+ txq->nb_tx_desc = nb_desc;
+ txq->rs_thresh = tx_rs_thresh;
+ txq->free_thresh = tx_free_thresh;
+ txq->queue_id = queue_idx;
+ txq->port_id = dev->data->port_id;
+ txq->offloads = offloads;
+ txq->tx_deferred_start = tx_conf->tx_deferred_start;
+
+ /* Allocate software ring */
+ txq->sw_ring =
+ rte_zmalloc_socket("avf tx sw ring",
+ sizeof(struct avf_tx_entry) * nb_desc,
+ RTE_CACHE_LINE_SIZE,
+ socket_id);
+ if (!txq->sw_ring) {
+ PMD_INIT_LOG(ERR, "Failed to allocate memory for SW TX ring");
+ rte_free(txq);
+ return -ENOMEM;
+ }
+
+ /* Allocate TX hardware ring descriptors. */
+ ring_size = sizeof(struct avf_tx_desc) * AVF_MAX_RING_DESC;
+ ring_size = RTE_ALIGN(ring_size, AVF_DMA_MEM_ALIGN);
+ mz = rte_eth_dma_zone_reserve(dev, "tx_ring", queue_idx,
+ ring_size, AVF_RING_BASE_ALIGN,
+ socket_id);
+ if (!mz) {
+ PMD_INIT_LOG(ERR, "Failed to reserve DMA memory for TX");
+ rte_free(txq->sw_ring);
+ rte_free(txq);
+ return -ENOMEM;
+ }
+ txq->tx_ring_phys_addr = mz->iova;
+ txq->tx_ring = (struct avf_tx_desc *)mz->addr;
+
+ txq->mz = mz;
+ reset_tx_queue(txq);
+ txq->q_set = TRUE;
+ dev->data->tx_queues[queue_idx] = txq;
+ txq->qtx_tail = hw->hw_addr + AVF_QTX_TAIL1(queue_idx);
+ txq->ops = &def_txq_ops;
+
+#ifdef RTE_LIBRTE_AVF_INC_VECTOR
+ if (check_tx_vec_allow(txq) == FALSE) {
+ struct avf_adapter *ad =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ ad->tx_vec_allowed = false;
+ }
+#endif
+
+ return 0;
+}
+
+int
+avf_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_hw *hw = AVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct avf_rx_queue *rxq;
+ int err = 0;
+
+ PMD_DRV_FUNC_TRACE();
+
+ if (rx_queue_id >= dev->data->nb_rx_queues)
+ return -EINVAL;
+
+ rxq = dev->data->rx_queues[rx_queue_id];
+
+ err = alloc_rxq_mbufs(rxq);
+ if (err) {
+ PMD_DRV_LOG(ERR, "Failed to allocate RX queue mbuf");
+ return err;
+ }
+
+ rte_wmb();
+
+ /* Init the RX tail register. */
+ AVF_PCI_REG_WRITE(rxq->qrx_tail, rxq->nb_rx_desc - 1);
+ AVF_WRITE_FLUSH(hw);
+
+ /* Ready to switch the queue on */
+ err = avf_switch_queue(adapter, rx_queue_id, TRUE, TRUE);
+ if (err)
+ PMD_DRV_LOG(ERR, "Failed to switch RX queue %u on",
+ rx_queue_id);
+ else
+ dev->data->rx_queue_state[rx_queue_id] =
+ RTE_ETH_QUEUE_STATE_STARTED;
+
+ return err;
+}
+
+int
+avf_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_hw *hw = AVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct avf_tx_queue *txq;
+ int err = 0;
+
+ PMD_DRV_FUNC_TRACE();
+
+ if (tx_queue_id >= dev->data->nb_tx_queues)
+ return -EINVAL;
+
+ txq = dev->data->tx_queues[tx_queue_id];
+
+ /* Init the RX tail register. */
+ AVF_PCI_REG_WRITE(txq->qtx_tail, 0);
+ AVF_WRITE_FLUSH(hw);
+
+ /* Ready to switch the queue on */
+ err = avf_switch_queue(adapter, tx_queue_id, FALSE, TRUE);
+
+ if (err)
+ PMD_DRV_LOG(ERR, "Failed to switch TX queue %u on",
+ tx_queue_id);
+ else
+ dev->data->tx_queue_state[tx_queue_id] =
+ RTE_ETH_QUEUE_STATE_STARTED;
+
+ return err;
+}
+
+int
+avf_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_rx_queue *rxq;
+ int err;
+
+ PMD_DRV_FUNC_TRACE();
+
+ if (rx_queue_id >= dev->data->nb_rx_queues)
+ return -EINVAL;
+
+ err = avf_switch_queue(adapter, rx_queue_id, TRUE, FALSE);
+ if (err) {
+ PMD_DRV_LOG(ERR, "Failed to switch RX queue %u off",
+ rx_queue_id);
+ return err;
+ }
+
+ rxq = dev->data->rx_queues[rx_queue_id];
+ rxq->ops->release_mbufs(rxq);
+ reset_rx_queue(rxq);
+ dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
+
+ return 0;
+}
+
+int
+avf_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_tx_queue *txq;
+ int err;
+
+ PMD_DRV_FUNC_TRACE();
+
+ if (tx_queue_id >= dev->data->nb_tx_queues)
+ return -EINVAL;
+
+ err = avf_switch_queue(adapter, tx_queue_id, FALSE, FALSE);
+ if (err) {
+ PMD_DRV_LOG(ERR, "Failed to switch TX queue %u off",
+ tx_queue_id);
+ return err;
+ }
+
+ txq = dev->data->tx_queues[tx_queue_id];
+ txq->ops->release_mbufs(txq);
+ reset_tx_queue(txq);
+ dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
+
+ return 0;
+}
+
+void
+avf_dev_rx_queue_release(void *rxq)
+{
+ struct avf_rx_queue *q = (struct avf_rx_queue *)rxq;
+
+ if (!q)
+ return;
+
+ q->ops->release_mbufs(q);
+ rte_free(q->sw_ring);
+ rte_memzone_free(q->mz);
+ rte_free(q);
+}
+
+void
+avf_dev_tx_queue_release(void *txq)
+{
+ struct avf_tx_queue *q = (struct avf_tx_queue *)txq;
+
+ if (!q)
+ return;
+
+ q->ops->release_mbufs(q);
+ rte_free(q->sw_ring);
+ rte_memzone_free(q->mz);
+ rte_free(q);
+}
+
+void
+avf_stop_queues(struct rte_eth_dev *dev)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_rx_queue *rxq;
+ struct avf_tx_queue *txq;
+ int ret, i;
+
+ /* Stop All queues */
+ ret = avf_disable_queues(adapter);
+ if (ret)
+ PMD_DRV_LOG(WARNING, "Fail to stop queues");
+
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ if (!txq)
+ continue;
+ txq->ops->release_mbufs(txq);
+ reset_tx_queue(txq);
+ dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+ }
+ for (i = 0; i < dev->data->nb_rx_queues; i++) {
+ rxq = dev->data->rx_queues[i];
+ if (!rxq)
+ continue;
+ rxq->ops->release_mbufs(rxq);
+ reset_rx_queue(rxq);
+ dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+ }
+}
+
+static inline void
+avf_rxd_to_vlan_tci(struct rte_mbuf *mb, volatile union avf_rx_desc *rxdp)
+{
+ if (rte_le_to_cpu_64(rxdp->wb.qword1.status_error_len) &
+ (1 << AVF_RX_DESC_STATUS_L2TAG1P_SHIFT)) {
+ mb->ol_flags |= PKT_RX_VLAN | PKT_RX_VLAN_STRIPPED;
+ mb->vlan_tci =
+ rte_le_to_cpu_16(rxdp->wb.qword0.lo_dword.l2tag1);
+ } else {
+ mb->vlan_tci = 0;
+ }
+}
+
+/* Translate the rx descriptor status and error fields to pkt flags */
+static inline uint64_t
+avf_rxd_to_pkt_flags(uint64_t qword)
+{
+ uint64_t flags;
+ uint64_t error_bits = (qword >> AVF_RXD_QW1_ERROR_SHIFT);
+
+#define AVF_RX_ERR_BITS 0x3f
+
+ /* Check if RSS_HASH */
+ flags = (((qword >> AVF_RX_DESC_STATUS_FLTSTAT_SHIFT) &
+ AVF_RX_DESC_FLTSTAT_RSS_HASH) ==
+ AVF_RX_DESC_FLTSTAT_RSS_HASH) ? PKT_RX_RSS_HASH : 0;
+
+ if (likely((error_bits & AVF_RX_ERR_BITS) == 0)) {
+ flags |= (PKT_RX_IP_CKSUM_GOOD | PKT_RX_L4_CKSUM_GOOD);
+ return flags;
+ }
+
+ if (unlikely(error_bits & (1 << AVF_RX_DESC_ERROR_IPE_SHIFT)))
+ flags |= PKT_RX_IP_CKSUM_BAD;
+ else
+ flags |= PKT_RX_IP_CKSUM_GOOD;
+
+ if (unlikely(error_bits & (1 << AVF_RX_DESC_ERROR_L4E_SHIFT)))
+ flags |= PKT_RX_L4_CKSUM_BAD;
+ else
+ flags |= PKT_RX_L4_CKSUM_GOOD;
+
+ /* TODO: Oversize error bit is not processed here */
+
+ return flags;
+}
+
+/* implement recv_pkts */
+uint16_t
+avf_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
+{
+ volatile union avf_rx_desc *rx_ring;
+ volatile union avf_rx_desc *rxdp;
+ struct avf_rx_queue *rxq;
+ union avf_rx_desc rxd;
+ struct rte_mbuf *rxe;
+ struct rte_eth_dev *dev;
+ struct rte_mbuf *rxm;
+ struct rte_mbuf *nmb;
+ uint16_t nb_rx;
+ uint32_t rx_status;
+ uint64_t qword1;
+ uint16_t rx_packet_len;
+ uint16_t rx_id, nb_hold;
+ uint64_t dma_addr;
+ uint64_t pkt_flags;
+ static const uint32_t ptype_tbl[UINT8_MAX + 1] __rte_cache_aligned = {
+ /* [0] reserved */
+ [1] = RTE_PTYPE_L2_ETHER,
+ /* [2] - [21] reserved */
+ [22] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_FRAG,
+ [23] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_NONFRAG,
+ [24] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_UDP,
+ /* [25] reserved */
+ [26] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_TCP,
+ [27] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_SCTP,
+ [28] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_ICMP,
+ /* All others reserved */
+ };
+
+ nb_rx = 0;
+ nb_hold = 0;
+ rxq = rx_queue;
+ rx_id = rxq->rx_tail;
+ rx_ring = rxq->rx_ring;
+
+ while (nb_rx < nb_pkts) {
+ rxdp = &rx_ring[rx_id];
+ qword1 = rte_le_to_cpu_64(rxdp->wb.qword1.status_error_len);
+ rx_status = (qword1 & AVF_RXD_QW1_STATUS_MASK) >>
+ AVF_RXD_QW1_STATUS_SHIFT;
+
+ /* Check the DD bit first */
+ if (!(rx_status & (1 << AVF_RX_DESC_STATUS_DD_SHIFT)))
+ break;
+ AVF_DUMP_RX_DESC(rxq, rxdp, rx_id);
+
+ nmb = rte_mbuf_raw_alloc(rxq->mp);
+ if (unlikely(!nmb)) {
+ dev = &rte_eth_devices[rxq->port_id];
+ dev->data->rx_mbuf_alloc_failed++;
+ PMD_RX_LOG(DEBUG, "RX mbuf alloc failed port_id=%u "
+ "queue_id=%u", rxq->port_id, rxq->queue_id);
+ break;
+ }
+
+ rxd = *rxdp;
+ nb_hold++;
+ rxe = rxq->sw_ring[rx_id];
+ rx_id++;
+ if (unlikely(rx_id == rxq->nb_rx_desc))
+ rx_id = 0;
+
+ /* Prefetch next mbuf */
+ rte_prefetch0(rxq->sw_ring[rx_id]);
+
+ /* When next RX descriptor is on a cache line boundary,
+ * prefetch the next 4 RX descriptors and next 8 pointers
+ * to mbufs.
+ */
+ if ((rx_id & 0x3) == 0) {
+ rte_prefetch0(&rx_ring[rx_id]);
+ rte_prefetch0(rxq->sw_ring[rx_id]);
+ }
+ rxm = rxe;
+ rxe = nmb;
+ dma_addr =
+ rte_cpu_to_le_64(rte_mbuf_data_iova_default(nmb));
+ rxdp->read.hdr_addr = 0;
+ rxdp->read.pkt_addr = dma_addr;
+
+ rx_packet_len = ((qword1 & AVF_RXD_QW1_LENGTH_PBUF_MASK) >>
+ AVF_RXD_QW1_LENGTH_PBUF_SHIFT) - rxq->crc_len;
+
+ rxm->data_off = RTE_PKTMBUF_HEADROOM;
+ rte_prefetch0(RTE_PTR_ADD(rxm->buf_addr, RTE_PKTMBUF_HEADROOM));
+ rxm->nb_segs = 1;
+ rxm->next = NULL;
+ rxm->pkt_len = rx_packet_len;
+ rxm->data_len = rx_packet_len;
+ rxm->port = rxq->port_id;
+ rxm->ol_flags = 0;
+ avf_rxd_to_vlan_tci(rxm, &rxd);
+ pkt_flags = avf_rxd_to_pkt_flags(qword1);
+ rxm->packet_type =
+ ptype_tbl[(uint8_t)((qword1 &
+ AVF_RXD_QW1_PTYPE_MASK) >> AVF_RXD_QW1_PTYPE_SHIFT)];
+
+ if (pkt_flags & PKT_RX_RSS_HASH)
+ rxm->hash.rss =
+ rte_le_to_cpu_32(rxd.wb.qword0.hi_dword.rss);
+
+ rxm->ol_flags |= pkt_flags;
+
+ rx_pkts[nb_rx++] = rxm;
+ }
+ rxq->rx_tail = rx_id;
+
+ /* If the number of free RX descriptors is greater than the RX free
+ * threshold of the queue, advance the receive tail register of queue.
+ * Update that register with the value of the last processed RX
+ * descriptor minus 1.
+ */
+ nb_hold = (uint16_t)(nb_hold + rxq->nb_rx_hold);
+ if (nb_hold > rxq->rx_free_thresh) {
+ PMD_RX_LOG(DEBUG, "port_id=%u queue_id=%u rx_tail=%u "
+ "nb_hold=%u nb_rx=%u",
+ rxq->port_id, rxq->queue_id,
+ rx_id, nb_hold, nb_rx);
+ rx_id = (uint16_t)((rx_id == 0) ?
+ (rxq->nb_rx_desc - 1) : (rx_id - 1));
+ AVF_PCI_REG_WRITE(rxq->qrx_tail, rx_id);
+ nb_hold = 0;
+ }
+ rxq->nb_rx_hold = nb_hold;
+
+ return nb_rx;
+}
+
+/* implement recv_scattered_pkts */
+uint16_t
+avf_recv_scattered_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+ uint16_t nb_pkts)
+{
+ struct avf_rx_queue *rxq = rx_queue;
+ union avf_rx_desc rxd;
+ struct rte_mbuf *rxe;
+ struct rte_mbuf *first_seg = rxq->pkt_first_seg;
+ struct rte_mbuf *last_seg = rxq->pkt_last_seg;
+ struct rte_mbuf *nmb, *rxm;
+ uint16_t rx_id = rxq->rx_tail;
+ uint16_t nb_rx = 0, nb_hold = 0, rx_packet_len;
+ struct rte_eth_dev *dev;
+ uint32_t rx_status;
+ uint64_t qword1;
+ uint64_t dma_addr;
+ uint64_t pkt_flags;
+
+ volatile union avf_rx_desc *rx_ring = rxq->rx_ring;
+ volatile union avf_rx_desc *rxdp;
+ static const uint32_t ptype_tbl[UINT8_MAX + 1] __rte_cache_aligned = {
+ /* [0] reserved */
+ [1] = RTE_PTYPE_L2_ETHER,
+ /* [2] - [21] reserved */
+ [22] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_FRAG,
+ [23] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_NONFRAG,
+ [24] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_UDP,
+ /* [25] reserved */
+ [26] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_TCP,
+ [27] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_SCTP,
+ [28] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_ICMP,
+ /* All others reserved */
+ };
+
+ while (nb_rx < nb_pkts) {
+ rxdp = &rx_ring[rx_id];
+ qword1 = rte_le_to_cpu_64(rxdp->wb.qword1.status_error_len);
+ rx_status = (qword1 & AVF_RXD_QW1_STATUS_MASK) >>
+ AVF_RXD_QW1_STATUS_SHIFT;
+
+ /* Check the DD bit */
+ if (!(rx_status & (1 << AVF_RX_DESC_STATUS_DD_SHIFT)))
+ break;
+ AVF_DUMP_RX_DESC(rxq, rxdp, rx_id);
+
+ nmb = rte_mbuf_raw_alloc(rxq->mp);
+ if (unlikely(!nmb)) {
+ PMD_RX_LOG(DEBUG, "RX mbuf alloc failed port_id=%u "
+ "queue_id=%u", rxq->port_id, rxq->queue_id);
+ dev = &rte_eth_devices[rxq->port_id];
+ dev->data->rx_mbuf_alloc_failed++;
+ break;
+ }
+
+ rxd = *rxdp;
+ nb_hold++;
+ rxe = rxq->sw_ring[rx_id];
+ rx_id++;
+ if (rx_id == rxq->nb_rx_desc)
+ rx_id = 0;
+
+ /* Prefetch next mbuf */
+ rte_prefetch0(rxq->sw_ring[rx_id]);
+
+ /* When next RX descriptor is on a cache line boundary,
+ * prefetch the next 4 RX descriptors and next 8 pointers
+ * to mbufs.
+ */
+ if ((rx_id & 0x3) == 0) {
+ rte_prefetch0(&rx_ring[rx_id]);
+ rte_prefetch0(rxq->sw_ring[rx_id]);
+ }
+
+ rxm = rxe;
+ rxe = nmb;
+ dma_addr =
+ rte_cpu_to_le_64(rte_mbuf_data_iova_default(nmb));
+
+ /* Set data buffer address and data length of the mbuf */
+ rxdp->read.hdr_addr = 0;
+ rxdp->read.pkt_addr = dma_addr;
+ rx_packet_len = (qword1 & AVF_RXD_QW1_LENGTH_PBUF_MASK) >>
+ AVF_RXD_QW1_LENGTH_PBUF_SHIFT;
+ rxm->data_len = rx_packet_len;
+ rxm->data_off = RTE_PKTMBUF_HEADROOM;
+
+ /* If this is the first buffer of the received packet, set the
+ * pointer to the first mbuf of the packet and initialize its
+ * context. Otherwise, update the total length and the number
+ * of segments of the current scattered packet, and update the
+ * pointer to the last mbuf of the current packet.
+ */
+ if (!first_seg) {
+ first_seg = rxm;
+ first_seg->nb_segs = 1;
+ first_seg->pkt_len = rx_packet_len;
+ } else {
+ first_seg->pkt_len =
+ (uint16_t)(first_seg->pkt_len +
+ rx_packet_len);
+ first_seg->nb_segs++;
+ last_seg->next = rxm;
+ }
+
+ /* If this is not the last buffer of the received packet,
+ * update the pointer to the last mbuf of the current scattered
+ * packet and continue to parse the RX ring.
+ */
+ if (!(rx_status & (1 << AVF_RX_DESC_STATUS_EOF_SHIFT))) {
+ last_seg = rxm;
+ continue;
+ }
+
+ /* This is the last buffer of the received packet. If the CRC
+ * is not stripped by the hardware:
+ * - Subtract the CRC length from the total packet length.
+ * - If the last buffer only contains the whole CRC or a part
+ * of it, free the mbuf associated to the last buffer. If part
+ * of the CRC is also contained in the previous mbuf, subtract
+ * the length of that CRC part from the data length of the
+ * previous mbuf.
+ */
+ rxm->next = NULL;
+ if (unlikely(rxq->crc_len > 0)) {
+ first_seg->pkt_len -= ETHER_CRC_LEN;
+ if (rx_packet_len <= ETHER_CRC_LEN) {
+ rte_pktmbuf_free_seg(rxm);
+ first_seg->nb_segs--;
+ last_seg->data_len =
+ (uint16_t)(last_seg->data_len -
+ (ETHER_CRC_LEN - rx_packet_len));
+ last_seg->next = NULL;
+ } else
+ rxm->data_len = (uint16_t)(rx_packet_len -
+ ETHER_CRC_LEN);
+ }
+
+ first_seg->port = rxq->port_id;
+ first_seg->ol_flags = 0;
+ avf_rxd_to_vlan_tci(first_seg, &rxd);
+ pkt_flags = avf_rxd_to_pkt_flags(qword1);
+ first_seg->packet_type =
+ ptype_tbl[(uint8_t)((qword1 &
+ AVF_RXD_QW1_PTYPE_MASK) >> AVF_RXD_QW1_PTYPE_SHIFT)];
+
+ if (pkt_flags & PKT_RX_RSS_HASH)
+ first_seg->hash.rss =
+ rte_le_to_cpu_32(rxd.wb.qword0.hi_dword.rss);
+
+ first_seg->ol_flags |= pkt_flags;
+
+ /* Prefetch data of first segment, if configured to do so. */
+ rte_prefetch0(RTE_PTR_ADD(first_seg->buf_addr,
+ first_seg->data_off));
+ rx_pkts[nb_rx++] = first_seg;
+ first_seg = NULL;
+ }
+
+ /* Record index of the next RX descriptor to probe. */
+ rxq->rx_tail = rx_id;
+ rxq->pkt_first_seg = first_seg;
+ rxq->pkt_last_seg = last_seg;
+
+ /* If the number of free RX descriptors is greater than the RX free
+ * threshold of the queue, advance the Receive Descriptor Tail (RDT)
+ * register. Update the RDT with the value of the last processed RX
+ * descriptor minus 1, to guarantee that the RDT register is never
+ * equal to the RDH register, which creates a "full" ring situtation
+ * from the hardware point of view.
+ */
+ nb_hold = (uint16_t)(nb_hold + rxq->nb_rx_hold);
+ if (nb_hold > rxq->rx_free_thresh) {
+ PMD_RX_LOG(DEBUG, "port_id=%u queue_id=%u rx_tail=%u "
+ "nb_hold=%u nb_rx=%u",
+ rxq->port_id, rxq->queue_id,
+ rx_id, nb_hold, nb_rx);
+ rx_id = (uint16_t)(rx_id == 0 ?
+ (rxq->nb_rx_desc - 1) : (rx_id - 1));
+ AVF_PCI_REG_WRITE(rxq->qrx_tail, rx_id);
+ nb_hold = 0;
+ }
+ rxq->nb_rx_hold = nb_hold;
+
+ return nb_rx;
+}
+
+#define AVF_LOOK_AHEAD 8
+static inline int
+avf_rx_scan_hw_ring(struct avf_rx_queue *rxq)
+{
+ volatile union avf_rx_desc *rxdp;
+ struct rte_mbuf **rxep;
+ struct rte_mbuf *mb;
+ uint16_t pkt_len;
+ uint64_t qword1;
+ uint32_t rx_status;
+ int32_t s[AVF_LOOK_AHEAD], nb_dd;
+ int32_t i, j, nb_rx = 0;
+ uint64_t pkt_flags;
+ static const uint32_t ptype_tbl[UINT8_MAX + 1] __rte_cache_aligned = {
+ /* [0] reserved */
+ [1] = RTE_PTYPE_L2_ETHER,
+ /* [2] - [21] reserved */
+ [22] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_FRAG,
+ [23] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_NONFRAG,
+ [24] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_UDP,
+ /* [25] reserved */
+ [26] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_TCP,
+ [27] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_SCTP,
+ [28] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_ICMP,
+ /* All others reserved */
+ };
+
+ rxdp = &rxq->rx_ring[rxq->rx_tail];
+ rxep = &rxq->sw_ring[rxq->rx_tail];
+
+ qword1 = rte_le_to_cpu_64(rxdp->wb.qword1.status_error_len);
+ rx_status = (qword1 & AVF_RXD_QW1_STATUS_MASK) >>
+ AVF_RXD_QW1_STATUS_SHIFT;
+
+ /* Make sure there is at least 1 packet to receive */
+ if (!(rx_status & (1 << AVF_RX_DESC_STATUS_DD_SHIFT)))
+ return 0;
+
+ /* Scan LOOK_AHEAD descriptors at a time to determine which
+ * descriptors reference packets that are ready to be received.
+ */
+ for (i = 0; i < AVF_RX_MAX_BURST; i += AVF_LOOK_AHEAD,
+ rxdp += AVF_LOOK_AHEAD, rxep += AVF_LOOK_AHEAD) {
+ /* Read desc statuses backwards to avoid race condition */
+ for (j = AVF_LOOK_AHEAD - 1; j >= 0; j--) {
+ qword1 = rte_le_to_cpu_64(
+ rxdp[j].wb.qword1.status_error_len);
+ s[j] = (qword1 & AVF_RXD_QW1_STATUS_MASK) >>
+ AVF_RXD_QW1_STATUS_SHIFT;
+ }
+
+ rte_smp_rmb();
+
+ /* Compute how many status bits were set */
+ for (j = 0, nb_dd = 0; j < AVF_LOOK_AHEAD; j++)
+ nb_dd += s[j] & (1 << AVF_RX_DESC_STATUS_DD_SHIFT);
+
+ nb_rx += nb_dd;
+
+ /* Translate descriptor info to mbuf parameters */
+ for (j = 0; j < nb_dd; j++) {
+ AVF_DUMP_RX_DESC(rxq, &rxdp[j],
+ rxq->rx_tail + i * AVF_LOOK_AHEAD + j);
+
+ mb = rxep[j];
+ qword1 = rte_le_to_cpu_64
+ (rxdp[j].wb.qword1.status_error_len);
+ pkt_len = ((qword1 & AVF_RXD_QW1_LENGTH_PBUF_MASK) >>
+ AVF_RXD_QW1_LENGTH_PBUF_SHIFT) - rxq->crc_len;
+ mb->data_len = pkt_len;
+ mb->pkt_len = pkt_len;
+ mb->ol_flags = 0;
+ avf_rxd_to_vlan_tci(mb, &rxdp[j]);
+ pkt_flags = avf_rxd_to_pkt_flags(qword1);
+ mb->packet_type =
+ ptype_tbl[(uint8_t)((qword1 &
+ AVF_RXD_QW1_PTYPE_MASK) >>
+ AVF_RXD_QW1_PTYPE_SHIFT)];
+
+ if (pkt_flags & PKT_RX_RSS_HASH)
+ mb->hash.rss = rte_le_to_cpu_32(
+ rxdp[j].wb.qword0.hi_dword.rss);
+
+ mb->ol_flags |= pkt_flags;
+ }
+
+ for (j = 0; j < AVF_LOOK_AHEAD; j++)
+ rxq->rx_stage[i + j] = rxep[j];
+
+ if (nb_dd != AVF_LOOK_AHEAD)
+ break;
+ }
+
+ /* Clear software ring entries */
+ for (i = 0; i < nb_rx; i++)
+ rxq->sw_ring[rxq->rx_tail + i] = NULL;
+
+ return nb_rx;
+}
+
+static inline uint16_t
+avf_rx_fill_from_stage(struct avf_rx_queue *rxq,
+ struct rte_mbuf **rx_pkts,
+ uint16_t nb_pkts)
+{
+ uint16_t i;
+ struct rte_mbuf **stage = &rxq->rx_stage[rxq->rx_next_avail];
+
+ nb_pkts = (uint16_t)RTE_MIN(nb_pkts, rxq->rx_nb_avail);
+
+ for (i = 0; i < nb_pkts; i++)
+ rx_pkts[i] = stage[i];
+
+ rxq->rx_nb_avail = (uint16_t)(rxq->rx_nb_avail - nb_pkts);
+ rxq->rx_next_avail = (uint16_t)(rxq->rx_next_avail + nb_pkts);
+
+ return nb_pkts;
+}
+
+static inline int
+avf_rx_alloc_bufs(struct avf_rx_queue *rxq)
+{
+ volatile union avf_rx_desc *rxdp;
+ struct rte_mbuf **rxep;
+ struct rte_mbuf *mb;
+ uint16_t alloc_idx, i;
+ uint64_t dma_addr;
+ int diag;
+
+ /* Allocate buffers in bulk */
+ alloc_idx = (uint16_t)(rxq->rx_free_trigger -
+ (rxq->rx_free_thresh - 1));
+ rxep = &rxq->sw_ring[alloc_idx];
+ diag = rte_mempool_get_bulk(rxq->mp, (void *)rxep,
+ rxq->rx_free_thresh);
+ if (unlikely(diag != 0)) {
+ PMD_RX_LOG(ERR, "Failed to get mbufs in bulk");
+ return -ENOMEM;
+ }
+
+ rxdp = &rxq->rx_ring[alloc_idx];
+ for (i = 0; i < rxq->rx_free_thresh; i++) {
+ if (likely(i < (rxq->rx_free_thresh - 1)))
+ /* Prefetch next mbuf */
+ rte_prefetch0(rxep[i + 1]);
+
+ mb = rxep[i];
+ rte_mbuf_refcnt_set(mb, 1);
+ mb->next = NULL;
+ mb->data_off = RTE_PKTMBUF_HEADROOM;
+ mb->nb_segs = 1;
+ mb->port = rxq->port_id;
+ dma_addr = rte_cpu_to_le_64(rte_mbuf_data_iova_default(mb));
+ rxdp[i].read.hdr_addr = 0;
+ rxdp[i].read.pkt_addr = dma_addr;
+ }
+
+ /* Update rx tail register */
+ rte_wmb();
+ AVF_PCI_REG_WRITE_RELAXED(rxq->qrx_tail, rxq->rx_free_trigger);
+
+ rxq->rx_free_trigger =
+ (uint16_t)(rxq->rx_free_trigger + rxq->rx_free_thresh);
+ if (rxq->rx_free_trigger >= rxq->nb_rx_desc)
+ rxq->rx_free_trigger = (uint16_t)(rxq->rx_free_thresh - 1);
+
+ return 0;
+}
+
+static inline uint16_t
+rx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
+{
+ struct avf_rx_queue *rxq = (struct avf_rx_queue *)rx_queue;
+ uint16_t nb_rx = 0;
+
+ if (!nb_pkts)
+ return 0;
+
+ if (rxq->rx_nb_avail)
+ return avf_rx_fill_from_stage(rxq, rx_pkts, nb_pkts);
+
+ nb_rx = (uint16_t)avf_rx_scan_hw_ring(rxq);
+ rxq->rx_next_avail = 0;
+ rxq->rx_nb_avail = nb_rx;
+ rxq->rx_tail = (uint16_t)(rxq->rx_tail + nb_rx);
+
+ if (rxq->rx_tail > rxq->rx_free_trigger) {
+ if (avf_rx_alloc_bufs(rxq) != 0) {
+ uint16_t i, j;
+
+ /* TODO: count rx_mbuf_alloc_failed here */
+
+ rxq->rx_nb_avail = 0;
+ rxq->rx_tail = (uint16_t)(rxq->rx_tail - nb_rx);
+ for (i = 0, j = rxq->rx_tail; i < nb_rx; i++, j++)
+ rxq->sw_ring[j] = rxq->rx_stage[i];
+
+ return 0;
+ }
+ }
+
+ if (rxq->rx_tail >= rxq->nb_rx_desc)
+ rxq->rx_tail = 0;
+
+ PMD_RX_LOG(DEBUG, "port_id=%u queue_id=%u rx_tail=%u, nb_rx=%u",
+ rxq->port_id, rxq->queue_id,
+ rxq->rx_tail, nb_rx);
+
+ if (rxq->rx_nb_avail)
+ return avf_rx_fill_from_stage(rxq, rx_pkts, nb_pkts);
+
+ return 0;
+}
+
+static uint16_t
+avf_recv_pkts_bulk_alloc(void *rx_queue,
+ struct rte_mbuf **rx_pkts,
+ uint16_t nb_pkts)
+{
+ uint16_t nb_rx = 0, n, count;
+
+ if (unlikely(nb_pkts == 0))
+ return 0;
+
+ if (likely(nb_pkts <= AVF_RX_MAX_BURST))
+ return rx_recv_pkts(rx_queue, rx_pkts, nb_pkts);
+
+ while (nb_pkts) {
+ n = RTE_MIN(nb_pkts, AVF_RX_MAX_BURST);
+ count = rx_recv_pkts(rx_queue, &rx_pkts[nb_rx], n);
+ nb_rx = (uint16_t)(nb_rx + count);
+ nb_pkts = (uint16_t)(nb_pkts - count);
+ if (count < n)
+ break;
+ }
+
+ return nb_rx;
+}
+
+static inline int
+avf_xmit_cleanup(struct avf_tx_queue *txq)
+{
+ struct avf_tx_entry *sw_ring = txq->sw_ring;
+ uint16_t last_desc_cleaned = txq->last_desc_cleaned;
+ uint16_t nb_tx_desc = txq->nb_tx_desc;
+ uint16_t desc_to_clean_to;
+ uint16_t nb_tx_to_clean;
+
+ volatile struct avf_tx_desc *txd = txq->tx_ring;
+
+ desc_to_clean_to = (uint16_t)(last_desc_cleaned + txq->rs_thresh);
+ if (desc_to_clean_to >= nb_tx_desc)
+ desc_to_clean_to = (uint16_t)(desc_to_clean_to - nb_tx_desc);
+
+ desc_to_clean_to = sw_ring[desc_to_clean_to].last_id;
+ if ((txd[desc_to_clean_to].cmd_type_offset_bsz &
+ rte_cpu_to_le_64(AVF_TXD_QW1_DTYPE_MASK)) !=
+ rte_cpu_to_le_64(AVF_TX_DESC_DTYPE_DESC_DONE)) {
+ PMD_TX_FREE_LOG(DEBUG, "TX descriptor %4u is not done "
+ "(port=%d queue=%d)", desc_to_clean_to,
+ txq->port_id, txq->queue_id);
+ return -1;
+ }
+
+ if (last_desc_cleaned > desc_to_clean_to)
+ nb_tx_to_clean = (uint16_t)((nb_tx_desc - last_desc_cleaned) +
+ desc_to_clean_to);
+ else
+ nb_tx_to_clean = (uint16_t)(desc_to_clean_to -
+ last_desc_cleaned);
+
+ txd[desc_to_clean_to].cmd_type_offset_bsz = 0;
+
+ txq->last_desc_cleaned = desc_to_clean_to;
+ txq->nb_free = (uint16_t)(txq->nb_free + nb_tx_to_clean);
+
+ return 0;
+}
+
+/* Check if the context descriptor is needed for TX offloading */
+static inline uint16_t
+avf_calc_context_desc(uint64_t flags)
+{
+ static uint64_t mask = PKT_TX_TCP_SEG;
+
+ return (flags & mask) ? 1 : 0;
+}
+
+static inline void
+avf_txd_enable_checksum(uint64_t ol_flags,
+ uint32_t *td_cmd,
+ uint32_t *td_offset,
+ union avf_tx_offload tx_offload)
+{
+ /* Set MACLEN */
+ *td_offset |= (tx_offload.l2_len >> 1) <<
+ AVF_TX_DESC_LENGTH_MACLEN_SHIFT;
+
+ /* Enable L3 checksum offloads */
+ if (ol_flags & PKT_TX_IP_CKSUM) {
+ *td_cmd |= AVF_TX_DESC_CMD_IIPT_IPV4_CSUM;
+ *td_offset |= (tx_offload.l3_len >> 2) <<
+ AVF_TX_DESC_LENGTH_IPLEN_SHIFT;
+ } else if (ol_flags & PKT_TX_IPV4) {
+ *td_cmd |= AVF_TX_DESC_CMD_IIPT_IPV4;
+ *td_offset |= (tx_offload.l3_len >> 2) <<
+ AVF_TX_DESC_LENGTH_IPLEN_SHIFT;
+ } else if (ol_flags & PKT_TX_IPV6) {
+ *td_cmd |= AVF_TX_DESC_CMD_IIPT_IPV6;
+ *td_offset |= (tx_offload.l3_len >> 2) <<
+ AVF_TX_DESC_LENGTH_IPLEN_SHIFT;
+ }
+
+ if (ol_flags & PKT_TX_TCP_SEG) {
+ *td_cmd |= AVF_TX_DESC_CMD_L4T_EOFT_TCP;
+ *td_offset |= (tx_offload.l4_len >> 2) <<
+ AVF_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;
+ return;
+ }
+
+ /* Enable L4 checksum offloads */
+ switch (ol_flags & PKT_TX_L4_MASK) {
+ case PKT_TX_TCP_CKSUM:
+ *td_cmd |= AVF_TX_DESC_CMD_L4T_EOFT_TCP;
+ *td_offset |= (sizeof(struct tcp_hdr) >> 2) <<
+ AVF_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;
+ break;
+ case PKT_TX_SCTP_CKSUM:
+ *td_cmd |= AVF_TX_DESC_CMD_L4T_EOFT_SCTP;
+ *td_offset |= (sizeof(struct sctp_hdr) >> 2) <<
+ AVF_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;
+ break;
+ case PKT_TX_UDP_CKSUM:
+ *td_cmd |= AVF_TX_DESC_CMD_L4T_EOFT_UDP;
+ *td_offset |= (sizeof(struct udp_hdr) >> 2) <<
+ AVF_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;
+ break;
+ default:
+ break;
+ }
+}
+
+/* set TSO context descriptor
+ * support IP -> L4 and IP -> IP -> L4
+ */
+static inline uint64_t
+avf_set_tso_ctx(struct rte_mbuf *mbuf, union avf_tx_offload tx_offload)
+{
+ uint64_t ctx_desc = 0;
+ uint32_t cd_cmd, hdr_len, cd_tso_len;
+
+ if (!tx_offload.l4_len) {
+ PMD_TX_LOG(DEBUG, "L4 length set to 0");
+ return ctx_desc;
+ }
+
+ /* in case of non tunneling packet, the outer_l2_len and
+ * outer_l3_len must be 0.
+ */
+ hdr_len = tx_offload.l2_len +
+ tx_offload.l3_len +
+ tx_offload.l4_len;
+
+ cd_cmd = AVF_TX_CTX_DESC_TSO;
+ cd_tso_len = mbuf->pkt_len - hdr_len;
+ ctx_desc |= ((uint64_t)cd_cmd << AVF_TXD_CTX_QW1_CMD_SHIFT) |
+ ((uint64_t)cd_tso_len << AVF_TXD_CTX_QW1_TSO_LEN_SHIFT) |
+ ((uint64_t)mbuf->tso_segsz << AVF_TXD_CTX_QW1_MSS_SHIFT);
+
+ return ctx_desc;
+}
+
+/* Construct the tx flags */
+static inline uint64_t
+avf_build_ctob(uint32_t td_cmd, uint32_t td_offset, unsigned int size,
+ uint32_t td_tag)
+{
+ return rte_cpu_to_le_64(AVF_TX_DESC_DTYPE_DATA |
+ ((uint64_t)td_cmd << AVF_TXD_QW1_CMD_SHIFT) |
+ ((uint64_t)td_offset <<
+ AVF_TXD_QW1_OFFSET_SHIFT) |
+ ((uint64_t)size <<
+ AVF_TXD_QW1_TX_BUF_SZ_SHIFT) |
+ ((uint64_t)td_tag <<
+ AVF_TXD_QW1_L2TAG1_SHIFT));
+}
+
+/* TX function */
+uint16_t
+avf_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+{
+ volatile struct avf_tx_desc *txd;
+ volatile struct avf_tx_desc *txr;
+ struct avf_tx_queue *txq;
+ struct avf_tx_entry *sw_ring;
+ struct avf_tx_entry *txe, *txn;
+ struct rte_mbuf *tx_pkt;
+ struct rte_mbuf *m_seg;
+ uint16_t tx_id;
+ uint16_t nb_tx;
+ uint32_t td_cmd;
+ uint32_t td_offset;
+ uint32_t td_tag;
+ uint64_t ol_flags;
+ uint16_t nb_used;
+ uint16_t nb_ctx;
+ uint16_t tx_last;
+ uint16_t slen;
+ uint64_t buf_dma_addr;
+ union avf_tx_offload tx_offload = {0};
+
+ txq = tx_queue;
+ sw_ring = txq->sw_ring;
+ txr = txq->tx_ring;
+ tx_id = txq->tx_tail;
+ txe = &sw_ring[tx_id];
+
+ /* Check if the descriptor ring needs to be cleaned. */
+ if (txq->nb_free < txq->free_thresh)
+ avf_xmit_cleanup(txq);
+
+ for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) {
+ td_cmd = 0;
+ td_tag = 0;
+ td_offset = 0;
+
+ tx_pkt = *tx_pkts++;
+ RTE_MBUF_PREFETCH_TO_FREE(txe->mbuf);
+
+ ol_flags = tx_pkt->ol_flags;
+ tx_offload.l2_len = tx_pkt->l2_len;
+ tx_offload.l3_len = tx_pkt->l3_len;
+ tx_offload.l4_len = tx_pkt->l4_len;
+ tx_offload.tso_segsz = tx_pkt->tso_segsz;
+
+ /* Calculate the number of context descriptors needed. */
+ nb_ctx = avf_calc_context_desc(ol_flags);
+
+ /* The number of descriptors that must be allocated for
+ * a packet equals to the number of the segments of that
+ * packet plus 1 context descriptor if needed.
+ */
+ nb_used = (uint16_t)(tx_pkt->nb_segs + nb_ctx);
+ tx_last = (uint16_t)(tx_id + nb_used - 1);
+
+ /* Circular ring */
+ if (tx_last >= txq->nb_tx_desc)
+ tx_last = (uint16_t)(tx_last - txq->nb_tx_desc);
+
+ PMD_TX_LOG(DEBUG, "port_id=%u queue_id=%u"
+ " tx_first=%u tx_last=%u",
+ txq->port_id, txq->queue_id, tx_id, tx_last);
+
+ if (nb_used > txq->nb_free) {
+ if (avf_xmit_cleanup(txq)) {
+ if (nb_tx == 0)
+ return 0;
+ goto end_of_tx;
+ }
+ if (unlikely(nb_used > txq->rs_thresh)) {
+ while (nb_used > txq->nb_free) {
+ if (avf_xmit_cleanup(txq)) {
+ if (nb_tx == 0)
+ return 0;
+ goto end_of_tx;
+ }
+ }
+ }
+ }
+
+ /* Descriptor based VLAN insertion */
+ if (ol_flags & PKT_TX_VLAN_PKT) {
+ td_cmd |= AVF_TX_DESC_CMD_IL2TAG1;
+ td_tag = tx_pkt->vlan_tci;
+ }
+
+ /* According to datasheet, the bit2 is reserved and must be
+ * set to 1.
+ */
+ td_cmd |= 0x04;
+
+ /* Enable checksum offloading */
+ if (ol_flags & AVF_TX_CKSUM_OFFLOAD_MASK)
+ avf_txd_enable_checksum(ol_flags, &td_cmd,
+ &td_offset, tx_offload);
+
+ if (nb_ctx) {
+ /* Setup TX context descriptor if required */
+ uint64_t cd_type_cmd_tso_mss =
+ AVF_TX_DESC_DTYPE_CONTEXT;
+
+ txn = &sw_ring[txe->next_id];
+ RTE_MBUF_PREFETCH_TO_FREE(txn->mbuf);
+ if (txe->mbuf) {
+ rte_pktmbuf_free_seg(txe->mbuf);
+ txe->mbuf = NULL;
+ }
+
+ /* TSO enabled */
+ if (ol_flags & PKT_TX_TCP_SEG)
+ cd_type_cmd_tso_mss |=
+ avf_set_tso_ctx(tx_pkt, tx_offload);
+
+ AVF_DUMP_TX_DESC(txq, &txr[tx_id], tx_id);
+ txe->last_id = tx_last;
+ tx_id = txe->next_id;
+ txe = txn;
+ }
+
+ m_seg = tx_pkt;
+ do {
+ txd = &txr[tx_id];
+ txn = &sw_ring[txe->next_id];
+
+ if (txe->mbuf)
+ rte_pktmbuf_free_seg(txe->mbuf);
+ txe->mbuf = m_seg;
+
+ /* Setup TX Descriptor */
+ slen = m_seg->data_len;
+ buf_dma_addr = rte_mbuf_data_iova(m_seg);
+ txd->buffer_addr = rte_cpu_to_le_64(buf_dma_addr);
+ txd->cmd_type_offset_bsz = avf_build_ctob(td_cmd,
+ td_offset,
+ slen,
+ td_tag);
+
+ AVF_DUMP_TX_DESC(txq, txd, tx_id);
+ txe->last_id = tx_last;
+ tx_id = txe->next_id;
+ txe = txn;
+ m_seg = m_seg->next;
+ } while (m_seg);
+
+ /* The last packet data descriptor needs End Of Packet (EOP) */
+ td_cmd |= AVF_TX_DESC_CMD_EOP;
+ txq->nb_used = (uint16_t)(txq->nb_used + nb_used);
+ txq->nb_free = (uint16_t)(txq->nb_free - nb_used);
+
+ if (txq->nb_used >= txq->rs_thresh) {
+ PMD_TX_LOG(DEBUG, "Setting RS bit on TXD id="
+ "%4u (port=%d queue=%d)",
+ tx_last, txq->port_id, txq->queue_id);
+
+ td_cmd |= AVF_TX_DESC_CMD_RS;
+
+ /* Update txq RS bit counters */
+ txq->nb_used = 0;
+ }
+
+ txd->cmd_type_offset_bsz |=
+ rte_cpu_to_le_64(((uint64_t)td_cmd) <<
+ AVF_TXD_QW1_CMD_SHIFT);
+ AVF_DUMP_TX_DESC(txq, txd, tx_id);
+ }
+
+end_of_tx:
+ rte_wmb();
+
+ PMD_TX_LOG(DEBUG, "port_id=%u queue_id=%u tx_tail=%u nb_tx=%u",
+ txq->port_id, txq->queue_id, tx_id, nb_tx);
+
+ AVF_PCI_REG_WRITE_RELAXED(txq->qtx_tail, tx_id);
+ txq->tx_tail = tx_id;
+
+ return nb_tx;
+}
+
+static uint16_t
+avf_xmit_pkts_vec(void *tx_queue, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts)
+{
+ uint16_t nb_tx = 0;
+ struct avf_tx_queue *txq = (struct avf_tx_queue *)tx_queue;
+
+ while (nb_pkts) {
+ uint16_t ret, num;
+
+ num = (uint16_t)RTE_MIN(nb_pkts, txq->rs_thresh);
+ ret = avf_xmit_fixed_burst_vec(tx_queue, &tx_pkts[nb_tx], num);
+ nb_tx += ret;
+ nb_pkts -= ret;
+ if (ret < num)
+ break;
+ }
+
+ return nb_tx;
+}
+
+/* TX prep functions */
+uint16_t
+avf_prep_pkts(__rte_unused void *tx_queue, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts)
+{
+ int i, ret;
+ uint64_t ol_flags;
+ struct rte_mbuf *m;
+
+ for (i = 0; i < nb_pkts; i++) {
+ m = tx_pkts[i];
+ ol_flags = m->ol_flags;
+
+ /* Check condition for nb_segs > AVF_TX_MAX_MTU_SEG. */
+ if (!(ol_flags & PKT_TX_TCP_SEG)) {
+ if (m->nb_segs > AVF_TX_MAX_MTU_SEG) {
+ rte_errno = -EINVAL;
+ return i;
+ }
+ } else if ((m->tso_segsz < AVF_MIN_TSO_MSS) ||
+ (m->tso_segsz > AVF_MAX_TSO_MSS)) {
+ /* MSS outside the range are considered malicious */
+ rte_errno = -EINVAL;
+ return i;
+ }
+
+ if (ol_flags & AVF_TX_OFFLOAD_NOTSUP_MASK) {
+ rte_errno = -ENOTSUP;
+ return i;
+ }
+
+#ifdef RTE_LIBRTE_ETHDEV_DEBUG
+ ret = rte_validate_tx_offload(m);
+ if (ret != 0) {
+ rte_errno = ret;
+ return i;
+ }
+#endif
+ ret = rte_net_intel_cksum_prepare(m);
+ if (ret != 0) {
+ rte_errno = ret;
+ return i;
+ }
+ }
+
+ return i;
+}
+
+/* choose rx function*/
+void
+avf_set_rx_function(struct rte_eth_dev *dev)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_rx_queue *rxq;
+ int i;
+
+ if (adapter->rx_vec_allowed) {
+ if (dev->data->scattered_rx) {
+ PMD_DRV_LOG(DEBUG, "Using Vector Scattered Rx callback"
+ " (port=%d).", dev->data->port_id);
+ dev->rx_pkt_burst = avf_recv_scattered_pkts_vec;
+ } else {
+ PMD_DRV_LOG(DEBUG, "Using Vector Rx callback"
+ " (port=%d).", dev->data->port_id);
+ dev->rx_pkt_burst = avf_recv_pkts_vec;
+ }
+ for (i = 0; i < dev->data->nb_rx_queues; i++) {
+ rxq = dev->data->rx_queues[i];
+ if (!rxq)
+ continue;
+ avf_rxq_vec_setup(rxq);
+ }
+ } else if (dev->data->scattered_rx) {
+ PMD_DRV_LOG(DEBUG, "Using a Scattered Rx callback (port=%d).",
+ dev->data->port_id);
+ dev->rx_pkt_burst = avf_recv_scattered_pkts;
+ } else if (adapter->rx_bulk_alloc_allowed) {
+ PMD_DRV_LOG(DEBUG, "Using bulk Rx callback (port=%d).",
+ dev->data->port_id);
+ dev->rx_pkt_burst = avf_recv_pkts_bulk_alloc;
+ } else {
+ PMD_DRV_LOG(DEBUG, "Using Basic Rx callback (port=%d).",
+ dev->data->port_id);
+ dev->rx_pkt_burst = avf_recv_pkts;
+ }
+}
+
+/* choose tx function*/
+void
+avf_set_tx_function(struct rte_eth_dev *dev)
+{
+ struct avf_adapter *adapter =
+ AVF_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct avf_tx_queue *txq;
+ int i;
+
+ if (adapter->tx_vec_allowed) {
+ PMD_DRV_LOG(DEBUG, "Using Vector Tx callback (port=%d).",
+ dev->data->port_id);
+ dev->tx_pkt_burst = avf_xmit_pkts_vec;
+ dev->tx_pkt_prepare = NULL;
+ for (i = 0; i < dev->data->nb_tx_queues; i++) {
+ txq = dev->data->tx_queues[i];
+ if (!txq)
+ continue;
+ avf_txq_vec_setup(txq);
+ }
+ } else {
+ PMD_DRV_LOG(DEBUG, "Using Basic Tx callback (port=%d).",
+ dev->data->port_id);
+ dev->tx_pkt_burst = avf_xmit_pkts;
+ dev->tx_pkt_prepare = avf_prep_pkts;
+ }
+}
+
+void
+avf_dev_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
+ struct rte_eth_rxq_info *qinfo)
+{
+ struct avf_rx_queue *rxq;
+
+ rxq = dev->data->rx_queues[queue_id];
+
+ qinfo->mp = rxq->mp;
+ qinfo->scattered_rx = dev->data->scattered_rx;
+ qinfo->nb_desc = rxq->nb_rx_desc;
+
+ qinfo->conf.rx_free_thresh = rxq->rx_free_thresh;
+ qinfo->conf.rx_drop_en = TRUE;
+ qinfo->conf.rx_deferred_start = rxq->rx_deferred_start;
+}
+
+void
+avf_dev_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
+ struct rte_eth_txq_info *qinfo)
+{
+ struct avf_tx_queue *txq;
+
+ txq = dev->data->tx_queues[queue_id];
+
+ qinfo->nb_desc = txq->nb_tx_desc;
+
+ qinfo->conf.tx_free_thresh = txq->free_thresh;
+ qinfo->conf.tx_rs_thresh = txq->rs_thresh;
+ qinfo->conf.offloads = txq->offloads;
+ qinfo->conf.tx_deferred_start = txq->tx_deferred_start;
+}
+
+/* Get the number of used descriptors of a rx queue */
+uint32_t
+avf_dev_rxq_count(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+#define AVF_RXQ_SCAN_INTERVAL 4
+ volatile union avf_rx_desc *rxdp;
+ struct avf_rx_queue *rxq;
+ uint16_t desc = 0;
+
+ rxq = dev->data->rx_queues[queue_id];
+ rxdp = &rxq->rx_ring[rxq->rx_tail];
+ while ((desc < rxq->nb_rx_desc) &&
+ ((rte_le_to_cpu_64(rxdp->wb.qword1.status_error_len) &
+ AVF_RXD_QW1_STATUS_MASK) >> AVF_RXD_QW1_STATUS_SHIFT) &
+ (1 << AVF_RX_DESC_STATUS_DD_SHIFT)) {
+ /* Check the DD bit of a rx descriptor of each 4 in a group,
+ * to avoid checking too frequently and downgrading performance
+ * too much.
+ */
+ desc += AVF_RXQ_SCAN_INTERVAL;
+ rxdp += AVF_RXQ_SCAN_INTERVAL;
+ if (rxq->rx_tail + desc >= rxq->nb_rx_desc)
+ rxdp = &(rxq->rx_ring[rxq->rx_tail +
+ desc - rxq->nb_rx_desc]);
+ }
+
+ return desc;
+}
+
+int
+avf_dev_rx_desc_status(void *rx_queue, uint16_t offset)
+{
+ struct avf_rx_queue *rxq = rx_queue;
+ volatile uint64_t *status;
+ uint64_t mask;
+ uint32_t desc;
+
+ if (unlikely(offset >= rxq->nb_rx_desc))
+ return -EINVAL;
+
+ if (offset >= rxq->nb_rx_desc - rxq->nb_rx_hold)
+ return RTE_ETH_RX_DESC_UNAVAIL;
+
+ desc = rxq->rx_tail + offset;
+ if (desc >= rxq->nb_rx_desc)
+ desc -= rxq->nb_rx_desc;
+
+ status = &rxq->rx_ring[desc].wb.qword1.status_error_len;
+ mask = rte_le_to_cpu_64((1ULL << AVF_RX_DESC_STATUS_DD_SHIFT)
+ << AVF_RXD_QW1_STATUS_SHIFT);
+ if (*status & mask)
+ return RTE_ETH_RX_DESC_DONE;
+
+ return RTE_ETH_RX_DESC_AVAIL;
+}
+
+int
+avf_dev_tx_desc_status(void *tx_queue, uint16_t offset)
+{
+ struct avf_tx_queue *txq = tx_queue;
+ volatile uint64_t *status;
+ uint64_t mask, expect;
+ uint32_t desc;
+
+ if (unlikely(offset >= txq->nb_tx_desc))
+ return -EINVAL;
+
+ desc = txq->tx_tail + offset;
+ /* go to next desc that has the RS bit */
+ desc = ((desc + txq->rs_thresh - 1) / txq->rs_thresh) *
+ txq->rs_thresh;
+ if (desc >= txq->nb_tx_desc) {
+ desc -= txq->nb_tx_desc;
+ if (desc >= txq->nb_tx_desc)
+ desc -= txq->nb_tx_desc;
+ }
+
+ status = &txq->tx_ring[desc].cmd_type_offset_bsz;
+ mask = rte_le_to_cpu_64(AVF_TXD_QW1_DTYPE_MASK);
+ expect = rte_cpu_to_le_64(
+ AVF_TX_DESC_DTYPE_DESC_DONE << AVF_TXD_QW1_DTYPE_SHIFT);
+ if ((*status & mask) == expect)
+ return RTE_ETH_TX_DESC_DONE;
+
+ return RTE_ETH_TX_DESC_FULL;
+}
+
+__rte_weak uint16_t
+avf_recv_pkts_vec(__rte_unused void *rx_queue,
+ __rte_unused struct rte_mbuf **rx_pkts,
+ __rte_unused uint16_t nb_pkts)
+{
+ return 0;
+}
+
+__rte_weak uint16_t
+avf_recv_scattered_pkts_vec(__rte_unused void *rx_queue,
+ __rte_unused struct rte_mbuf **rx_pkts,
+ __rte_unused uint16_t nb_pkts)
+{
+ return 0;
+}
+
+__rte_weak uint16_t
+avf_xmit_fixed_burst_vec(__rte_unused void *tx_queue,
+ __rte_unused struct rte_mbuf **tx_pkts,
+ __rte_unused uint16_t nb_pkts)
+{
+ return 0;
+}
+
+__rte_weak int
+avf_rxq_vec_setup(__rte_unused struct avf_rx_queue *rxq)
+{
+ return -1;
+}
+
+__rte_weak int
+avf_txq_vec_setup(__rte_unused struct avf_tx_queue *txq)
+{
+ return -1;
+}
diff --git a/drivers/net/iavf/iavf_rxtx.h b/drivers/net/iavf/iavf_rxtx.h
new file mode 100644
index 0000000..ffc835d
--- /dev/null
+++ b/drivers/net/iavf/iavf_rxtx.h
@@ -0,0 +1,268 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017 Intel Corporation
+ */
+
+#ifndef _AVF_RXTX_H_
+#define _AVF_RXTX_H_
+
+/* In QLEN must be whole number of 32 descriptors. */
+#define AVF_ALIGN_RING_DESC 32
+#define AVF_MIN_RING_DESC 64
+#define AVF_MAX_RING_DESC 4096
+#define AVF_DMA_MEM_ALIGN 4096
+/* Base address of the HW descriptor ring should be 128B aligned. */
+#define AVF_RING_BASE_ALIGN 128
+
+/* used for Rx Bulk Allocate */
+#define AVF_RX_MAX_BURST 32
+
+/* used for Vector PMD */
+#define AVF_VPMD_RX_MAX_BURST 32
+#define AVF_VPMD_TX_MAX_BURST 32
+#define AVF_VPMD_DESCS_PER_LOOP 4
+#define AVF_VPMD_TX_MAX_FREE_BUF 64
+
+#define AVF_NO_VECTOR_FLAGS ( \
+ DEV_TX_OFFLOAD_MULTI_SEGS | \
+ DEV_TX_OFFLOAD_VLAN_INSERT | \
+ DEV_TX_OFFLOAD_SCTP_CKSUM | \
+ DEV_TX_OFFLOAD_UDP_CKSUM | \
+ DEV_TX_OFFLOAD_TCP_CKSUM)
+
+#define DEFAULT_TX_RS_THRESH 32
+#define DEFAULT_TX_FREE_THRESH 32
+
+#define AVF_MIN_TSO_MSS 256
+#define AVF_MAX_TSO_MSS 9668
+#define AVF_TSO_MAX_SEG UINT8_MAX
+#define AVF_TX_MAX_MTU_SEG 8
+
+#define AVF_TX_CKSUM_OFFLOAD_MASK ( \
+ PKT_TX_IP_CKSUM | \
+ PKT_TX_L4_MASK | \
+ PKT_TX_TCP_SEG)
+
+#define AVF_TX_OFFLOAD_MASK ( \
+ PKT_TX_OUTER_IPV6 | \
+ PKT_TX_OUTER_IPV4 | \
+ PKT_TX_IPV6 | \
+ PKT_TX_IPV4 | \
+ PKT_TX_VLAN_PKT | \
+ PKT_TX_IP_CKSUM | \
+ PKT_TX_L4_MASK | \
+ PKT_TX_TCP_SEG)
+
+#define AVF_TX_OFFLOAD_NOTSUP_MASK \
+ (PKT_TX_OFFLOAD_MASK ^ AVF_TX_OFFLOAD_MASK)
+
+/* HW desc structure, both 16-byte and 32-byte types are supported */
+#ifdef RTE_LIBRTE_AVF_16BYTE_RX_DESC
+#define avf_rx_desc avf_16byte_rx_desc
+#else
+#define avf_rx_desc avf_32byte_rx_desc
+#endif
+
+struct avf_rxq_ops {
+ void (*release_mbufs)(struct avf_rx_queue *rxq);
+};
+
+struct avf_txq_ops {
+ void (*release_mbufs)(struct avf_tx_queue *txq);
+};
+
+/* Structure associated with each Rx queue. */
+struct avf_rx_queue {
+ struct rte_mempool *mp; /* mbuf pool to populate Rx ring */
+ const struct rte_memzone *mz; /* memzone for Rx ring */
+ volatile union avf_rx_desc *rx_ring; /* Rx ring virtual address */
+ uint64_t rx_ring_phys_addr; /* Rx ring DMA address */
+ struct rte_mbuf **sw_ring; /* address of SW ring */
+ uint16_t nb_rx_desc; /* ring length */
+ uint16_t rx_tail; /* current value of tail */
+ volatile uint8_t *qrx_tail; /* register address of tail */
+ uint16_t rx_free_thresh; /* max free RX desc to hold */
+ uint16_t nb_rx_hold; /* number of held free RX desc */
+ struct rte_mbuf *pkt_first_seg; /* first segment of current packet */
+ struct rte_mbuf *pkt_last_seg; /* last segment of current packet */
+ struct rte_mbuf fake_mbuf; /* dummy mbuf */
+
+ /* used for VPMD */
+ uint16_t rxrearm_nb; /* number of remaining to be re-armed */
+ uint16_t rxrearm_start; /* the idx we start the re-arming from */
+ uint64_t mbuf_initializer; /* value to init mbufs */
+
+ /* for rx bulk */
+ uint16_t rx_nb_avail; /* number of staged packets ready */
+ uint16_t rx_next_avail; /* index of next staged packets */
+ uint16_t rx_free_trigger; /* triggers rx buffer allocation */
+ struct rte_mbuf *rx_stage[AVF_RX_MAX_BURST * 2]; /* store mbuf */
+
+ uint16_t port_id; /* device port ID */
+ uint8_t crc_len; /* 0 if CRC stripped, 4 otherwise */
+ uint16_t queue_id; /* Rx queue index */
+ uint16_t rx_buf_len; /* The packet buffer size */
+ uint16_t rx_hdr_len; /* The header buffer size */
+ uint16_t max_pkt_len; /* Maximum packet length */
+
+ bool q_set; /* if rx queue has been configured */
+ bool rx_deferred_start; /* don't start this queue in dev start */
+ const struct avf_rxq_ops *ops;
+};
+
+struct avf_tx_entry {
+ struct rte_mbuf *mbuf;
+ uint16_t next_id;
+ uint16_t last_id;
+};
+
+/* Structure associated with each TX queue. */
+struct avf_tx_queue {
+ const struct rte_memzone *mz; /* memzone for Tx ring */
+ volatile struct avf_tx_desc *tx_ring; /* Tx ring virtual address */
+ uint64_t tx_ring_phys_addr; /* Tx ring DMA address */
+ struct avf_tx_entry *sw_ring; /* address array of SW ring */
+ uint16_t nb_tx_desc; /* ring length */
+ uint16_t tx_tail; /* current value of tail */
+ volatile uint8_t *qtx_tail; /* register address of tail */
+ /* number of used desc since RS bit set */
+ uint16_t nb_used;
+ uint16_t nb_free;
+ uint16_t last_desc_cleaned; /* last desc have been cleaned*/
+ uint16_t free_thresh;
+ uint16_t rs_thresh;
+
+ uint16_t port_id;
+ uint16_t queue_id;
+ uint64_t offloads;
+ uint16_t next_dd; /* next to set RS, for VPMD */
+ uint16_t next_rs; /* next to check DD, for VPMD */
+
+ bool q_set; /* if rx queue has been configured */
+ bool tx_deferred_start; /* don't start this queue in dev start */
+ const struct avf_txq_ops *ops;
+};
+
+/* Offload features */
+union avf_tx_offload {
+ uint64_t data;
+ struct {
+ uint64_t l2_len:7; /* L2 (MAC) Header Length. */
+ uint64_t l3_len:9; /* L3 (IP) Header Length. */
+ uint64_t l4_len:8; /* L4 Header Length. */
+ uint64_t tso_segsz:16; /* TCP TSO segment size */
+ /* uint64_t unused : 24; */
+ };
+};
+
+int avf_dev_rx_queue_setup(struct rte_eth_dev *dev,
+ uint16_t queue_idx,
+ uint16_t nb_desc,
+ unsigned int socket_id,
+ const struct rte_eth_rxconf *rx_conf,
+ struct rte_mempool *mp);
+
+int avf_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id);
+int avf_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id);
+void avf_dev_rx_queue_release(void *rxq);
+
+int avf_dev_tx_queue_setup(struct rte_eth_dev *dev,
+ uint16_t queue_idx,
+ uint16_t nb_desc,
+ unsigned int socket_id,
+ const struct rte_eth_txconf *tx_conf);
+int avf_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id);
+int avf_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id);
+void avf_dev_tx_queue_release(void *txq);
+void avf_stop_queues(struct rte_eth_dev *dev);
+uint16_t avf_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+ uint16_t nb_pkts);
+uint16_t avf_recv_scattered_pkts(void *rx_queue,
+ struct rte_mbuf **rx_pkts,
+ uint16_t nb_pkts);
+uint16_t avf_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts);
+uint16_t avf_prep_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts);
+void avf_set_rx_function(struct rte_eth_dev *dev);
+void avf_set_tx_function(struct rte_eth_dev *dev);
+void avf_dev_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
+ struct rte_eth_rxq_info *qinfo);
+void avf_dev_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
+ struct rte_eth_txq_info *qinfo);
+uint32_t avf_dev_rxq_count(struct rte_eth_dev *dev, uint16_t queue_id);
+int avf_dev_rx_desc_status(void *rx_queue, uint16_t offset);
+int avf_dev_tx_desc_status(void *tx_queue, uint16_t offset);
+
+uint16_t avf_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
+ uint16_t nb_pkts);
+uint16_t avf_recv_scattered_pkts_vec(void *rx_queue,
+ struct rte_mbuf **rx_pkts,
+ uint16_t nb_pkts);
+uint16_t avf_xmit_fixed_burst_vec(void *tx_queue, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts);
+int avf_rxq_vec_setup(struct avf_rx_queue *rxq);
+int avf_txq_vec_setup(struct avf_tx_queue *txq);
+
+static inline
+void avf_dump_rx_descriptor(struct avf_rx_queue *rxq,
+ const volatile void *desc,
+ uint16_t rx_id)
+{
+#ifdef RTE_LIBRTE_AVF_16BYTE_RX_DESC
+ const volatile union avf_16byte_rx_desc *rx_desc = desc;
+
+ printf("Queue %d Rx_desc %d: QW0: 0x%016"PRIx64" QW1: 0x%016"PRIx64"\n",
+ rxq->queue_id, rx_id, rx_desc->read.pkt_addr,
+ rx_desc->read.hdr_addr);
+#else
+ const volatile union avf_32byte_rx_desc *rx_desc = desc;
+
+ printf("Queue %d Rx_desc %d: QW0: 0x%016"PRIx64" QW1: 0x%016"PRIx64
+ " QW2: 0x%016"PRIx64" QW3: 0x%016"PRIx64"\n", rxq->queue_id,
+ rx_id, rx_desc->read.pkt_addr, rx_desc->read.hdr_addr,
+ rx_desc->read.rsvd1, rx_desc->read.rsvd2);
+#endif
+}
+
+/* All the descriptors are 16 bytes, so just use one of them
+ * to print the qwords
+ */
+static inline
+void avf_dump_tx_descriptor(const struct avf_tx_queue *txq,
+ const volatile void *desc, uint16_t tx_id)
+{
+ const char *name;
+ const volatile struct avf_tx_desc *tx_desc = desc;
+ enum avf_tx_desc_dtype_value type;
+
+ type = (enum avf_tx_desc_dtype_value)rte_le_to_cpu_64(
+ tx_desc->cmd_type_offset_bsz &
+ rte_cpu_to_le_64(AVF_TXD_QW1_DTYPE_MASK));
+ switch (type) {
+ case AVF_TX_DESC_DTYPE_DATA:
+ name = "Tx_data_desc";
+ break;
+ case AVF_TX_DESC_DTYPE_CONTEXT:
+ name = "Tx_context_desc";
+ break;
+ default:
+ name = "unknown_desc";
+ break;
+ }
+
+ printf("Queue %d %s %d: QW0: 0x%016"PRIx64" QW1: 0x%016"PRIx64"\n",
+ txq->queue_id, name, tx_id, tx_desc->buffer_addr,
+ tx_desc->cmd_type_offset_bsz);
+}
+
+#ifdef DEBUG_DUMP_DESC
+#define AVF_DUMP_RX_DESC(rxq, desc, rx_id) \
+ avf_dump_rx_descriptor(rxq, desc, rx_id)
+#define AVF_DUMP_TX_DESC(txq, desc, tx_id) \
+ avf_dump_tx_descriptor(txq, desc, tx_id)
+#else
+#define AVF_DUMP_RX_DESC(rxq, desc, rx_id) do { } while (0)
+#define AVF_DUMP_TX_DESC(txq, desc, tx_id) do { } while (0)
+#endif
+
+#endif /* _AVF_RXTX_H_ */
diff --git a/drivers/net/iavf/iavf_rxtx_vec_common.h b/drivers/net/iavf/iavf_rxtx_vec_common.h
new file mode 100644
index 0000000..16433e5
--- /dev/null
+++ b/drivers/net/iavf/iavf_rxtx_vec_common.h
@@ -0,0 +1,210 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017 Intel Corporation
+ */
+
+#ifndef _AVF_RXTX_VEC_COMMON_H_
+#define _AVF_RXTX_VEC_COMMON_H_
+#include <stdint.h>
+#include <rte_ethdev_driver.h>
+#include <rte_malloc.h>
+
+#include "iavf.h"
+#include "iavf_rxtx.h"
+
+static inline uint16_t
+reassemble_packets(struct avf_rx_queue *rxq, struct rte_mbuf **rx_bufs,
+ uint16_t nb_bufs, uint8_t *split_flags)
+{
+ struct rte_mbuf *pkts[AVF_VPMD_RX_MAX_BURST];
+ struct rte_mbuf *start = rxq->pkt_first_seg;
+ struct rte_mbuf *end = rxq->pkt_last_seg;
+ unsigned int pkt_idx, buf_idx;
+
+ for (buf_idx = 0, pkt_idx = 0; buf_idx < nb_bufs; buf_idx++) {
+ if (end) {
+ /* processing a split packet */
+ end->next = rx_bufs[buf_idx];
+ rx_bufs[buf_idx]->data_len += rxq->crc_len;
+
+ start->nb_segs++;
+ start->pkt_len += rx_bufs[buf_idx]->data_len;
+ end = end->next;
+
+ if (!split_flags[buf_idx]) {
+ /* it's the last packet of the set */
+ start->hash = end->hash;
+ start->ol_flags = end->ol_flags;
+ /* we need to strip crc for the whole packet */
+ start->pkt_len -= rxq->crc_len;
+ if (end->data_len > rxq->crc_len) {
+ end->data_len -= rxq->crc_len;
+ } else {
+ /* free up last mbuf */
+ struct rte_mbuf *secondlast = start;
+
+ start->nb_segs--;
+ while (secondlast->next != end)
+ secondlast = secondlast->next;
+ secondlast->data_len -= (rxq->crc_len -
+ end->data_len);
+ secondlast->next = NULL;
+ rte_pktmbuf_free_seg(end);
+ }
+ pkts[pkt_idx++] = start;
+ start = NULL;
+ end = NULL;
+ }
+ } else {
+ /* not processing a split packet */
+ if (!split_flags[buf_idx]) {
+ /* not a split packet, save and skip */
+ pkts[pkt_idx++] = rx_bufs[buf_idx];
+ continue;
+ }
+ end = start = rx_bufs[buf_idx];
+ rx_bufs[buf_idx]->data_len += rxq->crc_len;
+ rx_bufs[buf_idx]->pkt_len += rxq->crc_len;
+ }
+ }
+
+ /* save the partial packet for next time */
+ rxq->pkt_first_seg = start;
+ rxq->pkt_last_seg = end;
+ memcpy(rx_bufs, pkts, pkt_idx * (sizeof(*pkts)));
+ return pkt_idx;
+}
+
+static __rte_always_inline int
+avf_tx_free_bufs(struct avf_tx_queue *txq)
+{
+ struct avf_tx_entry *txep;
+ uint32_t n;
+ uint32_t i;
+ int nb_free = 0;
+ struct rte_mbuf *m, *free[AVF_VPMD_TX_MAX_FREE_BUF];
+
+ /* check DD bits on threshold descriptor */
+ if ((txq->tx_ring[txq->next_dd].cmd_type_offset_bsz &
+ rte_cpu_to_le_64(AVF_TXD_QW1_DTYPE_MASK)) !=
+ rte_cpu_to_le_64(AVF_TX_DESC_DTYPE_DESC_DONE))
+ return 0;
+
+ n = txq->rs_thresh;
+
+ /* first buffer to free from S/W ring is at index
+ * tx_next_dd - (tx_rs_thresh-1)
+ */
+ txep = &txq->sw_ring[txq->next_dd - (n - 1)];
+ m = rte_pktmbuf_prefree_seg(txep[0].mbuf);
+ if (likely(m != NULL)) {
+ free[0] = m;
+ nb_free = 1;
+ for (i = 1; i < n; i++) {
+ m = rte_pktmbuf_prefree_seg(txep[i].mbuf);
+ if (likely(m != NULL)) {
+ if (likely(m->pool == free[0]->pool)) {
+ free[nb_free++] = m;
+ } else {
+ rte_mempool_put_bulk(free[0]->pool,
+ (void *)free,
+ nb_free);
+ free[0] = m;
+ nb_free = 1;
+ }
+ }
+ }
+ rte_mempool_put_bulk(free[0]->pool, (void **)free, nb_free);
+ } else {
+ for (i = 1; i < n; i++) {
+ m = rte_pktmbuf_prefree_seg(txep[i].mbuf);
+ if (m)
+ rte_mempool_put(m->pool, m);
+ }
+ }
+
+ /* buffers were freed, update counters */
+ txq->nb_free = (uint16_t)(txq->nb_free + txq->rs_thresh);
+ txq->next_dd = (uint16_t)(txq->next_dd + txq->rs_thresh);
+ if (txq->next_dd >= txq->nb_tx_desc)
+ txq->next_dd = (uint16_t)(txq->rs_thresh - 1);
+
+ return txq->rs_thresh;
+}
+
+static __rte_always_inline void
+tx_backlog_entry(struct avf_tx_entry *txep,
+ struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
+{
+ int i;
+
+ for (i = 0; i < (int)nb_pkts; ++i)
+ txep[i].mbuf = tx_pkts[i];
+}
+
+static inline void
+_avf_rx_queue_release_mbufs_vec(struct avf_rx_queue *rxq)
+{
+ const unsigned int mask = rxq->nb_rx_desc - 1;
+ unsigned int i;
+
+ if (!rxq->sw_ring || rxq->rxrearm_nb >= rxq->nb_rx_desc)
+ return;
+
+ /* free all mbufs that are valid in the ring */
+ if (rxq->rxrearm_nb == 0) {
+ for (i = 0; i < rxq->nb_rx_desc; i++) {
+ if (rxq->sw_ring[i])
+ rte_pktmbuf_free_seg(rxq->sw_ring[i]);
+ }
+ } else {
+ for (i = rxq->rx_tail;
+ i != rxq->rxrearm_start;
+ i = (i + 1) & mask) {
+ if (rxq->sw_ring[i])
+ rte_pktmbuf_free_seg(rxq->sw_ring[i]);
+ }
+ }
+
+ rxq->rxrearm_nb = rxq->nb_rx_desc;
+
+ /* set all entries to NULL */
+ memset(rxq->sw_ring, 0, sizeof(rxq->sw_ring[0]) * rxq->nb_rx_desc);
+}
+
+static inline void
+_avf_tx_queue_release_mbufs_vec(struct avf_tx_queue *txq)
+{
+ unsigned i;
+ const uint16_t max_desc = (uint16_t)(txq->nb_tx_desc - 1);
+
+ if (!txq->sw_ring || txq->nb_free == max_desc)
+ return;
+
+ i = txq->next_dd - txq->rs_thresh + 1;
+ if (txq->tx_tail < i) {
+ for (; i < txq->nb_tx_desc; i++) {
+ rte_pktmbuf_free_seg(txq->sw_ring[i].mbuf);
+ txq->sw_ring[i].mbuf = NULL;
+ }
+ i = 0;
+ }
+}
+
+static inline int
+avf_rxq_vec_setup_default(struct avf_rx_queue *rxq)
+{
+ uintptr_t p;
+ struct rte_mbuf mb_def = { .buf_addr = 0 }; /* zeroed mbuf */
+
+ mb_def.nb_segs = 1;
+ mb_def.data_off = RTE_PKTMBUF_HEADROOM;
+ mb_def.port = rxq->port_id;
+ rte_mbuf_refcnt_set(&mb_def, 1);
+
+ /* prevent compiler reordering: rearm_data covers previous fields */
+ rte_compiler_barrier();
+ p = (uintptr_t)&mb_def.rearm_data;
+ rxq->mbuf_initializer = *(uint64_t *)p;
+ return 0;
+}
+#endif
diff --git a/drivers/net/iavf/iavf_rxtx_vec_sse.c b/drivers/net/iavf/iavf_rxtx_vec_sse.c
new file mode 100644
index 0000000..7071ed6
--- /dev/null
+++ b/drivers/net/iavf/iavf_rxtx_vec_sse.c
@@ -0,0 +1,656 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017 Intel Corporation
+ */
+
+#include <stdint.h>
+#include <rte_ethdev_driver.h>
+#include <rte_malloc.h>
+
+#include "base/iavf_prototype.h"
+#include "base/iavf_type.h"
+#include "iavf.h"
+#include "iavf_rxtx.h"
+#include "iavf_rxtx_vec_common.h"
+
+#include <tmmintrin.h>
+
+#ifndef __INTEL_COMPILER
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
+
+static inline void
+avf_rxq_rearm(struct avf_rx_queue *rxq)
+{
+ int i;
+ uint16_t rx_id;
+
+ volatile union avf_rx_desc *rxdp;
+ struct rte_mbuf **rxp = &rxq->sw_ring[rxq->rxrearm_start];
+ struct rte_mbuf *mb0, *mb1;
+ __m128i hdr_room = _mm_set_epi64x(RTE_PKTMBUF_HEADROOM,
+ RTE_PKTMBUF_HEADROOM);
+ __m128i dma_addr0, dma_addr1;
+
+ rxdp = rxq->rx_ring + rxq->rxrearm_start;
+
+ /* Pull 'n' more MBUFs into the software ring */
+ if (rte_mempool_get_bulk(rxq->mp, (void *)rxp,
+ rxq->rx_free_thresh) < 0) {
+ if (rxq->rxrearm_nb + rxq->rx_free_thresh >= rxq->nb_rx_desc) {
+ dma_addr0 = _mm_setzero_si128();
+ for (i = 0; i < AVF_VPMD_DESCS_PER_LOOP; i++) {
+ rxp[i] = &rxq->fake_mbuf;
+ _mm_store_si128((__m128i *)&rxdp[i].read,
+ dma_addr0);
+ }
+ }
+ rte_eth_devices[rxq->port_id].data->rx_mbuf_alloc_failed +=
+ rxq->rx_free_thresh;
+ return;
+ }
+
+ /* Initialize the mbufs in vector, process 2 mbufs in one loop */
+ for (i = 0; i < rxq->rx_free_thresh; i += 2, rxp += 2) {
+ __m128i vaddr0, vaddr1;
+
+ mb0 = rxp[0];
+ mb1 = rxp[1];
+
+ /* load buf_addr(lo 64bit) and buf_iova(hi 64bit) */
+ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, buf_iova) !=
+ offsetof(struct rte_mbuf, buf_addr) + 8);
+ vaddr0 = _mm_loadu_si128((__m128i *)&mb0->buf_addr);
+ vaddr1 = _mm_loadu_si128((__m128i *)&mb1->buf_addr);
+
+ /* convert pa to dma_addr hdr/data */
+ dma_addr0 = _mm_unpackhi_epi64(vaddr0, vaddr0);
+ dma_addr1 = _mm_unpackhi_epi64(vaddr1, vaddr1);
+
+ /* add headroom to pa values */
+ dma_addr0 = _mm_add_epi64(dma_addr0, hdr_room);
+ dma_addr1 = _mm_add_epi64(dma_addr1, hdr_room);
+
+ /* flush desc with pa dma_addr */
+ _mm_store_si128((__m128i *)&rxdp++->read, dma_addr0);
+ _mm_store_si128((__m128i *)&rxdp++->read, dma_addr1);
+ }
+
+ rxq->rxrearm_start += rxq->rx_free_thresh;
+ if (rxq->rxrearm_start >= rxq->nb_rx_desc)
+ rxq->rxrearm_start = 0;
+
+ rxq->rxrearm_nb -= rxq->rx_free_thresh;
+
+ rx_id = (uint16_t)((rxq->rxrearm_start == 0) ?
+ (rxq->nb_rx_desc - 1) : (rxq->rxrearm_start - 1));
+
+ PMD_RX_LOG(DEBUG, "port_id=%u queue_id=%u rx_tail=%u "
+ "rearm_start=%u rearm_nb=%u",
+ rxq->port_id, rxq->queue_id,
+ rx_id, rxq->rxrearm_start, rxq->rxrearm_nb);
+
+ /* Update the tail pointer on the NIC */
+ AVF_PCI_REG_WRITE(rxq->qrx_tail, rx_id);
+}
+
+static inline void
+desc_to_olflags_v(struct avf_rx_queue *rxq, __m128i descs[4],
+ struct rte_mbuf **rx_pkts)
+{
+ const __m128i mbuf_init = _mm_set_epi64x(0, rxq->mbuf_initializer);
+ __m128i rearm0, rearm1, rearm2, rearm3;
+
+ __m128i vlan0, vlan1, rss, l3_l4e;
+
+ /* mask everything except RSS, flow director and VLAN flags
+ * bit2 is for VLAN tag, bit11 for flow director indication
+ * bit13:12 for RSS indication.
+ */
+ const __m128i rss_vlan_msk = _mm_set_epi32(
+ 0x1c03804, 0x1c03804, 0x1c03804, 0x1c03804);
+
+ const __m128i cksum_mask = _mm_set_epi32(
+ PKT_RX_IP_CKSUM_GOOD | PKT_RX_IP_CKSUM_BAD |
+ PKT_RX_L4_CKSUM_GOOD | PKT_RX_L4_CKSUM_BAD |
+ PKT_RX_EIP_CKSUM_BAD,
+ PKT_RX_IP_CKSUM_GOOD | PKT_RX_IP_CKSUM_BAD |
+ PKT_RX_L4_CKSUM_GOOD | PKT_RX_L4_CKSUM_BAD |
+ PKT_RX_EIP_CKSUM_BAD,
+ PKT_RX_IP_CKSUM_GOOD | PKT_RX_IP_CKSUM_BAD |
+ PKT_RX_L4_CKSUM_GOOD | PKT_RX_L4_CKSUM_BAD |
+ PKT_RX_EIP_CKSUM_BAD,
+ PKT_RX_IP_CKSUM_GOOD | PKT_RX_IP_CKSUM_BAD |
+ PKT_RX_L4_CKSUM_GOOD | PKT_RX_L4_CKSUM_BAD |
+ PKT_RX_EIP_CKSUM_BAD);
+
+ /* map rss and vlan type to rss hash and vlan flag */
+ const __m128i vlan_flags = _mm_set_epi8(0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, PKT_RX_VLAN | PKT_RX_VLAN_STRIPPED,
+ 0, 0, 0, 0);
+
+ const __m128i rss_flags = _mm_set_epi8(0, 0, 0, 0,
+ 0, 0, 0, 0,
+ PKT_RX_RSS_HASH | PKT_RX_FDIR, PKT_RX_RSS_HASH, 0, 0,
+ 0, 0, PKT_RX_FDIR, 0);
+
+ const __m128i l3_l4e_flags = _mm_set_epi8(0, 0, 0, 0, 0, 0, 0, 0,
+ /* shift right 1 bit to make sure it not exceed 255 */
+ (PKT_RX_EIP_CKSUM_BAD | PKT_RX_L4_CKSUM_BAD |
+ PKT_RX_IP_CKSUM_BAD) >> 1,
+ (PKT_RX_IP_CKSUM_GOOD | PKT_RX_EIP_CKSUM_BAD |
+ PKT_RX_L4_CKSUM_BAD) >> 1,
+ (PKT_RX_EIP_CKSUM_BAD | PKT_RX_IP_CKSUM_BAD) >> 1,
+ (PKT_RX_IP_CKSUM_GOOD | PKT_RX_EIP_CKSUM_BAD) >> 1,
+ (PKT_RX_L4_CKSUM_BAD | PKT_RX_IP_CKSUM_BAD) >> 1,
+ (PKT_RX_IP_CKSUM_GOOD | PKT_RX_L4_CKSUM_BAD) >> 1,
+ PKT_RX_IP_CKSUM_BAD >> 1,
+ (PKT_RX_IP_CKSUM_GOOD | PKT_RX_L4_CKSUM_GOOD) >> 1);
+
+ vlan0 = _mm_unpackhi_epi32(descs[0], descs[1]);
+ vlan1 = _mm_unpackhi_epi32(descs[2], descs[3]);
+ vlan0 = _mm_unpacklo_epi64(vlan0, vlan1);
+
+ vlan1 = _mm_and_si128(vlan0, rss_vlan_msk);
+ vlan0 = _mm_shuffle_epi8(vlan_flags, vlan1);
+
+ rss = _mm_srli_epi32(vlan1, 11);
+ rss = _mm_shuffle_epi8(rss_flags, rss);
+
+ l3_l4e = _mm_srli_epi32(vlan1, 22);
+ l3_l4e = _mm_shuffle_epi8(l3_l4e_flags, l3_l4e);
+ /* then we shift left 1 bit */
+ l3_l4e = _mm_slli_epi32(l3_l4e, 1);
+ /* we need to mask out the reduntant bits */
+ l3_l4e = _mm_and_si128(l3_l4e, cksum_mask);
+
+ vlan0 = _mm_or_si128(vlan0, rss);
+ vlan0 = _mm_or_si128(vlan0, l3_l4e);
+
+ /* At this point, we have the 4 sets of flags in the low 16-bits
+ * of each 32-bit value in vlan0.
+ * We want to extract these, and merge them with the mbuf init data
+ * so we can do a single 16-byte write to the mbuf to set the flags
+ * and all the other initialization fields. Extracting the
+ * appropriate flags means that we have to do a shift and blend for
+ * each mbuf before we do the write.
+ */
+ rearm0 = _mm_blend_epi16(mbuf_init, _mm_slli_si128(vlan0, 8), 0x10);
+ rearm1 = _mm_blend_epi16(mbuf_init, _mm_slli_si128(vlan0, 4), 0x10);
+ rearm2 = _mm_blend_epi16(mbuf_init, vlan0, 0x10);
+ rearm3 = _mm_blend_epi16(mbuf_init, _mm_srli_si128(vlan0, 4), 0x10);
+
+ /* write the rearm data and the olflags in one write */
+ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, ol_flags) !=
+ offsetof(struct rte_mbuf, rearm_data) + 8);
+ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, rearm_data) !=
+ RTE_ALIGN(offsetof(struct rte_mbuf, rearm_data), 16));
+ _mm_store_si128((__m128i *)&rx_pkts[0]->rearm_data, rearm0);
+ _mm_store_si128((__m128i *)&rx_pkts[1]->rearm_data, rearm1);
+ _mm_store_si128((__m128i *)&rx_pkts[2]->rearm_data, rearm2);
+ _mm_store_si128((__m128i *)&rx_pkts[3]->rearm_data, rearm3);
+}
+
+#define PKTLEN_SHIFT 10
+
+static inline void
+desc_to_ptype_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
+{
+ __m128i ptype0 = _mm_unpackhi_epi64(descs[0], descs[1]);
+ __m128i ptype1 = _mm_unpackhi_epi64(descs[2], descs[3]);
+ static const uint32_t type_table[UINT8_MAX + 1] __rte_cache_aligned = {
+ /* [0] reserved */
+ [1] = RTE_PTYPE_L2_ETHER,
+ /* [2] - [21] reserved */
+ [22] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_FRAG,
+ [23] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_NONFRAG,
+ [24] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_UDP,
+ /* [25] reserved */
+ [26] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_TCP,
+ [27] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_SCTP,
+ [28] = RTE_PTYPE_L2_ETHER | RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
+ RTE_PTYPE_L4_ICMP,
+ /* All others reserved */
+ };
+
+ ptype0 = _mm_srli_epi64(ptype0, 30);
+ ptype1 = _mm_srli_epi64(ptype1, 30);
+
+ rx_pkts[0]->packet_type = type_table[_mm_extract_epi8(ptype0, 0)];
+ rx_pkts[1]->packet_type = type_table[_mm_extract_epi8(ptype0, 8)];
+ rx_pkts[2]->packet_type = type_table[_mm_extract_epi8(ptype1, 0)];
+ rx_pkts[3]->packet_type = type_table[_mm_extract_epi8(ptype1, 8)];
+}
+
+/* Notice:
+ * - nb_pkts < AVF_VPMD_DESCS_PER_LOOP, just return no packet
+ * - nb_pkts > AVF_VPMD_RX_MAX_BURST, only scan AVF_VPMD_RX_MAX_BURST
+ * numbers of DD bits
+ */
+static inline uint16_t
+_recv_raw_pkts_vec(struct avf_rx_queue *rxq, struct rte_mbuf **rx_pkts,
+ uint16_t nb_pkts, uint8_t *split_packet)
+{
+ volatile union avf_rx_desc *rxdp;
+ struct rte_mbuf **sw_ring;
+ uint16_t nb_pkts_recd;
+ int pos;
+ uint64_t var;
+ __m128i shuf_msk;
+
+ __m128i crc_adjust = _mm_set_epi16(
+ 0, 0, 0, /* ignore non-length fields */
+ -rxq->crc_len, /* sub crc on data_len */
+ 0, /* ignore high-16bits of pkt_len */
+ -rxq->crc_len, /* sub crc on pkt_len */
+ 0, 0 /* ignore pkt_type field */
+ );
+ /* compile-time check the above crc_adjust layout is correct.
+ * NOTE: the first field (lowest address) is given last in set_epi16
+ * call above.
+ */
+ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, pkt_len) !=
+ offsetof(struct rte_mbuf, rx_descriptor_fields1) + 4);
+ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_len) !=
+ offsetof(struct rte_mbuf, rx_descriptor_fields1) + 8);
+ __m128i dd_check, eop_check;
+
+ /* nb_pkts shall be less equal than AVF_VPMD_RX_MAX_BURST */
+ nb_pkts = RTE_MIN(nb_pkts, AVF_VPMD_RX_MAX_BURST);
+
+ /* nb_pkts has to be floor-aligned to AVF_VPMD_DESCS_PER_LOOP */
+ nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, AVF_VPMD_DESCS_PER_LOOP);
+
+ /* Just the act of getting into the function from the application is
+ * going to cost about 7 cycles
+ */
+ rxdp = rxq->rx_ring + rxq->rx_tail;
+
+ rte_prefetch0(rxdp);
+
+ /* See if we need to rearm the RX queue - gives the prefetch a bit
+ * of time to act
+ */
+ if (rxq->rxrearm_nb > rxq->rx_free_thresh)
+ avf_rxq_rearm(rxq);
+
+ /* Before we start moving massive data around, check to see if
+ * there is actually a packet available
+ */
+ if (!(rxdp->wb.qword1.status_error_len &
+ rte_cpu_to_le_32(1 << AVF_RX_DESC_STATUS_DD_SHIFT)))
+ return 0;
+
+ /* 4 packets DD mask */
+ dd_check = _mm_set_epi64x(0x0000000100000001LL, 0x0000000100000001LL);
+
+ /* 4 packets EOP mask */
+ eop_check = _mm_set_epi64x(0x0000000200000002LL, 0x0000000200000002LL);
+
+ /* mask to shuffle from desc. to mbuf */
+ shuf_msk = _mm_set_epi8(
+ 7, 6, 5, 4, /* octet 4~7, 32bits rss */
+ 3, 2, /* octet 2~3, low 16 bits vlan_macip */
+ 15, 14, /* octet 15~14, 16 bits data_len */
+ 0xFF, 0xFF, /* skip high 16 bits pkt_len, zero out */
+ 15, 14, /* octet 15~14, low 16 bits pkt_len */
+ 0xFF, 0xFF, 0xFF, 0xFF /* pkt_type set as unknown */
+ );
+ /* Compile-time verify the shuffle mask
+ * NOTE: some field positions already verified above, but duplicated
+ * here for completeness in case of future modifications.
+ */
+ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, pkt_len) !=
+ offsetof(struct rte_mbuf, rx_descriptor_fields1) + 4);
+ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_len) !=
+ offsetof(struct rte_mbuf, rx_descriptor_fields1) + 8);
+ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, vlan_tci) !=
+ offsetof(struct rte_mbuf, rx_descriptor_fields1) + 10);
+ RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, hash) !=
+ offsetof(struct rte_mbuf, rx_descriptor_fields1) + 12);
+
+ /* Cache is empty -> need to scan the buffer rings, but first move
+ * the next 'n' mbufs into the cache
+ */
+ sw_ring = &rxq->sw_ring[rxq->rx_tail];
+
+ /* A. load 4 packet in one loop
+ * [A*. mask out 4 unused dirty field in desc]
+ * B. copy 4 mbuf point from swring to rx_pkts
+ * C. calc the number of DD bits among the 4 packets
+ * [C*. extract the end-of-packet bit, if requested]
+ * D. fill info. from desc to mbuf
+ */
+
+ for (pos = 0, nb_pkts_recd = 0; pos < nb_pkts;
+ pos += AVF_VPMD_DESCS_PER_LOOP,
+ rxdp += AVF_VPMD_DESCS_PER_LOOP) {
+ __m128i descs[AVF_VPMD_DESCS_PER_LOOP];
+ __m128i pkt_mb1, pkt_mb2, pkt_mb3, pkt_mb4;
+ __m128i zero, staterr, sterr_tmp1, sterr_tmp2;
+ /* 2 64 bit or 4 32 bit mbuf pointers in one XMM reg. */
+ __m128i mbp1;
+#if defined(RTE_ARCH_X86_64)
+ __m128i mbp2;
+#endif
+
+ /* B.1 load 2 (64 bit) or 4 (32 bit) mbuf points */
+ mbp1 = _mm_loadu_si128((__m128i *)&sw_ring[pos]);
+ /* Read desc statuses backwards to avoid race condition */
+ /* A.1 load 4 pkts desc */
+ descs[3] = _mm_loadu_si128((__m128i *)(rxdp + 3));
+ rte_compiler_barrier();
+
+ /* B.2 copy 2 64 bit or 4 32 bit mbuf point into rx_pkts */
+ _mm_storeu_si128((__m128i *)&rx_pkts[pos], mbp1);
+
+#if defined(RTE_ARCH_X86_64)
+ /* B.1 load 2 64 bit mbuf points */
+ mbp2 = _mm_loadu_si128((__m128i *)&sw_ring[pos + 2]);
+#endif
+
+ descs[2] = _mm_loadu_si128((__m128i *)(rxdp + 2));
+ rte_compiler_barrier();
+ /* B.1 load 2 mbuf point */
+ descs[1] = _mm_loadu_si128((__m128i *)(rxdp + 1));
+ rte_compiler_barrier();
+ descs[0] = _mm_loadu_si128((__m128i *)(rxdp));
+
+#if defined(RTE_ARCH_X86_64)
+ /* B.2 copy 2 mbuf point into rx_pkts */
+ _mm_storeu_si128((__m128i *)&rx_pkts[pos + 2], mbp2);
+#endif
+
+ if (split_packet) {
+ rte_mbuf_prefetch_part2(rx_pkts[pos]);
+ rte_mbuf_prefetch_part2(rx_pkts[pos + 1]);
+ rte_mbuf_prefetch_part2(rx_pkts[pos + 2]);
+ rte_mbuf_prefetch_part2(rx_pkts[pos + 3]);
+ }
+
+ /* avoid compiler reorder optimization */
+ rte_compiler_barrier();
+
+ /* pkt 3,4 shift the pktlen field to be 16-bit aligned*/
+ const __m128i len3 = _mm_slli_epi32(descs[3], PKTLEN_SHIFT);
+ const __m128i len2 = _mm_slli_epi32(descs[2], PKTLEN_SHIFT);
+
+ /* merge the now-aligned packet length fields back in */
+ descs[3] = _mm_blend_epi16(descs[3], len3, 0x80);
+ descs[2] = _mm_blend_epi16(descs[2], len2, 0x80);
+
+ /* D.1 pkt 3,4 convert format from desc to pktmbuf */
+ pkt_mb4 = _mm_shuffle_epi8(descs[3], shuf_msk);
+ pkt_mb3 = _mm_shuffle_epi8(descs[2], shuf_msk);
+
+ /* C.1 4=>2 status err info only */
+ sterr_tmp2 = _mm_unpackhi_epi32(descs[3], descs[2]);
+ sterr_tmp1 = _mm_unpackhi_epi32(descs[1], descs[0]);
+
+ desc_to_olflags_v(rxq, descs, &rx_pkts[pos]);
+
+ /* D.2 pkt 3,4 set in_port/nb_seg and remove crc */
+ pkt_mb4 = _mm_add_epi16(pkt_mb4, crc_adjust);
+ pkt_mb3 = _mm_add_epi16(pkt_mb3, crc_adjust);
+
+ /* pkt 1,2 shift the pktlen field to be 16-bit aligned*/
+ const __m128i len1 = _mm_slli_epi32(descs[1], PKTLEN_SHIFT);
+ const __m128i len0 = _mm_slli_epi32(descs[0], PKTLEN_SHIFT);
+
+ /* merge the now-aligned packet length fields back in */
+ descs[1] = _mm_blend_epi16(descs[1], len1, 0x80);
+ descs[0] = _mm_blend_epi16(descs[0], len0, 0x80);
+
+ /* D.1 pkt 1,2 convert format from desc to pktmbuf */
+ pkt_mb2 = _mm_shuffle_epi8(descs[1], shuf_msk);
+ pkt_mb1 = _mm_shuffle_epi8(descs[0], shuf_msk);
+
+ /* C.2 get 4 pkts status err value */
+ zero = _mm_xor_si128(dd_check, dd_check);
+ staterr = _mm_unpacklo_epi32(sterr_tmp1, sterr_tmp2);
+
+ /* D.3 copy final 3,4 data to rx_pkts */
+ _mm_storeu_si128(
+ (void *)&rx_pkts[pos + 3]->rx_descriptor_fields1,
+ pkt_mb4);
+ _mm_storeu_si128(
+ (void *)&rx_pkts[pos + 2]->rx_descriptor_fields1,
+ pkt_mb3);
+
+ /* D.2 pkt 1,2 remove crc */
+ pkt_mb2 = _mm_add_epi16(pkt_mb2, crc_adjust);
+ pkt_mb1 = _mm_add_epi16(pkt_mb1, crc_adjust);
+
+ /* C* extract and record EOP bit */
+ if (split_packet) {
+ __m128i eop_shuf_mask = _mm_set_epi8(
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF,
+ 0x04, 0x0C, 0x00, 0x08
+ );
+
+ /* and with mask to extract bits, flipping 1-0 */
+ __m128i eop_bits = _mm_andnot_si128(staterr, eop_check);
+ /* the staterr values are not in order, as the count
+ * count of dd bits doesn't care. However, for end of
+ * packet tracking, we do care, so shuffle. This also
+ * compresses the 32-bit values to 8-bit
+ */
+ eop_bits = _mm_shuffle_epi8(eop_bits, eop_shuf_mask);
+ /* store the resulting 32-bit value */
+ *(int *)split_packet = _mm_cvtsi128_si32(eop_bits);
+ split_packet += AVF_VPMD_DESCS_PER_LOOP;
+ }
+
+ /* C.3 calc available number of desc */
+ staterr = _mm_and_si128(staterr, dd_check);
+ staterr = _mm_packs_epi32(staterr, zero);
+
+ /* D.3 copy final 1,2 data to rx_pkts */
+ _mm_storeu_si128(
+ (void *)&rx_pkts[pos + 1]->rx_descriptor_fields1,
+ pkt_mb2);
+ _mm_storeu_si128((void *)&rx_pkts[pos]->rx_descriptor_fields1,
+ pkt_mb1);
+ desc_to_ptype_v(descs, &rx_pkts[pos]);
+ /* C.4 calc avaialbe number of desc */
+ var = __builtin_popcountll(_mm_cvtsi128_si64(staterr));
+ nb_pkts_recd += var;
+ if (likely(var != AVF_VPMD_DESCS_PER_LOOP))
+ break;
+ }
+
+ /* Update our internal tail pointer */
+ rxq->rx_tail = (uint16_t)(rxq->rx_tail + nb_pkts_recd);
+ rxq->rx_tail = (uint16_t)(rxq->rx_tail & (rxq->nb_rx_desc - 1));
+ rxq->rxrearm_nb = (uint16_t)(rxq->rxrearm_nb + nb_pkts_recd);
+
+ return nb_pkts_recd;
+}
+
+/* Notice:
+ * - nb_pkts < AVF_DESCS_PER_LOOP, just return no packet
+ * - nb_pkts > AVF_VPMD_RX_MAX_BURST, only scan AVF_VPMD_RX_MAX_BURST
+ * numbers of DD bits
+ */
+uint16_t
+avf_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
+ uint16_t nb_pkts)
+{
+ return _recv_raw_pkts_vec(rx_queue, rx_pkts, nb_pkts, NULL);
+}
+
+/* vPMD receive routine that reassembles scattered packets
+ * Notice:
+ * - nb_pkts < AVF_VPMD_DESCS_PER_LOOP, just return no packet
+ * - nb_pkts > VPMD_RX_MAX_BURST, only scan AVF_VPMD_RX_MAX_BURST
+ * numbers of DD bits
+ */
+uint16_t
+avf_recv_scattered_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
+ uint16_t nb_pkts)
+{
+ struct avf_rx_queue *rxq = rx_queue;
+ uint8_t split_flags[AVF_VPMD_RX_MAX_BURST] = {0};
+ unsigned int i = 0;
+
+ /* get some new buffers */
+ uint16_t nb_bufs = _recv_raw_pkts_vec(rxq, rx_pkts, nb_pkts,
+ split_flags);
+ if (nb_bufs == 0)
+ return 0;
+
+ /* happy day case, full burst + no packets to be joined */
+ const uint64_t *split_fl64 = (uint64_t *)split_flags;
+
+ if (!rxq->pkt_first_seg &&
+ split_fl64[0] == 0 && split_fl64[1] == 0 &&
+ split_fl64[2] == 0 && split_fl64[3] == 0)
+ return nb_bufs;
+
+ /* reassemble any packets that need reassembly*/
+ if (!rxq->pkt_first_seg) {
+ /* find the first split flag, and only reassemble then*/
+ while (i < nb_bufs && !split_flags[i])
+ i++;
+ if (i == nb_bufs)
+ return nb_bufs;
+ }
+ return i + reassemble_packets(rxq, &rx_pkts[i], nb_bufs - i,
+ &split_flags[i]);
+}
+
+static inline void
+vtx1(volatile struct avf_tx_desc *txdp, struct rte_mbuf *pkt, uint64_t flags)
+{
+ uint64_t high_qw =
+ (AVF_TX_DESC_DTYPE_DATA |
+ ((uint64_t)flags << AVF_TXD_QW1_CMD_SHIFT) |
+ ((uint64_t)pkt->data_len <<
+ AVF_TXD_QW1_TX_BUF_SZ_SHIFT));
+
+ __m128i descriptor = _mm_set_epi64x(high_qw,
+ pkt->buf_iova + pkt->data_off);
+ _mm_store_si128((__m128i *)txdp, descriptor);
+}
+
+static inline void
+avf_vtx(volatile struct avf_tx_desc *txdp, struct rte_mbuf **pkt,
+ uint16_t nb_pkts, uint64_t flags)
+{
+ int i;
+
+ for (i = 0; i < nb_pkts; ++i, ++txdp, ++pkt)
+ vtx1(txdp, *pkt, flags);
+}
+
+uint16_t
+avf_xmit_fixed_burst_vec(void *tx_queue, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts)
+{
+ struct avf_tx_queue *txq = (struct avf_tx_queue *)tx_queue;
+ volatile struct avf_tx_desc *txdp;
+ struct avf_tx_entry *txep;
+ uint16_t n, nb_commit, tx_id;
+ uint64_t flags = AVF_TX_DESC_CMD_EOP | 0x04; /* bit 2 must be set */
+ uint64_t rs = AVF_TX_DESC_CMD_RS | flags;
+ int i;
+
+ /* cross rx_thresh boundary is not allowed */
+ nb_pkts = RTE_MIN(nb_pkts, txq->rs_thresh);
+
+ if (txq->nb_free < txq->free_thresh)
+ avf_tx_free_bufs(txq);
+
+ nb_pkts = (uint16_t)RTE_MIN(txq->nb_free, nb_pkts);
+ if (unlikely(nb_pkts == 0))
+ return 0;
+ nb_commit = nb_pkts;
+
+ tx_id = txq->tx_tail;
+ txdp = &txq->tx_ring[tx_id];
+ txep = &txq->sw_ring[tx_id];
+
+ txq->nb_free = (uint16_t)(txq->nb_free - nb_pkts);
+
+ n = (uint16_t)(txq->nb_tx_desc - tx_id);
+ if (nb_commit >= n) {
+ tx_backlog_entry(txep, tx_pkts, n);
+
+ for (i = 0; i < n - 1; ++i, ++tx_pkts, ++txdp)
+ vtx1(txdp, *tx_pkts, flags);
+
+ vtx1(txdp, *tx_pkts++, rs);
+
+ nb_commit = (uint16_t)(nb_commit - n);
+
+ tx_id = 0;
+ txq->next_rs = (uint16_t)(txq->rs_thresh - 1);
+
+ /* avoid reach the end of ring */
+ txdp = &txq->tx_ring[tx_id];
+ txep = &txq->sw_ring[tx_id];
+ }
+
+ tx_backlog_entry(txep, tx_pkts, nb_commit);
+
+ avf_vtx(txdp, tx_pkts, nb_commit, flags);
+
+ tx_id = (uint16_t)(tx_id + nb_commit);
+ if (tx_id > txq->next_rs) {
+ txq->tx_ring[txq->next_rs].cmd_type_offset_bsz |=
+ rte_cpu_to_le_64(((uint64_t)AVF_TX_DESC_CMD_RS) <<
+ AVF_TXD_QW1_CMD_SHIFT);
+ txq->next_rs =
+ (uint16_t)(txq->next_rs + txq->rs_thresh);
+ }
+
+ txq->tx_tail = tx_id;
+
+ PMD_TX_LOG(DEBUG, "port_id=%u queue_id=%u tx_tail=%u nb_pkts=%u",
+ txq->port_id, txq->queue_id, tx_id, nb_pkts);
+
+ AVF_PCI_REG_WRITE(txq->qtx_tail, txq->tx_tail);
+
+ return nb_pkts;
+}
+
+static void __attribute__((cold))
+avf_rx_queue_release_mbufs_sse(struct avf_rx_queue *rxq)
+{
+ _avf_rx_queue_release_mbufs_vec(rxq);
+}
+
+static void __attribute__((cold))
+avf_tx_queue_release_mbufs_sse(struct avf_tx_queue *txq)
+{
+ _avf_tx_queue_release_mbufs_vec(txq);
+}
+
+static const struct avf_rxq_ops sse_vec_rxq_ops = {
+ .release_mbufs = avf_rx_queue_release_mbufs_sse,
+};
+
+static const struct avf_txq_ops sse_vec_txq_ops = {
+ .release_mbufs = avf_tx_queue_release_mbufs_sse,
+};
+
+int __attribute__((cold))
+avf_txq_vec_setup(struct avf_tx_queue *txq)
+{
+ txq->ops = &sse_vec_txq_ops;
+ return 0;
+}
+
+int __attribute__((cold))
+avf_rxq_vec_setup(struct avf_rx_queue *rxq)
+{
+ rxq->ops = &sse_vec_rxq_ops;
+ return avf_rxq_vec_setup_default(rxq);
+}
diff --git a/drivers/net/iavf/iavf_vchnl.c b/drivers/net/iavf/iavf_vchnl.c
new file mode 100644
index 0000000..9b62553
--- /dev/null
+++ b/drivers/net/iavf/iavf_vchnl.c
@@ -0,0 +1,810 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017 Intel Corporation
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <inttypes.h>
+#include <rte_byteorder.h>
+#include <rte_common.h>
+
+#include <rte_debug.h>
+#include <rte_atomic.h>
+#include <rte_eal.h>
+#include <rte_ether.h>
+#include <rte_ethdev_driver.h>
+#include <rte_dev.h>
+
+#include "iavf_log.h"
+#include "base/iavf_prototype.h"
+#include "base/iavf_adminq_cmd.h"
+#include "base/iavf_type.h"
+
+#include "iavf.h"
+#include "iavf_rxtx.h"
+
+#define MAX_TRY_TIMES 200
+#define ASQ_DELAY_MS 10
+
+/* Read data in admin queue to get msg from pf driver */
+static enum avf_status_code
+avf_read_msg_from_pf(struct avf_adapter *adapter, uint16_t buf_len,
+ uint8_t *buf)
+{
+ struct avf_hw *hw = AVF_DEV_PRIVATE_TO_HW(adapter);
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ struct avf_arq_event_info event;
+ enum virtchnl_ops opcode;
+ int ret;
+
+ event.buf_len = buf_len;
+ event.msg_buf = buf;
+ ret = avf_clean_arq_element(hw, &event, NULL);
+ /* Can't read any msg from adminQ */
+ if (ret) {
+ PMD_DRV_LOG(DEBUG, "Can't read msg from AQ");
+ return ret;
+ }
+
+ opcode = (enum virtchnl_ops)rte_le_to_cpu_32(event.desc.cookie_high);
+ vf->cmd_retval = (enum virtchnl_status_code)rte_le_to_cpu_32(
+ event.desc.cookie_low);
+
+ PMD_DRV_LOG(DEBUG, "AQ from pf carries opcode %u, retval %d",
+ opcode, vf->cmd_retval);
+
+ if (opcode != vf->pend_cmd)
+ PMD_DRV_LOG(WARNING, "command mismatch, expect %u, get %u",
+ vf->pend_cmd, opcode);
+
+ return AVF_SUCCESS;
+}
+
+static int
+avf_execute_vf_cmd(struct avf_adapter *adapter, struct avf_cmd_info *args)
+{
+ struct avf_hw *hw = AVF_DEV_PRIVATE_TO_HW(adapter);
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ enum avf_status_code ret;
+ int err = 0;
+ int i = 0;
+
+ if (_atomic_set_cmd(vf, args->ops))
+ return -1;
+
+ ret = avf_aq_send_msg_to_pf(hw, args->ops, AVF_SUCCESS,
+ args->in_args, args->in_args_size, NULL);
+ if (ret) {
+ PMD_DRV_LOG(ERR, "fail to send cmd %d", args->ops);
+ _clear_cmd(vf);
+ return err;
+ }
+
+ switch (args->ops) {
+ case VIRTCHNL_OP_RESET_VF:
+ /*no need to wait for response */
+ _clear_cmd(vf);
+ break;
+ case VIRTCHNL_OP_VERSION:
+ case VIRTCHNL_OP_GET_VF_RESOURCES:
+ /* for init virtchnl ops, need to poll the response */
+ do {
+ ret = avf_read_msg_from_pf(adapter, args->out_size,
+ args->out_buffer);
+ if (ret == AVF_SUCCESS)
+ break;
+ rte_delay_ms(ASQ_DELAY_MS);
+ } while (i++ < MAX_TRY_TIMES);
+ if (i >= MAX_TRY_TIMES ||
+ vf->cmd_retval != VIRTCHNL_STATUS_SUCCESS) {
+ err = -1;
+ PMD_DRV_LOG(ERR, "No response or return failure (%d)"
+ " for cmd %d", vf->cmd_retval, args->ops);
+ }
+ _clear_cmd(vf);
+ break;
+
+ default:
+ /* For other virtchnl ops in running time,
+ * wait for the cmd done flag.
+ */
+ do {
+ if (vf->pend_cmd == VIRTCHNL_OP_UNKNOWN)
+ break;
+ rte_delay_ms(ASQ_DELAY_MS);
+ /* If don't read msg or read sys event, continue */
+ } while (i++ < MAX_TRY_TIMES);
+ /* If there's no response is received, clear command */
+ if (i >= MAX_TRY_TIMES ||
+ vf->cmd_retval != VIRTCHNL_STATUS_SUCCESS) {
+ err = -1;
+ PMD_DRV_LOG(ERR, "No response or return failure (%d)"
+ " for cmd %d", vf->cmd_retval, args->ops);
+ _clear_cmd(vf);
+ }
+ break;
+ }
+
+ return err;
+}
+
+static void
+avf_handle_pf_event_msg(struct rte_eth_dev *dev, uint8_t *msg,
+ uint16_t msglen)
+{
+ struct virtchnl_pf_event *pf_msg =
+ (struct virtchnl_pf_event *)msg;
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+
+ if (msglen < sizeof(struct virtchnl_pf_event)) {
+ PMD_DRV_LOG(DEBUG, "Error event");
+ return;
+ }
+ switch (pf_msg->event) {
+ case VIRTCHNL_EVENT_RESET_IMPENDING:
+ PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_RESET_IMPENDING event");
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET,
+ NULL);
+ break;
+ case VIRTCHNL_EVENT_LINK_CHANGE:
+ PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_LINK_CHANGE event");
+ vf->link_up = pf_msg->event_data.link_event.link_status;
+ vf->link_speed = pf_msg->event_data.link_event.link_speed;
+ avf_dev_link_update(dev, 0);
+ _rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC,
+ NULL);
+ break;
+ case VIRTCHNL_EVENT_PF_DRIVER_CLOSE:
+ PMD_DRV_LOG(DEBUG, "VIRTCHNL_EVENT_PF_DRIVER_CLOSE event");
+ break;
+ default:
+ PMD_DRV_LOG(ERR, " unknown event received %u", pf_msg->event);
+ break;
+ }
+}
+
+void
+avf_handle_virtchnl_msg(struct rte_eth_dev *dev)
+{
+ struct avf_hw *hw = AVF_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+ struct avf_arq_event_info info;
+ uint16_t pending, aq_opc;
+ enum virtchnl_ops msg_opc;
+ enum avf_status_code msg_ret;
+ int ret;
+
+ info.buf_len = AVF_AQ_BUF_SZ;
+ if (!vf->aq_resp) {
+ PMD_DRV_LOG(ERR, "Buffer for adminq resp should not be NULL");
+ return;
+ }
+ info.msg_buf = vf->aq_resp;
+
+ pending = 1;
+ while (pending) {
+ ret = avf_clean_arq_element(hw, &info, &pending);
+
+ if (ret != AVF_SUCCESS) {
+ PMD_DRV_LOG(INFO, "Failed to read msg from AdminQ,"
+ "ret: %d", ret);
+ break;
+ }
+ aq_opc = rte_le_to_cpu_16(info.desc.opcode);
+ /* For the message sent from pf to vf, opcode is stored in
+ * cookie_high of struct avf_aq_desc, while return error code
+ * are stored in cookie_low, Which is done by PF driver.
+ */
+ msg_opc = (enum virtchnl_ops)rte_le_to_cpu_32(
+ info.desc.cookie_high);
+ msg_ret = (enum avf_status_code)rte_le_to_cpu_32(
+ info.desc.cookie_low);
+ switch (aq_opc) {
+ case avf_aqc_opc_send_msg_to_vf:
+ if (msg_opc == VIRTCHNL_OP_EVENT) {
+ avf_handle_pf_event_msg(dev, info.msg_buf,
+ info.msg_len);
+ } else {
+ /* read message and it's expected one */
+ if (msg_opc == vf->pend_cmd) {
+ vf->cmd_retval = msg_ret;
+ /* prevent compiler reordering */
+ rte_compiler_barrier();
+ _clear_cmd(vf);
+ } else
+ PMD_DRV_LOG(ERR, "command mismatch,"
+ "expect %u, get %u",
+ vf->pend_cmd, msg_opc);
+ PMD_DRV_LOG(DEBUG,
+ "adminq response is received,"
+ " opcode = %d", msg_opc);
+ }
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "Request %u is not supported yet",
+ aq_opc);
+ break;
+ }
+ }
+}
+
+int
+avf_enable_vlan_strip(struct avf_adapter *adapter)
+{
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ struct avf_cmd_info args;
+ int ret;
+
+ memset(&args, 0, sizeof(args));
+ args.ops = VIRTCHNL_OP_ENABLE_VLAN_STRIPPING;
+ args.in_args = NULL;
+ args.in_args_size = 0;
+ args.out_buffer = vf->aq_resp;
+ args.out_size = AVF_AQ_BUF_SZ;
+ ret = avf_execute_vf_cmd(adapter, &args);
+ if (ret)
+ PMD_DRV_LOG(ERR, "Failed to execute command of"
+ " OP_ENABLE_VLAN_STRIPPING");
+
+ return ret;
+}
+
+int
+avf_disable_vlan_strip(struct avf_adapter *adapter)
+{
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ struct avf_cmd_info args;
+ int ret;
+
+ memset(&args, 0, sizeof(args));
+ args.ops = VIRTCHNL_OP_DISABLE_VLAN_STRIPPING;
+ args.in_args = NULL;
+ args.in_args_size = 0;
+ args.out_buffer = vf->aq_resp;
+ args.out_size = AVF_AQ_BUF_SZ;
+ ret = avf_execute_vf_cmd(adapter, &args);
+ if (ret)
+ PMD_DRV_LOG(ERR, "Failed to execute command of"
+ " OP_DISABLE_VLAN_STRIPPING");
+
+ return ret;
+}
+
+#define VIRTCHNL_VERSION_MAJOR_START 1
+#define VIRTCHNL_VERSION_MINOR_START 1
+
+/* Check API version with sync wait until version read from admin queue */
+int
+avf_check_api_version(struct avf_adapter *adapter)
+{
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ struct virtchnl_version_info version, *pver;
+ struct avf_cmd_info args;
+ int err;
+
+ version.major = VIRTCHNL_VERSION_MAJOR;
+ version.minor = VIRTCHNL_VERSION_MINOR;
+
+ args.ops = VIRTCHNL_OP_VERSION;
+ args.in_args = (uint8_t *)&version;
+ args.in_args_size = sizeof(version);
+ args.out_buffer = vf->aq_resp;
+ args.out_size = AVF_AQ_BUF_SZ;
+
+ err = avf_execute_vf_cmd(adapter, &args);
+ if (err) {
+ PMD_INIT_LOG(ERR, "Fail to execute command of OP_VERSION");
+ return err;
+ }
+
+ pver = (struct virtchnl_version_info *)args.out_buffer;
+ vf->virtchnl_version = *pver;
+
+ if (vf->virtchnl_version.major < VIRTCHNL_VERSION_MAJOR_START ||
+ (vf->virtchnl_version.major == VIRTCHNL_VERSION_MAJOR_START &&
+ vf->virtchnl_version.minor < VIRTCHNL_VERSION_MINOR_START)) {
+ PMD_INIT_LOG(ERR, "VIRTCHNL API version should not be lower"
+ " than (%u.%u) to support Adapative VF",
+ VIRTCHNL_VERSION_MAJOR_START,
+ VIRTCHNL_VERSION_MAJOR_START);
+ return -1;
+ } else if (vf->virtchnl_version.major > VIRTCHNL_VERSION_MAJOR ||
+ (vf->virtchnl_version.major == VIRTCHNL_VERSION_MAJOR &&
+ vf->virtchnl_version.minor > VIRTCHNL_VERSION_MINOR)) {
+ PMD_INIT_LOG(ERR, "PF/VF API version mismatch:(%u.%u)-(%u.%u)",
+ vf->virtchnl_version.major,
+ vf->virtchnl_version.minor,
+ VIRTCHNL_VERSION_MAJOR,
+ VIRTCHNL_VERSION_MINOR);
+ return -1;
+ }
+
+ PMD_DRV_LOG(DEBUG, "Peer is supported PF host");
+ return 0;
+}
+
+int
+avf_get_vf_resource(struct avf_adapter *adapter)
+{
+ struct avf_hw *hw = AVF_DEV_PRIVATE_TO_HW(adapter);
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ struct avf_cmd_info args;
+ uint32_t caps, len;
+ int err, i;
+
+ args.ops = VIRTCHNL_OP_GET_VF_RESOURCES;
+ args.out_buffer = vf->aq_resp;
+ args.out_size = AVF_AQ_BUF_SZ;
+
+ /* TODO: basic offload capabilities, need to
+ * add advanced/optional offload capabilities
+ */
+
+ caps = AVF_BASIC_OFFLOAD_CAPS;
+
+ args.in_args = (uint8_t *)&caps;
+ args.in_args_size = sizeof(caps);
+
+ err = avf_execute_vf_cmd(adapter, &args);
+
+ if (err) {
+ PMD_DRV_LOG(ERR,
+ "Failed to execute command of OP_GET_VF_RESOURCE");
+ return -1;
+ }
+
+ len = sizeof(struct virtchnl_vf_resource) +
+ AVF_MAX_VF_VSI * sizeof(struct virtchnl_vsi_resource);
+
+ rte_memcpy(vf->vf_res, args.out_buffer,
+ RTE_MIN(args.out_size, len));
+ /* parse VF config message back from PF*/
+ avf_parse_hw_config(hw, vf->vf_res);
+ for (i = 0; i < vf->vf_res->num_vsis; i++) {
+ if (vf->vf_res->vsi_res[i].vsi_type == VIRTCHNL_VSI_SRIOV)
+ vf->vsi_res = &vf->vf_res->vsi_res[i];
+ }
+
+ if (!vf->vsi_res) {
+ PMD_INIT_LOG(ERR, "no LAN VSI found");
+ return -1;
+ }
+
+ vf->vsi.vsi_id = vf->vsi_res->vsi_id;
+ vf->vsi.nb_qps = vf->vsi_res->num_queue_pairs;
+ vf->vsi.adapter = adapter;
+
+ return 0;
+}
+
+int
+avf_enable_queues(struct avf_adapter *adapter)
+{
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ struct virtchnl_queue_select queue_select;
+ struct avf_cmd_info args;
+ int err;
+
+ memset(&queue_select, 0, sizeof(queue_select));
+ queue_select.vsi_id = vf->vsi_res->vsi_id;
+
+ queue_select.rx_queues = BIT(adapter->eth_dev->data->nb_rx_queues) - 1;
+ queue_select.tx_queues = BIT(adapter->eth_dev->data->nb_tx_queues) - 1;
+
+ args.ops = VIRTCHNL_OP_ENABLE_QUEUES;
+ args.in_args = (u8 *)&queue_select;
+ args.in_args_size = sizeof(queue_select);
+ args.out_buffer = vf->aq_resp;
+ args.out_size = AVF_AQ_BUF_SZ;
+ err = avf_execute_vf_cmd(adapter, &args);
+ if (err) {
+ PMD_DRV_LOG(ERR,
+ "Failed to execute command of OP_ENABLE_QUEUES");
+ return err;
+ }
+ return 0;
+}
+
+int
+avf_disable_queues(struct avf_adapter *adapter)
+{
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ struct virtchnl_queue_select queue_select;
+ struct avf_cmd_info args;
+ int err;
+
+ memset(&queue_select, 0, sizeof(queue_select));
+ queue_select.vsi_id = vf->vsi_res->vsi_id;
+
+ queue_select.rx_queues = BIT(adapter->eth_dev->data->nb_rx_queues) - 1;
+ queue_select.tx_queues = BIT(adapter->eth_dev->data->nb_tx_queues) - 1;
+
+ args.ops = VIRTCHNL_OP_DISABLE_QUEUES;
+ args.in_args = (u8 *)&queue_select;
+ args.in_args_size = sizeof(queue_select);
+ args.out_buffer = vf->aq_resp;
+ args.out_size = AVF_AQ_BUF_SZ;
+ err = avf_execute_vf_cmd(adapter, &args);
+ if (err) {
+ PMD_DRV_LOG(ERR,
+ "Failed to execute command of OP_DISABLE_QUEUES");
+ return err;
+ }
+ return 0;
+}
+
+int
+avf_switch_queue(struct avf_adapter *adapter, uint16_t qid,
+ bool rx, bool on)
+{
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ struct virtchnl_queue_select queue_select;
+ struct avf_cmd_info args;
+ int err;
+
+ memset(&queue_select, 0, sizeof(queue_select));
+ queue_select.vsi_id = vf->vsi_res->vsi_id;
+ if (rx)
+ queue_select.rx_queues |= 1 << qid;
+ else
+ queue_select.tx_queues |= 1 << qid;
+
+ if (on)
+ args.ops = VIRTCHNL_OP_ENABLE_QUEUES;
+ else
+ args.ops = VIRTCHNL_OP_DISABLE_QUEUES;
+ args.in_args = (u8 *)&queue_select;
+ args.in_args_size = sizeof(queue_select);
+ args.out_buffer = vf->aq_resp;
+ args.out_size = AVF_AQ_BUF_SZ;
+ err = avf_execute_vf_cmd(adapter, &args);
+ if (err)
+ PMD_DRV_LOG(ERR, "Failed to execute command of %s",
+ on ? "OP_ENABLE_QUEUES" : "OP_DISABLE_QUEUES");
+ return err;
+}
+
+int
+avf_configure_rss_lut(struct avf_adapter *adapter)
+{
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ struct virtchnl_rss_lut *rss_lut;
+ struct avf_cmd_info args;
+ int len, err = 0;
+
+ len = sizeof(*rss_lut) + vf->vf_res->rss_lut_size - 1;
+ rss_lut = rte_zmalloc("rss_lut", len, 0);
+ if (!rss_lut)
+ return -ENOMEM;
+
+ rss_lut->vsi_id = vf->vsi_res->vsi_id;
+ rss_lut->lut_entries = vf->vf_res->rss_lut_size;
+ rte_memcpy(rss_lut->lut, vf->rss_lut, vf->vf_res->rss_lut_size);
+
+ args.ops = VIRTCHNL_OP_CONFIG_RSS_LUT;
+ args.in_args = (u8 *)rss_lut;
+ args.in_args_size = len;
+ args.out_buffer = vf->aq_resp;
+ args.out_size = AVF_AQ_BUF_SZ;
+
+ err = avf_execute_vf_cmd(adapter, &args);
+ if (err)
+ PMD_DRV_LOG(ERR,
+ "Failed to execute command of OP_CONFIG_RSS_LUT");
+
+ rte_free(rss_lut);
+ return err;
+}
+
+int
+avf_configure_rss_key(struct avf_adapter *adapter)
+{
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ struct virtchnl_rss_key *rss_key;
+ struct avf_cmd_info args;
+ int len, err = 0;
+
+ len = sizeof(*rss_key) + vf->vf_res->rss_key_size - 1;
+ rss_key = rte_zmalloc("rss_key", len, 0);
+ if (!rss_key)
+ return -ENOMEM;
+
+ rss_key->vsi_id = vf->vsi_res->vsi_id;
+ rss_key->key_len = vf->vf_res->rss_key_size;
+ rte_memcpy(rss_key->key, vf->rss_key, vf->vf_res->rss_key_size);
+
+ args.ops = VIRTCHNL_OP_CONFIG_RSS_KEY;
+ args.in_args = (u8 *)rss_key;
+ args.in_args_size = len;
+ args.out_buffer = vf->aq_resp;
+ args.out_size = AVF_AQ_BUF_SZ;
+
+ err = avf_execute_vf_cmd(adapter, &args);
+ if (err)
+ PMD_DRV_LOG(ERR,
+ "Failed to execute command of OP_CONFIG_RSS_KEY");
+
+ rte_free(rss_key);
+ return err;
+}
+
+int
+avf_configure_queues(struct avf_adapter *adapter)
+{
+ struct avf_rx_queue **rxq =
+ (struct avf_rx_queue **)adapter->eth_dev->data->rx_queues;
+ struct avf_tx_queue **txq =
+ (struct avf_tx_queue **)adapter->eth_dev->data->tx_queues;
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ struct virtchnl_vsi_queue_config_info *vc_config;
+ struct virtchnl_queue_pair_info *vc_qp;
+ struct avf_cmd_info args;
+ uint16_t i, size;
+ int err;
+
+ size = sizeof(*vc_config) +
+ sizeof(vc_config->qpair[0]) * vf->num_queue_pairs;
+ vc_config = rte_zmalloc("cfg_queue", size, 0);
+ if (!vc_config)
+ return -ENOMEM;
+
+ vc_config->vsi_id = vf->vsi_res->vsi_id;
+ vc_config->num_queue_pairs = vf->num_queue_pairs;
+
+ for (i = 0, vc_qp = vc_config->qpair;
+ i < vf->num_queue_pairs;
+ i++, vc_qp++) {
+ vc_qp->txq.vsi_id = vf->vsi_res->vsi_id;
+ vc_qp->txq.queue_id = i;
+ /* Virtchnnl configure queues by pairs */
+ if (i < adapter->eth_dev->data->nb_tx_queues) {
+ vc_qp->txq.ring_len = txq[i]->nb_tx_desc;
+ vc_qp->txq.dma_ring_addr = txq[i]->tx_ring_phys_addr;
+ }
+ vc_qp->rxq.vsi_id = vf->vsi_res->vsi_id;
+ vc_qp->rxq.queue_id = i;
+ vc_qp->rxq.max_pkt_size = vf->max_pkt_len;
+ /* Virtchnnl configure queues by pairs */
+ if (i < adapter->eth_dev->data->nb_rx_queues) {
+ vc_qp->rxq.ring_len = rxq[i]->nb_rx_desc;
+ vc_qp->rxq.dma_ring_addr = rxq[i]->rx_ring_phys_addr;
+ vc_qp->rxq.databuffer_size = rxq[i]->rx_buf_len;
+ }
+ }
+
+ memset(&args, 0, sizeof(args));
+ args.ops = VIRTCHNL_OP_CONFIG_VSI_QUEUES;
+ args.in_args = (uint8_t *)vc_config;
+ args.in_args_size = size;
+ args.out_buffer = vf->aq_resp;
+ args.out_size = AVF_AQ_BUF_SZ;
+
+ err = avf_execute_vf_cmd(adapter, &args);
+ if (err)
+ PMD_DRV_LOG(ERR, "Failed to execute command of"
+ " VIRTCHNL_OP_CONFIG_VSI_QUEUES");
+
+ rte_free(vc_config);
+ return err;
+}
+
+int
+avf_config_irq_map(struct avf_adapter *adapter)
+{
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ struct virtchnl_irq_map_info *map_info;
+ struct virtchnl_vector_map *vecmap;
+ struct avf_cmd_info args;
+ int len, i, err;
+
+ len = sizeof(struct virtchnl_irq_map_info) +
+ sizeof(struct virtchnl_vector_map) * vf->nb_msix;
+
+ map_info = rte_zmalloc("map_info", len, 0);
+ if (!map_info)
+ return -ENOMEM;
+
+ map_info->num_vectors = vf->nb_msix;
+ for (i = 0; i < vf->nb_msix; i++) {
+ vecmap = &map_info->vecmap[i];
+ vecmap->vsi_id = vf->vsi_res->vsi_id;
+ vecmap->rxitr_idx = AVF_ITR_INDEX_DEFAULT;
+ vecmap->vector_id = vf->msix_base + i;
+ vecmap->txq_map = 0;
+ vecmap->rxq_map = vf->rxq_map[vf->msix_base + i];
+ }
+
+ args.ops = VIRTCHNL_OP_CONFIG_IRQ_MAP;
+ args.in_args = (u8 *)map_info;
+ args.in_args_size = len;
+ args.out_buffer = vf->aq_resp;
+ args.out_size = AVF_AQ_BUF_SZ;
+ err = avf_execute_vf_cmd(adapter, &args);
+ if (err)
+ PMD_DRV_LOG(ERR, "fail to execute command OP_CONFIG_IRQ_MAP");
+
+ rte_free(map_info);
+ return err;
+}
+
+void
+avf_add_del_all_mac_addr(struct avf_adapter *adapter, bool add)
+{
+ struct virtchnl_ether_addr_list *list;
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ struct ether_addr *addr;
+ struct avf_cmd_info args;
+ int len, err, i, j;
+ int next_begin = 0;
+ int begin = 0;
+
+ do {
+ j = 0;
+ len = sizeof(struct virtchnl_ether_addr_list);
+ for (i = begin; i < AVF_NUM_MACADDR_MAX; i++, next_begin++) {
+ addr = &adapter->eth_dev->data->mac_addrs[i];
+ if (is_zero_ether_addr(addr))
+ continue;
+ len += sizeof(struct virtchnl_ether_addr);
+ if (len >= AVF_AQ_BUF_SZ) {
+ next_begin = i + 1;
+ break;
+ }
+ }
+
+ list = rte_zmalloc("avf_del_mac_buffer", len, 0);
+ if (!list) {
+ PMD_DRV_LOG(ERR, "fail to allocate memory");
+ return;
+ }
+
+ for (i = begin; i < next_begin; i++) {
+ addr = &adapter->eth_dev->data->mac_addrs[i];
+ if (is_zero_ether_addr(addr))
+ continue;
+ rte_memcpy(list->list[j].addr, addr->addr_bytes,
+ sizeof(addr->addr_bytes));
+ PMD_DRV_LOG(DEBUG, "add/rm mac:%x:%x:%x:%x:%x:%x",
+ addr->addr_bytes[0], addr->addr_bytes[1],
+ addr->addr_bytes[2], addr->addr_bytes[3],
+ addr->addr_bytes[4], addr->addr_bytes[5]);
+ j++;
+ }
+ list->vsi_id = vf->vsi_res->vsi_id;
+ list->num_elements = j;
+ args.ops = add ? VIRTCHNL_OP_ADD_ETH_ADDR :
+ VIRTCHNL_OP_DEL_ETH_ADDR;
+ args.in_args = (uint8_t *)list;
+ args.in_args_size = len;
+ args.out_buffer = vf->aq_resp;
+ args.out_size = AVF_AQ_BUF_SZ;
+ err = avf_execute_vf_cmd(adapter, &args);
+ if (err)
+ PMD_DRV_LOG(ERR, "fail to execute command %s",
+ add ? "OP_ADD_ETHER_ADDRESS" :
+ "OP_DEL_ETHER_ADDRESS");
+ rte_free(list);
+ begin = next_begin;
+ } while (begin < AVF_NUM_MACADDR_MAX);
+}
+
+int
+avf_query_stats(struct avf_adapter *adapter,
+ struct virtchnl_eth_stats **pstats)
+{
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ struct virtchnl_queue_select q_stats;
+ struct avf_cmd_info args;
+ int err;
+
+ memset(&q_stats, 0, sizeof(q_stats));
+ q_stats.vsi_id = vf->vsi_res->vsi_id;
+ args.ops = VIRTCHNL_OP_GET_STATS;
+ args.in_args = (uint8_t *)&q_stats;
+ args.in_args_size = sizeof(q_stats);
+ args.out_buffer = vf->aq_resp;
+ args.out_size = AVF_AQ_BUF_SZ;
+
+ err = avf_execute_vf_cmd(adapter, &args);
+ if (err) {
+ PMD_DRV_LOG(ERR, "fail to execute command OP_GET_STATS");
+ *pstats = NULL;
+ return err;
+ }
+ *pstats = (struct virtchnl_eth_stats *)args.out_buffer;
+ return 0;
+}
+
+int
+avf_config_promisc(struct avf_adapter *adapter,
+ bool enable_unicast,
+ bool enable_multicast)
+{
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ struct virtchnl_promisc_info promisc;
+ struct avf_cmd_info args;
+ int err;
+
+ promisc.flags = 0;
+ promisc.vsi_id = vf->vsi_res->vsi_id;
+
+ if (enable_unicast)
+ promisc.flags |= FLAG_VF_UNICAST_PROMISC;
+
+ if (enable_multicast)
+ promisc.flags |= FLAG_VF_MULTICAST_PROMISC;
+
+ args.ops = VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE;
+ args.in_args = (uint8_t *)&promisc;
+ args.in_args_size = sizeof(promisc);
+ args.out_buffer = vf->aq_resp;
+ args.out_size = AVF_AQ_BUF_SZ;
+
+ err = avf_execute_vf_cmd(adapter, &args);
+
+ if (err)
+ PMD_DRV_LOG(ERR,
+ "fail to execute command CONFIG_PROMISCUOUS_MODE");
+ return err;
+}
+
+int
+avf_add_del_eth_addr(struct avf_adapter *adapter, struct ether_addr *addr,
+ bool add)
+{
+ struct virtchnl_ether_addr_list *list;
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ uint8_t cmd_buffer[sizeof(struct virtchnl_ether_addr_list) +
+ sizeof(struct virtchnl_ether_addr)];
+ struct avf_cmd_info args;
+ int err;
+
+ list = (struct virtchnl_ether_addr_list *)cmd_buffer;
+ list->vsi_id = vf->vsi_res->vsi_id;
+ list->num_elements = 1;
+ rte_memcpy(list->list[0].addr, addr->addr_bytes,
+ sizeof(addr->addr_bytes));
+
+ args.ops = add ? VIRTCHNL_OP_ADD_ETH_ADDR : VIRTCHNL_OP_DEL_ETH_ADDR;
+ args.in_args = cmd_buffer;
+ args.in_args_size = sizeof(cmd_buffer);
+ args.out_buffer = vf->aq_resp;
+ args.out_size = AVF_AQ_BUF_SZ;
+ err = avf_execute_vf_cmd(adapter, &args);
+ if (err)
+ PMD_DRV_LOG(ERR, "fail to execute command %s",
+ add ? "OP_ADD_ETH_ADDR" : "OP_DEL_ETH_ADDR");
+ return err;
+}
+
+int
+avf_add_del_vlan(struct avf_adapter *adapter, uint16_t vlanid, bool add)
+{
+ struct virtchnl_vlan_filter_list *vlan_list;
+ struct avf_info *vf = AVF_DEV_PRIVATE_TO_VF(adapter);
+ uint8_t cmd_buffer[sizeof(struct virtchnl_vlan_filter_list) +
+ sizeof(uint16_t)];
+ struct avf_cmd_info args;
+ int err;
+
+ vlan_list = (struct virtchnl_vlan_filter_list *)cmd_buffer;
+ vlan_list->vsi_id = vf->vsi_res->vsi_id;
+ vlan_list->num_elements = 1;
+ vlan_list->vlan_id[0] = vlanid;
+
+ args.ops = add ? VIRTCHNL_OP_ADD_VLAN : VIRTCHNL_OP_DEL_VLAN;
+ args.in_args = cmd_buffer;
+ args.in_args_size = sizeof(cmd_buffer);
+ args.out_buffer = vf->aq_resp;
+ args.out_size = AVF_AQ_BUF_SZ;
+ err = avf_execute_vf_cmd(adapter, &args);
+ if (err)
+ PMD_DRV_LOG(ERR, "fail to execute command %s",
+ add ? "OP_ADD_VLAN" : "OP_DEL_VLAN");
+
+ return err;
+}
diff --git a/drivers/net/iavf/meson.build b/drivers/net/iavf/meson.build
new file mode 100644
index 0000000..bc22ad1
--- /dev/null
+++ b/drivers/net/iavf/meson.build
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2018 Luca Boccassi <bluca@debian.org>
+
+cflags += ['-Wno-strict-aliasing']
+
+allow_experimental_apis = true
+
+subdir('base')
+objs = [base_objs]
+
+sources = files(
+ 'iavf_ethdev.c',
+ 'iavf_rxtx.c',
+ 'iavf_vchnl.c',
+)
+
+if arch_subdir == 'x86'
+ dpdk_conf.set('RTE_LIBRTE_AVF_INC_VECTOR', 1)
+ sources += files('iavf_rxtx_vec_sse.c')
+endif
diff --git a/drivers/net/iavf/rte_pmd_iavf_version.map b/drivers/net/iavf/rte_pmd_iavf_version.map
new file mode 100644
index 0000000..179140f
--- /dev/null
+++ b/drivers/net/iavf/rte_pmd_iavf_version.map
@@ -0,0 +1,4 @@
+DPDK_18.02 {
+
+ local: *;
+};